[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:
Evgeny Astigeevich 2017-10-03 12:00:40 +00:00
parent 11415ac44e
commit d3558b5d5e
1 changed files with 24 additions and 29 deletions

View File

@ -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;