From 7e02b7e600ce8b719b34e2df7a7e44310229564d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 30 Jun 2001 04:36:40 +0000 Subject: [PATCH] Optimizations got their own header files Optimizations now live in the 'opt' namespace include/llvm/Opt was renamed include/llvm/Optimizations git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/InlineSimple.cpp | 11 +- lib/Transforms/Scalar/ConstantProp.cpp | 18 +- lib/Transforms/Scalar/DCE.cpp | 246 ++++++++++++---------- lib/Transforms/Scalar/InductionVars.cpp | 10 +- lib/Transforms/Scalar/SCCP.cpp | 22 +- lib/Transforms/Scalar/SymbolStripping.cpp | 6 +- lib/VMCore/ConstantFold.cpp | 7 +- 7 files changed, 172 insertions(+), 148 deletions(-) diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp index e5bc171beb1..d85b33dffd1 100644 --- a/lib/Transforms/IPO/InlineSimple.cpp +++ b/lib/Transforms/IPO/InlineSimple.cpp @@ -19,17 +19,18 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Optimizations/MethodInlining.h" #include "llvm/Module.h" #include "llvm/Method.h" -#include "llvm/BasicBlock.h" #include "llvm/iTerminators.h" #include "llvm/iOther.h" -#include "llvm/Opt/AllOpts.h" #include #include #include "llvm/Assembly/Writer.h" +using namespace opt; + // RemapInstruction - Convert the instruction operands from referencing the // current values into those specified by ValueMap. // @@ -60,7 +61,7 @@ static inline void RemapInstruction(Instruction *I, // exists in the instruction stream. Similiarly this will inline a recursive // method by one level. // -bool InlineMethod(BasicBlock::iterator CIIt) { +bool opt::InlineMethod(BasicBlock::iterator CIIt) { assert((*CIIt)->getInstType() == Instruction::Call && "InlineMethod only works on CallInst nodes!"); assert((*CIIt)->getParent() && "Instruction not embedded in basic block!"); @@ -218,7 +219,7 @@ bool InlineMethod(BasicBlock::iterator CIIt) { return true; } -bool InlineMethod(CallInst *CI) { +bool opt::InlineMethod(CallInst *CI) { assert(CI->getParent() && "CallInst not embeded in BasicBlock!"); BasicBlock *PBB = CI->getParent(); @@ -260,7 +261,7 @@ static inline bool DoMethodInlining(BasicBlock *BB) { return false; } -bool DoMethodInlining(Method *M) { +bool opt::DoMethodInlining(Method *M) { bool Changed = false; // Loop through now and inline instructions a basic block at a time... diff --git a/lib/Transforms/Scalar/ConstantProp.cpp b/lib/Transforms/Scalar/ConstantProp.cpp index 51800f5a6b6..7a0254bca7a 100644 --- a/lib/Transforms/Scalar/ConstantProp.cpp +++ b/lib/Transforms/Scalar/ConstantProp.cpp @@ -21,6 +21,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Optimizations/ConstantProp.h" +#include "llvm/Optimizations/ConstantHandling.h" #include "llvm/Module.h" #include "llvm/Method.h" #include "llvm/BasicBlock.h" @@ -28,18 +30,16 @@ #include "llvm/iOther.h" #include "llvm/ConstPoolVals.h" #include "llvm/ConstantPool.h" -#include "llvm/Opt/AllOpts.h" -#include "llvm/Opt/ConstantHandling.h" // Merge identical constant values in the constant pool. // // TODO: We can do better than this simplistic N^2 algorithm... // -bool DoConstantPoolMerging(Method *M) { +bool opt::DoConstantPoolMerging(Method *M) { return DoConstantPoolMerging(M->getConstantPool()); } -bool DoConstantPoolMerging(ConstantPool &CP) { +bool opt::DoConstantPoolMerging(ConstantPool &CP) { bool Modified = false; for (ConstantPool::plane_iterator PI = CP.begin(); PI != CP.end(); ++PI) { for (ConstantPool::PlaneType::iterator I = (*PI)->begin(); @@ -73,7 +73,7 @@ inline static bool ConstantFoldUnaryInst(Method *M, Method::inst_iterator &DI, UnaryOperator *Op, ConstPoolVal *D) { ConstPoolVal *ReplaceWith = - ConstantFoldUnaryInstruction(Op->getInstType(), D); + opt::ConstantFoldUnaryInstruction(Op->getInstType(), D); if (!ReplaceWith) return false; // Nothing new to change... @@ -100,7 +100,7 @@ ConstantFoldBinaryInst(Method *M, Method::inst_iterator &DI, BinaryOperator *Op, ConstPoolVal *D1, ConstPoolVal *D2) { ConstPoolVal *ReplaceWith = - ConstantFoldBinaryInstruction(Op->getInstType(), D1, D2); + opt::ConstantFoldBinaryInstruction(Op->getInstType(), D1, D2); if (!ReplaceWith) return false; // Nothing new to change... // Add the new value to the constant pool... @@ -124,7 +124,7 @@ ConstantFoldBinaryInst(Method *M, Method::inst_iterator &DI, // constant value, convert it into an unconditional branch to the constant // destination. // -bool ConstantFoldTerminator(TerminatorInst *T) { +bool opt::ConstantFoldTerminator(TerminatorInst *T) { // Branch - See if we are conditional jumping on constant if (T->getInstType() == Instruction::Br) { BranchInst *BI = (BranchInst*)T; @@ -186,7 +186,7 @@ ConstantFoldInstruction(Method *M, Method::inst_iterator &II) { ConstPoolVal *D = Inst->getOperand(0)->castConstant(); if (D) return ConstantFoldUnaryInst(M, II, (UnaryOperator*)Inst, D); } else if (Inst->isTerminator()) { - return ConstantFoldTerminator((TerminatorInst*)Inst); + return opt::ConstantFoldTerminator((TerminatorInst*)Inst); } else if (Inst->isPHINode()) { PHINode *PN = (PHINode*)Inst; // If it's a PHI node and only has one operand @@ -238,7 +238,7 @@ static bool DoConstPropPass(Method *M) { // returns true on failure, false on success... // -bool DoConstantPropogation(Method *M) { +bool opt::DoConstantPropogation(Method *M) { bool Modified = false; // Fold constants until we make no progress... diff --git a/lib/Transforms/Scalar/DCE.cpp b/lib/Transforms/Scalar/DCE.cpp index be502691992..8e37279178d 100644 --- a/lib/Transforms/Scalar/DCE.cpp +++ b/lib/Transforms/Scalar/DCE.cpp @@ -22,15 +22,15 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Optimizations/DCE.h" +#include "llvm/Tools/STLExtras.h" #include "llvm/Module.h" #include "llvm/Method.h" #include "llvm/BasicBlock.h" #include "llvm/iTerminators.h" #include "llvm/iOther.h" -#include "llvm/Opt/AllOpts.h" #include "llvm/Assembly/Writer.h" #include "llvm/CFG.h" -#include "llvm/Tools/STLExtras.h" #include using namespace cfg; @@ -103,7 +103,7 @@ static bool RemoveSingularPHIs(BasicBlock *BB) { return true; // Yes, we nuked at least one phi node } -bool DoRemoveUnusedConstants(SymTabValue *S) { +bool opt::DoRemoveUnusedConstants(SymTabValue *S) { bool Changed = false; ConstantPool &CP = S->getConstantPool(); for (ConstantPool::plane_iterator PI = CP.begin(); PI != CP.end(); ++PI) @@ -164,6 +164,125 @@ static void PropogatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) { } while ((*I)->isPHINode()); } + +// SimplifyCFG - This function is used to do simplification of a CFG. For +// example, it adjusts branches to branches to eliminate the extra hop, it +// eliminates unreachable basic blocks, and does other "peephole" optimization +// of the CFG. It returns true if a modification was made, and returns an +// iterator that designates the first element remaining after the block that +// was deleted. +// +// WARNING: The entry node of a method may not be simplified. +// +bool opt::SimplifyCFG(Method::iterator &BBIt) { + assert(*BBIt && (*BBIt)->getParent() && "Block not embedded in method!"); + BasicBlock *BB = *BBIt; + Method *M = BB->getParent(); + assert(BB->getTerminator() && "Degenerate basic block encountered!"); + assert(BB->getParent()->front() != BB && "Can't Simplify entry block!"); + + // Remove basic blocks that have no predecessors... which are unreachable. + if (pred_begin(BB) == pred_end(BB) && + !BB->hasConstantPoolReferences()) { + //cerr << "Removing BB: \n" << BB; + + // Loop through all of our successors and make sure they know that one + // of their predecessors is going away. + for_each(succ_begin(BB), succ_end(BB), + std::bind2nd(std::mem_fun(&BasicBlock::removePredecessor), BB)); + + while (!BB->empty()) { + Instruction *I = BB->back(); + // If this instruction is used, replace uses with an arbitrary + // constant value. Because control flow can't get here, we don't care + // what we replace the value with. Note that since this block is + // unreachable, and all values contained within it must dominate their + // uses, that all uses will eventually be removed. + if (!I->use_empty()) ReplaceUsesWithConstant(I); + + // Remove the instruction from the basic block + delete BB->getInstList().pop_back(); + } + delete M->getBasicBlocks().remove(BBIt); + return true; + } + + // Check to see if this block has no instructions and only a single + // successor. If so, replace block references with successor. + succ_iterator SI(succ_begin(BB)); + if (SI != succ_end(BB) && ++SI == succ_end(BB)) { // One succ? + Instruction *I = BB->front(); + if (I->isTerminator()) { // Terminator is the only instruction! + BasicBlock *Succ = *succ_begin(BB); // There is exactly one successor + //cerr << "Killing Trivial BB: \n" << BB; + + if (Succ != BB) { // Arg, don't hurt infinite loops! + if (Succ->front()->isPHINode()) { + // If our successor has PHI nodes, then we need to update them to + // include entries for BB's predecessors, not for BB itself. + // + PropogatePredecessorsForPHIs(BB, Succ); + } + + BB->replaceAllUsesWith(Succ); + BB = M->getBasicBlocks().remove(BBIt); + + if (BB->hasName() && !Succ->hasName()) // Transfer name if we can + Succ->setName(BB->getName()); + delete BB; // Delete basic block + + //cerr << "Method after removal: \n" << M; + return true; + } + } + } + + // Merge basic blocks into their predecessor if there is only one pred, + // and if there is only one successor of the predecessor. + pred_iterator PI(pred_begin(BB)); + if (PI != pred_end(BB) && *PI != BB && // Not empty? Not same BB? + ++PI == pred_end(BB) && !BB->hasConstantPoolReferences()) { + BasicBlock *Pred = *pred_begin(BB); + TerminatorInst *Term = Pred->getTerminator(); + assert(Term != 0 && "malformed basic block without terminator!"); + + // Does the predecessor block only have a single successor? + succ_iterator SI(succ_begin(Pred)); + if (++SI == succ_end(Pred)) { + //cerr << "Merging: " << BB << "into: " << Pred; + + // Delete the unconditianal branch from the predecessor... + BasicBlock::iterator DI = Pred->end(); + assert(Pred->getTerminator() && + "Degenerate basic block encountered!"); // Empty bb??? + delete Pred->getInstList().remove(--DI); // Destroy uncond branch + + // Move all definitions in the succecessor to the predecessor... + while (!BB->empty()) { + DI = BB->begin(); + Instruction *Def = BB->getInstList().remove(DI); // Remove from front + Pred->getInstList().push_back(Def); // Add to end... + } + + // Remove basic block from the method... and advance iterator to the + // next valid block... + BB = M->getBasicBlocks().remove(BBIt); + + // Make all PHI nodes that refered to BB now refer to Pred as their + // source... + BB->replaceAllUsesWith(Pred); + + // Inherit predecessors name if it exists... + if (BB->hasName() && !Pred->hasName()) Pred->setName(BB->getName()); + + delete BB; // You ARE the weakest link... goodbye + return true; + } + } + + return false; +} + static bool DoDCEPass(Method *M) { Method::iterator BBIt, BBEnd = M->end(); if (M->begin() == BBEnd) return false; // Nothing to do @@ -178,134 +297,31 @@ static bool DoDCEPass(Method *M) { // Loop over all of the basic blocks (except the first one) and remove them // if they are unneeded... // - for (BBIt = M->begin(), ++BBIt; BBIt != M->end(); ++BBIt) { - BasicBlock *BB = *BBIt; - assert(BB->getTerminator() && "Degenerate basic block encountered!"); - - // Remove basic blocks that have no predecessors... which are unreachable. - if (pred_begin(BB) == pred_end(BB) && - !BB->hasConstantPoolReferences() && 0) { - //cerr << "Removing BB: \n" << BB; - - // Loop through all of our successors and make sure they know that one - // of their predecessors is going away. - for_each(succ_begin(BB), succ_end(BB), - bind_obj(BB, &BasicBlock::removePredecessor)); - - while (!BB->empty()) { - Instruction *I = BB->front(); - // If this instruction is used, replace uses with an arbitrary - // constant value. Because control flow can't get here, we don't care - // what we replace the value with. - if (!I->use_empty()) ReplaceUsesWithConstant(I); - - // Remove the instruction from the basic block - delete BB->getInstList().remove(BB->begin()); - } - delete M->getBasicBlocks().remove(BBIt); - --BBIt; // remove puts use on the next block, we want the previous one + for (BBIt = M->begin(), ++BBIt; BBIt != M->end(); ) { + if (opt::SimplifyCFG(BBIt)) { Changed = true; - continue; - } - - // Check to see if this block has no instructions and only a single - // successor. If so, replace block references with successor. - succ_iterator SI(succ_begin(BB)); - if (SI != succ_end(BB) && ++SI == succ_end(BB)) { // One succ? - Instruction *I = BB->front(); - if (I->isTerminator()) { // Terminator is the only instruction! - BasicBlock *Succ = *succ_begin(BB); // There is exactly one successor - //cerr << "Killing Trivial BB: \n" << BB; - - if (Succ != BB) { // Arg, don't hurt infinite loops! - if (Succ->front()->isPHINode()) { - // If our successor has PHI nodes, then we need to update them to - // include entries for BB's predecessors, not for BB itself. - // - PropogatePredecessorsForPHIs(BB, Succ); - } - - BB->replaceAllUsesWith(Succ); - - BB = M->getBasicBlocks().remove(BBIt); - --BBIt; // remove puts use on the next block, we want the previous one - - if (BB->hasName() && !Succ->hasName()) // Transfer name if we can - Succ->setName(BB->getName()); - delete BB; // Delete basic block - - //cerr << "Method after removal: \n" << M; - Changed = true; - continue; - } - } - } - - // Merge basic blocks into their predecessor if there is only one pred, - // and if there is only one successor of the predecessor. - pred_iterator PI(pred_begin(BB)); - if (PI != pred_end(BB) && *PI != BB && // Not empty? Not same BB? - ++PI == pred_end(BB) && !BB->hasConstantPoolReferences()) { - BasicBlock *Pred = *pred_begin(BB); - TerminatorInst *Term = Pred->getTerminator(); - assert(Term != 0 && "malformed basic block without terminator!"); - - // Does the predecessor block only have a single successor? - succ_iterator SI(succ_begin(Pred)); - if (++SI == succ_end(Pred)) { - //cerr << "Merging: " << BB << "into: " << Pred; - - // Delete the unconditianal branch from the predecessor... - BasicBlock::iterator DI = Pred->end(); - assert(Pred->getTerminator() && - "Degenerate basic block encountered!"); // Empty bb??? - delete Pred->getInstList().remove(--DI); // Destroy uncond branch - - // Move all definitions in the succecessor to the predecessor... - while (!BB->empty()) { - DI = BB->begin(); - Instruction *Def = BB->getInstList().remove(DI); // Remove from front - Pred->getInstList().push_back(Def); // Add to end... - } - - // Remove basic block from the method... and advance iterator to the - // next valid block... - BB = M->getBasicBlocks().remove(BBIt); - --BBIt; // remove puts us on the NEXT bb. We want the prev BB - Changed = true; - - // Make all PHI nodes that refered to BB now refer to Pred as their - // source... - BB->replaceAllUsesWith(Pred); - - // Inherit predecessors name if it exists... - if (BB->hasName() && !Pred->hasName()) Pred->setName(BB->getName()); - - // You ARE the weakest link... goodbye - delete BB; - - //WriteToVCG(M, "MergedInto"); - } + } else { + ++BBIt; } } // Remove unused constants - Changed |= DoRemoveUnusedConstants(M); - return Changed; + return Changed | opt::DoRemoveUnusedConstants(M); } // It is possible that we may require multiple passes over the code to fully // eliminate dead code. Iterate until we are done. // -bool DoDeadCodeElimination(Method *M) { +bool opt::DoDeadCodeElimination(Method *M) { bool Changed = false; while (DoDCEPass(M)) Changed = true; return Changed; } -bool DoDeadCodeElimination(Module *C) { - bool Val = ApplyOptToAllMethods(C, DoDeadCodeElimination); +bool opt::DoDeadCodeElimination(Module *C) { + bool Val = C->reduceApply(DoDeadCodeElimination); + while (DoRemoveUnusedConstants(C)) Val = true; return Val; } diff --git a/lib/Transforms/Scalar/InductionVars.cpp b/lib/Transforms/Scalar/InductionVars.cpp index 28ab29fd49c..b39a523f591 100644 --- a/lib/Transforms/Scalar/InductionVars.cpp +++ b/lib/Transforms/Scalar/InductionVars.cpp @@ -19,7 +19,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Opt/AllOpts.h" +#include "llvm/Optimizations/InductionVars.h" #include "llvm/ConstPoolVals.h" #include "llvm/Analysis/IntervalPartition.h" #include "llvm/Assembly/Writer.h" @@ -29,6 +29,10 @@ #include "llvm/CFG.h" #include +#include "llvm/Analysis/LoopDepth.h" + +using namespace opt; + // isLoopInvariant - Return true if the specified value/basic block source is // an interval invariant computation. // @@ -379,13 +383,11 @@ static bool ProcessIntervalPartition(cfg::IntervalPartition &IP) { ptr_fun(ProcessInterval)); } -#include "llvm/Analysis/LoopDepth.h" - // DoInductionVariableCannonicalize - Simplify induction variables in loops. // This function loops over an interval partition of a program, reducing it // until the graph is gone. // -bool DoInductionVariableCannonicalize(Method *M) { +bool opt::DoInductionVariableCannonicalize(Method *M) { // TODO: REMOVE if (0) { // Print basic blocks with their depth LoopDepthCalculator LDC(M); diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 7273aec3f4d..30c625475f6 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -15,21 +15,21 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Opt/AllOpts.h" +#include "llvm/Optimizations/ConstantProp.h" +#include "llvm/Optimizations/ConstantHandling.h" #include "llvm/Method.h" #include "llvm/BasicBlock.h" #include "llvm/ConstPoolVals.h" #include "llvm/ConstantPool.h" -#include "llvm/Opt/ConstantHandling.h" #include "llvm/InstrTypes.h" #include "llvm/iOther.h" #include "llvm/iTerminators.h" +#include "llvm/Tools/STLExtras.h" //#include "llvm/Assembly/Writer.h" #include #include #include - // InstVal class - This class represents the different lattice values that an // instruction may occupy. It is a simple class with value semantics. The // potential constant value that is pointed to is owned by the constant pool @@ -270,7 +270,7 @@ bool SCCP::doSCCP() { MadeChanges = true; continue; // Skip the ++II at the end of the loop here... } else if (Inst->isTerminator()) { - MadeChanges |= ConstantFoldTerminator((TerminatorInst*)Inst); + MadeChanges |= opt::ConstantFoldTerminator((TerminatorInst*)Inst); } ++II; @@ -280,7 +280,7 @@ bool SCCP::doSCCP() { // introduced constants that already exist, and we don't want to pollute later // stages with extraneous constants. // - return MadeChanges | DoConstantPoolMerging(M->getConstantPool()); + return MadeChanges | opt::DoConstantPoolMerging(M->getConstantPool()); } @@ -437,7 +437,8 @@ void SCCP::UpdateInstruction(Instruction *I) { markOverdefined(I); } else if (VState.isConstant()) { // Propogate constant value ConstPoolVal *Result = - ConstantFoldUnaryInstruction(I->getInstType(), VState.getConstant()); + opt::ConstantFoldUnaryInstruction(I->getInstType(), + VState.getConstant()); if (Result) { // This instruction constant folds! The only problem is that the value @@ -465,9 +466,9 @@ void SCCP::UpdateInstruction(Instruction *I) { markOverdefined(I); } else if (V1State.isConstant() && V2State.isConstant()) { ConstPoolVal *Result = - ConstantFoldBinaryInstruction(I->getInstType(), V1State.getConstant(), - V2State.getConstant()); - + opt::ConstantFoldBinaryInstruction(I->getInstType(), + V1State.getConstant(), + V2State.getConstant()); if (Result) { // This instruction constant folds! The only problem is that the value // returned is newly allocated. Make sure to stick it into the methods @@ -506,8 +507,7 @@ void SCCP::OperandChangedState(User *U) { // DoSparseConditionalConstantProp - Use Sparse Conditional Constant Propogation // to prove whether a value is constant and whether blocks are used. // -bool DoSparseConditionalConstantProp(Method *M) { +bool opt::DoSparseConditionalConstantProp(Method *M) { SCCP S(M); return S.doSCCP(); } - diff --git a/lib/Transforms/Scalar/SymbolStripping.cpp b/lib/Transforms/Scalar/SymbolStripping.cpp index 33b600560ac..bafcee6be7c 100644 --- a/lib/Transforms/Scalar/SymbolStripping.cpp +++ b/lib/Transforms/Scalar/SymbolStripping.cpp @@ -14,10 +14,10 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Optimizations/AllOpts.h" #include "llvm/Module.h" #include "llvm/Method.h" #include "llvm/SymbolTable.h" -#include "llvm/Opt/AllOpts.h" static bool StripSymbolTable(SymbolTable *SymTab) { if (SymTab == 0) return false; // No symbol table? No problem. @@ -40,14 +40,14 @@ static bool StripSymbolTable(SymbolTable *SymTab) { // DoSymbolStripping - Remove all symbolic information from a method // -bool DoSymbolStripping(Method *M) { +bool opt::DoSymbolStripping(Method *M) { return StripSymbolTable(M->getSymbolTable()); } // DoFullSymbolStripping - Remove all symbolic information from all methods // in a module, and all module level symbols. (method names, etc...) // -bool DoFullSymbolStripping(Module *M) { +bool opt::DoFullSymbolStripping(Module *M) { // Remove all symbols from methods in this module... and then strip all of the // symbols in this module... // diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 438ea4b37c2..54a79804818 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -4,7 +4,9 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Opt/ConstantHandling.h" +#include "llvm/Optimizations/ConstantHandling.h" + +namespace opt { //===----------------------------------------------------------------------===// // TemplateRules Class @@ -195,3 +197,6 @@ const ConstRules *ConstRules::find(const Type *Ty) { Ty->setConstRules(Result); // Cache the value for future short circuiting! return Result; } + + +} // End namespace opt