Add function GetConstantValueAsUnsignedInt.

Fix 2 bugs in FoldGetElemChain so index vector is not modified
when no GEPs are folded in, and so a hasLeadingZero is computed
only for the last folded GEP, not the one after that if any.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3244 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve
2002-08-04 20:49:49 +00:00
parent 75ac4e511a
commit 1b51b1b4f9
2 changed files with 100 additions and 106 deletions

View File

@@ -57,11 +57,13 @@ InsertCodeToLoadConstant(Function *F,
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Function GetConstantValueAsUnsignedInt
// Function GetConstantValueAsSignedInt // Function GetConstantValueAsSignedInt
// //
// Convenience function to get the value of an integer constant, for an // Convenience functions to get the value of an integral constant, for an
// appropriate integer or non-integer type that can be held in an integer. // appropriate integer or non-integer type that can be held in a signed
// The type of the argument must be the following: // or unsigned integer respectively. The type of the argument must be
// the following:
// Signed or unsigned integer // Signed or unsigned integer
// Boolean // Boolean
// Pointer // Pointer
@@ -69,36 +71,37 @@ InsertCodeToLoadConstant(Function *F,
// isValidConstant is set to true if a valid constant was found. // isValidConstant is set to true if a valid constant was found.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
int64_t uint64_t
GetConstantValueAsSignedInt(const Value *V, GetConstantValueAsUnsignedInt(const Value *V,
bool &isValidConstant) bool &isValidConstant)
{ {
if (!isa<Constant>(V))
{
isValidConstant = false;
return 0;
}
isValidConstant = true; isValidConstant = true;
if (V->getType() == Type::BoolTy) if (isa<Constant>(V))
return (int64_t) cast<ConstantBool>(V)->getValue(); if (V->getType() == Type::BoolTy)
return (int64_t) cast<ConstantBool>(V)->getValue();
if (V->getType()->isIntegral()) else if (V->getType()->isIntegral())
{ return (V->getType()->isUnsigned()
if (V->getType()->isSigned()) ? cast<ConstantUInt>(V)->getValue()
return cast<ConstantSInt>(V)->getValue(); : (uint64_t) cast<ConstantSInt>(V)->getValue());
assert(V->getType()->isUnsigned());
uint64_t Val = cast<ConstantUInt>(V)->getValue();
if (Val < INT64_MAX) // then safe to cast to signed
return (int64_t)Val;
}
isValidConstant = false; isValidConstant = false;
return 0; return 0;
} }
int64_t
GetConstantValueAsSignedInt(const Value *V,
bool &isValidConstant)
{
uint64_t C = GetConstantValueAsUnsignedInt(V, isValidConstant);
if (isValidConstant) {
if (V->getType()->isSigned() || C < INT64_MAX) // safe to cast to signed
return (int64_t) C;
else
isValidConstant = false;
}
return 0;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Function: FoldGetElemChain // Function: FoldGetElemChain
@@ -131,47 +134,41 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode,
ptrChild->getOpLabel() == GetElemPtrIdx) ptrChild->getOpLabel() == GetElemPtrIdx)
{ {
// Child is a GetElemPtr instruction // Child is a GetElemPtr instruction
getElemInst = (MemAccessInst*) getElemInst = cast<MemAccessInst>(ptrChild->getValue());
((InstructionNode*) ptrChild)->getInstruction(); MemAccessInst::op_iterator OI, firstIdx = getElemInst->idx_begin();
const vector<Value*>& idxVec = getElemInst->copyIndices(); MemAccessInst::op_iterator lastIdx = getElemInst->idx_end();
bool allConstantOffsets = true; bool allConstantOffsets = true;
// Check for a leading [0] index, if any. It will be discarded later.
ConstantUInt* CV = dyn_cast<ConstantUInt>(idxVec[0]);
hasLeadingZero = bool(CV && CV->getType() == Type::UIntTy &&
(CV->getValue() == 0));
// Check that all offsets are constant for this instruction // Check that all offsets are constant for this instruction
for (unsigned int i=0; i < idxVec.size(); i++) for (OI = firstIdx; allConstantOffsets && OI != lastIdx; ++OI)
if (! isa<ConstantUInt>(idxVec[i])) allConstantOffsets = isa<ConstantInt>(*OI);
{
allConstantOffsets = false;
break;
}
if (allConstantOffsets) if (allConstantOffsets)
{ // Get pointer value out of ptrChild. { // Get pointer value out of ptrChild.
ptrVal = getElemInst->getPointerOperand(); ptrVal = getElemInst->getPointerOperand();
// Insert its index vector at the start. // Check for a leading [0] index, if any. It will be discarded later.
ConstantUInt* CV = dyn_cast<ConstantUInt>((Value*) *firstIdx);
hasLeadingZero = bool(CV && CV->getValue() == 0);
// Insert its index vector at the start, skipping any leading [0]
chainIdxVec.insert(chainIdxVec.begin(), chainIdxVec.insert(chainIdxVec.begin(),
idxVec.begin() + (hasLeadingZero? 1:0), firstIdx + hasLeadingZero, lastIdx);
idxVec.end());
// Mark the folded node so no code is generated for it. // Mark the folded node so no code is generated for it.
((InstructionNode*) ptrChild)->markFoldedIntoParent(); ((InstructionNode*) ptrChild)->markFoldedIntoParent();
} }
else // cannot fold this getElementPtr instr. or any further ones else // cannot fold this getElementPtr instr. or any further ones
break; break;
ptrChild = ptrChild->leftChild(); ptrChild = ptrChild->leftChild();
} }
// If the first getElementPtr instruction had a leading [0], add it back. // If the first getElementPtr instruction had a leading [0], add it back.
// Note that this instruction is the *last* one handled above. // Note that this instruction is the *last* one successfully folded above.
if (hasLeadingZero) if (ptrVal && hasLeadingZero)
chainIdxVec.insert(chainIdxVec.begin(), ConstantUInt::get(Type::UIntTy,0)); chainIdxVec.insert(chainIdxVec.begin(), ConstantUInt::get(Type::UIntTy,0));
return ptrVal; return ptrVal;
} }

View File

@@ -57,11 +57,13 @@ InsertCodeToLoadConstant(Function *F,
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Function GetConstantValueAsUnsignedInt
// Function GetConstantValueAsSignedInt // Function GetConstantValueAsSignedInt
// //
// Convenience function to get the value of an integer constant, for an // Convenience functions to get the value of an integral constant, for an
// appropriate integer or non-integer type that can be held in an integer. // appropriate integer or non-integer type that can be held in a signed
// The type of the argument must be the following: // or unsigned integer respectively. The type of the argument must be
// the following:
// Signed or unsigned integer // Signed or unsigned integer
// Boolean // Boolean
// Pointer // Pointer
@@ -69,36 +71,37 @@ InsertCodeToLoadConstant(Function *F,
// isValidConstant is set to true if a valid constant was found. // isValidConstant is set to true if a valid constant was found.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
int64_t uint64_t
GetConstantValueAsSignedInt(const Value *V, GetConstantValueAsUnsignedInt(const Value *V,
bool &isValidConstant) bool &isValidConstant)
{ {
if (!isa<Constant>(V))
{
isValidConstant = false;
return 0;
}
isValidConstant = true; isValidConstant = true;
if (V->getType() == Type::BoolTy) if (isa<Constant>(V))
return (int64_t) cast<ConstantBool>(V)->getValue(); if (V->getType() == Type::BoolTy)
return (int64_t) cast<ConstantBool>(V)->getValue();
if (V->getType()->isIntegral()) else if (V->getType()->isIntegral())
{ return (V->getType()->isUnsigned()
if (V->getType()->isSigned()) ? cast<ConstantUInt>(V)->getValue()
return cast<ConstantSInt>(V)->getValue(); : (uint64_t) cast<ConstantSInt>(V)->getValue());
assert(V->getType()->isUnsigned());
uint64_t Val = cast<ConstantUInt>(V)->getValue();
if (Val < INT64_MAX) // then safe to cast to signed
return (int64_t)Val;
}
isValidConstant = false; isValidConstant = false;
return 0; return 0;
} }
int64_t
GetConstantValueAsSignedInt(const Value *V,
bool &isValidConstant)
{
uint64_t C = GetConstantValueAsUnsignedInt(V, isValidConstant);
if (isValidConstant) {
if (V->getType()->isSigned() || C < INT64_MAX) // safe to cast to signed
return (int64_t) C;
else
isValidConstant = false;
}
return 0;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Function: FoldGetElemChain // Function: FoldGetElemChain
@@ -131,47 +134,41 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode,
ptrChild->getOpLabel() == GetElemPtrIdx) ptrChild->getOpLabel() == GetElemPtrIdx)
{ {
// Child is a GetElemPtr instruction // Child is a GetElemPtr instruction
getElemInst = (MemAccessInst*) getElemInst = cast<MemAccessInst>(ptrChild->getValue());
((InstructionNode*) ptrChild)->getInstruction(); MemAccessInst::op_iterator OI, firstIdx = getElemInst->idx_begin();
const vector<Value*>& idxVec = getElemInst->copyIndices(); MemAccessInst::op_iterator lastIdx = getElemInst->idx_end();
bool allConstantOffsets = true; bool allConstantOffsets = true;
// Check for a leading [0] index, if any. It will be discarded later.
ConstantUInt* CV = dyn_cast<ConstantUInt>(idxVec[0]);
hasLeadingZero = bool(CV && CV->getType() == Type::UIntTy &&
(CV->getValue() == 0));
// Check that all offsets are constant for this instruction // Check that all offsets are constant for this instruction
for (unsigned int i=0; i < idxVec.size(); i++) for (OI = firstIdx; allConstantOffsets && OI != lastIdx; ++OI)
if (! isa<ConstantUInt>(idxVec[i])) allConstantOffsets = isa<ConstantInt>(*OI);
{
allConstantOffsets = false;
break;
}
if (allConstantOffsets) if (allConstantOffsets)
{ // Get pointer value out of ptrChild. { // Get pointer value out of ptrChild.
ptrVal = getElemInst->getPointerOperand(); ptrVal = getElemInst->getPointerOperand();
// Insert its index vector at the start. // Check for a leading [0] index, if any. It will be discarded later.
ConstantUInt* CV = dyn_cast<ConstantUInt>((Value*) *firstIdx);
hasLeadingZero = bool(CV && CV->getValue() == 0);
// Insert its index vector at the start, skipping any leading [0]
chainIdxVec.insert(chainIdxVec.begin(), chainIdxVec.insert(chainIdxVec.begin(),
idxVec.begin() + (hasLeadingZero? 1:0), firstIdx + hasLeadingZero, lastIdx);
idxVec.end());
// Mark the folded node so no code is generated for it. // Mark the folded node so no code is generated for it.
((InstructionNode*) ptrChild)->markFoldedIntoParent(); ((InstructionNode*) ptrChild)->markFoldedIntoParent();
} }
else // cannot fold this getElementPtr instr. or any further ones else // cannot fold this getElementPtr instr. or any further ones
break; break;
ptrChild = ptrChild->leftChild(); ptrChild = ptrChild->leftChild();
} }
// If the first getElementPtr instruction had a leading [0], add it back. // If the first getElementPtr instruction had a leading [0], add it back.
// Note that this instruction is the *last* one handled above. // Note that this instruction is the *last* one successfully folded above.
if (hasLeadingZero) if (ptrVal && hasLeadingZero)
chainIdxVec.insert(chainIdxVec.begin(), ConstantUInt::get(Type::UIntTy,0)); chainIdxVec.insert(chainIdxVec.begin(), ConstantUInt::get(Type::UIntTy,0));
return ptrVal; return ptrVal;
} }