Skip to content

Commit 8f31ee9

Browse files
authored
[SandboxVec][DAG] Implement DGNode::isMem() (#109504)
DGNode::isMem() returns true if the node is a memory dependency candidate.
1 parent c9e5c42 commit 8f31ee9

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,16 @@ class DGNode {
3535
Instruction *I;
3636
/// Memory predecessors.
3737
DenseSet<DGNode *> MemPreds;
38+
/// This is true if this may read/write memory, or if it has some ordering
39+
/// constraings, like with stacksave/stackrestore and alloca/inalloca.
40+
bool IsMem;
3841

3942
public:
40-
DGNode(Instruction *I) : I(I) {}
43+
DGNode(Instruction *I) : I(I) {
44+
IsMem = I->isMemDepCandidate() ||
45+
(isa<AllocaInst>(I) && cast<AllocaInst>(I)->isUsedWithInAlloca()) ||
46+
I->isStackSaveOrRestoreIntrinsic();
47+
}
4148
Instruction *getInstruction() const { return I; }
4249
void addMemPred(DGNode *PredN) { MemPreds.insert(PredN); }
4350
/// \Returns all memory dependency predecessors.
@@ -46,6 +53,9 @@ class DGNode {
4653
}
4754
/// \Returns true if there is a memory dependency N->this.
4855
bool hasMemPred(DGNode *N) const { return MemPreds.count(N); }
56+
/// \Returns true if this may read/write memory, or if it has some ordering
57+
/// constraings, like with stacksave/stackrestore and alloca/inalloca.
58+
bool isMem() const { return IsMem; }
4959
#ifndef NDEBUG
5060
void print(raw_ostream &OS, bool PrintDeps = true) const;
5161
friend raw_ostream &operator<<(DGNode &N, raw_ostream &OS) {

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,55 @@ struct DependencyGraphTest : public testing::Test {
2727
}
2828
};
2929

30+
TEST_F(DependencyGraphTest, DGNode_IsMem) {
31+
parseIR(C, R"IR(
32+
declare void @llvm.sideeffect()
33+
declare void @llvm.pseudoprobe(i64, i64, i32, i64)
34+
declare void @llvm.fake.use(...)
35+
declare void @bar()
36+
define void @foo(i8 %v1, ptr %ptr) {
37+
store i8 %v1, ptr %ptr
38+
%ld0 = load i8, ptr %ptr
39+
%add = add i8 %v1, %v1
40+
%stacksave = call ptr @llvm.stacksave()
41+
call void @llvm.stackrestore(ptr %stacksave)
42+
call void @llvm.sideeffect()
43+
call void @llvm.pseudoprobe(i64 42, i64 1, i32 0, i64 -1)
44+
call void @llvm.fake.use(ptr %ptr)
45+
call void @bar()
46+
ret void
47+
}
48+
)IR");
49+
llvm::Function *LLVMF = &*M->getFunction("foo");
50+
sandboxir::Context Ctx(C);
51+
auto *F = Ctx.createFunction(LLVMF);
52+
auto *BB = &*F->begin();
53+
auto It = BB->begin();
54+
auto *Store = cast<sandboxir::StoreInst>(&*It++);
55+
auto *Load = cast<sandboxir::LoadInst>(&*It++);
56+
auto *Add = cast<sandboxir::BinaryOperator>(&*It++);
57+
auto *StackSave = cast<sandboxir::CallInst>(&*It++);
58+
auto *StackRestore = cast<sandboxir::CallInst>(&*It++);
59+
auto *SideEffect = cast<sandboxir::CallInst>(&*It++);
60+
auto *PseudoProbe = cast<sandboxir::CallInst>(&*It++);
61+
auto *FakeUse = cast<sandboxir::CallInst>(&*It++);
62+
auto *Call = cast<sandboxir::CallInst>(&*It++);
63+
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
64+
65+
sandboxir::DependencyGraph DAG;
66+
DAG.extend({&*BB->begin(), BB->getTerminator()});
67+
EXPECT_TRUE(DAG.getNode(Store)->isMem());
68+
EXPECT_TRUE(DAG.getNode(Load)->isMem());
69+
EXPECT_FALSE(DAG.getNode(Add)->isMem());
70+
EXPECT_TRUE(DAG.getNode(StackSave)->isMem());
71+
EXPECT_TRUE(DAG.getNode(StackRestore)->isMem());
72+
EXPECT_FALSE(DAG.getNode(SideEffect)->isMem());
73+
EXPECT_FALSE(DAG.getNode(PseudoProbe)->isMem());
74+
EXPECT_TRUE(DAG.getNode(FakeUse)->isMem());
75+
EXPECT_TRUE(DAG.getNode(Call)->isMem());
76+
EXPECT_FALSE(DAG.getNode(Ret)->isMem());
77+
}
78+
3079
TEST_F(DependencyGraphTest, Basic) {
3180
parseIR(C, R"IR(
3281
define void @foo(ptr %ptr, i8 %v0, i8 %v1) {

0 commit comments

Comments
 (0)