aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/StackColoring.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-29 18:10:07 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-09-29 18:10:41 +0000
commit4bbf1f460eb3fabdb7cf7cd731af0c227e6539c8 (patch)
tree8fb51c31848f1d9835688ea1730410efb2c3f7ee /llvm/lib/CodeGen/StackColoring.cpp
parent8092e001bcd76c0b9fec2311f3a515aa60d2ed07 (diff)
Diffstat (limited to 'llvm/lib/CodeGen/StackColoring.cpp')
-rw-r--r--llvm/lib/CodeGen/StackColoring.cpp62
1 files changed, 14 insertions, 48 deletions
diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp
index 66b9086e1d88..3453b718b453 100644
--- a/llvm/lib/CodeGen/StackColoring.cpp
+++ b/llvm/lib/CodeGen/StackColoring.cpp
@@ -370,37 +370,6 @@ STATISTIC(EscapedAllocas, "Number of allocas that escaped the lifetime region");
// If in RPO ordering chosen to walk the CFG we happen to visit the b[k]
// 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 {
@@ -462,9 +431,6 @@ 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;
@@ -660,13 +626,10 @@ 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.
@@ -722,13 +685,6 @@ 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;
}
}
}
@@ -739,14 +695,24 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
return 0;
}
- // 1) PR27903: slots with multiple start or end lifetime ops are not
+ // PR27903: slots with multiple start or end lifetime ops are not
// safe to enable for "lifetime-start-on-first-use".
- // 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)))
+ if (NumStartLifetimes[slot] > 1 || NumEndLifetimes[slot] > 1)
ConservativeSlots.set(slot);
}
+
+ // The write to the catch object by the personality function is not propely
+ // modeled in IR: It happens before any cleanuppads are executed, even if the
+ // first mention of the catch object is in a catchpad. As such, mark catch
+ // object slots as conservative, so they are excluded from first-use analysis.
+ if (WinEHFuncInfo *EHInfo = MF->getWinEHFuncInfo())
+ for (WinEHTryBlockMapEntry &TBME : EHInfo->TryBlockMap)
+ for (WinEHHandlerType &H : TBME.HandlerArray)
+ if (H.CatchObj.FrameIndex != std::numeric_limits<int>::max() &&
+ H.CatchObj.FrameIndex >= 0)
+ ConservativeSlots.set(H.CatchObj.FrameIndex);
+
LLVM_DEBUG(dumpBV("Conservative slots", ConservativeSlots));
// Step 2: compute begin/end sets for each block