mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	to declare that they preserve other passes without needing to pull in additional header file or library dependencies. Convert MachineFunctionPass and CodeGenLICM to make use of this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83555 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			113 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===- CodeGenLICM.cpp - LICM a function for code generation --------------===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This function performs late LICM, hoisting constants out of loops that
 | |
| // are not valid immediates. It should not be followed by instcombine,
 | |
| // because instcombine would quickly stuff the constants back into the loop.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #define DEBUG_TYPE "codegen-licm"
 | |
| #include "llvm/Transforms/Scalar.h"
 | |
| #include "llvm/Constants.h"
 | |
| #include "llvm/DerivedTypes.h"
 | |
| #include "llvm/Instructions.h"
 | |
| #include "llvm/IntrinsicInst.h"
 | |
| #include "llvm/LLVMContext.h"
 | |
| #include "llvm/Analysis/LoopPass.h"
 | |
| #include "llvm/Analysis/AliasAnalysis.h"
 | |
| #include "llvm/ADT/DenseMap.h"
 | |
| using namespace llvm;
 | |
| 
 | |
| namespace {
 | |
|   class CodeGenLICM : public LoopPass {
 | |
|     virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
 | |
|     virtual void getAnalysisUsage(AnalysisUsage &AU) const;
 | |
|   public:
 | |
|     static char ID; // Pass identification, replacement for typeid
 | |
|     explicit CodeGenLICM() : LoopPass(&ID) {}
 | |
|   };
 | |
| }
 | |
| 
 | |
| char CodeGenLICM::ID = 0;
 | |
| static RegisterPass<CodeGenLICM> X("codegen-licm",
 | |
|                                    "hoist constants out of loops");
 | |
| 
 | |
| Pass *llvm::createCodeGenLICMPass() {
 | |
|   return new CodeGenLICM();
 | |
| }
 | |
| 
 | |
| bool CodeGenLICM::runOnLoop(Loop *L, LPPassManager &) {
 | |
|   bool Changed = false;
 | |
| 
 | |
|   // Only visit outermost loops.
 | |
|   if (L->getParentLoop()) return Changed;
 | |
| 
 | |
|   Instruction *PreheaderTerm = L->getLoopPreheader()->getTerminator();
 | |
|   DenseMap<Constant *, BitCastInst *> HoistedConstants;
 | |
| 
 | |
|   for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
 | |
|        I != E; ++I) {
 | |
|     BasicBlock *BB = *I;
 | |
|     for (BasicBlock::iterator BBI = BB->begin(), BBE = BB->end();
 | |
|          BBI != BBE; ++BBI) {
 | |
|       Instruction *I = BBI;
 | |
|       // TODO: For now, skip all intrinsic instructions, because some of them
 | |
|       // can require their operands to be constants, and we don't want to
 | |
|       // break that.
 | |
|       if (isa<IntrinsicInst>(I))
 | |
|         continue;
 | |
|       // LLVM represents fneg as -0.0-x; don't hoist the -0.0 out.
 | |
|       if (BinaryOperator::isFNeg(I) ||
 | |
|           BinaryOperator::isNeg(I) ||
 | |
|           BinaryOperator::isNot(I))
 | |
|         continue;
 | |
|       for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
 | |
|         // Don't hoist out switch case constants.
 | |
|         if (isa<SwitchInst>(I) && i == 1)
 | |
|           break;
 | |
|         // Don't hoist out shuffle masks.
 | |
|         if (isa<ShuffleVectorInst>(I) && i == 2)
 | |
|           break;
 | |
|         Value *Op = I->getOperand(i);
 | |
|         Constant *C = dyn_cast<Constant>(Op);
 | |
|         if (!C) continue;
 | |
|         // TODO: Ask the target which constants are legal. This would allow
 | |
|         // us to add support for hoisting ConstantInts and GlobalValues too.
 | |
|         if (isa<ConstantFP>(C) ||
 | |
|             isa<ConstantVector>(C) ||
 | |
|             isa<ConstantAggregateZero>(C)) {
 | |
|           BitCastInst *&BC = HoistedConstants[C];
 | |
|           if (!BC)
 | |
|             BC = new BitCastInst(C, C->getType(), "hoist", PreheaderTerm);
 | |
|           I->setOperand(i, BC);
 | |
|           Changed = true;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return Changed;
 | |
| }
 | |
| 
 | |
| void CodeGenLICM::getAnalysisUsage(AnalysisUsage &AU) const {
 | |
|   // This pass preserves just about everything. List some popular things here.
 | |
|   AU.setPreservesCFG();
 | |
|   AU.addPreservedID(LoopSimplifyID);
 | |
|   AU.addPreserved<LoopInfo>();
 | |
|   AU.addPreserved<AliasAnalysis>();
 | |
|   AU.addPreserved("scalar-evolution");
 | |
|   AU.addPreserved("iv-users");
 | |
|   AU.addPreserved("lda");
 | |
|   AU.addPreserved("live-values");
 | |
| 
 | |
|   // Hoisting requires a loop preheader.
 | |
|   AU.addRequiredID(LoopSimplifyID);
 | |
| }
 |