aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/InstrSelection
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2002-08-24 21:00:08 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2002-08-24 21:00:08 +0000
commit685133382d214b0ea7a2cf40e4cd2d2c5cff8dd4 (patch)
tree5d12ed3ef75db16a32d419dc29a79205cca8f85f /lib/CodeGen/InstrSelection
parentf28d9d643e3aff0a2737c317f6e75f57ed74bb07 (diff)
downloadexternal_llvm-685133382d214b0ea7a2cf40e4cd2d2c5cff8dd4.zip
external_llvm-685133382d214b0ea7a2cf40e4cd2d2c5cff8dd4.tar.gz
external_llvm-685133382d214b0ea7a2cf40e4cd2d2c5cff8dd4.tar.bz2
Moved code here to extract memory instruction indices and to check
whether FoldGetElemNodes should be called. This is machine-independent but was in the Sparc directory. This is in a new function: GetMemInstArgs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3500 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/InstrSelection')
-rw-r--r--lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp113
1 files changed, 96 insertions, 17 deletions
diff --git a/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp b/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp
index 294fdae..5004d90 100644
--- a/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp
+++ b/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp
@@ -97,6 +97,7 @@ GetConstantValueAsSignedInt(const Value *V,
return 0;
}
+
//---------------------------------------------------------------------------
// Function: FoldGetElemChain
//
@@ -104,33 +105,39 @@ GetConstantValueAsSignedInt(const Value *V,
// Fold a chain of GetElementPtr instructions containing only
// constant offsets into an equivalent (Pointer, IndexVector) pair.
// Returns the pointer Value, and stores the resulting IndexVector
-// in argument chainIdxVec.
+// in argument chainIdxVec. This is a helper function for
+// FoldConstantIndices that does the actual folding.
//---------------------------------------------------------------------------
-Value*
-FoldGetElemChain(const InstructionNode* getElemInstrNode,
- vector<Value*>& chainIdxVec)
+static Value*
+FoldGetElemChain(InstrTreeNode* ptrNode, vector<Value*>& chainIdxVec)
{
- GetElementPtrInst* getElemInst =
- cast<GetElementPtrInst>(getElemInstrNode->getInstruction());
-
+ InstructionNode* gepNode = dyn_cast<InstructionNode>(ptrNode);
+ if (gepNode == NULL)
+ return NULL; // ptr value is not computed in this tree
+
+ GetElementPtrInst* gepInst =
+ dyn_cast<GetElementPtrInst>(gepNode->getInstruction());
+ if (gepInst == NULL) // ptr value does not come from GEP instruction
+ return NULL;
+
// Return NULL if we don't fold any instructions in.
Value* ptrVal = NULL;
-
+
// Remember if the last instruction had a leading [0] index.
bool hasLeadingZero = false;
-
+
// Now chase the chain of getElementInstr instructions, if any.
// Check for any non-constant indices and stop there.
//
- const InstrTreeNode* ptrChild = getElemInstrNode;
- while (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
- ptrChild->getOpLabel() == GetElemPtrIdx)
+ InstructionNode* ptrChild = gepNode;
+ while (ptrChild && (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
+ ptrChild->getOpLabel() == GetElemPtrIdx))
{
// Child is a GetElemPtr instruction
- getElemInst = cast<GetElementPtrInst>(ptrChild->getValue());
- User::op_iterator OI, firstIdx = getElemInst->idx_begin();
- User::op_iterator lastIdx = getElemInst->idx_end();
+ gepInst = cast<GetElementPtrInst>(ptrChild->getValue());
+ User::op_iterator OI, firstIdx = gepInst->idx_begin();
+ User::op_iterator lastIdx = gepInst->idx_end();
bool allConstantOffsets = true;
// Check that all offsets are constant for this instruction
@@ -139,7 +146,7 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode,
if (allConstantOffsets)
{ // Get pointer value out of ptrChild.
- ptrVal = getElemInst->getPointerOperand();
+ ptrVal = gepInst->getPointerOperand();
// Check for a leading [0] index, if any. It will be discarded later.
ConstantUInt* CV = dyn_cast<ConstantUInt>((Value*) *firstIdx);
@@ -155,7 +162,7 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode,
else // cannot fold this getElementPtr instr. or any further ones
break;
- ptrChild = ptrChild->leftChild();
+ ptrChild = dyn_cast<InstructionNode>(ptrChild->leftChild());
}
// If the first getElementPtr instruction had a leading [0], add it back.
@@ -167,6 +174,78 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode,
}
+//---------------------------------------------------------------------------
+// Function: GetMemInstArgs
+//
+// Purpose:
+// Get the pointer value and the index vector for a memory operation
+// (GetElementPtr, Load, or Store). If all indices of the given memory
+// operation are constant, fold in constant indices in a chain of
+// preceding GetElementPtr instructions (if any), and return the
+// pointer value of the first instruction in the chain.
+// All folded instructions are marked so no code is generated for them.
+//
+// Return values:
+// Returns the pointer Value to use.
+// Returns the resulting IndexVector in idxVec.
+// Returns true/false in allConstantIndices if all indices are/aren't const.
+//---------------------------------------------------------------------------
+
+
+// Check for a constant (uint) 0.
+inline bool
+IsZero(Value* idx)
+{
+ return (isa<ConstantInt>(idx) && cast<ConstantInt>(idx)->isNullValue());
+}
+
+Value*
+GetMemInstArgs(const InstructionNode* memInstrNode,
+ vector<Value*>& idxVec,
+ bool& allConstantIndices)
+{
+ allConstantIndices = true;
+ Instruction* memInst = memInstrNode->getInstruction();
+
+ // 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 = (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. gepI is used below.
+ GetElementPtrInst* gepI = dyn_cast<GetElementPtrInst>(memInst);
+
+ // If memInst is a GEP, check if all indices are constant for this instruction
+ 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;
+ if (allConstantIndices)
+ if (Value* newPtr = FoldGetElemChain(ptrChild, idxVec))
+ {
+ ptrVal = newPtr;
+ foldedGEPs = true;
+ assert((!gepI || IsZero(*gepI->idx_begin())) && "1st index not 0");
+ }
+
+ // 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, gepI->idx_end());
+
+ return ptrVal;
+}
+
//------------------------------------------------------------------------
// Function Set2OperandsFromInstr
// Function Set3OperandsFromInstr