Sign-extend values used to index arrays (and Simplify

SetOperandsForMemInstr significantly).  Load and Store
no longer have any indices.  Eliminate spurious sign-extension
on a cast to float/double.

llvm-svn: 3498
This commit is contained in:
Vikram S. Adve 2002-08-24 20:56:53 +00:00
parent 9068efdce6
commit 541862fbf3
1 changed files with 28 additions and 89 deletions

View File

@ -27,15 +27,6 @@ using std::vector;
//************************* Forward Declarations ***************************/ //************************* Forward Declarations ***************************/
static void SetMemOperands_Internal (vector<MachineInstr*>& mvec,
vector<MachineInstr*>::iterator mvecI,
const InstructionNode* vmInstrNode,
Value* ptrVal,
std::vector<Value*>& idxVec,
bool allConstantIndices,
const TargetMachine& target);
//************************ Internal Functions ******************************/ //************************ Internal Functions ******************************/
@ -325,15 +316,15 @@ CreateConvertToIntInstr(Type::PrimitiveID destTID, Value* srcVal,Value* destVal)
return M; return M;
} }
// CreateCodeToConvertIntToFloat: Convert FP value to signed or unsigned integer // CreateCodeToConvertFloatToInt: Convert FP value to signed or unsigned integer
// The FP value must be converted to the dest type in an FP register, // The FP value must be converted to the dest type in an FP register,
// and the result is then copied from FP to int register via memory. // and the result is then copied from FP to int register via memory.
static void static void
CreateCodeToConvertIntToFloat (const TargetMachine& target, CreateCodeToConvertFloatToInt(const TargetMachine& target,
Value* opVal, Value* opVal,
Instruction* destI, Instruction* destI,
std::vector<MachineInstr*>& mvec, std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) MachineCodeForInstruction& mcfi)
{ {
// Create a temporary to represent the FP register into which the // Create a temporary to represent the FP register into which the
// int value will placed after conversion. The type of this temporary // int value will placed after conversion. The type of this temporary
@ -959,76 +950,19 @@ IsZero(Value* idx)
static void static void
SetOperandsForMemInstr(vector<MachineInstr*>& mvec, SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
vector<MachineInstr*>::iterator mvecI,
const InstructionNode* vmInstrNode, const InstructionNode* vmInstrNode,
const TargetMachine& target) const TargetMachine& target)
{ {
GetElementPtrInst* memInst = Instruction* memInst = vmInstrNode->getInstruction();
cast<GetElementPtrInst>(vmInstrNode->getInstruction()); vector<MachineInstr*>::iterator mvecI = mvec.end() - 1;
// Variables to hold the index vector and ptr value. // Index vector, ptr value, and flag if all indices are const.
// The major work here is to extract these for all 3 instruction types
// and to try to fold chains of constant indices into a single offset.
// After that, we call SetMemOperands_Internal(), which creates the
// appropriate operands for the machine instruction.
vector<Value*> idxVec; vector<Value*> idxVec;
bool allConstantIndices = true; bool allConstantIndices;
Value* ptrVal = memInst->getPointerOperand(); Value* ptrVal = GetMemInstArgs(vmInstrNode, idxVec, allConstantIndices);
// If there is a GetElemPtr instruction to fold in to this instr, // Now create the appropriate operands for the machine instruction.
// it must be in the left child for Load and GetElemPtr, and in the // First, initialize so we default to storing the offset in a register.
// right child for Store instructions.
InstrTreeNode* ptrChild = (vmInstrNode->getOpLabel() == Instruction::Store
? vmInstrNode->rightChild()
: vmInstrNode->leftChild());
// Check if all indices are constant for this instruction
for (User::op_iterator OI=memInst->idx_begin(),OE=memInst->idx_end();
allConstantIndices && OI != OE; ++OI)
if (! isa<Constant>(*OI))
allConstantIndices = false;
// If we have only constant indices, fold chains of constant indices
// in this and any preceding GetElemPtr instructions.
bool foldedGEPs = false;
if (allConstantIndices &&
(ptrChild->getOpLabel() == Instruction::GetElementPtr ||
ptrChild->getOpLabel() == GetElemPtrIdx))
if (Value* newPtr = FoldGetElemChain((InstructionNode*) ptrChild, idxVec)) {
ptrVal = newPtr;
foldedGEPs = true;
}
// Append the index vector of the current instruction, if any.
// Skip the leading [0] index if preceding GEPs were folded into this.
if (memInst->getNumIndices() > 0) {
assert((!foldedGEPs || IsZero(*memInst->idx_begin())) && "1st index not 0");
idxVec.insert(idxVec.end(),
memInst->idx_begin() + foldedGEPs, memInst->idx_end());
}
// Now create the appropriate operands for the machine instruction
SetMemOperands_Internal(mvec, mvecI, vmInstrNode,
ptrVal, idxVec, allConstantIndices, target);
}
// Generate the correct operands (and additional instructions if needed)
// for the given pointer and given index vector.
//
static void
SetMemOperands_Internal(vector<MachineInstr*>& mvec,
vector<MachineInstr*>::iterator mvecI,
const InstructionNode* vmInstrNode,
Value* ptrVal,
vector<Value*>& idxVec,
bool allConstantIndices,
const TargetMachine& target)
{
GetElementPtrInst* memInst =
cast<GetElementPtrInst>(vmInstrNode->getInstruction());
// Initialize so we default to storing the offset in a register.
int64_t smallConstOffset = 0; int64_t smallConstOffset = 0;
Value* valueForRegOffset = NULL; Value* valueForRegOffset = NULL;
MachineOperand::MachineOperandType offsetOpType = MachineOperand::MachineOperandType offsetOpType =
@ -1060,6 +994,7 @@ SetMemOperands_Internal(vector<MachineInstr*>& mvec,
&& "Array refs must be lowered before Instruction Selection"); && "Array refs must be lowered before Instruction Selection");
Value* idxVal = idxVec[IsZero(idxVec[0])]; Value* idxVal = idxVec[IsZero(idxVec[0])];
assert(! isa<Constant>(idxVal) && "Need to sign-extend uint to 64b!");
vector<MachineInstr*> mulVec; vector<MachineInstr*> mulVec;
Instruction* addr = new TmpInstruction(Type::UIntTy, memInst); Instruction* addr = new TmpInstruction(Type::UIntTy, memInst);
@ -1081,6 +1016,9 @@ SetMemOperands_Internal(vector<MachineInstr*>& mvec,
MachineCodeForInstruction::get(memInst), MachineCodeForInstruction::get(memInst),
INVALID_MACHINE_OPCODE); INVALID_MACHINE_OPCODE);
// Sign-extend the result of MUL from 32 to 64 bits.
target.getInstrInfo().CreateSignExtensionInstructions(target, memInst->getParent()->getParent(), addr, /*srcSizeInBits*/32, addr, mulVec, MachineCodeForInstruction::get(memInst));
// Insert mulVec[] before *mvecI in mvec[] and update mvecI // Insert mulVec[] before *mvecI in mvec[] and update mvecI
// to point to the same instruction it pointed to before. // to point to the same instruction it pointed to before.
assert(mulVec.size() > 0 && "No multiply code created?"); assert(mulVec.size() > 0 && "No multiply code created?");
@ -1333,7 +1271,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
mvec.push_back(new MachineInstr( mvec.push_back(new MachineInstr(
ChooseStoreInstruction( ChooseStoreInstruction(
subtreeRoot->leftChild()->getValue()->getType()))); subtreeRoot->leftChild()->getValue()->getType())));
SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target); SetOperandsForMemInstr(mvec, subtreeRoot, target);
break; break;
case 5: // stmt: BrUncond case 5: // stmt: BrUncond
@ -1531,8 +1469,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
forwardOperandNum = 0; // forward first operand to user forwardOperandNum = 0; // forward first operand to user
} }
else if (opType->isFloatingPoint()) else if (opType->isFloatingPoint())
CreateCodeToConvertIntToFloat(target, opVal, destI, mvec, {
MachineCodeForInstruction::get(destI)); CreateCodeToConvertFloatToInt(target, opVal, destI, mvec,
MachineCodeForInstruction::get(destI));
maskUnsignedResult = true; // not handled by convert code
}
else else
assert(0 && "Unrecognized operand type for convert-to-unsigned"); assert(0 && "Unrecognized operand type for convert-to-unsigned");
@ -1589,7 +1530,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
} }
} }
else if (opType->isFloatingPoint()) else if (opType->isFloatingPoint())
CreateCodeToConvertIntToFloat(target, opVal, destI, mvec, mcfi); CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, mcfi);
else else
assert(0 && "Unrecognized operand type for convert-to-signed"); assert(0 && "Unrecognized operand type for convert-to-signed");
@ -1975,11 +1916,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
case 51: // reg: Load(reg) case 51: // reg: Load(reg)
case 52: // reg: Load(ptrreg) case 52: // reg: Load(ptrreg)
case 53: // reg: LoadIdx(reg,reg)
case 54: // reg: LoadIdx(ptrreg,reg)
mvec.push_back(new MachineInstr(ChooseLoadInstruction( mvec.push_back(new MachineInstr(ChooseLoadInstruction(
subtreeRoot->getValue()->getType()))); subtreeRoot->getValue()->getType())));
SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target); SetOperandsForMemInstr(mvec, subtreeRoot, target);
break; break;
case 55: // reg: GetElemPtr(reg) case 55: // reg: GetElemPtr(reg)
@ -1987,7 +1926,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// If the GetElemPtr was folded into the user (parent), it will be // If the GetElemPtr was folded into the user (parent), it will be
// caught above. For other cases, we have to compute the address. // caught above. For other cases, we have to compute the address.
mvec.push_back(new MachineInstr(ADD)); mvec.push_back(new MachineInstr(ADD));
SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target); SetOperandsForMemInstr(mvec, subtreeRoot, target);
break; break;
case 57: // reg: Alloca: Implement as 1 instruction: case 57: // reg: Alloca: Implement as 1 instruction:
@ -2214,7 +2153,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// we need to clear high bits of result value. // we need to clear high bits of result value.
assert(forwardOperandNum < 0 && "Need mask but no instruction generated"); assert(forwardOperandNum < 0 && "Need mask but no instruction generated");
Instruction* dest = subtreeRoot->getInstruction(); Instruction* dest = subtreeRoot->getInstruction();
if (! dest->getType()->isSigned()) if (dest->getType()->isUnsigned())
{ {
unsigned destSize = target.DataLayout.getTypeSize(dest->getType()); unsigned destSize = target.DataLayout.getTypeSize(dest->getType());
if (destSize < target.DataLayout.getIntegerRegize()) if (destSize < target.DataLayout.getIntegerRegize())