Skip to content

Commit 211be9e

Browse files
committed
Modify forward dependency check
1 parent ced443b commit 211be9e

File tree

1 file changed

+55
-36
lines changed

1 file changed

+55
-36
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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

147164
static 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

Comments
 (0)