summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/StackColoring.cpp
diff options
context:
space:
mode:
authorXiang1 Zhang <xiang1.zhang@intel.com>2020-11-03 09:12:35 +0800
committerXiang1 Zhang <xiang1.zhang@intel.com>2020-11-04 10:49:56 +0800
commit7ba3293691beb9a2c6ea4a81064c24580afe5816 (patch)
tree1e46c06609f35c9aa39f759a42c844f399a6989a /llvm/lib/CodeGen/StackColoring.cpp
parent4b1120159274ca98b4a58064b116aba88372ac98 (diff)
[StackColoring] Conservatively merge catch point of V for catch(V)
Reviewed By: thanm, clin1 Differential Revision: https://reviews.llvm.org/D86673
Diffstat (limited to 'llvm/lib/CodeGen/StackColoring.cpp')
-rw-r--r--llvm/lib/CodeGen/StackColoring.cpp52
1 files changed, 49 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp
index 7258feafb7e9..2b3715d02e9b 100644
--- a/llvm/lib/CodeGen/StackColoring.cpp
+++ b/llvm/lib/CodeGen/StackColoring.cpp
@@ -373,6 +373,36 @@ STATISTIC(EscapedAllocas, "Number of allocas that escaped the lifetime region");
// before visiting the memcpy block (which will contain the lifetime start
// for "b" then it will appear that 'b' has a degenerate lifetime.
//
+// Handle Windows Exception with LifetimeStartOnFirstUse:
+// -----------------
+//
+// There was a bug for using LifetimeStartOnFirstUse in win32.
+// class Type1 {
+// ...
+// ~Type1(){ write memory;}
+// }
+// ...
+// try{
+// Type1 V
+// ...
+// } catch (Type2 X){
+// ...
+// }
+// For variable X in catch(X), we put point pX=&(&X) into ConservativeSlots
+// to prevent using LifetimeStartOnFirstUse. Because pX may merged with
+// object V which may call destructor after implicitly writing pX. All these
+// are done in C++ EH runtime libs (through CxxThrowException), and can't
+// obviously check it in IR level.
+//
+// The loader of pX, without obvious writing IR, is usually the first LOAD MI
+// in EHPad, Some like:
+// bb.x.catch.i (landing-pad, ehfunclet-entry):
+// ; predecessors: %bb...
+// successors: %bb...
+// %n:gr32 = MOV32rm %stack.pX ...
+// ...
+// The Type2** %stack.pX will only be written in EH runtime libs, so we
+// check the StoreSlots to screen it out.
namespace {
@@ -434,6 +464,9 @@ class StackColoring : public MachineFunctionPass {
/// slots lifetime-start-on-first-use is disabled).
BitVector ConservativeSlots;
+ /// Record the FI slots referenced by a 'may write to memory'.
+ BitVector StoreSlots;
+
/// Number of iterations taken during data flow analysis.
unsigned NumIterations;
@@ -629,10 +662,13 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
InterestingSlots.resize(NumSlot);
ConservativeSlots.clear();
ConservativeSlots.resize(NumSlot);
+ StoreSlots.clear();
+ StoreSlots.resize(NumSlot);
// number of start and end lifetime ops for each slot
SmallVector<int, 8> NumStartLifetimes(NumSlot, 0);
SmallVector<int, 8> NumEndLifetimes(NumSlot, 0);
+ SmallVector<int, 8> NumLoadInCatchPad(NumSlot, 0);
// Step 1: collect markers and populate the "InterestingSlots"
// and "ConservativeSlots" sets.
@@ -687,6 +723,13 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
if (! BetweenStartEnd.test(Slot)) {
ConservativeSlots.set(Slot);
}
+ // Here we check the StoreSlots to screen catch point out. For more
+ // information, please refer "Handle Windows Exception with
+ // LifetimeStartOnFirstUse" at the head of this file.
+ if (MI.mayStore())
+ StoreSlots.set(Slot);
+ if (MF->getWinEHFuncInfo() && MBB->isEHPad() && MI.mayLoad())
+ NumLoadInCatchPad[Slot] += 1;
}
}
}
@@ -697,11 +740,14 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
return 0;
}
- // PR27903: slots with multiple start or end lifetime ops are not
+ // 1) PR27903: slots with multiple start or end lifetime ops are not
// safe to enable for "lifetime-start-on-first-use".
- for (unsigned slot = 0; slot < NumSlot; ++slot)
- if (NumStartLifetimes[slot] > 1 || NumEndLifetimes[slot] > 1)
+ // 2) And also not safe for variable X in catch(X) in windows.
+ for (unsigned slot = 0; slot < NumSlot; ++slot) {
+ if (NumStartLifetimes[slot] > 1 || NumEndLifetimes[slot] > 1 ||
+ (NumLoadInCatchPad[slot] > 1 && !StoreSlots.test(slot)))
ConservativeSlots.set(slot);
+ }
LLVM_DEBUG(dumpBV("Conservative slots", ConservativeSlots));
// Step 2: compute begin/end sets for each block