mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	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
This commit is contained in:
		| @@ -19,17 +19,18 @@ | |||||||
| // | // | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
|  | #include "llvm/Optimizations/MethodInlining.h" | ||||||
| #include "llvm/Module.h" | #include "llvm/Module.h" | ||||||
| #include "llvm/Method.h" | #include "llvm/Method.h" | ||||||
| #include "llvm/BasicBlock.h" |  | ||||||
| #include "llvm/iTerminators.h" | #include "llvm/iTerminators.h" | ||||||
| #include "llvm/iOther.h" | #include "llvm/iOther.h" | ||||||
| #include "llvm/Opt/AllOpts.h" |  | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <map> | #include <map> | ||||||
|  |  | ||||||
| #include "llvm/Assembly/Writer.h" | #include "llvm/Assembly/Writer.h" | ||||||
|  |  | ||||||
|  | using namespace opt; | ||||||
|  |  | ||||||
| // RemapInstruction - Convert the instruction operands from referencing the  | // RemapInstruction - Convert the instruction operands from referencing the  | ||||||
| // current values into those specified by ValueMap. | // 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 | // exists in the instruction stream.  Similiarly this will inline a recursive | ||||||
| // method by one level. | // method by one level. | ||||||
| // | // | ||||||
| bool InlineMethod(BasicBlock::iterator CIIt) { | bool opt::InlineMethod(BasicBlock::iterator CIIt) { | ||||||
|   assert((*CIIt)->getInstType() == Instruction::Call &&  |   assert((*CIIt)->getInstType() == Instruction::Call &&  | ||||||
| 	 "InlineMethod only works on CallInst nodes!"); | 	 "InlineMethod only works on CallInst nodes!"); | ||||||
|   assert((*CIIt)->getParent() && "Instruction not embedded in basic block!"); |   assert((*CIIt)->getParent() && "Instruction not embedded in basic block!"); | ||||||
| @@ -218,7 +219,7 @@ bool InlineMethod(BasicBlock::iterator CIIt) { | |||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool InlineMethod(CallInst *CI) { | bool opt::InlineMethod(CallInst *CI) { | ||||||
|   assert(CI->getParent() && "CallInst not embeded in BasicBlock!"); |   assert(CI->getParent() && "CallInst not embeded in BasicBlock!"); | ||||||
|   BasicBlock *PBB = CI->getParent(); |   BasicBlock *PBB = CI->getParent(); | ||||||
|  |  | ||||||
| @@ -260,7 +261,7 @@ static inline bool DoMethodInlining(BasicBlock *BB) { | |||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool DoMethodInlining(Method *M) { | bool opt::DoMethodInlining(Method *M) { | ||||||
|   bool Changed = false; |   bool Changed = false; | ||||||
|  |  | ||||||
|   // Loop through now and inline instructions a basic block at a time... |   // Loop through now and inline instructions a basic block at a time... | ||||||
|   | |||||||
| @@ -21,6 +21,8 @@ | |||||||
| // | // | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
|  | #include "llvm/Optimizations/ConstantProp.h" | ||||||
|  | #include "llvm/Optimizations/ConstantHandling.h" | ||||||
| #include "llvm/Module.h" | #include "llvm/Module.h" | ||||||
| #include "llvm/Method.h" | #include "llvm/Method.h" | ||||||
| #include "llvm/BasicBlock.h" | #include "llvm/BasicBlock.h" | ||||||
| @@ -28,18 +30,16 @@ | |||||||
| #include "llvm/iOther.h" | #include "llvm/iOther.h" | ||||||
| #include "llvm/ConstPoolVals.h" | #include "llvm/ConstPoolVals.h" | ||||||
| #include "llvm/ConstantPool.h" | #include "llvm/ConstantPool.h" | ||||||
| #include "llvm/Opt/AllOpts.h" |  | ||||||
| #include "llvm/Opt/ConstantHandling.h" |  | ||||||
|  |  | ||||||
| // Merge identical constant values in the constant pool. | // Merge identical constant values in the constant pool. | ||||||
| //  | //  | ||||||
| // TODO: We can do better than this simplistic N^2 algorithm... | // TODO: We can do better than this simplistic N^2 algorithm... | ||||||
| // | // | ||||||
| bool DoConstantPoolMerging(Method *M) { | bool opt::DoConstantPoolMerging(Method *M) { | ||||||
|   return DoConstantPoolMerging(M->getConstantPool()); |   return DoConstantPoolMerging(M->getConstantPool()); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool DoConstantPoolMerging(ConstantPool &CP) { | bool opt::DoConstantPoolMerging(ConstantPool &CP) { | ||||||
|   bool Modified = false; |   bool Modified = false; | ||||||
|   for (ConstantPool::plane_iterator PI = CP.begin(); PI != CP.end(); ++PI) { |   for (ConstantPool::plane_iterator PI = CP.begin(); PI != CP.end(); ++PI) { | ||||||
|     for (ConstantPool::PlaneType::iterator I = (*PI)->begin();  |     for (ConstantPool::PlaneType::iterator I = (*PI)->begin();  | ||||||
| @@ -73,7 +73,7 @@ inline static bool | |||||||
| ConstantFoldUnaryInst(Method *M, Method::inst_iterator &DI, | ConstantFoldUnaryInst(Method *M, Method::inst_iterator &DI, | ||||||
|                       UnaryOperator *Op, ConstPoolVal *D) { |                       UnaryOperator *Op, ConstPoolVal *D) { | ||||||
|   ConstPoolVal *ReplaceWith =  |   ConstPoolVal *ReplaceWith =  | ||||||
|     ConstantFoldUnaryInstruction(Op->getInstType(), D); |     opt::ConstantFoldUnaryInstruction(Op->getInstType(), D); | ||||||
|  |  | ||||||
|   if (!ReplaceWith) return false;   // Nothing new to change... |   if (!ReplaceWith) return false;   // Nothing new to change... | ||||||
|  |  | ||||||
| @@ -100,7 +100,7 @@ ConstantFoldBinaryInst(Method *M, Method::inst_iterator &DI, | |||||||
| 		       BinaryOperator *Op, | 		       BinaryOperator *Op, | ||||||
| 		       ConstPoolVal *D1, ConstPoolVal *D2) { | 		       ConstPoolVal *D1, ConstPoolVal *D2) { | ||||||
|   ConstPoolVal *ReplaceWith = |   ConstPoolVal *ReplaceWith = | ||||||
|     ConstantFoldBinaryInstruction(Op->getInstType(), D1, D2); |     opt::ConstantFoldBinaryInstruction(Op->getInstType(), D1, D2); | ||||||
|   if (!ReplaceWith) return false;   // Nothing new to change... |   if (!ReplaceWith) return false;   // Nothing new to change... | ||||||
|  |  | ||||||
|   // Add the new value to the constant pool... |   // 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 | // constant value, convert it into an unconditional branch to the constant | ||||||
| // destination. | // destination. | ||||||
| // | // | ||||||
| bool ConstantFoldTerminator(TerminatorInst *T) { | bool opt::ConstantFoldTerminator(TerminatorInst *T) { | ||||||
|   // Branch - See if we are conditional jumping on constant |   // Branch - See if we are conditional jumping on constant | ||||||
|   if (T->getInstType() == Instruction::Br) { |   if (T->getInstType() == Instruction::Br) { | ||||||
|     BranchInst *BI = (BranchInst*)T; |     BranchInst *BI = (BranchInst*)T; | ||||||
| @@ -186,7 +186,7 @@ ConstantFoldInstruction(Method *M, Method::inst_iterator &II) { | |||||||
|     ConstPoolVal *D = Inst->getOperand(0)->castConstant(); |     ConstPoolVal *D = Inst->getOperand(0)->castConstant(); | ||||||
|     if (D) return ConstantFoldUnaryInst(M, II, (UnaryOperator*)Inst, D); |     if (D) return ConstantFoldUnaryInst(M, II, (UnaryOperator*)Inst, D); | ||||||
|   } else if (Inst->isTerminator()) { |   } else if (Inst->isTerminator()) { | ||||||
|     return ConstantFoldTerminator((TerminatorInst*)Inst); |     return opt::ConstantFoldTerminator((TerminatorInst*)Inst); | ||||||
|  |  | ||||||
|   } else if (Inst->isPHINode()) { |   } else if (Inst->isPHINode()) { | ||||||
|     PHINode *PN = (PHINode*)Inst; // If it's a PHI node and only has one operand |     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... | // returns true on failure, false on success... | ||||||
| // | // | ||||||
| bool DoConstantPropogation(Method *M) { | bool opt::DoConstantPropogation(Method *M) { | ||||||
|   bool Modified = false; |   bool Modified = false; | ||||||
|  |  | ||||||
|   // Fold constants until we make no progress... |   // Fold constants until we make no progress... | ||||||
|   | |||||||
| @@ -22,15 +22,15 @@ | |||||||
| // | // | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
|  | #include "llvm/Optimizations/DCE.h" | ||||||
|  | #include "llvm/Tools/STLExtras.h" | ||||||
| #include "llvm/Module.h" | #include "llvm/Module.h" | ||||||
| #include "llvm/Method.h" | #include "llvm/Method.h" | ||||||
| #include "llvm/BasicBlock.h" | #include "llvm/BasicBlock.h" | ||||||
| #include "llvm/iTerminators.h" | #include "llvm/iTerminators.h" | ||||||
| #include "llvm/iOther.h" | #include "llvm/iOther.h" | ||||||
| #include "llvm/Opt/AllOpts.h" |  | ||||||
| #include "llvm/Assembly/Writer.h" | #include "llvm/Assembly/Writer.h" | ||||||
| #include "llvm/CFG.h" | #include "llvm/CFG.h" | ||||||
| #include "llvm/Tools/STLExtras.h" |  | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
|  |  | ||||||
| using namespace cfg; | using namespace cfg; | ||||||
| @@ -103,7 +103,7 @@ static bool RemoveSingularPHIs(BasicBlock *BB) { | |||||||
|   return true;  // Yes, we nuked at least one phi node |   return true;  // Yes, we nuked at least one phi node | ||||||
| } | } | ||||||
|  |  | ||||||
| bool DoRemoveUnusedConstants(SymTabValue *S) { | bool opt::DoRemoveUnusedConstants(SymTabValue *S) { | ||||||
|   bool Changed = false; |   bool Changed = false; | ||||||
|   ConstantPool &CP = S->getConstantPool(); |   ConstantPool &CP = S->getConstantPool(); | ||||||
|   for (ConstantPool::plane_iterator PI = CP.begin(); PI != CP.end(); ++PI) |   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()); |   } 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) { | static bool DoDCEPass(Method *M) { | ||||||
|   Method::iterator BBIt, BBEnd = M->end(); |   Method::iterator BBIt, BBEnd = M->end(); | ||||||
|   if (M->begin() == BBEnd) return false;  // Nothing to do |   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 |   // Loop over all of the basic blocks (except the first one) and remove them | ||||||
|   // if they are unneeded... |   // if they are unneeded... | ||||||
|   // |   // | ||||||
|   for (BBIt = M->begin(), ++BBIt; BBIt != M->end(); ++BBIt) { |   for (BBIt = M->begin(), ++BBIt; BBIt != M->end(); ) { | ||||||
|     BasicBlock *BB = *BBIt; |     if (opt::SimplifyCFG(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 |  | ||||||
|       Changed = true; |       Changed = true; | ||||||
|       continue; |     } else { | ||||||
|     }  |       ++BBIt; | ||||||
|  |  | ||||||
|     // 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"); |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Remove unused constants |   // Remove unused constants | ||||||
|   Changed |= DoRemoveUnusedConstants(M); |   return Changed | opt::DoRemoveUnusedConstants(M); | ||||||
|   return Changed; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| // It is possible that we may require multiple passes over the code to fully | // It is possible that we may require multiple passes over the code to fully | ||||||
| // eliminate dead code.  Iterate until we are done. | // eliminate dead code.  Iterate until we are done. | ||||||
| // | // | ||||||
| bool DoDeadCodeElimination(Method *M) { | bool opt::DoDeadCodeElimination(Method *M) { | ||||||
|   bool Changed = false; |   bool Changed = false; | ||||||
|   while (DoDCEPass(M)) Changed = true; |   while (DoDCEPass(M)) Changed = true; | ||||||
|   return Changed; |   return Changed; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool DoDeadCodeElimination(Module *C) {  | bool opt::DoDeadCodeElimination(Module *C) {  | ||||||
|   bool Val = ApplyOptToAllMethods(C, DoDeadCodeElimination); |   bool Val = C->reduceApply(DoDeadCodeElimination); | ||||||
|  |  | ||||||
|   while (DoRemoveUnusedConstants(C)) Val = true; |   while (DoRemoveUnusedConstants(C)) Val = true; | ||||||
|   return Val; |   return Val; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ | |||||||
| // | // | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
| #include "llvm/Opt/AllOpts.h" | #include "llvm/Optimizations/InductionVars.h" | ||||||
| #include "llvm/ConstPoolVals.h" | #include "llvm/ConstPoolVals.h" | ||||||
| #include "llvm/Analysis/IntervalPartition.h" | #include "llvm/Analysis/IntervalPartition.h" | ||||||
| #include "llvm/Assembly/Writer.h" | #include "llvm/Assembly/Writer.h" | ||||||
| @@ -29,6 +29,10 @@ | |||||||
| #include "llvm/CFG.h" | #include "llvm/CFG.h" | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
|  |  | ||||||
|  | #include "llvm/Analysis/LoopDepth.h" | ||||||
|  |  | ||||||
|  | using namespace opt; | ||||||
|  |  | ||||||
| // isLoopInvariant - Return true if the specified value/basic block source is  | // isLoopInvariant - Return true if the specified value/basic block source is  | ||||||
| // an interval invariant computation. | // an interval invariant computation. | ||||||
| // | // | ||||||
| @@ -379,13 +383,11 @@ static bool ProcessIntervalPartition(cfg::IntervalPartition &IP) { | |||||||
| 		      ptr_fun(ProcessInterval)); | 		      ptr_fun(ProcessInterval)); | ||||||
| } | } | ||||||
|  |  | ||||||
| #include "llvm/Analysis/LoopDepth.h" |  | ||||||
|  |  | ||||||
| // DoInductionVariableCannonicalize - Simplify induction variables in loops. | // DoInductionVariableCannonicalize - Simplify induction variables in loops. | ||||||
| // This function loops over an interval partition of a program, reducing it | // This function loops over an interval partition of a program, reducing it | ||||||
| // until the graph is gone. | // until the graph is gone. | ||||||
| // | // | ||||||
| bool DoInductionVariableCannonicalize(Method *M) { | bool opt::DoInductionVariableCannonicalize(Method *M) { | ||||||
|   // TODO: REMOVE |   // TODO: REMOVE | ||||||
|   if (0) {   // Print basic blocks with their depth |   if (0) {   // Print basic blocks with their depth | ||||||
|     LoopDepthCalculator LDC(M); |     LoopDepthCalculator LDC(M); | ||||||
|   | |||||||
| @@ -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/Method.h" | ||||||
| #include "llvm/BasicBlock.h" | #include "llvm/BasicBlock.h" | ||||||
| #include "llvm/ConstPoolVals.h" | #include "llvm/ConstPoolVals.h" | ||||||
| #include "llvm/ConstantPool.h" | #include "llvm/ConstantPool.h" | ||||||
| #include "llvm/Opt/ConstantHandling.h" |  | ||||||
| #include "llvm/InstrTypes.h" | #include "llvm/InstrTypes.h" | ||||||
| #include "llvm/iOther.h" | #include "llvm/iOther.h" | ||||||
| #include "llvm/iTerminators.h" | #include "llvm/iTerminators.h" | ||||||
|  | #include "llvm/Tools/STLExtras.h" | ||||||
| //#include "llvm/Assembly/Writer.h" | //#include "llvm/Assembly/Writer.h" | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <map> | #include <map> | ||||||
| #include <set> | #include <set> | ||||||
|  |  | ||||||
|  |  | ||||||
| // InstVal class - This class represents the different lattice values that an  | // InstVal class - This class represents the different lattice values that an  | ||||||
| // instruction may occupy.  It is a simple class with value semantics.  The | // 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 | // potential constant value that is pointed to is owned by the constant pool | ||||||
| @@ -270,7 +270,7 @@ bool SCCP::doSCCP() { | |||||||
|       MadeChanges = true; |       MadeChanges = true; | ||||||
|       continue;   // Skip the ++II at the end of the loop here... |       continue;   // Skip the ++II at the end of the loop here... | ||||||
|     } else if (Inst->isTerminator()) { |     } else if (Inst->isTerminator()) { | ||||||
|       MadeChanges |= ConstantFoldTerminator((TerminatorInst*)Inst); |       MadeChanges |= opt::ConstantFoldTerminator((TerminatorInst*)Inst); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ++II; |     ++II; | ||||||
| @@ -280,7 +280,7 @@ bool SCCP::doSCCP() { | |||||||
|   // introduced constants that already exist, and we don't want to pollute later |   // introduced constants that already exist, and we don't want to pollute later | ||||||
|   // stages with extraneous constants. |   // 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); |       markOverdefined(I); | ||||||
|     } else if (VState.isConstant()) {    // Propogate constant value |     } else if (VState.isConstant()) {    // Propogate constant value | ||||||
|       ConstPoolVal *Result =  |       ConstPoolVal *Result =  | ||||||
| 	ConstantFoldUnaryInstruction(I->getInstType(), VState.getConstant()); | 	opt::ConstantFoldUnaryInstruction(I->getInstType(),  | ||||||
|  | 					  VState.getConstant()); | ||||||
|  |  | ||||||
|       if (Result) { |       if (Result) { | ||||||
| 	// This instruction constant folds!  The only problem is that the value | 	// This instruction constant folds!  The only problem is that the value | ||||||
| @@ -465,9 +466,9 @@ void SCCP::UpdateInstruction(Instruction *I) { | |||||||
|       markOverdefined(I); |       markOverdefined(I); | ||||||
|     } else if (V1State.isConstant() && V2State.isConstant()) { |     } else if (V1State.isConstant() && V2State.isConstant()) { | ||||||
|       ConstPoolVal *Result =  |       ConstPoolVal *Result =  | ||||||
| 	ConstantFoldBinaryInstruction(I->getInstType(), V1State.getConstant(), | 	opt::ConstantFoldBinaryInstruction(I->getInstType(),  | ||||||
| 				      V2State.getConstant()); | 					   V1State.getConstant(), | ||||||
|  | 					   V2State.getConstant()); | ||||||
|       if (Result) { |       if (Result) { | ||||||
| 	// This instruction constant folds!  The only problem is that the value | 	// This instruction constant folds!  The only problem is that the value | ||||||
| 	// returned is newly allocated.  Make sure to stick it into the methods | 	// 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 | // DoSparseConditionalConstantProp - Use Sparse Conditional Constant Propogation | ||||||
| // to prove whether a value is constant and whether blocks are used. | // to prove whether a value is constant and whether blocks are used. | ||||||
| // | // | ||||||
| bool DoSparseConditionalConstantProp(Method *M) { | bool opt::DoSparseConditionalConstantProp(Method *M) { | ||||||
|   SCCP S(M); |   SCCP S(M); | ||||||
|   return S.doSCCP(); |   return S.doSCCP(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,10 +14,10 @@ | |||||||
| // | // | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
|  | #include "llvm/Optimizations/AllOpts.h" | ||||||
| #include "llvm/Module.h" | #include "llvm/Module.h" | ||||||
| #include "llvm/Method.h" | #include "llvm/Method.h" | ||||||
| #include "llvm/SymbolTable.h" | #include "llvm/SymbolTable.h" | ||||||
| #include "llvm/Opt/AllOpts.h" |  | ||||||
|  |  | ||||||
| static bool StripSymbolTable(SymbolTable *SymTab) { | static bool StripSymbolTable(SymbolTable *SymTab) { | ||||||
|   if (SymTab == 0) return false;    // No symbol table?  No problem. |   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 | // DoSymbolStripping - Remove all symbolic information from a method | ||||||
| // | // | ||||||
| bool DoSymbolStripping(Method *M) { | bool opt::DoSymbolStripping(Method *M) { | ||||||
|   return StripSymbolTable(M->getSymbolTable()); |   return StripSymbolTable(M->getSymbolTable()); | ||||||
| } | } | ||||||
|  |  | ||||||
| // DoFullSymbolStripping - Remove all symbolic information from all methods  | // DoFullSymbolStripping - Remove all symbolic information from all methods  | ||||||
| // in a module, and all module level symbols. (method names, etc...) | // 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 |   // Remove all symbols from methods in this module... and then strip all of the | ||||||
|   // symbols in this module... |   // symbols in this module... | ||||||
|   //   |   //   | ||||||
|   | |||||||
| @@ -4,7 +4,9 @@ | |||||||
| // | // | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
| #include "llvm/Opt/ConstantHandling.h" | #include "llvm/Optimizations/ConstantHandling.h" | ||||||
|  |  | ||||||
|  | namespace opt { | ||||||
|  |  | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
| //                             TemplateRules Class | //                             TemplateRules Class | ||||||
| @@ -195,3 +197,6 @@ const ConstRules *ConstRules::find(const Type *Ty) { | |||||||
|   Ty->setConstRules(Result);   // Cache the value for future short circuiting! |   Ty->setConstRules(Result);   // Cache the value for future short circuiting! | ||||||
|   return Result; |   return Result; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } // End namespace opt | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user