mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-27 14:24:40 +00:00
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:
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user