@@ -127,14 +127,6 @@ class StreamPipeliner {
127127 stages[SCHED_LOCAL_STORE] = _globalPrefetch;
128128 stages[SCHED_LOCAL_LOAD] = lastStage - _localPrefetch;
129129 stages[SCHED_COMPUTE] = lastStage;
130-
131- options.supportDynamicLoops = true ;
132- options.peelEpilogue = true ;
133- options.guardEpilogue = _mustGuardEpilogue;
134- if (_mustGuardEpilogue)
135- options.predicateFn = streamPredication;
136- else
137- options.predicateFn = tt::predicateOp;
138130 }
139131
140132 LogicalResult pipelineLoop ();
@@ -210,9 +202,6 @@ class StreamPipeliner {
210202
211203 // Capture list of new shared memory buffers.
212204 SmallVector<Value> sharedMemAllocs;
213-
214- // Pipelining options for the PipelineExpander
215- tt::PipeliningOption options;
216205};
217206
218207} // namespace
@@ -277,7 +266,8 @@ bool StreamPipeliner::safeDAG(Value v, int index) {
277266 }
278267 return false ;
279268}
280-
269+ // TODO(crobeck): is this valid if we have loop-carried
270+ // results needed for the next epilogue stage?
281271void StreamPipeliner::checkResultResilience () {
282272 auto yieldVals = forOp.getYieldedValuesMutable ().value ();
283273 for (auto [index, res] : llvm::enumerate (forOp.getResults ())) {
@@ -1016,18 +1006,6 @@ LogicalResult StreamPipeliner::preprocessLoopAndBuildSchedule() {
10161006 schedule.dump ();
10171007 });
10181008
1019- // Create the final schedule for the kernel loop. This will dictate the
1020- // stages and order of operations to the pipeline expander.
1021- std::vector<std::pair<Operation *, unsigned >> coarseSchedule =
1022- schedule.createFinalSchedule (forOp);
1023-
1024- // Fill out the pipeline options.
1025- options.getScheduleFn =
1026- [coarseSchedule](scf::ForOp,
1027- std::vector<std::pair<Operation *, unsigned >> &s) {
1028- s = std::move (coarseSchedule);
1029- };
1030-
10311009 OpBuilder builder (forOp);
10321010 builder.setInsertionPointAfter (forOp);
10331011 // Explicitly deallocate created allocations.
@@ -1041,6 +1019,27 @@ LogicalResult StreamPipeliner::pipelineLoop() {
10411019 if (failed (preprocessLoopAndBuildSchedule ()))
10421020 return failure ();
10431021 LDBG (" Loop before sending to expander:\n " << *forOp);
1022+ // Create the final schedule for the kernel loop. This will dictate the
1023+ // stages and order of operations to the pipeline expander.
1024+ std::vector<std::pair<Operation *, unsigned >> coarseSchedule =
1025+ schedule.createFinalSchedule (forOp);
1026+
1027+ // Pipelining options for the PipelineExpander
1028+ tt::PipeliningOption options;
1029+ options.supportDynamicLoops = true ;
1030+ options.peelEpilogue = true ;
1031+ options.guardEpilogue = mustGuardEpilogue;
1032+
1033+ if (mustGuardEpilogue)
1034+ options.predicateFn = streamPredication;
1035+ else
1036+ options.predicateFn = tt::predicateOp;
1037+
1038+ options.getScheduleFn =
1039+ [&coarseSchedule](scf::ForOp,
1040+ std::vector<std::pair<Operation *, unsigned >> &s) {
1041+ s = std::move (coarseSchedule);
1042+ };
10441043
10451044 IRRewriter rewriter (forOp->getContext ());
10461045 rewriter.setInsertionPoint (forOp);
0 commit comments