Skip to content

Commit 3e3af86

Browse files
authored
[SandboxVec][DAG] Add MemDGNode::MemSuccs (llvm#127253)
This patch adds Memory successors to the memory nodes of the DAG. This will help maintain the memory dependencies when nodes get removed.
1 parent ed48398 commit 3e3af86

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ class DGNode {
117117
virtual ~DGNode();
118118
/// \Returns the number of unscheduled successors.
119119
unsigned getNumUnscheduledSuccs() const { return UnscheduledSuccs; }
120+
// TODO: Make this private?
120121
void decrUnscheduledSuccs() {
121122
assert(UnscheduledSuccs > 0 && "Counting error!");
122123
--UnscheduledSuccs;
@@ -214,6 +215,8 @@ class MemDGNode final : public DGNode {
214215
MemDGNode *NextMemN = nullptr;
215216
/// Memory predecessors.
216217
DenseSet<MemDGNode *> MemPreds;
218+
/// Memory successors.
219+
DenseSet<MemDGNode *> MemSuccs;
217220
friend class PredIterator; // For MemPreds.
218221
/// Creates both edges: this<->N.
219222
void setNextNode(MemDGNode *N) {
@@ -265,10 +268,20 @@ class MemDGNode final : public DGNode {
265268
[[maybe_unused]] auto Inserted = MemPreds.insert(PredN).second;
266269
assert(Inserted && "PredN already exists!");
267270
assert(PredN != this && "Trying to add a dependency to self!");
271+
PredN->MemSuccs.insert(this);
268272
if (!Scheduled) {
269273
++PredN->UnscheduledSuccs;
270274
}
271275
}
276+
/// Removes the memory dependency PredN->this. This also updates the
277+
/// UnscheduledSuccs counter of PredN if this node has not been scheduled.
278+
void removeMemPred(MemDGNode *PredN) {
279+
MemPreds.erase(PredN);
280+
PredN->MemSuccs.erase(this);
281+
if (!Scheduled) {
282+
PredN->decrUnscheduledSuccs();
283+
}
284+
}
272285
/// \Returns true if there is a memory dependency N->this.
273286
bool hasMemPred(DGNode *N) const {
274287
if (auto *MN = dyn_cast<MemDGNode>(N))
@@ -279,6 +292,10 @@ class MemDGNode final : public DGNode {
279292
iterator_range<DenseSet<MemDGNode *>::const_iterator> memPreds() const {
280293
return make_range(MemPreds.begin(), MemPreds.end());
281294
}
295+
/// \Returns all memory dependency successors.
296+
iterator_range<DenseSet<MemDGNode *>::const_iterator> memSuccs() const {
297+
return make_range(MemSuccs.begin(), MemSuccs.end());
298+
}
282299
#ifndef NDEBUG
283300
virtual void print(raw_ostream &OS, bool PrintDeps = true) const override;
284301
#endif // NDEBUG

llvm/unittests/Transforms/Vectorize/SandboxVectorizer/DependencyGraphTest.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ define void @foo(ptr %ptr, i8 %v0, i8 %v1) {
250250
EXPECT_THAT(N1->memPreds(), testing::ElementsAre(N0));
251251
EXPECT_TRUE(N2->preds(DAG).empty());
252252

253+
// Check memSuccs().
254+
EXPECT_THAT(N0->memSuccs(), testing::ElementsAre(N1));
255+
253256
// Check UnscheduledSuccs.
254257
EXPECT_EQ(N0->getNumUnscheduledSuccs(), 1u); // N1
255258
EXPECT_EQ(N1->getNumUnscheduledSuccs(), 0u);
@@ -268,6 +271,41 @@ define void @foo(ptr %ptr, i8 %v0, i8 %v1) {
268271
EXPECT_TRUE(N0->scheduled());
269272
}
270273

274+
TEST_F(DependencyGraphTest, AddRemoveMemPred) {
275+
parseIR(C, R"IR(
276+
define void @foo(ptr %ptr, i8 %v0, i8 %v1) {
277+
store i8 %v0, ptr %ptr
278+
store i8 %v1, ptr %ptr
279+
ret void
280+
}
281+
)IR");
282+
llvm::Function *LLVMF = &*M->getFunction("foo");
283+
sandboxir::Context Ctx(C);
284+
auto *F = Ctx.createFunction(LLVMF);
285+
auto *BB = &*F->begin();
286+
auto It = BB->begin();
287+
auto *S0 = cast<sandboxir::StoreInst>(&*It++);
288+
auto *S1 = cast<sandboxir::StoreInst>(&*It++);
289+
290+
sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
291+
DAG.extend({&*BB->begin(), BB->getTerminator()});
292+
auto *N0 = cast<sandboxir::MemDGNode>(DAG.getNode(S0));
293+
auto *N1 = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
294+
295+
// Check removeMemPred().
296+
EXPECT_FALSE(N0->memSuccs().empty());
297+
EXPECT_EQ(N0->getNumUnscheduledSuccs(), 1u);
298+
N1->removeMemPred(N0);
299+
EXPECT_TRUE(N1->memPreds().empty());
300+
EXPECT_EQ(N0->getNumUnscheduledSuccs(), 0u);
301+
302+
// Check addMemPred().
303+
N1->addMemPred(N0);
304+
EXPECT_THAT(N1->memPreds(), testing::UnorderedElementsAre(N0));
305+
EXPECT_THAT(N0->memSuccs(), testing::UnorderedElementsAre(N1));
306+
EXPECT_THAT(N0->getNumUnscheduledSuccs(), 1u);
307+
}
308+
271309
TEST_F(DependencyGraphTest, Preds) {
272310
parseIR(C, R"IR(
273311
declare ptr @bar(i8)
@@ -533,7 +571,7 @@ define void @foo(ptr noalias %ptr0, ptr noalias %ptr1) {
533571
EXPECT_TRUE(RetN->preds(DAG).empty());
534572
}
535573

536-
TEST_F(DependencyGraphTest, VolatileSotres) {
574+
TEST_F(DependencyGraphTest, VolatileStores) {
537575
parseIR(C, R"IR(
538576
define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, i8 %v) {
539577
store volatile i8 %v, ptr %ptr0

0 commit comments

Comments
 (0)