- MemAccessInst* memInst = (MemAccessInst*) vmInstrNode->getInstruction();
-
- // Variables to hold the index vector and ptr value.
- // 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;
- 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;
- }
-
- // 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;
- }
-
- // 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());
- }
-
- // Now create the appropriate operands for the machine instruction
- SetMemOperands_Internal(mvec, mvecI, vmInstrNode,
- ptrVal, idxVec, allConstantIndices, target);
-}