Skip to content

Commit

Permalink
GEP Loop Strength Reduction pass improvements
Browse files Browse the repository at this point in the history
1. Use one instance of SCEVExpander for all reduction in the functions.
   Limits number of duplicated instructions.

2. Improve comparison of SCEV expressions. More cases should be grouped
   together, lowering number of duplicated instructions.
  • Loading branch information
pkwasnie-intel authored and igcbot committed Sep 20, 2023
1 parent 7e7165e commit bd09197
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,8 @@ class Scorer
class Reducer
{
public:
Reducer(const DataLayout &DL, DominatorTree &DT, Loop &L, LoopInfo &LI, ModuleMetaData &MMD, RegisterPressureEstimate &RPE, ScalarEvolution &SE, unsigned MaxPressure, bool AllowLICM)
: DT(DT), L(L), LI(LI), RPE(RPE), SE(SE), E(SE, DL, "gep-loop-strength-reduction"), MaxPressure(MaxPressure), AllowLICM(AllowLICM), Scorer(DL, L, MMD) {}
Reducer(const DataLayout &DL, DominatorTree &DT, Loop &L, LoopInfo &LI, ModuleMetaData &MMD, RegisterPressureEstimate &RPE, ScalarEvolution &SE, SCEVExpander &E, unsigned MaxPressure, bool AllowLICM)
: DT(DT), L(L), LI(LI), RPE(RPE), SE(SE), E(E), MaxPressure(MaxPressure), AllowLICM(AllowLICM), Scorer(DL, L, MMD) {}

bool reduce();

Expand All @@ -280,7 +280,7 @@ class Reducer
LoopInfo &LI;
RegisterPressureEstimate &RPE;
ScalarEvolution &SE;
SCEVExpander E;
SCEVExpander &E;

Scorer Scorer;

Expand All @@ -305,22 +305,26 @@ namespace SCEVHelper
class SCEVAddBuilder
{
public:
SCEVAddBuilder(ScalarEvolution &SE, Type *T) :
SE(SE), T(T)
{
IGC_ASSERT_MESSAGE(T->isIntegerTy(), "builder requires integer type");
}
SCEVAddBuilder(ScalarEvolution &SE) : SE(SE) {}

SCEVAddBuilder &add(const SCEV *S, bool Negative = false);

SCEVAddBuilder &addNegative(const SCEV *S) { return add(S, true); }

const SCEV *build() { return SE.getAddExpr(Ops); }
const SCEV *build();

private:

struct Op
{
Op(const SCEV *S, bool Negative) : S(S), Negative(Negative) {}

const SCEV *S;
bool Negative;
};

ScalarEvolution &SE;
Type *T;
SmallVector<const SCEV*, 16> Ops;
SmallVector<Op, 16> Ops;
};
};

Expand Down Expand Up @@ -406,7 +410,7 @@ bool ReductionCandidateGroup::addToGroup(ScalarEvolution &SE, GetElementPtrInst
// Can't use ScalarEvolution::computeConstantDifference, as it only
// supports SCEVAddExpr with two operands. Calculate difference as:
// new candidate's operands + (-1 * base's operands)
SCEVHelper::SCEVAddBuilder Builder(SE, SE.getWiderType(S->getType(), Base.S->getType()));
SCEVHelper::SCEVAddBuilder Builder(SE);
const SCEVConstant *Sum = dyn_cast<SCEVConstant>(Builder.add(S).addNegative(Base.S).build());
if (!Sum)
return false;
Expand Down Expand Up @@ -900,7 +904,7 @@ bool Reducer::deconstructSCEV(const SCEV *S, const SCEV *&Start, int64_t &Step)

const SCEV *OpSCEV = nullptr;
int64_t OpStep = 0;
SCEVHelper::SCEVAddBuilder Builder(SE, S->getType());
SCEVHelper::SCEVAddBuilder Builder(SE);

for (auto *Op : Add->operands())
{
Expand Down Expand Up @@ -1036,16 +1040,33 @@ SCEVHelper::SCEVAddBuilder &SCEVHelper::SCEVAddBuilder::add(const SCEV *S, bool
return *this;
}

Ops.emplace_back(S, Negative);

return *this;
}


const SCEV *SCEVHelper::SCEVAddBuilder::build()
{
// ScalarEvolution::getAddExpr requires all operands to have the same
// type. Extend type if required.
S = S->getType() == T ? S : SE.getSignExtendExpr(S, T);
// type. First find the widest type.
Type *T = nullptr;
for (auto *It = Ops.begin(); It != Ops.end(); ++It)
{
T = T ? SE.getWiderType(T, It->S->getType()) : It->S->getType();
}

// Change expresion to "-1 * expression"
S = Negative ? SE.getNegativeSCEV(S) : S;
// Join list of operands, extending type if required.
SmallVector<const SCEV*, 16> FinalOps;

Ops.push_back(S);
for (auto *It = Ops.begin(); It != Ops.end(); ++It)
{
const SCEV *S = It->S;
S = S->getType() == T ? S : SE.getSignExtendExpr(S, T);
FinalOps.push_back(It->Negative ? SE.getNegativeSCEV(S) : S);
}

return *this;
return SE.getAddExpr(FinalOps);
}


Expand Down Expand Up @@ -1093,9 +1114,12 @@ bool GEPLoopStrengthReduction::runOnFunction(llvm::Function &F)

bool changed = false;

// Using one SCEV expander between all reductions reduces number of duplicated new instructions.
auto E = SCEVExpander(SE, DL, "gep-loop-strength-reduction");

for (Loop *L : LI.getLoopsInPreorder())
{
changed |= Reducer(DL, DT, *L, LI, MMD, RPE, SE, MaxPressure, AllowLICM).reduce();
changed |= Reducer(DL, DT, *L, LI, MMD, RPE, SE, E, MaxPressure, AllowLICM).reduce();
}

return changed;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,10 @@ entry:
br i1 %cmp1, label %for.body.lr.ph, label %for.end

; CHECK-LABEL: for.body.lr.ph:
; CHECK: [[EXT1:%.*]] = sext i32 %b to i64
; CHECK: [[EXT2:%.*]] = sext i32 %a to i64
; CHECK: [[ADD1:%.*]] = add i64 [[EXT1]], [[EXT2]]
; CHECK: [[ADD2:%.*]] = add i32 %b, %a
; CHECK: [[MUL:%.*]] = mul i32 %c, [[ADD2]]
; CHECK: [[EXT3:%.*]] = sext i32 [[MUL]] to i64
; CHECK: [[ADD3:%.*]] = add i64 [[ADD1]], [[EXT3]]
; CHECK: [[GEP_PHI1:%.*]] = getelementptr i32, i32 addrspace(1)* %p, i64 [[ADD3]]
; CHECK: [[ADD1:%.*]] = add i32 %b, %a
; CHECK: [[MUL:%.*]] = mul i32 %c, [[ADD1]]
; CHECK: [[ADD2:%.*]] = add i32 [[ADD1]], [[MUL]]
; CHECK: [[GEP_PHI1:%.*]] = getelementptr i32, i32 addrspace(1)* %p, i32 [[ADD2]]
; CHECK: br label %for.body
for.body.lr.ph: ; preds = %entry
br label %for.body
Expand Down

0 comments on commit bd09197

Please sign in to comment.