-
-
Notifications
You must be signed in to change notification settings - Fork 265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add pragma(musttail) #4366
base: master
Are you sure you want to change the base?
Add pragma(musttail) #4366
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -841,7 +841,8 @@ static LLValue *DtoCallableValue(llvm::FunctionType * ft,DValue *fn) { | |
|
||
// FIXME: this function is a mess ! | ||
DValue *DtoCallFunction(const Loc &loc, Type *resulttype, DValue *fnval, | ||
Expressions *arguments, LLValue *sretPointer) { | ||
Expressions *arguments, LLValue *sretPointer, | ||
bool isMustTail) { | ||
IF_LOG Logger::println("DtoCallFunction()"); | ||
LOG_SCOPE | ||
|
||
|
@@ -1065,6 +1066,18 @@ DValue *DtoCallFunction(const Loc &loc, Type *resulttype, DValue *fnval, | |
llvm::AttrBuilder(call->getAttributes(), LLAttributeList::FunctionIndex)); | ||
#endif | ||
call->setAttributes(attrlist); | ||
if (isMustTail) { | ||
if (auto ci = llvm::dyn_cast<llvm::CallInst>(call)) { | ||
ci->setTailCallKind(llvm::CallInst::TCK_MustTail); | ||
} else { | ||
if (!tf->isnothrow()) { | ||
error(loc, "cannot perform tail-call - callee must be nothrow"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can this error not be caught during semantic analysis? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where in semantic can I check this? I'm not really familiar with the code. |
||
} else { | ||
error(loc, "cannot perform tail-call - no code like destructors or scope(exit) should run after the call"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above, can this error not be caught during semantic analysis? |
||
} | ||
fatal(); | ||
} | ||
} | ||
|
||
// Special case for struct constructor calls: For temporaries, using the | ||
// this pointer value returned from the constructor instead of the alloca | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Tests successfull musttail application | ||
|
||
// RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll | ||
|
||
// CHECK-LABEL: define{{.*}} @{{.*}}foo | ||
int foo(int x) nothrow | ||
{ | ||
// CHECK: musttail call{{.*}} @{{.*}}bar | ||
// CHECK-NEXT: ret i32 | ||
pragma(musttail) return bar(x); | ||
} | ||
|
||
// CHECK-LABEL: define{{.*}} @{{.*}}bar | ||
int bar(int x) nothrow { return x; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a frontend file too (everything in
dmd/
), soIN_LLVM
again. Note that there's aIN_LLVM
global/enum somewhere too, so that it's easy to use inif
expressions.And
version (IN_LLVM)
forpragmaMustTailSemantic()
below too.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should non-ldc compilers do for this pragma? Will this file be syncronized with dmd at some point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upstreaming our frontend diff is probably not realistic; some of it are hacks, and some others really totally LDC-specific and would just clutter the DMD frontend IMO. If another compiler supported it, we'd upstream a proper semantic for the new pragma though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clutter is meaningless versus the asymptotic cost of complexity - it should be upstreamed. LDC is the real D compiler, the codebase should be honest about that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slightly less abstract: we should get a way upstream for there to no more IN_LLVM and so on other than registering a behaviour (and not "just override a weak symbol")