forked from OSchip/llvm-project
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:
parent
a83804a29a
commit
ba6f8e274a
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue