diff options
author | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-08-03 13:48:21 +0000 |
---|---|---|
committer | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-08-03 13:48:21 +0000 |
commit | ed3fefb34cbb043c969140401519ea7e86120394 (patch) | |
tree | ea74975fe8aa2889773b0d7f9bc909babb6d1db3 | |
parent | 607bfadd8c586981eb395e7e8d5a352d262eadc1 (diff) | |
download | external_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.cpp | 139 |
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, |