Major overhaul to FoldGetElemPtr to handle mixed array and struct refs.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1968 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve
2002-03-24 03:37:53 +00:00
parent 4e7bc49b54
commit c941b87397
2 changed files with 70 additions and 20 deletions

View File

@ -107,9 +107,10 @@ GetConstantValueAsSignedInt(const Value *V,
// Function: FoldGetElemChain // Function: FoldGetElemChain
// //
// Purpose: // Purpose:
// Fold a chain of GetElementPtr instructions into an equivalent // Fold a chain of GetElementPtr instructions containing only
// (Pointer, IndexVector) pair. Returns the pointer Value, and // structure offsets into an equivalent (Pointer, IndexVector) pair.
// stores the resulting IndexVector in argument chainIdxVec. // Returns the pointer Value, and stores the resulting IndexVector
// in argument chainIdxVec.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
Value* Value*
@ -120,11 +121,13 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode,
getElemInstrNode->getInstruction(); getElemInstrNode->getInstruction();
// Initialize return values from the incoming instruction // Initialize return values from the incoming instruction
Value* ptrVal = getElemInst->getPointerOperand(); Value* ptrVal = NULL;
chainIdxVec = getElemInst->copyIndices(); assert(chainIdxVec.size() == 0);
// Now chase the chain of getElementInstr instructions, if any // Now chase the chain of getElementInstr instructions, if any.
InstrTreeNode* ptrChild = getElemInstrNode->leftChild(); // Check for any array indices and stop there.
//
const InstrTreeNode* ptrChild = getElemInstrNode;
while (ptrChild->getOpLabel() == Instruction::GetElementPtr || while (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
ptrChild->getOpLabel() == GetElemPtrIdx) ptrChild->getOpLabel() == GetElemPtrIdx)
{ {
@ -132,10 +135,32 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode,
getElemInst = (MemAccessInst*) getElemInst = (MemAccessInst*)
((InstructionNode*) ptrChild)->getInstruction(); ((InstructionNode*) ptrChild)->getInstruction();
const vector<Value*>& idxVec = getElemInst->copyIndices(); const vector<Value*>& idxVec = getElemInst->copyIndices();
bool allStructureOffsets = true;
// Get the pointer value out of ptrChild and *prepend* its index vector // If it is a struct* access, the first offset must be array index [0],
ptrVal = getElemInst->getPointerOperand(); // and all other offsets must be structure (not array) offsets
chainIdxVec.insert(chainIdxVec.begin(), idxVec.begin(), idxVec.end()); if (!isa<ConstantUInt>(idxVec.front()) ||
cast<ConstantUInt>(idxVec.front())->getValue() != 0)
allStructureOffsets = false;
if (allStructureOffsets)
for (unsigned int i=1; i < idxVec.size(); i++)
if (idxVec[i]->getType() == Type::UIntTy)
{
allStructureOffsets = false;
break;
}
if (allStructureOffsets)
{ // Get pointer value out of ptrChild and *prepend* its index vector
ptrVal = getElemInst->getPointerOperand();
chainIdxVec.insert(chainIdxVec.begin(),
idxVec.begin()+1, idxVec.end());
((InstructionNode*) ptrChild)->markFoldedIntoParent();
// mark so no code is generated
}
else // cannot fold this getElementPtr instr. or any further ones
break;
ptrChild = ptrChild->leftChild(); ptrChild = ptrChild->leftChild();
} }

View File

@ -107,9 +107,10 @@ GetConstantValueAsSignedInt(const Value *V,
// Function: FoldGetElemChain // Function: FoldGetElemChain
// //
// Purpose: // Purpose:
// Fold a chain of GetElementPtr instructions into an equivalent // Fold a chain of GetElementPtr instructions containing only
// (Pointer, IndexVector) pair. Returns the pointer Value, and // structure offsets into an equivalent (Pointer, IndexVector) pair.
// stores the resulting IndexVector in argument chainIdxVec. // Returns the pointer Value, and stores the resulting IndexVector
// in argument chainIdxVec.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
Value* Value*
@ -120,11 +121,13 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode,
getElemInstrNode->getInstruction(); getElemInstrNode->getInstruction();
// Initialize return values from the incoming instruction // Initialize return values from the incoming instruction
Value* ptrVal = getElemInst->getPointerOperand(); Value* ptrVal = NULL;
chainIdxVec = getElemInst->copyIndices(); assert(chainIdxVec.size() == 0);
// Now chase the chain of getElementInstr instructions, if any // Now chase the chain of getElementInstr instructions, if any.
InstrTreeNode* ptrChild = getElemInstrNode->leftChild(); // Check for any array indices and stop there.
//
const InstrTreeNode* ptrChild = getElemInstrNode;
while (ptrChild->getOpLabel() == Instruction::GetElementPtr || while (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
ptrChild->getOpLabel() == GetElemPtrIdx) ptrChild->getOpLabel() == GetElemPtrIdx)
{ {
@ -132,10 +135,32 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode,
getElemInst = (MemAccessInst*) getElemInst = (MemAccessInst*)
((InstructionNode*) ptrChild)->getInstruction(); ((InstructionNode*) ptrChild)->getInstruction();
const vector<Value*>& idxVec = getElemInst->copyIndices(); const vector<Value*>& idxVec = getElemInst->copyIndices();
bool allStructureOffsets = true;
// Get the pointer value out of ptrChild and *prepend* its index vector // If it is a struct* access, the first offset must be array index [0],
ptrVal = getElemInst->getPointerOperand(); // and all other offsets must be structure (not array) offsets
chainIdxVec.insert(chainIdxVec.begin(), idxVec.begin(), idxVec.end()); if (!isa<ConstantUInt>(idxVec.front()) ||
cast<ConstantUInt>(idxVec.front())->getValue() != 0)
allStructureOffsets = false;
if (allStructureOffsets)
for (unsigned int i=1; i < idxVec.size(); i++)
if (idxVec[i]->getType() == Type::UIntTy)
{
allStructureOffsets = false;
break;
}
if (allStructureOffsets)
{ // Get pointer value out of ptrChild and *prepend* its index vector
ptrVal = getElemInst->getPointerOperand();
chainIdxVec.insert(chainIdxVec.begin(),
idxVec.begin()+1, idxVec.end());
((InstructionNode*) ptrChild)->markFoldedIntoParent();
// mark so no code is generated
}
else // cannot fold this getElementPtr instr. or any further ones
break;
ptrChild = ptrChild->leftChild(); ptrChild = ptrChild->leftChild();
} }