diff options
author | Chad Rosier <mcrosier@codeaurora.org> | 2016-08-17 15:54:39 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@codeaurora.org> | 2016-08-17 15:54:39 +0000 |
commit | ea7e4647dbebcbbf327b747cba651e13e1fc65b0 (patch) | |
tree | 71296325466b661f33338fb35e00dfa27e4d05ff /llvm/lib/Transforms/Scalar/Reassociate.cpp | |
parent | cbce96c3afbccc0c8b703ca818b6d4d60402f141 (diff) | |
download | bcm5719-llvm-ea7e4647dbebcbbf327b747cba651e13e1fc65b0.tar.gz bcm5719-llvm-ea7e4647dbebcbbf327b747cba651e13e1fc65b0.zip |
Revert "Reassociate: Reprocess RedoInsts after each inst".
This reverts commit r258830, which introduced a bug described in PR28367.
PR28367
llvm-svn: 278938
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Reassociate.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/Reassociate.cpp | 64 |
1 files changed, 27 insertions, 37 deletions
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index b930a8fb7e9..e42e2c6d8aa 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -145,8 +145,7 @@ static BinaryOperator *isReassociableOp(Value *V, unsigned Opcode1, return nullptr; } -void ReassociatePass::BuildRankMap( - Function &F, ReversePostOrderTraversal<Function *> &RPOT) { +void ReassociatePass::BuildRankMap(Function &F) { unsigned i = 2; // Assign distinct ranks to function arguments. @@ -155,6 +154,7 @@ void ReassociatePass::BuildRankMap( DEBUG(dbgs() << "Calculated Rank[" << I->getName() << "] = " << i << "\n"); } + ReversePostOrderTraversal<Function *> RPOT(&F); for (BasicBlock *BB : RPOT) { unsigned BBRank = RankMap[BB] = ++i << 16; @@ -2172,28 +2172,13 @@ void ReassociatePass::ReassociateExpression(BinaryOperator *I) { } PreservedAnalyses ReassociatePass::run(Function &F, FunctionAnalysisManager &) { - // Reassociate needs for each instruction to have its operands already - // processed, so we first perform a RPOT of the basic blocks so that - // when we process a basic block, all its dominators have been processed - // before. - ReversePostOrderTraversal<Function *> RPOT(&F); - BuildRankMap(F, RPOT); + // Calculate the rank map for F. + BuildRankMap(F); MadeChange = false; - for (BasicBlock *BI : RPOT) { - // Use a worklist to keep track of which instructions have been processed - // (and which insts won't be optimized again) so when redoing insts, - // optimize insts rightaway which won't be processed later. - SmallSet<Instruction *, 8> Worklist; - - // Insert all instructions in the BB - for (Instruction &I : *BI) - Worklist.insert(&I); - + for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) { // Optimize every instruction in the basic block. - for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE;) { - // This instruction has been processed. - Worklist.erase(&*II); + for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE;) if (isInstructionTriviallyDead(&*II)) { EraseInst(&*II++); } else { @@ -2202,22 +2187,27 @@ PreservedAnalyses ReassociatePass::run(Function &F, FunctionAnalysisManager &) { ++II; } - // If the above optimizations produced new instructions to optimize or - // made modifications which need to be redone, do them now if they won't - // be handled later. - while (!RedoInsts.empty()) { - Instruction *I = RedoInsts.pop_back_val(); - // Process instructions that won't be processed later, either - // inside the block itself or in another basic block (based on rank), - // since these will be processed later. - if ((I->getParent() != BI || !Worklist.count(I)) && - RankMap[I->getParent()] <= RankMap[BI]) { - if (isInstructionTriviallyDead(I)) - EraseInst(I); - else - OptimizeInst(I); - } - } + // Make a copy of all the instructions to be redone so we can remove dead + // instructions. + SetVector<AssertingVH<Instruction>> ToRedo(RedoInsts); + // Iterate over all instructions to be reevaluated and remove trivially dead + // instructions. If any operand of the trivially dead instruction becomes + // dead mark it for deletion as well. Continue this process until all + // trivially dead instructions have been removed. + while (!ToRedo.empty()) { + Instruction *I = ToRedo.pop_back_val(); + if (isInstructionTriviallyDead(I)) + RecursivelyEraseDeadInsts(I, ToRedo); + } + + // Now that we have removed dead instructions, we can reoptimize the + // remaining instructions. + while (!RedoInsts.empty()) { + Instruction *I = RedoInsts.pop_back_val(); + if (isInstructionTriviallyDead(I)) + EraseInst(I); + else + OptimizeInst(I); } } |