diff options
author | Bill Wendling <isanbard@gmail.com> | 2012-01-27 02:02:24 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2012-01-27 02:02:24 +0000 |
commit | 4cc4666268c6c62de763c46fefe304adf08a01a1 (patch) | |
tree | 518e69bd700b6d36c5ef97f87a11f0cb259852b6 /lib/CodeGen | |
parent | 6b2760759b23b8b96beb43966b9b8088e832efc7 (diff) | |
download | external_llvm-4cc4666268c6c62de763c46fefe304adf08a01a1.zip external_llvm-4cc4666268c6c62de763c46fefe304adf08a01a1.tar.gz external_llvm-4cc4666268c6c62de763c46fefe304adf08a01a1.tar.bz2 |
Place the GEP instructions nearer to the instructions which use them.
GEP instructions are there for the compiler and shouldn't really output much
code (if any at all). When a GEP is stored in the entry block, Fast ISel (for
one) will not know that it could fold it into further uses. For instance, inside
of the EH handling code. This results in a lot of unnecessary spills and loads
which bloat code and slows down pretty much everything.
<rdar://problem/10694814>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149114 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SjLjEHPrepare.cpp | 73 |
1 files changed, 36 insertions, 37 deletions
diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp index b944fa0..5412c97 100644 --- a/lib/CodeGen/SjLjEHPrepare.cpp +++ b/lib/CodeGen/SjLjEHPrepare.cpp @@ -55,7 +55,7 @@ namespace { Value *PersonalityFn; Constant *CallSiteFn; Constant *FuncCtxFn; - Value *CallSite; + AllocaInst *FuncCtx; public: static char ID; // Pass identification, replacement for typeid explicit SjLjEHPass(const TargetLowering *tli = NULL) @@ -75,7 +75,7 @@ namespace { Value *setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads); void lowerIncomingArguments(Function &F); void lowerAcrossUnwindEdges(Function &F, ArrayRef<InvokeInst*> Invokes); - void insertCallSiteStore(Instruction *I, int Number, Value *CallSite); + void insertCallSiteStore(Instruction *I, int Number); }; } // end anonymous namespace @@ -123,12 +123,20 @@ bool SjLjEHPass::doInitialization(Module &M) { /// insertCallSiteStore - Insert a store of the call-site value to the /// function context -void SjLjEHPass::insertCallSiteStore(Instruction *I, int Number, - Value *CallSite) { +void SjLjEHPass::insertCallSiteStore(Instruction *I, int Number) { + IRBuilder<> Builder(I); + + // Get a reference to the call_site field. + Type *Int32Ty = Type::getInt32Ty(I->getContext()); + Value *Zero = ConstantInt::get(Int32Ty, 0); + Value *One = ConstantInt::get(Int32Ty, 1); + Value *Idxs[2] = { Zero, One }; + Value *CallSite = Builder.CreateGEP(FuncCtx, Idxs, "call_site"); + + // Insert a store of the call-site number ConstantInt *CallSiteNoC = ConstantInt::get(Type::getInt32Ty(I->getContext()), Number); - // Insert a store of the call-site number - new StoreInst(CallSiteNoC, CallSite, true, I); // volatile + Builder.CreateStore(CallSiteNoC, CallSite, true/*volatile*/); } /// MarkBlocksLiveIn - Insert BB and all of its predescessors into LiveBBs until @@ -184,51 +192,42 @@ setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads) { // because the value needs to be added to the global context list. unsigned Align = TLI->getTargetData()->getPrefTypeAlignment(FunctionContextTy); - AllocaInst *FuncCtx = + FuncCtx = new AllocaInst(FunctionContextTy, 0, Align, "fn_context", EntryBB->begin()); // Fill in the function context structure. - Value *Idxs[2]; Type *Int32Ty = Type::getInt32Ty(F.getContext()); Value *Zero = ConstantInt::get(Int32Ty, 0); Value *One = ConstantInt::get(Int32Ty, 1); + Value *Two = ConstantInt::get(Int32Ty, 2); + Value *Three = ConstantInt::get(Int32Ty, 3); + Value *Four = ConstantInt::get(Int32Ty, 4); - // Keep around a reference to the call_site field. - Idxs[0] = Zero; - Idxs[1] = One; - CallSite = GetElementPtrInst::Create(FuncCtx, Idxs, "call_site", - EntryBB->getTerminator()); - - // Reference the __data field. - Idxs[1] = ConstantInt::get(Int32Ty, 2); - Value *FCData = GetElementPtrInst::Create(FuncCtx, Idxs, "__data", - EntryBB->getTerminator()); - - // The exception value comes back in context->__data[0]. - Idxs[1] = Zero; - Value *ExceptionAddr = GetElementPtrInst::Create(FCData, Idxs, - "exception_gep", - EntryBB->getTerminator()); - - // The exception selector comes back in context->__data[1]. - Idxs[1] = One; - Value *SelectorAddr = GetElementPtrInst::Create(FCData, Idxs, - "exn_selector_gep", - EntryBB->getTerminator()); + Value *Idxs[2] = { Zero, 0 }; for (unsigned I = 0, E = LPads.size(); I != E; ++I) { LandingPadInst *LPI = LPads[I]; IRBuilder<> Builder(LPI->getParent()->getFirstInsertionPt()); + // Reference the __data field. + Idxs[1] = Two; + Value *FCData = Builder.CreateGEP(FuncCtx, Idxs, "__data"); + + // The exception values come back in context->__data[0]. + Idxs[1] = Zero; + Value *ExceptionAddr = Builder.CreateGEP(FCData, Idxs, "exception_gep"); Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val"); ExnVal = Builder.CreateIntToPtr(ExnVal, Type::getInt8PtrTy(F.getContext())); + + Idxs[1] = One; + Value *SelectorAddr = Builder.CreateGEP(FCData, Idxs, "exn_selector_gep"); Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val"); substituteLPadValues(LPI, ExnVal, SelVal); } // Personality function - Idxs[1] = ConstantInt::get(Int32Ty, 3); + Idxs[1] = Three; if (!PersonalityFn) PersonalityFn = LPads[0]->getPersonalityFn(); Value *PersonalityFieldPtr = @@ -238,11 +237,11 @@ setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads) { EntryBB->getTerminator()); // LSDA address - Idxs[1] = ConstantInt::get(Int32Ty, 4); - Value *LSDAFieldPtr = GetElementPtrInst::Create(FuncCtx, Idxs, "lsda_gep", - EntryBB->getTerminator()); Value *LSDA = CallInst::Create(LSDAAddrFn, "lsda_addr", EntryBB->getTerminator()); + Idxs[1] = Four; + Value *LSDAFieldPtr = GetElementPtrInst::Create(FuncCtx, Idxs, "lsda_gep", + EntryBB->getTerminator()); new StoreInst(LSDA, LSDAFieldPtr, true, EntryBB->getTerminator()); return FuncCtx; @@ -464,7 +463,7 @@ bool SjLjEHPass::setupEntryBlockAndCallSites(Function &F) { // At this point, we are all set up, update the invoke instructions to mark // their call_site values. for (unsigned I = 0, E = Invokes.size(); I != E; ++I) { - insertCallSiteStore(Invokes[I], I + 1, CallSite); + insertCallSiteStore(Invokes[I], I + 1); ConstantInt *CallSiteNum = ConstantInt::get(Type::getInt32Ty(F.getContext()), I + 1); @@ -483,9 +482,9 @@ bool SjLjEHPass::setupEntryBlockAndCallSites(Function &F) { for (BasicBlock::iterator I = BB->begin(), end = BB->end(); I != end; ++I) if (CallInst *CI = dyn_cast<CallInst>(I)) { if (!CI->doesNotThrow()) - insertCallSiteStore(CI, -1, CallSite); + insertCallSiteStore(CI, -1); } else if (ResumeInst *RI = dyn_cast<ResumeInst>(I)) { - insertCallSiteStore(RI, -1, CallSite); + insertCallSiteStore(RI, -1); } // Register the function context and make sure it's known to not throw |