@@ -190,29 +190,35 @@ void PostPipeliner::computeLoopCarriedParameters() {
190
190
}
191
191
192
192
// Propagate Earliest upstream, initialize Latest
193
+ // Unrestricted: last cycle of last stage
194
+ const int Latest = NCopies * II - 1 ;
193
195
for (int K = 0 ; K < NInstr; K++) {
194
196
const int K2 = K + NInstr;
195
197
const int Earliest = Info[K2].Earliest - II;
196
198
Info[K].Earliest = std::max (Info[K].Earliest , Earliest);
197
- // Unrestricted: Beyond the last stage.
198
- Info[K ].Latest = NCopies * II ;
199
+ Info[K]. Latest = Latest;
200
+ Info[K2 ].Latest = Latest ;
199
201
}
200
- // Propagate Latest upstream. Latest is the latest
201
- // that is admissible for Earliest to be achievable within II
202
- for (int K = 0 ; K < NInstr; K++) {
203
- const int K2 = K + NInstr;
204
- const int Earliest = Info[K2].Earliest ;
205
- const auto &SU = DAG->SUnits [K2];
206
- for (auto &Dep : SU.Preds ) {
207
- const auto *Pred = Dep.getSUnit ();
208
- // Any predecessor in the first iteration
209
- int K1 = Pred->NodeNum ;
210
- if (K1 < NInstr) {
211
- const int Latest = Earliest - Dep.getSignedLatency ();
212
- Info[K1].Latest = std::min (Info[K1].Latest , Latest);
202
+
203
+ // Compute Latest. Use a fixpoint loop, because plain reversed
204
+ // order may not be topological for predecessors
205
+ bool Changed = true ;
206
+ while (Changed) {
207
+ Changed = false ;
208
+ for (int K = NInstr - 1 ; K >= 0 ; K--) {
209
+ SUnit &SU = DAG->SUnits [K];
210
+ const int Latest = Info[K].Latest ;
211
+ for (auto &Dep : SU.Preds ) {
212
+ int P = Dep.getSUnit ()->NodeNum ;
213
+ int NewLatest = Latest - Dep.getSignedLatency ();
214
+ if (NewLatest < Info[P].Latest ) {
215
+ Info[P].Latest = NewLatest;
216
+ Changed = true ;
217
+ }
213
218
}
214
219
}
215
220
}
221
+
216
222
LLVM_DEBUG (for (int K = 0 ; K < NInstr; K++) {
217
223
dbgs () << " SU" << K << " : " << Info[K].Earliest << " - " << Info[K].Latest
218
224
<< " \n " ;
0 commit comments