mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-26 07:34:14 +00:00
Factor out the code for creating SCEVs for GEPs into a
separate function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71252 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
185cf0395c
commit
26466c0eb3
@ -279,6 +279,10 @@ namespace llvm {
|
|||||||
/// SCEVs.
|
/// SCEVs.
|
||||||
SCEVHandle createNodeForPHI(PHINode *PN);
|
SCEVHandle createNodeForPHI(PHINode *PN);
|
||||||
|
|
||||||
|
/// createNodeForGEP - Provide the special handling we need to analyze GEP
|
||||||
|
/// SCEVs.
|
||||||
|
SCEVHandle createNodeForGEP(GetElementPtrInst *GEP);
|
||||||
|
|
||||||
/// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value
|
/// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value
|
||||||
/// for the specified instruction and replaces any references to the
|
/// for the specified instruction and replaces any references to the
|
||||||
/// symbolic value SymName with the specified value. This is used during
|
/// symbolic value SymName with the specified value. This is used during
|
||||||
|
@ -1863,6 +1863,44 @@ SCEVHandle ScalarEvolution::createNodeForPHI(PHINode *PN) {
|
|||||||
return getUnknown(PN);
|
return getUnknown(PN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// createNodeForGEP - Expand GEP instructions into add and multiply
|
||||||
|
/// operations. This allows them to be analyzed by regular SCEV code.
|
||||||
|
///
|
||||||
|
SCEVHandle ScalarEvolution::createNodeForGEP(GetElementPtrInst *GEP) {
|
||||||
|
|
||||||
|
const Type *IntPtrTy = TD->getIntPtrType();
|
||||||
|
Value *Base = U->getOperand(0);
|
||||||
|
SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy);
|
||||||
|
gep_type_iterator GTI = gep_type_begin(U);
|
||||||
|
for (GetElementPtrInst::op_iterator I = next(U->op_begin()),
|
||||||
|
E = U->op_end();
|
||||||
|
I != E; ++I) {
|
||||||
|
Value *Index = *I;
|
||||||
|
// Compute the (potentially symbolic) offset in bytes for this index.
|
||||||
|
if (const StructType *STy = dyn_cast<StructType>(*GTI++)) {
|
||||||
|
// For a struct, add the member offset.
|
||||||
|
const StructLayout &SL = *TD->getStructLayout(STy);
|
||||||
|
unsigned FieldNo = cast<ConstantInt>(Index)->getZExtValue();
|
||||||
|
uint64_t Offset = SL.getElementOffset(FieldNo);
|
||||||
|
TotalOffset = getAddExpr(TotalOffset,
|
||||||
|
getIntegerSCEV(Offset, IntPtrTy));
|
||||||
|
} else {
|
||||||
|
// For an array, add the element offset, explicitly scaled.
|
||||||
|
SCEVHandle LocalOffset = getSCEV(Index);
|
||||||
|
if (!isa<PointerType>(LocalOffset->getType()))
|
||||||
|
// Getelementptr indicies are signed.
|
||||||
|
LocalOffset = getTruncateOrSignExtend(LocalOffset,
|
||||||
|
IntPtrTy);
|
||||||
|
LocalOffset =
|
||||||
|
getMulExpr(LocalOffset,
|
||||||
|
getIntegerSCEV(TD->getTypePaddedSize(*GTI),
|
||||||
|
IntPtrTy));
|
||||||
|
TotalOffset = getAddExpr(TotalOffset, LocalOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getAddExpr(getSCEV(Base), TotalOffset);
|
||||||
|
}
|
||||||
|
|
||||||
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S is
|
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S is
|
||||||
/// guaranteed to end in (at every loop iteration). It is, at the same time,
|
/// guaranteed to end in (at every loop iteration). It is, at the same time,
|
||||||
/// the minimum number of times S is divisible by 2. For example, given {4,+,8}
|
/// the minimum number of times S is divisible by 2. For example, given {4,+,8}
|
||||||
@ -2073,40 +2111,9 @@ SCEVHandle ScalarEvolution::createSCEV(Value *V) {
|
|||||||
return getTruncateOrZeroExtend(getSCEV(U->getOperand(0)),
|
return getTruncateOrZeroExtend(getSCEV(U->getOperand(0)),
|
||||||
U->getType());
|
U->getType());
|
||||||
|
|
||||||
case Instruction::GetElementPtr: {
|
case Instruction::GetElementPtr:
|
||||||
if (!TD) break; // Without TD we can't analyze pointers.
|
if (!TD) break; // Without TD we can't analyze pointers.
|
||||||
const Type *IntPtrTy = TD->getIntPtrType();
|
return createNodeForGEP(cast<GetElementPtrInst>(U));
|
||||||
Value *Base = U->getOperand(0);
|
|
||||||
SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy);
|
|
||||||
gep_type_iterator GTI = gep_type_begin(U);
|
|
||||||
for (GetElementPtrInst::op_iterator I = next(U->op_begin()),
|
|
||||||
E = U->op_end();
|
|
||||||
I != E; ++I) {
|
|
||||||
Value *Index = *I;
|
|
||||||
// Compute the (potentially symbolic) offset in bytes for this index.
|
|
||||||
if (const StructType *STy = dyn_cast<StructType>(*GTI++)) {
|
|
||||||
// For a struct, add the member offset.
|
|
||||||
const StructLayout &SL = *TD->getStructLayout(STy);
|
|
||||||
unsigned FieldNo = cast<ConstantInt>(Index)->getZExtValue();
|
|
||||||
uint64_t Offset = SL.getElementOffset(FieldNo);
|
|
||||||
TotalOffset = getAddExpr(TotalOffset,
|
|
||||||
getIntegerSCEV(Offset, IntPtrTy));
|
|
||||||
} else {
|
|
||||||
// For an array, add the element offset, explicitly scaled.
|
|
||||||
SCEVHandle LocalOffset = getSCEV(Index);
|
|
||||||
if (!isa<PointerType>(LocalOffset->getType()))
|
|
||||||
// Getelementptr indicies are signed.
|
|
||||||
LocalOffset = getTruncateOrSignExtend(LocalOffset,
|
|
||||||
IntPtrTy);
|
|
||||||
LocalOffset =
|
|
||||||
getMulExpr(LocalOffset,
|
|
||||||
getIntegerSCEV(TD->getTypePaddedSize(*GTI),
|
|
||||||
IntPtrTy));
|
|
||||||
TotalOffset = getAddExpr(TotalOffset, LocalOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return getAddExpr(getSCEV(Base), TotalOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Instruction::PHI:
|
case Instruction::PHI:
|
||||||
return createNodeForPHI(cast<PHINode>(U));
|
return createNodeForPHI(cast<PHINode>(U));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user