aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2002-08-03 13:48:21 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2002-08-03 13:48:21 +0000
commited3fefb34cbb043c969140401519ea7e86120394 (patch)
treeea74975fe8aa2889773b0d7f9bc909babb6d1db3
parent607bfadd8c586981eb395e7e8d5a352d262eadc1 (diff)
downloadexternal_llvm-ed3fefb34cbb043c969140401519ea7e86120394.zip
external_llvm-ed3fefb34cbb043c969140401519ea7e86120394.tar.gz
external_llvm-ed3fefb34cbb043c969140401519ea7e86120394.tar.bz2
Simplified handling of array indexes in SetMemOperands_Internal.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3236 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/SparcV9/SparcV9InstrSelection.cpp139
1 files changed, 62 insertions, 77 deletions
diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
index 36c05f0..6b9085b 100644
--- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp
+++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
@@ -939,6 +939,12 @@ CreateCodeForFixedSizeAlloca(const TargetMachine& target,
+// Check for a constant (uint) 0.
+inline bool
+IsZero(Value* idx)
+{
+ return (isa<ConstantInt>(idx) && cast<ConstantInt>(idx)->isNullValue());
+}
//------------------------------------------------------------------------
@@ -973,45 +979,35 @@ SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
vector<Value*> idxVec;
bool allConstantIndices = true;
Value* ptrVal = memInst->getPointerOperand();
-
+
// If there is a GetElemPtr instruction to fold in to this instr,
// it must be in the left child for Load and GetElemPtr, and in the
// 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 (MemAccessInst::op_iterator OI=memInst->idx_begin();
- OI != memInst->idx_end(); ++OI)
- if (! isa<ConstantUInt>(*OI))
- {
- allConstantIndices = false;
- break;
- }
-
+ for (MemAccessInst::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.
if (allConstantIndices &&
- ptrChild->getOpLabel() == Instruction::GetElementPtr ||
- ptrChild->getOpLabel() == GetElemPtrIdx)
- {
- Value* newPtr = FoldGetElemChain((InstructionNode*) ptrChild, idxVec);
- if (newPtr)
- ptrVal = newPtr;
- }
-
+ (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
+ ptrChild->getOpLabel() == GetElemPtrIdx))
+ if (Value* newPtr = FoldGetElemChain((InstructionNode*) ptrChild, idxVec))
+ ptrVal = newPtr;
+
// Append the index vector of the current instruction, if any.
// Discard any leading [0] index.
- if (memInst->idx_begin() != memInst->idx_end())
- {
- const ConstantUInt* CV = dyn_cast<ConstantUInt>(memInst->idx_begin()->get());
- unsigned zeroOrIOne = (CV && CV->getType() == Type::UIntTy &&
- (CV->getValue() == 0))? 1 : 0;
- idxVec.insert(idxVec.end(),
- memInst->idx_begin()+zeroOrIOne, memInst->idx_end());
- }
-
+ if (memInst->getNumIndices() > 0)
+ idxVec.insert(idxVec.end(), memInst->idx_begin()
+ + (IndexIsZero(*memInst->idx_begin())? 1 : 0),
+ memInst->idx_end());
+
// Now create the appropriate operands for the machine instruction
SetMemOperands_Internal(mvec, mvecI, vmInstrNode,
ptrVal, idxVec, allConstantIndices, target);
@@ -1035,7 +1031,8 @@ SetMemOperands_Internal(vector<MachineInstr*>& mvec,
// Initialize so we default to storing the offset in a register.
int64_t smallConstOffset = 0;
Value* valueForRegOffset = NULL;
- MachineOperand::MachineOperandType offsetOpType =MachineOperand::MO_VirtualRegister;
+ MachineOperand::MachineOperandType offsetOpType =
+ MachineOperand::MO_VirtualRegister;
// Check if there is an index vector and if so, compute the
// right offset for structures and for arrays
@@ -1055,57 +1052,45 @@ SetMemOperands_Internal(vector<MachineInstr*>& mvec,
else
{
// There is at least one non-constant offset. Therefore, this must
- // be an array ref, and must have been lowered to a single offset.
- assert((memInst->getNumOperands()
- == (unsigned) 1 + memInst->getFirstIndexOperandNumber())
+ // be an array ref, and must have been lowered to a single non-zero
+ // offset. (An extra leading zero offset, if any, can be ignored.)
+ // Generate code sequence to compute address from index.
+ //
+ bool firstIndexIsZero = IndexIsZero(idxVec[0]);
+
+ assert(idxVec.size() == 1 + (unsigned) (firstIndexIsZero? 1 : 0)
&& "Array refs must be lowered before Instruction Selection");
-
- Value* arrayOffsetVal = * memInst->idx_begin();
-
- // Handle special common case of leading [0] index.
- ConstantUInt* CV = dyn_cast<ConstantUInt>(idxVec.front());
- bool firstIndexIsZero = bool(CV && CV->getType() == Type::UIntTy &&
- (CV->getValue() == 0));
-
- // If index is 0, the offset value is just 0. Otherwise,
- // generate a MUL instruction to compute address from index.
+
+ Value* idxVal = idxVec[(firstIndexIsZero? 1 : 0)];
+
+ vector<MachineInstr*> mulVec;
+ Instruction* addr = new TmpInstruction(Type::UIntTy, memInst);
+ MachineCodeForInstruction::get(memInst).addTemp(addr);
+
// The call to getTypeSize() will fail if size is not constant.
+ unsigned int eltSize =
+ target.DataLayout.getTypeSize(ptrType->getElementType());
+ assert(eltSize > 0 && "Invalid or non-const array element size");
+ ConstantUInt* eltVal = ConstantUInt::get(Type::UIntTy, eltSize);
+
// CreateMulInstruction() folds constants intelligently enough.
- //
- if (firstIndexIsZero)
- {
- offsetOpType = MachineOperand::MO_SignExtendedImmed;
- smallConstOffset = 0;
- }
- else
- {
- vector<MachineInstr*> mulVec;
- Instruction* addr = new TmpInstruction(Type::UIntTy, memInst);
- MachineCodeForInstruction::get(memInst).addTemp(addr);
-
- unsigned int eltSize =
- target.DataLayout.getTypeSize(ptrType->getElementType());
- assert(eltSize > 0 && "Invalid or non-const array element size");
- ConstantUInt* eltVal = ConstantUInt::get(Type::UIntTy, eltSize);
-
- CreateMulInstruction(target,
- memInst->getParent()->getParent(),
- arrayOffsetVal, /* lval, not likely const */
- eltVal, /* rval, likely constant */
- addr, /* result*/
- mulVec,
- MachineCodeForInstruction::get(memInst),
- INVALID_MACHINE_OPCODE);
- assert(mulVec.size() > 0 && "No multiply instruction created?");
- for (vector<MachineInstr*>::const_iterator I = mulVec.begin();
- I != mulVec.end(); ++I)
- {
- mvecI = mvec.insert(mvecI, *I); // ptr to inserted value
- ++mvecI; // ptr to mem. instr.
- }
-
- valueForRegOffset = addr;
- }
+ CreateMulInstruction(target,
+ memInst->getParent()->getParent(),
+ idxVal, /* lval, not likely const */
+ eltVal, /* rval, likely constant */
+ addr, /* result*/
+ mulVec,
+ MachineCodeForInstruction::get(memInst),
+ INVALID_MACHINE_OPCODE);
+
+ // Insert mulVec[] before *mvecI in mvec[] and update mvecI
+ // to point to the same instruction it pointed to before.
+ assert(mulVec.size() > 0 && "No multiply code created?");
+ vector<MachineInstr*>::iterator oldMvecI = mvecI;
+ for (unsigned i=0, N=mulVec.size(); i < N; ++i)
+ mvecI = mvec.insert(mvecI, mulVec[i]) + 1; // pts to mem instr
+
+ valueForRegOffset = addr;
}
}
else
@@ -1113,7 +1098,7 @@ SetMemOperands_Internal(vector<MachineInstr*>& mvec,
offsetOpType = MachineOperand::MO_SignExtendedImmed;
smallConstOffset = 0;
}
-
+
// For STORE:
// Operand 0 is value, operand 1 is ptr, operand 2 is offset
// For LOAD or GET_ELEMENT_PTR,