From b1086a9c6d6d5ee3070a68076f38eec841cefd58 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Mon, 17 Jan 2011 07:26:51 +0000 Subject: [PATCH] Roll out r123609 due to failures on the llvm-x86_64-linux-checks bot. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123618 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/Transforms/Utils/PromoteMemToReg.h | 3 +- .../Scalar/ScalarReplAggregates.cpp | 9 +- lib/Transforms/Utils/Mem2Reg.cpp | 5 +- .../Utils/PromoteMemoryToRegister.cpp | 171 ++++++------------ 4 files changed, 64 insertions(+), 124 deletions(-) diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h index 98d51a29ad7..35cfaddb737 100644 --- a/include/llvm/Transforms/Utils/PromoteMemToReg.h +++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h @@ -38,7 +38,8 @@ bool isAllocaPromotable(const AllocaInst *AI); /// made to the IR. /// void PromoteMemToReg(const std::vector &Allocas, - DominatorTree &DT, AliasSetTracker *AST = 0); + DominatorTree &DT, DominanceFrontier &DF, + AliasSetTracker *AST = 0); } // End llvm namespace diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 5c90a360237..a068556b734 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -152,6 +152,7 @@ namespace { // will not alter the CFG, so say so. virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequired(); AU.setPreservesCFG(); } }; @@ -179,6 +180,7 @@ char SROA_SSAUp::ID = 0; INITIALIZE_PASS_BEGIN(SROA_DF, "scalarrepl", "Scalar Replacement of Aggregates (DF)", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(DominanceFrontier) INITIALIZE_PASS_END(SROA_DF, "scalarrepl", "Scalar Replacement of Aggregates (DF)", false, false) @@ -875,8 +877,11 @@ public: bool SROA::performPromotion(Function &F) { std::vector Allocas; DominatorTree *DT = 0; - if (HasDomFrontiers) + DominanceFrontier *DF = 0; + if (HasDomFrontiers) { DT = &getAnalysis(); + DF = &getAnalysis(); + } BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function @@ -895,7 +900,7 @@ bool SROA::performPromotion(Function &F) { if (Allocas.empty()) break; if (HasDomFrontiers) - PromoteMemToReg(Allocas, *DT); + PromoteMemToReg(Allocas, *DT, *DF); else { SSAUpdater SSA; for (unsigned i = 0, e = Allocas.size(); i != e; ++i) { diff --git a/lib/Transforms/Utils/Mem2Reg.cpp b/lib/Transforms/Utils/Mem2Reg.cpp index ea2f8fca5f2..2b1364c81e7 100644 --- a/lib/Transforms/Utils/Mem2Reg.cpp +++ b/lib/Transforms/Utils/Mem2Reg.cpp @@ -40,6 +40,7 @@ namespace { // virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequired(); AU.setPreservesCFG(); // This is a cluster of orthogonal Transforms AU.addPreserved(); @@ -53,6 +54,7 @@ char PromotePass::ID = 0; INITIALIZE_PASS_BEGIN(PromotePass, "mem2reg", "Promote Memory to Register", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(DominanceFrontier) INITIALIZE_PASS_END(PromotePass, "mem2reg", "Promote Memory to Register", false, false) @@ -64,6 +66,7 @@ bool PromotePass::runOnFunction(Function &F) { bool Changed = false; DominatorTree &DT = getAnalysis(); + DominanceFrontier &DF = getAnalysis(); while (1) { Allocas.clear(); @@ -77,7 +80,7 @@ bool PromotePass::runOnFunction(Function &F) { if (Allocas.empty()) break; - PromoteMemToReg(Allocas, DT); + PromoteMemToReg(Allocas, DT, DF); NumPromoted += Allocas.size(); Changed = true; } diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index a4d7c151169..d00f870fdfa 100644 --- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -9,19 +9,10 @@ // // This file promotes memory references to be register references. It promotes // alloca instructions which only have loads and stores as uses. An alloca is -// transformed by using iterated dominator frontiers to place PHI nodes, then -// traversing the function in depth-first order to rewrite loads and stores as -// appropriate. -// -// The algorithm used here is based on: -// -// Sreedhar and Gao. A linear time algorithm for placing phi-nodes. -// In Proceedings of the 22nd ACM SIGPLAN-SIGACT Symposium on Principles of -// Programming Languages -// POPL '95. ACM, New York, NY, 62-73. -// -// It has been modified to not explicitly use the DJ graph data structure and to -// directly compute pruned SSA using per-variable liveness information. +// transformed by using dominator frontiers to place PHI nodes, then traversing +// the function in depth-first order to rewrite loads and stores as appropriate. +// This is just the standard SSA construction algorithm to construct "pruned" +// SSA form. // //===----------------------------------------------------------------------===// @@ -44,7 +35,6 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.h" #include -#include using namespace llvm; STATISTIC(NumLocalPromoted, "Number of alloca's promoted within one block"); @@ -189,6 +179,7 @@ namespace { /// std::vector Allocas; DominatorTree &DT; + DominanceFrontier &DF; DIFactory *DIF; /// AST - An AliasSetTracker object to update. If null, don't update it. @@ -226,15 +217,12 @@ namespace { /// non-determinstic behavior. DenseMap BBNumbers; - /// DomLevels - Maps DomTreeNodes to their level in the dominator tree. - DenseMap DomLevels; - /// BBNumPreds - Lazily compute the number of predecessors a block has. DenseMap BBNumPreds; public: PromoteMem2Reg(const std::vector &A, DominatorTree &dt, - AliasSetTracker *ast) - : Allocas(A), DT(dt), DIF(0), AST(ast) {} + DominanceFrontier &df, AliasSetTracker *ast) + : Allocas(A), DT(dt), DF(df), DIF(0), AST(ast) {} ~PromoteMem2Reg() { delete DIF; } @@ -341,7 +329,7 @@ namespace { void PromoteMem2Reg::run() { - Function &F = *DT.getRoot()->getParent(); + Function &F = *DF.getRoot()->getParent(); if (AST) PointerAllocaValues.resize(Allocas.size()); AllocaDbgDeclares.resize(Allocas.size()); @@ -434,26 +422,7 @@ void PromoteMem2Reg::run() { continue; } } - - // If we haven't computed dominator tree levels, do so now. - if (DomLevels.empty()) { - SmallVector Worklist; - - DomTreeNode *Root = DT.getRootNode(); - DomLevels[Root] = 0; - Worklist.push_back(Root); - - while (!Worklist.empty()) { - DomTreeNode *Node = Worklist.pop_back_val(); - unsigned ChildLevel = DomLevels[Node] + 1; - for (DomTreeNode::iterator CI = Node->begin(), CE = Node->end(); - CI != CE; ++CI) { - DomLevels[*CI] = ChildLevel; - Worklist.push_back(*CI); - } - } - } - + // If we haven't computed a numbering for the BB's in the function, do so // now. if (BBNumbers.empty()) { @@ -688,14 +657,6 @@ ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info, } } -typedef std::pair DomTreeNodePair; - -struct DomTreeNodeCompare { - bool operator()(const DomTreeNodePair &LHS, const DomTreeNodePair &RHS) { - return LHS.second <= RHS.second; - } -}; - /// DetermineInsertionPoint - At this point, we're committed to promoting the /// alloca using IDF's, and the standard SSA construction algorithm. Determine /// which blocks need phi nodes and see if we can optimize out some work by @@ -712,77 +673,46 @@ void PromoteMem2Reg::DetermineInsertionPoint(AllocaInst *AI, unsigned AllocaNum, SmallPtrSet LiveInBlocks; ComputeLiveInBlocks(AI, Info, DefBlocks, LiveInBlocks); - // Use a priority queue keyed on dominator tree level so that inserted nodes - // are handled from the bottom of the dominator tree upwards. - typedef std::priority_queue, - DomTreeNodeCompare> IDFPriorityQueue; - IDFPriorityQueue PQ; - - for (unsigned i = 0, e = Info.DefiningBlocks.size(); i != e; ++i) { - if (DomTreeNode *Node = DT.getNode(Info.DefiningBlocks[i])) - PQ.push(std::make_pair(Node, DomLevels[Node])); - } - - std::vector > DFBlocks; - SmallPtrSet Visited; - SmallVector Worklist; - while (!PQ.empty()) { - DomTreeNodePair RootPair = PQ.top(); - PQ.pop(); - DomTreeNode *Root = RootPair.first; - unsigned RootLevel = RootPair.second; - - // Walk all dominator tree children of Root, inspecting their CFG edges with - // targets elsewhere on the dominator tree. Only targets whose level is at - // most Root's level are added to the iterated dominance frontier of the - // definition set. - - Worklist.clear(); - Worklist.push_back(Root); - - while (!Worklist.empty()) { - DomTreeNode *Node = Worklist.pop_back_val(); - BasicBlock *BB = Node->getBlock(); - - for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; - ++SI) { - DomTreeNode *SuccNode = DT.getNode(*SI); - - // Quickly skip all CFG edges that are also dominator tree edges instead - // of catching them below. - if (SuccNode->getIDom() == Node) - continue; - - unsigned SuccLevel = DomLevels[SuccNode]; - if (SuccLevel > RootLevel) - continue; - - if (!Visited.insert(SuccNode)) - continue; - - BasicBlock *SuccBB = SuccNode->getBlock(); - if (!LiveInBlocks.count(SuccBB)) - continue; - - DFBlocks.push_back(std::make_pair(BBNumbers[SuccBB], SuccBB)); - if (!DefBlocks.count(SuccBB)) - PQ.push(std::make_pair(SuccNode, SuccLevel)); - } - - for (DomTreeNode::iterator CI = Node->begin(), CE = Node->end(); CI != CE; - ++CI) { - if (!Visited.count(*CI)) - Worklist.push_back(*CI); - } - } - } - - if (DFBlocks.size() > 1) - std::sort(DFBlocks.begin(), DFBlocks.end()); - + // Compute the locations where PhiNodes need to be inserted. Look at the + // dominance frontier of EACH basic-block we have a write in. unsigned CurrentVersion = 0; - for (unsigned i = 0, e = DFBlocks.size(); i != e; ++i) - QueuePhiNode(DFBlocks[i].second, AllocaNum, CurrentVersion); + std::vector > DFBlocks; + while (!Info.DefiningBlocks.empty()) { + BasicBlock *BB = Info.DefiningBlocks.back(); + Info.DefiningBlocks.pop_back(); + + // Look up the DF for this write, add it to defining blocks. + DominanceFrontier::const_iterator it = DF.find(BB); + if (it == DF.end()) continue; + + const DominanceFrontier::DomSetType &S = it->second; + + // In theory we don't need the indirection through the DFBlocks vector. + // In practice, the order of calling QueuePhiNode would depend on the + // (unspecified) ordering of basic blocks in the dominance frontier, + // which would give PHI nodes non-determinstic subscripts. Fix this by + // processing blocks in order of the occurance in the function. + for (DominanceFrontier::DomSetType::const_iterator P = S.begin(), + PE = S.end(); P != PE; ++P) { + // If the frontier block is not in the live-in set for the alloca, don't + // bother processing it. + if (!LiveInBlocks.count(*P)) + continue; + + DFBlocks.push_back(std::make_pair(BBNumbers[*P], *P)); + } + + // Sort by which the block ordering in the function. + if (DFBlocks.size() > 1) + std::sort(DFBlocks.begin(), DFBlocks.end()); + + for (unsigned i = 0, e = DFBlocks.size(); i != e; ++i) { + BasicBlock *BB = DFBlocks[i].second; + if (QueuePhiNode(BB, AllocaNum, CurrentVersion)) + Info.DefiningBlocks.push_back(BB); + } + DFBlocks.clear(); + } } /// RewriteSingleStoreAlloca - If there is only a single store to this value, @@ -1110,9 +1040,10 @@ NextIteration: /// made to the IR. /// void llvm::PromoteMemToReg(const std::vector &Allocas, - DominatorTree &DT, AliasSetTracker *AST) { + DominatorTree &DT, DominanceFrontier &DF, + AliasSetTracker *AST) { // If there is nothing to do, bail out... if (Allocas.empty()) return; - PromoteMem2Reg(Allocas, DT, AST).run(); + PromoteMem2Reg(Allocas, DT, DF, AST).run(); }