forked from OSchip/llvm-project
[InlineCost, NFC] Extract code dealing with inbounds GEPs from visitGetElementPtr into a function
The code responsible for analysis of inbounds GEPs is extracted into a separate function: CallAnalyzer::canFoldInboundsGEP. With the patch SROA enabling/disabling code is localized at one place instead of spreading across the code of CallAnalyzer::visitGetElementPtr. Differential Revision: https://reviews.llvm.org/D38233 llvm-svn: 314787
This commit is contained in:
parent
11415ac44e
commit
d3558b5d5e
|
@ -172,6 +172,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
|
|||
void accumulateSROACost(DenseMap<Value *, int>::iterator CostIt,
|
||||
int InstructionCost);
|
||||
bool isGEPFree(GetElementPtrInst &GEP);
|
||||
bool canFoldInboundsGEP(GetElementPtrInst &I);
|
||||
bool accumulateGEPOffset(GEPOperator &GEP, APInt &Offset);
|
||||
bool simplifyCallSite(Function *F, CallSite CS);
|
||||
template <typename Callable>
|
||||
|
@ -431,40 +432,34 @@ bool CallAnalyzer::visitPHI(PHINode &I) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// \brief Check we can fold GEPs of constant-offset call site argument pointers.
|
||||
/// This requires target data and inbounds GEPs.
|
||||
///
|
||||
/// \return true if the specified GEP can be folded.
|
||||
bool CallAnalyzer::canFoldInboundsGEP(GetElementPtrInst &I) {
|
||||
// Check if we have a base + offset for the pointer.
|
||||
std::pair<Value *, APInt> BaseAndOffset =
|
||||
ConstantOffsetPtrs.lookup(I.getPointerOperand());
|
||||
if (!BaseAndOffset.first)
|
||||
return false;
|
||||
|
||||
// Check if the offset of this GEP is constant, and if so accumulate it
|
||||
// into Offset.
|
||||
if (!accumulateGEPOffset(cast<GEPOperator>(I), BaseAndOffset.second))
|
||||
return false;
|
||||
|
||||
// Add the result as a new mapping to Base + Offset.
|
||||
ConstantOffsetPtrs[&I] = BaseAndOffset;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &I) {
|
||||
Value *SROAArg;
|
||||
DenseMap<Value *, int>::iterator CostIt;
|
||||
bool SROACandidate =
|
||||
lookupSROAArgAndCost(I.getPointerOperand(), SROAArg, CostIt);
|
||||
|
||||
// Try to fold GEPs of constant-offset call site argument pointers. This
|
||||
// requires target data and inbounds GEPs.
|
||||
if (I.isInBounds()) {
|
||||
// Check if we have a base + offset for the pointer.
|
||||
Value *Ptr = I.getPointerOperand();
|
||||
std::pair<Value *, APInt> BaseAndOffset = ConstantOffsetPtrs.lookup(Ptr);
|
||||
if (BaseAndOffset.first) {
|
||||
// Check if the offset of this GEP is constant, and if so accumulate it
|
||||
// into Offset.
|
||||
if (!accumulateGEPOffset(cast<GEPOperator>(I), BaseAndOffset.second)) {
|
||||
// Non-constant GEPs aren't folded, and disable SROA.
|
||||
if (SROACandidate)
|
||||
disableSROA(CostIt);
|
||||
return isGEPFree(I);
|
||||
}
|
||||
|
||||
// Add the result as a new mapping to Base + Offset.
|
||||
ConstantOffsetPtrs[&I] = BaseAndOffset;
|
||||
|
||||
// Also handle SROA candidates here, we already know that the GEP is
|
||||
// all-constant indexed.
|
||||
if (SROACandidate)
|
||||
SROAArgValues[&I] = SROAArg;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Lambda to check whether a GEP's indices are all constant.
|
||||
auto IsGEPOffsetConstant = [&](GetElementPtrInst &GEP) {
|
||||
for (User::op_iterator I = GEP.idx_begin(), E = GEP.idx_end(); I != E; ++I)
|
||||
|
@ -473,7 +468,7 @@ bool CallAnalyzer::visitGetElementPtr(GetElementPtrInst &I) {
|
|||
return true;
|
||||
};
|
||||
|
||||
if (IsGEPOffsetConstant(I)) {
|
||||
if ((I.isInBounds() && canFoldInboundsGEP(I)) || IsGEPOffsetConstant(I)) {
|
||||
if (SROACandidate)
|
||||
SROAArgValues[&I] = SROAArg;
|
||||
|
||||
|
|
Loading…
Reference in New Issue