From ed3fefb34cbb043c969140401519ea7e86120394 Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Sat, 3 Aug 2002 13:48:21 +0000 Subject: [PATCH] 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 --- lib/Target/SparcV9/SparcV9InstrSelection.cpp | 143 +++++++++---------- 1 file changed, 64 insertions(+), 79 deletions(-) diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp index 36c05f09176..6b9085b5d37 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(idx) && cast(idx)->isNullValue()); +} //------------------------------------------------------------------------ @@ -973,45 +979,35 @@ SetOperandsForMemInstr(vector& mvec, vector 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(*OI)) - { - allConstantIndices = false; - break; - } - + for (MemAccessInst::op_iterator OI=memInst->idx_begin(),OE=memInst->idx_end(); + allConstantIndices && OI != OE; ++OI) + if (! isa(*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(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& 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& 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()) - && "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(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. - // The call to getTypeSize() will fail if size is not constant. - // CreateMulInstruction() folds constants intelligently enough. + // 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. // - if (firstIndexIsZero) - { - offsetOpType = MachineOperand::MO_SignExtendedImmed; - smallConstOffset = 0; - } - else - { - vector 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::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; - } + bool firstIndexIsZero = IndexIsZero(idxVec[0]); + + assert(idxVec.size() == 1 + (unsigned) (firstIndexIsZero? 1 : 0) + && "Array refs must be lowered before Instruction Selection"); + + Value* idxVal = idxVec[(firstIndexIsZero? 1 : 0)]; + + vector 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. + 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::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& 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,