[IslNodeBuilder] [NFC] Refactor creation of loop induction variables of loops outside scops.

This logic is duplicated, so we refactor it into a separate function.
 This will be used in a later patch to teach PPCGCodeGen code generation
 for loops that are outside the scop.

 Differential Revision: https://reviews.llvm.org/D36310

llvm-svn: 310192
This commit is contained in:
Siddharth Bhat 2017-08-06 02:07:11 +00:00
parent 9d8e9ff620
commit 0caed1fbe6
2 changed files with 33 additions and 11 deletions

View File

@ -412,6 +412,16 @@ private:
/// ids to new access expressions.
void generateCopyStmt(ScopStmt *Stmt,
__isl_keep isl_id_to_ast_expr *NewAccesses);
/// Materialize a canonical loop induction variable for `L`, which is a loop
/// that is *not* present in the Scop.
///
/// Note that this is materialized at the point where the `Builder` is
/// currently pointing.
/// We also populate the `OutsideLoopIterations` map with `L`s SCEV to keep
/// track of the induction variable.
/// See [Code generation of induction variables of loops outside Scops]
Value *materializeNonScopLoopInductionVariable(const Loop *L);
};
#endif // POLLY_ISL_NODE_BUILDER_H

View File

@ -309,9 +309,17 @@ void IslNodeBuilder::getReferencesInSubtree(__isl_keep isl_ast_node *For,
Values.remove_if([](const Value *V) { return isa<GlobalValue>(V); });
/// Note: Code generation of induction variables of loops outside Scops
///
/// Remove loops that contain the scop or that are part of the scop, as they
/// are considered local. This leaves only loops that are before the scop, but
/// do not contain the scop itself.
/// We ignore loops perfectly contained in the Scop because these are already
/// generated at `IslNodeBuilder::addParameters`. These `Loops` are loops
/// whose induction variables are referred to by the Scop, but the Scop is not
/// fully contained in these Loops. Since there can be many of these,
/// we choose to codegen these on-demand.
/// @see IslNodeBuilder::materializeNonScopLoopInductionVariable.
Loops.remove_if([this](const Loop *L) {
return S.contains(L) || L->contains(S.getEntry());
});
@ -627,13 +635,10 @@ void IslNodeBuilder::createForParallel(__isl_take isl_ast_node *For) {
// Create for all loops we depend on values that contain the current loop
// iteration. These values are necessary to generate code for SCEVs that
// depend on such loops. As a result we need to pass them to the subfunction.
// See [Code generation of induction variables of loops outside Scops]
for (const Loop *L : Loops) {
const SCEV *OuterLIV = SE.getAddRecExpr(SE.getUnknown(Builder.getInt64(0)),
SE.getUnknown(Builder.getInt64(1)),
L, SCEV::FlagAnyWrap);
Value *V = generateSCEV(OuterLIV);
OutsideLoopIterations[L] = SE.getUnknown(V);
SubtreeValues.insert(V);
Value *LoopInductionVar = materializeNonScopLoopInductionVariable(L);
SubtreeValues.insert(LoopInductionVar);
}
ValueMapT NewValues;
@ -896,6 +901,17 @@ void IslNodeBuilder::generateCopyStmt(
Builder.CreateStore(LoadValue, StoreAddr);
}
Value *IslNodeBuilder::materializeNonScopLoopInductionVariable(const Loop *L) {
assert(OutsideLoopIterations.find(L) == OutsideLoopIterations.end() &&
"trying to materialize loop induction variable twice");
const SCEV *OuterLIV = SE.getAddRecExpr(SE.getUnknown(Builder.getInt64(0)),
SE.getUnknown(Builder.getInt64(1)), L,
SCEV::FlagAnyWrap);
Value *V = generateSCEV(OuterLIV);
OutsideLoopIterations[L] = SE.getUnknown(V);
return V;
}
void IslNodeBuilder::createUser(__isl_take isl_ast_node *User) {
LoopToScevMapT LTS;
isl_id *Id;
@ -1484,11 +1500,7 @@ void IslNodeBuilder::addParameters(__isl_take isl_set *Context) {
L = L->getParentLoop();
while (L != nullptr) {
const SCEV *OuterLIV = SE.getAddRecExpr(SE.getUnknown(Builder.getInt64(0)),
SE.getUnknown(Builder.getInt64(1)),
L, SCEV::FlagAnyWrap);
Value *V = generateSCEV(OuterLIV);
OutsideLoopIterations[L] = SE.getUnknown(V);
materializeNonScopLoopInductionVariable(L);
L = L->getParentLoop();
}