mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-13 08:25:27 +00:00
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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user