diff options
author | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-10-14 16:30:55 +0000 |
---|---|---|
committer | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-10-14 16:30:55 +0000 |
commit | cf911de3c61db9291e9338f09b435e9a4868c2de (patch) | |
tree | a83891b443321a2b4e5678589c2da99d1c877db0 /lib | |
parent | 8becaedfa8af39a470c249c11d3dc3ee0d75bb84 (diff) | |
download | external_llvm-cf911de3c61db9291e9338f09b435e9a4868c2de.zip external_llvm-cf911de3c61db9291e9338f09b435e9a4868c2de.tar.gz external_llvm-cf911de3c61db9291e9338f09b435e9a4868c2de.tar.bz2 |
Significant improvement: GEP used by a load or store no longer generates
a separate ADD; instead just use the indexed load/store instruction!
Also, a bug fix: folding a GEP with a leading non-zero index with
its predecessor was incorrect: now it only happens if the predecessor
is pointing to an indexable type (aka SequentialType).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4168 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp | 110 | ||||
-rw-r--r-- | lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp | 110 |
2 files changed, 148 insertions, 72 deletions
diff --git a/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp b/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp index aff6c30..731f335 100644 --- a/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp +++ b/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp @@ -154,14 +154,14 @@ FoldGetElemChain(InstrTreeNode* ptrNode, vector<Value*>& chainIdxVec, assert((*firstIdx)->getType() == Type::LongTy && "INTERNAL ERROR: Structure index for a pointer type!"); - // If the last instruction had a leading non-zero index, - // check if the current one ends with an array index. If not, - // the code is not type-safe and we would create an illegal GEP + // If the last instruction had a leading non-zero index, check if the + // current one references a sequential (i.e., indexable) type. + // If not, the code is not type-safe and we would create an illegal GEP // by folding them, so don't fold any more instructions. // if (lastInstHasLeadingNonZero) - if (firstIdx != lastIdx && (*(lastIdx-1))->getType() != Type::LongTy) - break; // cannot fold in any preceding getElementPtr instrs. + if (! isa<SequentialType>(gepInst->getType()->getElementType())) + break; // cannot fold in any preceding getElementPtr instrs. // Check that all offsets are constant for this instruction for (OI = firstIdx; allConstantOffsets && OI != lastIdx; ++OI) @@ -198,6 +198,56 @@ FoldGetElemChain(InstrTreeNode* ptrNode, vector<Value*>& chainIdxVec, //--------------------------------------------------------------------------- +// Function: GetGEPInstArgs +// +// Purpose: +// Helper function for GetMemInstArgs that handles the final getElementPtr +// instruction used by (or same as) the memory operation. +// Extracts the indices of the current instruction and tries to fold in +// preceding ones if all indices of the current one are constant. +//--------------------------------------------------------------------------- + +Value* +GetGEPInstArgs(InstructionNode* gepNode, + vector<Value*>& idxVec, + bool& allConstantIndices) +{ + allConstantIndices = true; + GetElementPtrInst* gepI = cast<GetElementPtrInst>(gepNode->getInstruction()); + + // Default pointer is the one from the current instruction. + Value* ptrVal = gepI->getPointerOperand(); + InstrTreeNode* ptrChild = gepNode->leftChild(); + + // Extract the index vector of the GEP instructin. + // If all indices are constant and first index is zero, try to fold + // in preceding GEPs with all constant indices. + for (User::op_iterator OI=gepI->idx_begin(), OE=gepI->idx_end(); + allConstantIndices && OI != OE; ++OI) + if (! isa<Constant>(*OI)) + allConstantIndices = false; // note: this also terminates loop! + + // If we have only constant indices, fold chains of constant indices + // in this and any preceding GetElemPtr instructions. + bool foldedGEPs = false; + bool leadingNonZeroIdx = gepI && ! IsZero(*gepI->idx_begin()); + if (allConstantIndices) + if (Value* newPtr = FoldGetElemChain(ptrChild, idxVec, leadingNonZeroIdx)) + { + ptrVal = newPtr; + foldedGEPs = true; + } + + // Append the index vector of the current instruction. + // Skip the leading [0] index if preceding GEPs were folded into this. + idxVec.insert(idxVec.end(), + gepI->idx_begin() + (foldedGEPs && !leadingNonZeroIdx), + gepI->idx_end()); + + return ptrVal; +} + +//--------------------------------------------------------------------------- // Function: GetMemInstArgs // // Purpose: @@ -215,11 +265,11 @@ FoldGetElemChain(InstrTreeNode* ptrNode, vector<Value*>& chainIdxVec, //--------------------------------------------------------------------------- Value* -GetMemInstArgs(const InstructionNode* memInstrNode, +GetMemInstArgs(InstructionNode* memInstrNode, vector<Value*>& idxVec, bool& allConstantIndices) { - allConstantIndices = true; + allConstantIndices = false; Instruction* memInst = memInstrNode->getInstruction(); assert(idxVec.size() == 0 && "Need empty vector to return indices"); @@ -229,41 +279,29 @@ GetMemInstArgs(const InstructionNode* memInstrNode, InstrTreeNode* ptrChild = (memInst->getOpcode() == Instruction::Store ? memInstrNode->rightChild() : memInstrNode->leftChild()); - + // Default pointer is the one from the current instruction. Value* ptrVal = ptrChild->getValue(); - // GEP is the only indexed memory instruction. Extract its index vector. - // Also, if all indices are constant and first index is zero, try to fold - // in preceding GEPs with all constant indices. - GetElementPtrInst* gepI = dyn_cast<GetElementPtrInst>(memInst); - if (gepI) - for (User::op_iterator OI=gepI->idx_begin(), OE=gepI->idx_end(); - allConstantIndices && OI != OE; ++OI) - if (! isa<Constant>(*OI)) - allConstantIndices = false; // note: this also terminates loop! - - // If we have only constant indices, fold chains of constant indices - // in this and any preceding GetElemPtr instructions. - bool foldedGEPs = false; - bool leadingNonZeroIdx = gepI && ! IsZero(*gepI->idx_begin()); - if (allConstantIndices) - if (Value* newPtr = FoldGetElemChain(ptrChild, idxVec, leadingNonZeroIdx)) - { - ptrVal = newPtr; - foldedGEPs = true; - } - - // Append the index vector of the current instruction, if any. - // Skip the leading [0] index if preceding GEPs were folded into this. - if (gepI) - idxVec.insert(idxVec.end(), - gepI->idx_begin() + (foldedGEPs && !leadingNonZeroIdx), - gepI->idx_end()); + // Find the "last" GetElemPtr instruction: this one or the immediate child. + // There will be none if this is a load or a store from a scalar pointer. + InstructionNode* gepNode = NULL; + if (isa<GetElementPtrInst>(memInst)) + gepNode = memInstrNode; + else if (isa<InstructionNode>(ptrChild) && isa<GetElementPtrInst>(ptrVal)) + { // Child of load/store is a GEP and memInst is its only use. + // Use its indices and mark it as folded. + gepNode = cast<InstructionNode>(ptrChild); + gepNode->markFoldedIntoParent(); + } - return ptrVal; + // If there are no indices, return the current pointer. + // Else extract the pointer from the GEP and fold the indices. + return (gepNode)? GetGEPInstArgs(gepNode, idxVec, allConstantIndices) + : ptrVal; } + //------------------------------------------------------------------------ // Function Set2OperandsFromInstr // Function Set3OperandsFromInstr diff --git a/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp b/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp index aff6c30..731f335 100644 --- a/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp +++ b/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp @@ -154,14 +154,14 @@ FoldGetElemChain(InstrTreeNode* ptrNode, vector<Value*>& chainIdxVec, assert((*firstIdx)->getType() == Type::LongTy && "INTERNAL ERROR: Structure index for a pointer type!"); - // If the last instruction had a leading non-zero index, - // check if the current one ends with an array index. If not, - // the code is not type-safe and we would create an illegal GEP + // If the last instruction had a leading non-zero index, check if the + // current one references a sequential (i.e., indexable) type. + // If not, the code is not type-safe and we would create an illegal GEP // by folding them, so don't fold any more instructions. // if (lastInstHasLeadingNonZero) - if (firstIdx != lastIdx && (*(lastIdx-1))->getType() != Type::LongTy) - break; // cannot fold in any preceding getElementPtr instrs. + if (! isa<SequentialType>(gepInst->getType()->getElementType())) + break; // cannot fold in any preceding getElementPtr instrs. // Check that all offsets are constant for this instruction for (OI = firstIdx; allConstantOffsets && OI != lastIdx; ++OI) @@ -198,6 +198,56 @@ FoldGetElemChain(InstrTreeNode* ptrNode, vector<Value*>& chainIdxVec, //--------------------------------------------------------------------------- +// Function: GetGEPInstArgs +// +// Purpose: +// Helper function for GetMemInstArgs that handles the final getElementPtr +// instruction used by (or same as) the memory operation. +// Extracts the indices of the current instruction and tries to fold in +// preceding ones if all indices of the current one are constant. +//--------------------------------------------------------------------------- + +Value* +GetGEPInstArgs(InstructionNode* gepNode, + vector<Value*>& idxVec, + bool& allConstantIndices) +{ + allConstantIndices = true; + GetElementPtrInst* gepI = cast<GetElementPtrInst>(gepNode->getInstruction()); + + // Default pointer is the one from the current instruction. + Value* ptrVal = gepI->getPointerOperand(); + InstrTreeNode* ptrChild = gepNode->leftChild(); + + // Extract the index vector of the GEP instructin. + // If all indices are constant and first index is zero, try to fold + // in preceding GEPs with all constant indices. + for (User::op_iterator OI=gepI->idx_begin(), OE=gepI->idx_end(); + allConstantIndices && OI != OE; ++OI) + if (! isa<Constant>(*OI)) + allConstantIndices = false; // note: this also terminates loop! + + // If we have only constant indices, fold chains of constant indices + // in this and any preceding GetElemPtr instructions. + bool foldedGEPs = false; + bool leadingNonZeroIdx = gepI && ! IsZero(*gepI->idx_begin()); + if (allConstantIndices) + if (Value* newPtr = FoldGetElemChain(ptrChild, idxVec, leadingNonZeroIdx)) + { + ptrVal = newPtr; + foldedGEPs = true; + } + + // Append the index vector of the current instruction. + // Skip the leading [0] index if preceding GEPs were folded into this. + idxVec.insert(idxVec.end(), + gepI->idx_begin() + (foldedGEPs && !leadingNonZeroIdx), + gepI->idx_end()); + + return ptrVal; +} + +//--------------------------------------------------------------------------- // Function: GetMemInstArgs // // Purpose: @@ -215,11 +265,11 @@ FoldGetElemChain(InstrTreeNode* ptrNode, vector<Value*>& chainIdxVec, //--------------------------------------------------------------------------- Value* -GetMemInstArgs(const InstructionNode* memInstrNode, +GetMemInstArgs(InstructionNode* memInstrNode, vector<Value*>& idxVec, bool& allConstantIndices) { - allConstantIndices = true; + allConstantIndices = false; Instruction* memInst = memInstrNode->getInstruction(); assert(idxVec.size() == 0 && "Need empty vector to return indices"); @@ -229,41 +279,29 @@ GetMemInstArgs(const InstructionNode* memInstrNode, InstrTreeNode* ptrChild = (memInst->getOpcode() == Instruction::Store ? memInstrNode->rightChild() : memInstrNode->leftChild()); - + // Default pointer is the one from the current instruction. Value* ptrVal = ptrChild->getValue(); - // GEP is the only indexed memory instruction. Extract its index vector. - // Also, if all indices are constant and first index is zero, try to fold - // in preceding GEPs with all constant indices. - GetElementPtrInst* gepI = dyn_cast<GetElementPtrInst>(memInst); - if (gepI) - for (User::op_iterator OI=gepI->idx_begin(), OE=gepI->idx_end(); - allConstantIndices && OI != OE; ++OI) - if (! isa<Constant>(*OI)) - allConstantIndices = false; // note: this also terminates loop! - - // If we have only constant indices, fold chains of constant indices - // in this and any preceding GetElemPtr instructions. - bool foldedGEPs = false; - bool leadingNonZeroIdx = gepI && ! IsZero(*gepI->idx_begin()); - if (allConstantIndices) - if (Value* newPtr = FoldGetElemChain(ptrChild, idxVec, leadingNonZeroIdx)) - { - ptrVal = newPtr; - foldedGEPs = true; - } - - // Append the index vector of the current instruction, if any. - // Skip the leading [0] index if preceding GEPs were folded into this. - if (gepI) - idxVec.insert(idxVec.end(), - gepI->idx_begin() + (foldedGEPs && !leadingNonZeroIdx), - gepI->idx_end()); + // Find the "last" GetElemPtr instruction: this one or the immediate child. + // There will be none if this is a load or a store from a scalar pointer. + InstructionNode* gepNode = NULL; + if (isa<GetElementPtrInst>(memInst)) + gepNode = memInstrNode; + else if (isa<InstructionNode>(ptrChild) && isa<GetElementPtrInst>(ptrVal)) + { // Child of load/store is a GEP and memInst is its only use. + // Use its indices and mark it as folded. + gepNode = cast<InstructionNode>(ptrChild); + gepNode->markFoldedIntoParent(); + } - return ptrVal; + // If there are no indices, return the current pointer. + // Else extract the pointer from the GEP and fold the indices. + return (gepNode)? GetGEPInstArgs(gepNode, idxVec, allConstantIndices) + : ptrVal; } + //------------------------------------------------------------------------ // Function Set2OperandsFromInstr // Function Set3OperandsFromInstr |