diff options
Diffstat (limited to 'llvm/lib/CodeGen/StackColoring.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/StackColoring.cpp | 71 |
1 files changed, 20 insertions, 51 deletions
diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp index 66b9086e1d88..37f7aa929005 100644 --- a/llvm/lib/CodeGen/StackColoring.cpp +++ b/llvm/lib/CodeGen/StackColoring.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // // This pass implements the stack-coloring optimization that looks for -// lifetime markers machine instructions (LIFESTART_BEGIN and LIFESTART_END), +// lifetime markers machine instructions (LIFETIME_START and LIFETIME_END), // which represent the possible lifetime of stack slots. It attempts to // merge disjoint stack slots and reduce the used stack space. // NOTE: This pass is not StackSlotColoring, which optimizes spill slots. @@ -36,6 +36,7 @@ #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/PseudoSourceValueManager.h" #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/WinEHFuncInfo.h" @@ -370,37 +371,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 +432,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 +627,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 +686,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 +696,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 @@ -1372,8 +1339,10 @@ bool StackColoring::runOnMachineFunction(MachineFunction &Func) { // Scan the entire function and update all machine operands that use frame // indices to use the remapped frame index. - expungeSlotMap(SlotRemap, NumSlots); - remapInstructions(SlotRemap); + if (!SlotRemap.empty()) { + expungeSlotMap(SlotRemap, NumSlots); + remapInstructions(SlotRemap); + } return removeAllMarkers(); } |
