Minor tuning -- avoid a non-inlinable function call on every operand.

Also, reorder a couple of functions for inlining.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6635 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve 2003-06-05 21:12:56 +00:00
parent 9783301b9d
commit cf819454e4

View File

@ -115,6 +115,7 @@ namespace {
class PreSelection : public BasicBlockPass, public InstVisitor<PreSelection>
{
const TargetMachine &target;
const TargetInstrInfo &instrInfo;
Function* function;
GlobalVariable* getGlobalForConstant(Constant* CV) {
@ -123,7 +124,8 @@ namespace {
}
public:
PreSelection (const TargetMachine &T): target(T), function(NULL) {}
PreSelection (const TargetMachine &T):
target(T), instrInfo(T.getInstrInfo()), function(NULL) {}
// runOnBasicBlock - apply this pass to each BB
bool runOnBasicBlock(BasicBlock &BB) {
@ -237,6 +239,75 @@ static Instruction* DecomposeConstantExpr(ConstantExpr* CE,
//------------------------------------------------------------------------------
// Instruction visitor methods to perform instruction-specific operations
//------------------------------------------------------------------------------
inline void
PreSelection::visitOneOperand(Instruction &I, Value* Op, unsigned opNum,
Instruction& insertBefore)
{
if (GetElementPtrInst* gep = getGlobalAddr(Op, insertBefore)) {
I.setOperand(opNum, gep); // replace global operand
return;
}
Constant* CV = dyn_cast<Constant>(Op);
if (CV == NULL)
return;
if (ConstantExpr* CE = dyn_cast<ConstantExpr>(CV))
{ // load-time constant: factor it out so we optimize as best we can
Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore);
I.setOperand(opNum, computeConst); // replace expr operand with result
}
else if (instrInfo.ConstantTypeMustBeLoaded(CV))
{ // load address of constant into a register, then load the constant
GetElementPtrInst* gep = getGlobalAddr(getGlobalForConstant(CV),
insertBefore);
LoadInst* ldI = new LoadInst(gep, "loadConst", &insertBefore);
I.setOperand(opNum, ldI); // replace operand with copy in v.reg.
}
else if (instrInfo.ConstantMayNotFitInImmedField(CV, &I))
{ // put the constant into a virtual register using a cast
CastInst* castI = new CastInst(CV, CV->getType(), "copyConst",
&insertBefore);
I.setOperand(opNum, castI); // replace operand with copy in v.reg.
}
}
// visitOperands() transforms individual operands of all instructions:
// -- Load "large" int constants into a virtual register. What is large
// depends on the type of instruction and on the target architecture.
// -- For any constants that cannot be put in an immediate field,
// load address into virtual register first, and then load the constant.
//
// firstOp and lastOp can be used to skip leading and trailing operands.
// If lastOp is 0, it defaults to #operands or #incoming Phi values.
//
inline void
PreSelection::visitOperands(Instruction &I, int firstOp, int lastOp)
{
// For any instruction other than PHI, copies go just before the instr.
// For a PHI, operand copies must be before the terminator of the
// appropriate predecessor basic block. Remaining logic is simple
// so just handle PHIs and other instructions separately.
//
if (PHINode* phi = dyn_cast<PHINode>(&I))
{
if (lastOp == 0)
lastOp = phi->getNumIncomingValues();
for (unsigned i=firstOp, N=lastOp; i < N; ++i)
this->visitOneOperand(I, phi->getIncomingValue(i),
phi->getOperandNumForIncomingValue(i),
* phi->getIncomingBlock(i)->getTerminator());
}
else
{
if (lastOp == 0)
lastOp = I.getNumOperands();
for (unsigned i=firstOp, N=lastOp; i < N; ++i)
this->visitOneOperand(I, I.getOperand(i), i, I);
}
}
// Common work for *all* instructions. This needs to be called explicitly
// by other visit<InstructionType> functions.
@ -329,75 +400,6 @@ PreSelection::visitCallInst(CallInst &I)
}
// visitOperands() transforms individual operands of all instructions:
// -- Load "large" int constants into a virtual register. What is large
// depends on the type of instruction and on the target architecture.
// -- For any constants that cannot be put in an immediate field,
// load address into virtual register first, and then load the constant.
//
// firstOp and lastOp can be used to skip leading and trailing operands.
// If lastOp is 0, it defaults to #operands or #incoming Phi values.
//
void
PreSelection::visitOperands(Instruction &I, int firstOp, int lastOp)
{
// For any instruction other than PHI, copies go just before the instr.
// For a PHI, operand copies must be before the terminator of the
// appropriate predecessor basic block. Remaining logic is simple
// so just handle PHIs and other instructions separately.
//
if (PHINode* phi = dyn_cast<PHINode>(&I))
{
if (lastOp == 0)
lastOp = phi->getNumIncomingValues();
for (unsigned i=firstOp, N=lastOp; i < N; ++i)
this->visitOneOperand(I, phi->getIncomingValue(i),
phi->getOperandNumForIncomingValue(i),
* phi->getIncomingBlock(i)->getTerminator());
}
else
{
if (lastOp == 0)
lastOp = I.getNumOperands();
for (unsigned i=firstOp, N=lastOp; i < N; ++i)
this->visitOneOperand(I, I.getOperand(i), i, I);
}
}
void
PreSelection::visitOneOperand(Instruction &I, Value* Op, unsigned opNum,
Instruction& insertBefore)
{
if (GetElementPtrInst* gep = getGlobalAddr(Op, insertBefore)) {
I.setOperand(opNum, gep); // replace global operand
return;
}
Constant* CV = dyn_cast<Constant>(Op);
if (CV == NULL)
return;
if (ConstantExpr* CE = dyn_cast<ConstantExpr>(CV))
{ // load-time constant: factor it out so we optimize as best we can
Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore);
I.setOperand(opNum, computeConst); // replace expr operand with result
}
else if (target.getInstrInfo().ConstantTypeMustBeLoaded(CV))
{ // load address of constant into a register, then load the constant
GetElementPtrInst* gep = getGlobalAddr(getGlobalForConstant(CV),
insertBefore);
LoadInst* ldI = new LoadInst(gep, "loadConst", &insertBefore);
I.setOperand(opNum, ldI); // replace operand with copy in v.reg.
}
else if (target.getInstrInfo().ConstantMayNotFitInImmedField(CV, &I))
{ // put the constant into a virtual register using a cast
CastInst* castI = new CastInst(CV, CV->getType(), "copyConst",
&insertBefore);
I.setOperand(opNum, castI); // replace operand with copy in v.reg.
}
}
//===----------------------------------------------------------------------===//
// createPreSelectionPass - Public entrypoint for pre-selection pass
// and this file as a whole...