(1) Major bug fix: DecomposeArrayRef() replaces its argument instr. and

deletes it, but we were merrily trying to fix the operands of that
    instruction anyway!  Instead, fix the replacement instruction.

(2) An Improvement: Check for and extract global values in all operands,
    not just in known pointer operands.  For example, they can occur in
    call arguments, and probably other unforeseeable places as well.
    This also eliminates the special-case handling of Load and Store.

llvm-svn: 7053
This commit is contained in:
Vikram S. Adve 2003-07-02 01:23:15 +00:00
parent fa1dde06aa
commit cf952cb504
1 changed files with 22 additions and 45 deletions

View File

@ -144,10 +144,8 @@ namespace {
// These methods do the actual work of specializing code // These methods do the actual work of specializing code
void visitInstruction(Instruction &I); // common work for every instr. void visitInstruction(Instruction &I); // common work for every instr.
void visitGetElementPtrInst(GetElementPtrInst &I); void visitGetElementPtrInst(GetElementPtrInst &I);
void visitLoadInst(LoadInst &I);
void visitCastInst(CastInst &I); void visitCastInst(CastInst &I);
void visitCallInst(CallInst &I); void visitCallInst(CallInst &I);
void visitStoreInst(StoreInst &I);
// Helper functions for visiting operands of every instruction // Helper functions for visiting operands of every instruction
// //
@ -243,9 +241,11 @@ inline void
PreSelection::visitOneOperand(Instruction &I, Value* Op, unsigned opNum, PreSelection::visitOneOperand(Instruction &I, Value* Op, unsigned opNum,
Instruction& insertBefore) Instruction& insertBefore)
{ {
assert(&insertBefore != NULL && "Must have instruction to insert before.");
if (GetElementPtrInst* gep = getGlobalAddr(Op, insertBefore)) { if (GetElementPtrInst* gep = getGlobalAddr(Op, insertBefore)) {
I.setOperand(opNum, gep); // replace global operand I.setOperand(opNum, gep); // replace global operand
return; return; // nothing more to do for this op.
} }
Constant* CV = dyn_cast<Constant>(Op); Constant* CV = dyn_cast<Constant>(Op);
@ -322,52 +322,33 @@ PreSelection::visitInstruction(Instruction &I)
void void
PreSelection::visitGetElementPtrInst(GetElementPtrInst &I) PreSelection::visitGetElementPtrInst(GetElementPtrInst &I)
{ {
// Check for a global and put its address into a register before this instr Instruction* curI = &I;
if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), I))
I.setOperand(I.getPointerOperandIndex(), gep); // replace pointer operand
// Decompose multidimensional array references // Decompose multidimensional array references
DecomposeArrayRef(&I); if (I.getNumIndices() >= 2) {
// DecomposeArrayRef() replaces I and deletes it, if successful,
// Perform other transformations common to all instructions // so remember predecessor in order to find the replacement instruction.
visitInstruction(I); // Also remember the basic block in case there is no predecessor.
Instruction* prevI = I.getPrev();
BasicBlock* bb = I.getParent();
if (DecomposeArrayRef(&I))
// first instr. replacing I
curI = cast<GetElementPtrInst>(prevI? prevI->getNext() : &bb->front());
} }
// Load instructions: check if pointer is a global
void
PreSelection::visitLoadInst(LoadInst &I)
{
// Check for a global and put its address into a register before this instr
if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), I))
I.setOperand(I.getPointerOperandIndex(), gep); // replace pointer operand
// Perform other transformations common to all instructions // Perform other transformations common to all instructions
visitInstruction(I); visitInstruction(*curI);
}
// Store instructions: check if pointer is a global
void
PreSelection::visitStoreInst(StoreInst &I)
{
// Check for a global and put its address into a register before this instr
if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), I))
I.setOperand(I.getPointerOperandIndex(), gep); // replace pointer operand
// Perform other transformations common to all instructions
visitInstruction(I);
} }
// Cast instructions: // Cast instructions:
// -- check if argument is a global
// -- make multi-step casts explicit: // -- make multi-step casts explicit:
// -- float/double to uint32_t: // -- float/double to uint32_t:
// If target does not have a float-to-unsigned instruction, we // If target does not have a float-to-unsigned instruction, we
// need to convert to uint64_t and then to uint32_t, or we may // need to convert to uint64_t and then to uint32_t, or we may
// overflow the signed int representation for legal uint32_t // overflow the signed int representation for legal uint32_t
// values. Expand this without checking target. // values. Expand this without checking target.
// -- other common transformations on operands
// //
void void
PreSelection::visitCastInst(CastInst &I) PreSelection::visitCastInst(CastInst &I)
@ -375,13 +356,9 @@ PreSelection::visitCastInst(CastInst &I)
CastInst* castI = NULL; CastInst* castI = NULL;
// Check for a global and put its address into a register before this instr // Check for a global and put its address into a register before this instr
if (GetElementPtrInst* gep = getGlobalAddr(I.getOperand(0), I)) if (I.getType() == Type::UIntTy &&
{ I.getOperand(0)->getType()->isFloatingPoint()) {
I.setOperand(0, gep); // replace pointer operand // insert a cast-fp-to-long before I, and then replace the operand of I
}
else if (I.getType() == Type::UIntTy &&
I.getOperand(0)->getType()->isFloatingPoint())
{ // insert a cast-fp-to-long before I, and then replace the operand of I
castI = new CastInst(I.getOperand(0), Type::LongTy, "fp2Long2Uint", &I); castI = new CastInst(I.getOperand(0), Type::LongTy, "fp2Long2Uint", &I);
I.setOperand(0, castI); // replace fp operand with long I.setOperand(0, castI); // replace fp operand with long
} }