llvm.org GIT mirror llvm / 22efc18
Stop using the dom frontier in DwarfEHPrepare by not promoting alloca's any more. I plan to reimplement alloca promotion using SSAUpdater later. It looks like Bill's URoR logic really always needs domtree, so the pass now always asks for domtree info. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112597 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan Sands 9 years ago
3 changed file(s) with 11 addition(s) and 88 deletion(s). Raw diff Collapse all Expand all
191191
192192 /// createDwarfEHPass - This pass mulches exception handling code into a form
193193 /// adapted to code generation. Required if using dwarf exception handling.
194 FunctionPass *createDwarfEHPass(const TargetMachine *tm, bool fast);
194 FunctionPass *createDwarfEHPass(const TargetMachine *tm);
195195
196196 /// createSjLjEHPass - This pass adapts exception handling code to use
197197 /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
2424 #include "llvm/Support/CallSite.h"
2525 #include "llvm/Target/TargetLowering.h"
2626 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
27 #include "llvm/Transforms/Utils/PromoteMemToReg.h"
2827 using namespace llvm;
2928
3029 STATISTIC(NumLandingPadsSplit, "Number of landing pads split");
3635 class DwarfEHPrepare : public FunctionPass {
3736 const TargetMachine *TM;
3837 const TargetLowering *TLI;
39 bool CompileFast;
4038
4139 // The eh.exception intrinsic.
4240 Function *ExceptionValueIntrinsic;
5351 // _Unwind_Resume or the target equivalent.
5452 Constant *RewindFunction;
5553
56 // Dominator info is used when turning stack temporaries into registers.
54 // We both use and preserve dominator info.
5755 DominatorTree *DT;
58 DominanceFrontier *DF;
5956
6057 // The function we are running on.
6158 Function *F;
7168 bool LowerUnwinds();
7269 bool MoveExceptionValueCalls();
7370 bool FinishStackTemporaries();
74 bool PromoteStackTemporaries();
7571
7672 Instruction *CreateExceptionValueCall(BasicBlock *BB);
7773 Instruction *CreateValueLoad(BasicBlock *BB);
111107 bool FindSelectorAndURoR(Instruction *Inst, bool &URoRInvoke,
112108 SmallPtrSet &SelCalls);
113109
114 /// PromoteStoreInst - Perform Mem2Reg on a StoreInst.
115 bool PromoteStoreInst(StoreInst *SI) {
116 if (!SI || !DT || !DF) return false;
117
118 AllocaInst *AI = dyn_cast(SI->getOperand(1));
119 if (!AI || !isAllocaPromotable(AI)) return false;
120
121 // Turn the alloca into a register.
122 std::vector Allocas(1, AI);
123 PromoteMemToReg(Allocas, *DT, *DF);
124 return true;
125 }
126
127 /// PromoteEHPtrStore - Promote the storing of an EH pointer into a
128 /// register. This should get rid of the store and subsequent loads.
129 bool PromoteEHPtrStore(IntrinsicInst *II) {
130 if (!DT || !DF) return false;
131
132 bool Changed = false;
133 StoreInst *SI;
134
135 while (1) {
136 SI = 0;
137 for (Value::use_iterator
138 I = II->use_begin(), E = II->use_end(); I != E; ++I) {
139 SI = dyn_cast(*I);
140 if (SI) break;
141 }
142
143 if (!PromoteStoreInst(SI))
144 break;
145
146 Changed = true;
147 }
148
149 return Changed;
150 }
151
152110 public:
153111 static char ID; // Pass identification, replacement for typeid.
154 DwarfEHPrepare(const TargetMachine *tm, bool fast) :
112 DwarfEHPrepare(const TargetMachine *tm) :
155113 FunctionPass(ID), TM(tm), TLI(TM->getTargetLowering()),
156 CompileFast(fast),
157114 ExceptionValueIntrinsic(0), SelectorIntrinsic(0),
158115 URoR(0), EHCatchAllValue(0), RewindFunction(0) {}
159116
161118
162119 // getAnalysisUsage - We need dominance frontiers for memory promotion.
163120 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
164 if (!CompileFast)
165 AU.addRequired();
121 AU.addRequired();
166122 AU.addPreserved();
167 if (!CompileFast)
168 AU.addRequired();
169 AU.addPreserved();
170123 }
171124
172125 const char *getPassName() const {
178131
179132 char DwarfEHPrepare::ID = 0;
180133
181 FunctionPass *llvm::createDwarfEHPass(const TargetMachine *tm, bool fast) {
182 return new DwarfEHPrepare(tm, fast);
134 FunctionPass *llvm::createDwarfEHPass(const TargetMachine *tm) {
135 return new DwarfEHPrepare(tm);
183136 }
184137
185138 /// HasCatchAllInSelector - Return true if the intrinsic instruction has a
260213 SmallPtrSet SeenPHIs;
261214 bool Changed = false;
262215
263 restart:
264216 for (Value::use_iterator
265217 I = Inst->use_begin(), E = Inst->use_end(); I != E; ++I) {
266218 Instruction *II = dyn_cast(*I);
274226 URoRInvoke = true;
275227 } else if (CastInst *CI = dyn_cast(II)) {
276228 Changed |= FindSelectorAndURoR(CI, URoRInvoke, SelCalls);
277 } else if (StoreInst *SI = dyn_cast(II)) {
278 if (!PromoteStoreInst(SI)) continue;
279 Changed = true;
280 SeenPHIs.clear();
281 goto restart; // Uses may have changed, restart loop.
282229 } else if (PHINode *PN = dyn_cast(II)) {
283230 if (SeenPHIs.insert(PN))
284231 // Don't process a PHI node more than once.
309256 SmallPtrSet Sels;
310257 SmallPtrSet CatchAllSels;
311258 FindAllCleanupSelectors(Sels, CatchAllSels);
312
313 if (!DT)
314 // We require DominatorTree information.
315 return CleanupSelectors(CatchAllSels);
316259
317260 if (!URoR) {
318261 URoR = F->getParent()->getFunction("_Unwind_Resume_or_Rethrow");
354297 E = ExceptionValueIntrinsic->use_end(); I != E; ++I) {
355298 IntrinsicInst *EHPtr = dyn_cast(*I);
356299 if (!EHPtr || EHPtr->getParent()->getParent() != F) continue;
357
358 Changed |= PromoteEHPtrStore(EHPtr);
359300
360301 bool URoRInvoke = false;
361302 SmallPtrSet SelCalls;
524465 // Add a fallthrough from NewBB to the original landing pad.
525466 BranchInst::Create(LPad, NewBB);
526467
527 // Now update DominatorTree and DominanceFrontier analysis information.
528 if (DT)
529 DT->splitBlock(NewBB);
530 if (DF)
531 DF->splitBlock(NewBB);
468 // Now update DominatorTree analysis information.
469 DT->splitBlock(NewBB);
532470
533471 // Remember the newly constructed landing pad. The original landing pad
534472 // LPad is no longer a landing pad now that all unwind edges have been
651589 return Changed;
652590 }
653591
654 /// PromoteStackTemporaries - Turn any stack temporaries we introduced into
655 /// registers if possible.
656 bool DwarfEHPrepare::PromoteStackTemporaries() {
657 if (ExceptionValueVar && DT && DF && isAllocaPromotable(ExceptionValueVar)) {
658 // Turn the exception temporary into registers and phi nodes if possible.
659 std::vector Allocas(1, ExceptionValueVar);
660 PromoteMemToReg(Allocas, *DT, *DF);
661 return true;
662 }
663 return false;
664 }
665
666592 /// CreateExceptionValueCall - Insert a call to the eh.exception intrinsic at
667593 /// the start of the basic block (unless there already is one, in which case
668594 /// the existing call is returned).
710636 bool Changed = false;
711637
712638 // Initialize internal state.
713 DT = getAnalysisIfAvailable();
714 DF = getAnalysisIfAvailable>();
639 DT = &getAnalysis>();
715640 ExceptionValueVar = 0;
716641 F = &Fn;
717642
730655 // Initialize any stack temporaries we introduced.
731656 Changed |= FinishStackTemporaries();
732657
733 // Turn any stack temporaries into registers if possible.
734 if (!CompileFast)
735 Changed |= PromoteStackTemporaries();
658 // TODO: Turn any stack temporaries into registers if possible.
736659
737660 Changed |= HandleURoRInvokes();
738661
288288 PM.add(createSjLjEHPass(getTargetLowering()));
289289 // FALLTHROUGH
290290 case ExceptionHandling::Dwarf:
291 PM.add(createDwarfEHPass(this, OptLevel==CodeGenOpt::None));
291 PM.add(createDwarfEHPass(this));
292292 break;
293293 case ExceptionHandling::None:
294294 PM.add(createLowerInvokePass(getTargetLowering()));