aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2003-05-31 07:34:57 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2003-05-31 07:34:57 +0000
commit9635867d6f89a5615591b43f04fb79c3d067c520 (patch)
tree9c29e2d85ba971c158bd90ec7f602471dfd26490
parentd0d06ad4f3b2db53e68a9615b282a7474c61820b (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6466 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/SparcV9/SparcV9PreSelection.cpp55
1 files changed, 43 insertions, 12 deletions
diff --git a/lib/Target/SparcV9/SparcV9PreSelection.cpp b/lib/Target/SparcV9/SparcV9PreSelection.cpp
index 20974e6daf..bd85d3a4bc 100644
--- a/lib/Target/SparcV9/SparcV9PreSelection.cpp
+++ b/lib/Target/SparcV9/SparcV9PreSelection.cpp
@@ -144,12 +144,19 @@ namespace {
void visitGetElementPtrInst(GetElementPtrInst &I);
void visitLoadInst(LoadInst &I);
void visitCastInst(CastInst &I);
+ void visitCallInst(CallInst &I);
void visitStoreInst(StoreInst &I);
// 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,
- Instruction& insertBefore); // iworks on one operand
+ //
+ // visitOperands() works on every operand in [firstOp, lastOp-1].
+ // 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...
@@ -314,6 +321,13 @@ PreSelection::visitCastInst(CastInst &I)
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:
// -- 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,
// 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)
+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
@@ -331,21 +348,35 @@ PreSelection::visitOperands(Instruction &I)
//
if (PHINode* phi = dyn_cast<PHINode>(&I))
{
- for (unsigned i=0, N=phi->getNumIncomingValues(); i < N; ++i)
- if (Constant* CV = dyn_cast<Constant>(phi->getIncomingValue(i)))
- this->visitOneOperand(I, CV, phi->getOperandNumForIncomingValue(i),
- * phi->getIncomingBlock(i)->getTerminator());
+ 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
- for (unsigned i=0, N=I.getNumOperands(); i < N; ++i)
- if (Constant* CV = dyn_cast<Constant>(I.getOperand(i)))
- this->visitOneOperand(I, CV, i, I);
+ {
+ 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, Constant* CV, unsigned opNum,
+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);