llvm-6502/lib/Transforms/Scalar/CodeGenLICM.cpp
Dan Gohman 8a261e44f7 Add a form of addPreserved which takes a string argument, to allow passes
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
2009-10-08 17:00:02 +00:00

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);
}