From 5dd75b4ca7e582f44da2f50362e8ab4c59972b5f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 4 Aug 2007 01:47:41 +0000 Subject: [PATCH] split rewriting of single-store allocas into its own method. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40806 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Utils/PromoteMemoryToRegister.cpp | 96 +++++++++++-------- 1 file changed, 57 insertions(+), 39 deletions(-) diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index f895d1955c2..6be25d6dfe2 100644 --- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -78,6 +78,7 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) { } namespace { + struct AllocaInfo; // Data package used by RenamePass() class VISIBILITY_HIDDEN RenamePassData { @@ -165,6 +166,8 @@ namespace { --AllocaIdx; } + void RewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info); + void MarkDominatingPHILive(BasicBlock *BB, unsigned AllocaNum, SmallPtrSet &DeadPHINodes); bool PromoteLocallyUsedAlloca(BasicBlock *BB, AllocaInst *AI); @@ -232,6 +235,7 @@ namespace { } // end of anonymous namespace + void PromoteMem2Reg::run() { Function &F = *DF.getRoot()->getParent(); @@ -282,45 +286,7 @@ void PromoteMem2Reg::run() { // If there is only a single store to this value, replace any loads of // it that are directly dominated by the definition with the value stored. if (Info.DefiningBlocks.size() == 1) { - // Be aware of loads before the store. - std::set ProcessedBlocks; - for (unsigned i = 0, e = Info.UsingBlocks.size(); i != e; ++i) - // If the store dominates the block and if we haven't processed it yet, - // do so now. - if (dominates(Info.OnlyStore->getParent(), Info.UsingBlocks[i])) - if (ProcessedBlocks.insert(Info.UsingBlocks[i]).second) { - BasicBlock *UseBlock = Info.UsingBlocks[i]; - - // If the use and store are in the same block, do a quick scan to - // verify that there are no uses before the store. - if (UseBlock == Info.OnlyStore->getParent()) { - BasicBlock::iterator I = UseBlock->begin(); - for (; &*I != Info.OnlyStore; ++I) { // scan block for store. - if (isa(I) && I->getOperand(0) == AI) - break; - } - if (&*I != Info.OnlyStore) break; // Do not handle this case. - } - - // Otherwise, if this is a different block or if all uses happen - // after the store, do a simple linear scan to replace loads with - // the stored value. - for (BasicBlock::iterator I = UseBlock->begin(),E = UseBlock->end(); - I != E; ) { - if (LoadInst *LI = dyn_cast(I++)) { - if (LI->getOperand(0) == AI) { - LI->replaceAllUsesWith(Info.OnlyStore->getOperand(0)); - if (AST && isa(LI->getType())) - AST->deleteValue(LI); - LI->eraseFromParent(); - } - } - } - - // Finally, remove this block from the UsingBlock set. - Info.UsingBlocks[i] = Info.UsingBlocks.back(); - --i; --e; - } + RewriteSingleStoreAlloca(AI, Info); // Finally, after the scan, check to see if the store is all that is left. if (Info.UsingBlocks.empty()) { @@ -559,6 +525,58 @@ void PromoteMem2Reg::run() { NewPhiNodes.clear(); } + +/// RewriteSingleStoreAlloca - If there is only a single store to this value, +/// replace any loads of it that are directly dominated by the definition with +/// the value stored. +void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI, + AllocaInfo &Info) { + // Be aware of loads before the store. + std::set ProcessedBlocks; + for (unsigned i = 0, e = Info.UsingBlocks.size(); i != e; ++i) { + // If the store dominates the block and if we haven't processed it yet, + // do so now. + if (!dominates(Info.OnlyStore->getParent(), Info.UsingBlocks[i])) + continue; + + if (!ProcessedBlocks.insert(Info.UsingBlocks[i]).second) + continue; + + BasicBlock *UseBlock = Info.UsingBlocks[i]; + + // If the use and store are in the same block, do a quick scan to + // verify that there are no uses before the store. + if (UseBlock == Info.OnlyStore->getParent()) { + BasicBlock::iterator I = UseBlock->begin(); + for (; &*I != Info.OnlyStore; ++I) { // scan block for store. + if (isa(I) && I->getOperand(0) == AI) + break; + } + if (&*I != Info.OnlyStore) break; // Do not handle this case. + } + + // Otherwise, if this is a different block or if all uses happen + // after the store, do a simple linear scan to replace loads with + // the stored value. + for (BasicBlock::iterator I = UseBlock->begin(),E = UseBlock->end(); + I != E; ) { + if (LoadInst *LI = dyn_cast(I++)) { + if (LI->getOperand(0) == AI) { + LI->replaceAllUsesWith(Info.OnlyStore->getOperand(0)); + if (AST && isa(LI->getType())) + AST->deleteValue(LI); + LI->eraseFromParent(); + } + } + } + + // Finally, remove this block from the UsingBlock set. + Info.UsingBlocks[i] = Info.UsingBlocks.back(); + --i; --e; + } +} + + // MarkDominatingPHILive - Mem2Reg wants to construct "pruned" SSA form, not // "minimal" SSA form. To do this, it inserts all of the PHI nodes on the IDF // as usual (inserting the PHI nodes in the DeadPHINodes set), then processes -- 2.34.1