Skip to content

Commit

Permalink
[StackColoring] Conservatively merge catch point of V for catch(V)
Browse files Browse the repository at this point in the history
Reviewed By: thanm, clin1

Differential Revision: https://reviews.llvm.org/D86673
  • Loading branch information
xiangzh1 committed Nov 4, 2020
1 parent 4b11201 commit 7ba3293
Show file tree
Hide file tree
Showing 2 changed files with 484 additions and 3 deletions.
52 changes: 49 additions & 3 deletions llvm/lib/CodeGen/StackColoring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}
}
}
Expand All @@ -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
Expand Down
Loading

0 comments on commit 7ba3293

Please sign in to comment.