diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2016-04-01 22:58:55 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2016-04-01 22:58:55 +0000 |
commit | 8af7bb28aa225fe30e0a682325b5b9f4df74d6fe (patch) | |
tree | 2c57e78d83e44e464a746ae2151cde903978202d /clang/lib/CodeGen | |
parent | 58a15d5a235c57aafdc881250c25d8ce37a0f47e (diff) | |
download | bcm5719-llvm-8af7bb28aa225fe30e0a682325b5b9f4df74d6fe.tar.gz bcm5719-llvm-8af7bb28aa225fe30e0a682325b5b9f4df74d6fe.zip |
[CodeGen] Emit lifetime.end intrinsic after objects are destructed in
landing pads.
Previously, lifetime.end intrinsics were inserted only on normal control
flows. This prevented StackColoring from merging stack slots for objects
that were destroyed on the exception handling control flow since it
couldn't tell their lifetime ranges were disjoint. This patch fixes
code-gen to emit the intrinsic on both control flows.
rdar://problem/22181976
Differential Revision: http://reviews.llvm.org/D18196
llvm-svn: 265197
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCleanup.cpp | 14 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/EHScopeStack.h | 4 |
3 files changed, 16 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index 2678b33f392..95333d0ddac 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -157,6 +157,20 @@ bool EHScopeStack::containsOnlyLifetimeMarkers( return true; } +bool EHScopeStack::requiresLandingPad() const { + for (stable_iterator si = getInnermostEHScope(); si != stable_end(); ) { + // Skip lifetime markers. + if (auto *cleanup = dyn_cast<EHCleanupScope>(&*find(si))) + if (cleanup->isLifetimeMarker()) { + si = cleanup->getEnclosingEHScope(); + continue; + } + return true; + } + + return false; +} + EHScopeStack::stable_iterator EHScopeStack::getInnermostActiveNormalCleanup() const { for (stable_iterator si = getInnermostNormalCleanup(), se = stable_end(); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index e0c297508fa..c39b980ef2c 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1388,7 +1388,7 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) { // Make sure we call @llvm.lifetime.end. This needs to happen // *last*, so the cleanup needs to be pushed *first*. if (emission.useLifetimeMarkers()) { - EHStack.pushCleanup<CallLifetimeEnd>(NormalCleanup, + EHStack.pushCleanup<CallLifetimeEnd>(NormalAndEHCleanup, emission.getAllocatedAddress(), emission.getSizeForLifetimeMarkers()); EHCleanupScope &cleanup = cast<EHCleanupScope>(*EHStack.begin()); diff --git a/clang/lib/CodeGen/EHScopeStack.h b/clang/lib/CodeGen/EHScopeStack.h index 85cd1543e5b..8352c75d64f 100644 --- a/clang/lib/CodeGen/EHScopeStack.h +++ b/clang/lib/CodeGen/EHScopeStack.h @@ -341,9 +341,7 @@ public: /// Determines whether the exception-scopes stack is empty. bool empty() const { return StartOfData == EndOfBuffer; } - bool requiresLandingPad() const { - return InnermostEHScope != stable_end(); - } + bool requiresLandingPad() const; /// Determines whether there are any normal cleanups on the stack. bool hasNormalCleanups() const { |