Several bug fixes: globals in call operands were not being pulled out;

globals in some other places may not have been pulled out either;
globals in phi operands were being put just before the phi instead of
in the predecessor basic blocks.

llvm-svn: 6466
This commit is contained in:
Vikram S. Adve 2003-05-31 07:34:57 +00:00
parent a83804a29a
commit ba6f8e274a
1 changed files with 43 additions and 12 deletions

View File

@ -144,12 +144,19 @@ namespace {
void visitGetElementPtrInst(GetElementPtrInst &I); void visitGetElementPtrInst(GetElementPtrInst &I);
void visitLoadInst(LoadInst &I); void visitLoadInst(LoadInst &I);
void visitCastInst(CastInst &I); void visitCastInst(CastInst &I);
void visitCallInst(CallInst &I);
void visitStoreInst(StoreInst &I); void visitStoreInst(StoreInst &I);
// Helper functions for visiting operands of every instruction // Helper functions for visiting operands of every instruction
void visitOperands(Instruction &I); // work on all operands of instr. //
void visitOneOperand(Instruction &I, Constant* CV, unsigned opNum, // visitOperands() works on every operand in [firstOp, lastOp-1].
Instruction& insertBefore); // iworks on one operand // If lastOp==0, lastOp defaults to #operands or #incoming Phi values.
//
// visitOneOperand() does all the work for one operand.
//
void visitOperands(Instruction &I, int firstOp=0, int lastOp=0);
void visitOneOperand(Instruction &I, Value* Op, unsigned opNum,
Instruction& insertBefore);
}; };
// Register the pass... // Register the pass...
@ -314,6 +321,13 @@ PreSelection::visitCastInst(CastInst &I)
visitInstruction(*castI); visitInstruction(*castI);
} }
void
PreSelection::visitCallInst(CallInst &I)
{
// Tell visitOperands to ignore the function name if this is a direct call.
visitOperands(I, (/*firstOp=*/ I.getCalledFunction()? 1 : 0));
}
// visitOperands() transforms individual operands of all instructions: // visitOperands() transforms individual operands of all instructions:
// -- Load "large" int constants into a virtual register. What is large // -- Load "large" int constants into a virtual register. What is large
@ -321,8 +335,11 @@ PreSelection::visitCastInst(CastInst &I)
// -- For any constants that cannot be put in an immediate field, // -- For any constants that cannot be put in an immediate field,
// load address into virtual register first, and then load the constant. // 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 void
PreSelection::visitOperands(Instruction &I) PreSelection::visitOperands(Instruction &I, int firstOp, int lastOp)
{ {
// For any instruction other than PHI, copies go just before the instr. // For any instruction other than PHI, copies go just before the instr.
// For a PHI, operand copies must be before the terminator of the // For a PHI, operand copies must be before the terminator of the
@ -331,21 +348,35 @@ PreSelection::visitOperands(Instruction &I)
// //
if (PHINode* phi = dyn_cast<PHINode>(&I)) if (PHINode* phi = dyn_cast<PHINode>(&I))
{ {
for (unsigned i=0, N=phi->getNumIncomingValues(); i < N; ++i) if (lastOp == 0)
if (Constant* CV = dyn_cast<Constant>(phi->getIncomingValue(i))) lastOp = phi->getNumIncomingValues();
this->visitOneOperand(I, CV, phi->getOperandNumForIncomingValue(i), for (unsigned i=firstOp, N=lastOp; i < N; ++i)
* phi->getIncomingBlock(i)->getTerminator()); this->visitOneOperand(I, phi->getIncomingValue(i),
phi->getOperandNumForIncomingValue(i),
* phi->getIncomingBlock(i)->getTerminator());
} }
else else
for (unsigned i=0, N=I.getNumOperands(); i < N; ++i) {
if (Constant* CV = dyn_cast<Constant>(I.getOperand(i))) if (lastOp == 0)
this->visitOneOperand(I, CV, i, I); lastOp = I.getNumOperands();
for (unsigned i=firstOp, N=lastOp; i < N; ++i)
this->visitOneOperand(I, I.getOperand(i), i, I);
}
} }
void void
PreSelection::visitOneOperand(Instruction &I, Constant* CV, unsigned opNum, PreSelection::visitOneOperand(Instruction &I, Value* Op, unsigned opNum,
Instruction& insertBefore) 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)) if (ConstantExpr* CE = dyn_cast<ConstantExpr>(CV))
{ // load-time constant: factor it out so we optimize as best we can { // load-time constant: factor it out so we optimize as best we can
Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore); Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore);