Skip to content

Commit 547b3b2

Browse files
pkwasnie-inteligcbot
authored andcommitted
GEP LSR pass: improve MulExpr handling
Improve how mul expressions are handled in GEP LSR pass.
1 parent 97698ad commit 547b3b2

File tree

1 file changed

+63
-41
lines changed

1 file changed

+63
-41
lines changed

IGC/Compiler/Optimizer/OpenCLPasses/GEPLoopStrengthReduction/GEPLoopStrengthReduction.cpp

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,30 @@ class Analyzer
289289
void analyze(SmallVectorImpl<ReductionCandidateGroup> &Result);
290290

291291
private:
292+
293+
// Represents deconstructed SCEV expression { start, +, step }.
294+
// Start SCEV will be used to calculate base pointer, and Step SCEV
295+
// will increase new induction variable on each iteration.
296+
struct DeconstructedSCEV
297+
{
298+
DeconstructedSCEV() : Start(nullptr), Step(nullptr), ConvertedMulExpr(false) {}
299+
300+
bool isValid();
301+
302+
const SCEV* Start;
303+
const SCEV* Step;
304+
305+
// True if input SCEV:
306+
// x * { start, +, step }
307+
// Was converted into:
308+
// { x * start, +, x * step }
309+
bool ConvertedMulExpr;
310+
};
311+
292312
void analyzeGEP(GetElementPtrInst *GEP);
293313
bool doInitialValidation(GetElementPtrInst *GEP);
294314

295-
bool deconstructSCEV(const SCEV *S, const SCEV *&Start, const SCEV *&Step);
296-
bool isValidStep(const SCEV* S);
315+
bool deconstructSCEV(const SCEV *S, DeconstructedSCEV &Result);
297316

298317
DominatorTree &DT;
299318
Loop &L;
@@ -961,15 +980,16 @@ void Analyzer::analyzeGEP(GetElementPtrInst *GEP)
961980
if (!SCEVHelper::isValid(S))
962981
return;
963982

964-
const SCEV *Start = nullptr;
965-
const SCEV *Step = nullptr;
966-
967-
if (!deconstructSCEV(S, Start, Step))
983+
Analyzer::DeconstructedSCEV Result;
984+
if (!deconstructSCEV(S, Result))
968985
return;
969986

970-
if (!isValidStep(Step))
987+
if (!Result.isValid())
971988
return;
972989

990+
const SCEV* Start = Result.Start;
991+
const SCEV* Step = Result.Step;
992+
973993
if (S->getType() != Start->getType())
974994
Start = isa<SCEVSignExtendExpr>(S) ? SE.getSignExtendExpr(Start, S->getType()) : SE.getZeroExtendExpr(Start, S->getType());
975995

@@ -1063,7 +1083,7 @@ bool Analyzer::doInitialValidation(GetElementPtrInst *GEP)
10631083
// Takes SCEV expression returned by ScalarEvolution and deconstructs it into
10641084
// expected format { start, +, step }. Returns false if expressions can't be
10651085
// parsed and reduced.
1066-
bool Analyzer::deconstructSCEV(const SCEV *S, const SCEV *&Start, const SCEV *&Step)
1086+
bool Analyzer::deconstructSCEV(const SCEV *S, Analyzer::DeconstructedSCEV &Result)
10671087
{
10681088
// Drop ext instructions to analyze nested content.
10691089
S = SCEVHelper::dropExt(S);
@@ -1075,8 +1095,8 @@ bool Analyzer::deconstructSCEV(const SCEV *S, const SCEV *&Start, const SCEV *&S
10751095
// induction variable.
10761096
if (SE.isLoopInvariant(S, &L))
10771097
{
1078-
Start = S;
1079-
Step = SE.getConstant(Type::getInt64Ty(L.getHeader()->getContext()), 0);
1098+
Result.Start = S;
1099+
Result.Step = SE.getConstant(Type::getInt64Ty(L.getHeader()->getContext()), 0);
10801100
return true;
10811101
}
10821102

@@ -1097,10 +1117,10 @@ bool Analyzer::deconstructSCEV(const SCEV *S, const SCEV *&Start, const SCEV *&S
10971117
if (!SE.isLoopInvariant(OpStep, &L))
10981118
return false;
10991119

1100-
Start = Add->getStart();
1101-
Step = OpStep;
1120+
Result.Start = Add->getStart();
1121+
Result.Step = OpStep;
11021122

1103-
return IGCLLVM::isSafeToExpandAt(Start, &L.getLoopPreheader()->back(), &SE, &E);
1123+
return IGCLLVM::isSafeToExpandAt(Result.Start, &L.getLoopPreheader()->back(), &SE, &E);
11041124
}
11051125

11061126
// If expression is:
@@ -1114,30 +1134,30 @@ bool Analyzer::deconstructSCEV(const SCEV *S, const SCEV *&Start, const SCEV *&S
11141134
if (auto *Add = dyn_cast<SCEVAddExpr>(S))
11151135
{
11161136
// There can be only one expression with step != 0.
1117-
Step = SE.getConstant(Type::getInt64Ty(L.getHeader()->getContext()), 0);
1137+
Result.Step = SE.getConstant(Type::getInt64Ty(L.getHeader()->getContext()), 0);
11181138

1119-
const SCEV *OpSCEV = nullptr;
1120-
const SCEV *OpStep = nullptr;
11211139
SCEVHelper::SCEVAddBuilder Builder(SE);
11221140

11231141
for (auto *Op : Add->operands())
11241142
{
1125-
if (!deconstructSCEV(Op, OpSCEV, OpStep))
1143+
Analyzer::DeconstructedSCEV OpResult;
1144+
1145+
if (!deconstructSCEV(Op, OpResult))
11261146
return false;
11271147

1128-
if (!OpStep->isZero())
1148+
if (!OpResult.Step->isZero())
11291149
{
1130-
if (!Step->isZero())
1150+
if (!Result.Step->isZero())
11311151
return false; // unsupported expression with multiple steps
1132-
Step = OpStep;
1152+
Result.Step = OpResult.Step;
11331153
}
11341154

1135-
Builder.add(OpSCEV);
1155+
Builder.add(OpResult.Start);
11361156
}
11371157

1138-
Start = Builder.build();
1158+
Result.Start = Builder.build();
11391159

1140-
return IGCLLVM::isSafeToExpandAt(Start, &L.getLoopPreheader()->back(), &SE, &E);
1160+
return IGCLLVM::isSafeToExpandAt(Result.Start, &L.getLoopPreheader()->back(), &SE, &E);
11411161
}
11421162

11431163
// If expression is:
@@ -1148,60 +1168,62 @@ bool Analyzer::deconstructSCEV(const SCEV *S, const SCEV *&Start, const SCEV *&S
11481168
// Warning: GEP's new index will not be a constant integer, but a new SCEV expression.
11491169
if (auto *Mul = dyn_cast<SCEVMulExpr>(S))
11501170
{
1151-
if (IGC_IS_FLAG_DISABLED(EnableGEPLSRMulExpr))
1152-
return false;
1153-
11541171
// SCEVAddRecExpr will be SCEV with step != 0. Any other SCEV is a multiplier.
11551172
bool FoundAddRec = false;
11561173
SCEVHelper::SCEVMulBuilder StartBuilder(SE), StepBuilder(SE);
11571174

11581175
for (auto *Op : Mul->operands())
11591176
{
1160-
const SCEV *OpSCEV = nullptr;
1161-
const SCEV *OpStep = nullptr;
1162-
if (!deconstructSCEV(Op, OpSCEV, OpStep))
1177+
Analyzer::DeconstructedSCEV OpResult;
1178+
if (!deconstructSCEV(Op, OpResult))
11631179
return false;
11641180

1165-
if (OpStep->isZero())
1181+
if (OpResult.Step->isZero())
11661182
{
1167-
StartBuilder.add(OpSCEV);
1168-
StepBuilder.add(OpSCEV);
1183+
StartBuilder.add(OpResult.Start);
1184+
StepBuilder.add(OpResult.Start);
11691185
}
11701186
else
11711187
{
11721188
if (FoundAddRec)
11731189
return false; // unsupported expression with multiple SCEVAddRecExpr
11741190
FoundAddRec = true;
11751191

1176-
StartBuilder.add(OpSCEV);
1177-
StepBuilder.add(OpStep);
1192+
StartBuilder.add(OpResult.Start);
1193+
StepBuilder.add(OpResult.Step);
11781194
}
11791195
}
11801196

11811197
if (!FoundAddRec)
11821198
return false;
11831199

1184-
Start = StartBuilder.build();
1185-
Step = StepBuilder.build();
1200+
Result.Start = StartBuilder.build();
1201+
Result.Step = StepBuilder.build();
1202+
Result.ConvertedMulExpr = true;
11861203

1187-
if (!SE.isLoopInvariant(Step, &L))
1204+
if (!SE.isLoopInvariant(Result.Step, &L))
11881205
return false;
11891206

1190-
return IGCLLVM::isSafeToExpandAt(Start, &L.getLoopPreheader()->back(), &SE, &E);
1207+
return IGCLLVM::isSafeToExpandAt(Result.Start, &L.getLoopPreheader()->back(), &SE, &E);
11911208
}
11921209

11931210
return false;
11941211
}
11951212

11961213

1197-
bool Analyzer::isValidStep(const SCEV* S)
1214+
bool Analyzer::DeconstructedSCEV::isValid()
11981215
{
1199-
auto Ty = SCEVHelper::dropExt(S)->getSCEVType();
1216+
if (!Start || !Step)
1217+
return false;
1218+
1219+
// Validate step.
1220+
auto Ty = SCEVHelper::dropExt(Step)->getSCEVType();
12001221

12011222
if (Ty == scConstant)
12021223
return true;
12031224

1204-
if (Ty == scMulExpr && IGC_IS_FLAG_ENABLED(EnableGEPLSRMulExpr))
1225+
bool IsMul = Ty == scMulExpr || ConvertedMulExpr;
1226+
if (IsMul && IGC_IS_FLAG_ENABLED(EnableGEPLSRMulExpr))
12051227
return true;
12061228

12071229
return IGC_IS_FLAG_ENABLED(EnableGEPLSRUnknownConstantStep);

0 commit comments

Comments
 (0)