@@ -142,6 +142,23 @@ static void printDepMatrix(CharMatrix &DepMatrix) {
142142 LLVM_DEBUG (dbgs () << " \n " );
143143 }
144144}
145+
146+ static bool inThisOrder (const Instruction *Src, const Instruction *Dst) {
147+ assert (Src->getParent () == Dst->getParent () && Src != Dst &&
148+ " Expected Src and Dst to be different instructions in the same BB" );
149+
150+ bool FoundSrc = false ;
151+ for (const Instruction &I : *(Src->getParent ())) {
152+ if (&I == Src) {
153+ FoundSrc = true ;
154+ continue ;
155+ }
156+ if (&I == Dst)
157+ return FoundSrc;
158+ }
159+
160+ llvm_unreachable (" Dst not found" );
161+ }
145162#endif
146163
147164static bool populateDependencyMatrix (CharMatrix &DepMatrix, unsigned Level,
@@ -190,16 +207,6 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
190207 // to an index of DepMatrix at which it is stored.
191208 StringMap<unsigned > Seen;
192209
193- // The i-th element is set iff all dependencies corresponding to the i-th
194- // direction vector in DepMatrix are "lexically forward". The notion
195- // "lexically forward" aligns with what is defined in LAA
196- // (LoopAccessAnalysis).
197- //
198- // We deem a dependence lexically forward if we can prove that the
199- // destination instruction is always executed after the source instruction
200- // within each iteration.
201- BitVector IsForwardFlags;
202-
203210 for (I = MemInstr.begin (), IE = MemInstr.end (); I != IE; ++I) {
204211 for (J = I, JE = MemInstr.end (); J != JE; ++J) {
205212 std::vector<char > Dep;
@@ -211,22 +218,11 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
211218 // Track Output, Flow, and Anti dependencies.
212219 if (auto D = DI->depends (Src, Dst)) {
213220 assert (D->isOrdered () && " Expected an output, flow or anti dep." );
214- bool IsForward = true ;
215-
216- // If Src and Dst are in the same BB, Src is always executed before Dst
217- // in the same loop iteration. If not, we must check whether one BB
218- // dominates the other to determine if Src and Dst are executed in this
219- // order. At the moment, we don't perform such check.
220- if (Src->getParent () != Dst->getParent ())
221- IsForward = false ;
222221
223222 // If the direction vector is negative, normalize it to
224223 // make it non-negative.
225- bool Normalized = D->normalize (SE);
226- if (Normalized) {
224+ if (D->normalize (SE))
227225 LLVM_DEBUG (dbgs () << " Negative dependence vector normalized.\n " );
228- IsForward = false ;
229- }
230226 LLVM_DEBUG (StringRef DepType =
231227 D->isFlow () ? " flow" : D->isAnti () ? " anti" : " output" ;
232228 dbgs () << " Found " << DepType
@@ -264,28 +260,51 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
264260 Dep.push_back (' I' );
265261 }
266262
263+ // Test whether the dependency is forward or not.
264+ bool IsKnownForward = true ;
265+ if (Src->getParent () != Dst->getParent ()) {
266+ // In general, when Src and Dst are in different BBs, the execution
267+ // order of them within a single iteration is not guaranteed. Treat
268+ // conservatively as not-forward dependency in this case.
269+ IsKnownForward = false ;
270+ } else {
271+ // Src and Dst are in the same BB. If they are the different
272+ // instructions, Src should appear before Dst in the BB as they are
273+ // stored to MemInstr in that order.
274+ assert ((Src == Dst || inThisOrder (Src, Dst)) &&
275+ " Unexpected instructions" );
276+
277+ // If the Dependence object is reversed (due to normalization), it
278+ // represents the dependency from Dst to Src, meaning it is a backward
279+ // dependency. Otherwise it should be a forward dependency.
280+ bool IsReversed = D->getSrc () != Src;
281+ if (IsReversed)
282+ IsKnownForward = false ;
283+ }
284+
285+ // Initialize the last element.
286+ Dep.push_back (' <' );
287+
288+ // The last element should express the "summary" among one or more
289+ // direction vectors whose first N elements are the same (where N is
290+ // the depth of the loop nest). Hence we exclude the last element from
291+ // the Seen map.
267292 auto [Ite, Inserted] = Seen.try_emplace (
268- StringRef (Dep.data (), Dep.size ()), DepMatrix.size ());
293+ StringRef (Dep.data (), Dep.size () - 1 ), DepMatrix.size ());
269294
270295 // Make sure we only add unique entries to the dependency matrix.
271- if (Inserted) {
296+ if (Inserted)
272297 DepMatrix.push_back (Dep);
273- IsForwardFlags.push_back (true );
274- }
275- if (!IsForward)
276- IsForwardFlags.reset (Ite->second );
298+
299+ // If we cannot prove that this dependency is forward, change the last
300+ // element of the corresponding entry. Note that the existing entry in
301+ // DepMatrix can be modified.
302+ if (!IsKnownForward)
303+ DepMatrix[Ite->second ].back () = ' *' ;
277304 }
278305 }
279306 }
280307
281- assert (DepMatrix.size () == IsForwardFlags.size () &&
282- " Dependency matrix and IsForwardVec should have the same size." );
283-
284- // If all dependencies corresponding to a direction vector are forward, encode
285- // it to '<', otherwise to '*'.
286- for (unsigned I = 0 ; I != DepMatrix.size (); I++)
287- DepMatrix[I].push_back (IsForwardFlags[I] ? ' <' : ' *' );
288-
289308 return true ;
290309}
291310
0 commit comments