diff options
author | Francis Visoiu Mistrih <francisvm@yahoo.com> | 2019-10-08 22:10:38 +0000 |
---|---|---|
committer | Francis Visoiu Mistrih <francisvm@yahoo.com> | 2019-10-08 22:10:38 +0000 |
commit | 143f6b837790dd695c140c0cc6c5164ec54e0c0e (patch) | |
tree | f3514d0c3a6f1d36d5a327f2aa1fee966ed368c3 /clang/lib/CodeGen | |
parent | d5f92e345cb6780d01debdcbfe56fe5720d8d50b (diff) | |
download | bcm5719-llvm-143f6b837790dd695c140c0cc6c5164ec54e0c0e.tar.gz bcm5719-llvm-143f6b837790dd695c140c0cc6c5164ec54e0c0e.zip |
[IRGen] Emit lifetime markers for temporary struct allocas
When passing arguments using temporary allocas, we need to add the
appropriate lifetime markers so that the stack coloring passes can
re-use the stack space.
This patch keeps track of all the lifetime.start calls emited before the
codegened call, and adds the corresponding lifetime.end calls after the
call.
Differential Revision: https://reviews.llvm.org/D68611
llvm-svn: 374126
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index b016b46acfe..682a7ccb493 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -3878,6 +3878,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, Address swiftErrorTemp = Address::invalid(); Address swiftErrorArg = Address::invalid(); + // When passing arguments using temporary allocas, we need to add the + // appropriate lifetime markers. This vector keeps track of all the lifetime + // markers that need to be ended right after the call. + SmallVector<CallLifetimeEnd, 2> CallLifetimeEndAfterCall; + // Translate all of the arguments as necessary to match the IR lowering. assert(CallInfo.arg_size() == CallArgs.size() && "Mismatch between function signature & arguments."); @@ -3994,6 +3999,18 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, Address AI = CreateMemTempWithoutCast( I->Ty, ArgInfo.getIndirectAlign(), "byval-temp"); IRCallArgs[FirstIRArg] = AI.getPointer(); + + // Emit lifetime markers for the temporary alloca. + uint64_t ByvalTempElementSize = + CGM.getDataLayout().getTypeAllocSize(AI.getElementType()); + llvm::Value *LifetimeSize = + EmitLifetimeStart(ByvalTempElementSize, AI.getPointer()); + + // Add cleanup code to emit the end lifetime marker after the call. + if (LifetimeSize) // In case we disabled lifetime markers. + CallLifetimeEndAfterCall.emplace_back(AI, LifetimeSize); + + // Generate the copy. I->copyInto(*this, AI); } else { // Skip the extra memcpy call. @@ -4562,6 +4579,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } } + // Explicitly call CallLifetimeEnd::Emit just to re-use the code even though + // we can't use the full cleanup mechanism. + for (CallLifetimeEnd &LifetimeEnd : CallLifetimeEndAfterCall) + LifetimeEnd.Emit(*this, /*Flags=*/{}); + return Ret; } |