21TEST(TraceTests, TestTraceOutputIntraProcedural_Gamma)
26 const auto controlType = ControlType::Create(2);
27 const auto valueType = TestType::createValueType();
30 auto & i0 = GraphImport::Create(rvsdg, controlType,
"i0");
31 auto & i1 = GraphImport::Create(rvsdg, valueType,
"i1");
32 auto & i2 = GraphImport::Create(rvsdg, valueType,
"i2");
34 const auto gammaNode = GammaNode::create(&i0, 2);
35 auto entryVar1 = gammaNode->AddEntryVar(&i1);
36 auto entryVar1Copy = gammaNode->AddEntryVar(&i1);
37 auto entryVar2 = gammaNode->AddEntryVar(&i2);
39 auto node = TestOperation::createNode(
40 gammaNode->subregion(1),
41 { entryVar2.branchArgument[1] },
45 gammaNode->AddExitVar({ entryVar1.branchArgument[0], entryVar1Copy.branchArgument[1] });
47 gammaNode->AddExitVar({ entryVar1.branchArgument[0], entryVar2.branchArgument[1] });
48 auto exitVar2 = gammaNode->AddExitVar({ entryVar2.branchArgument[0], node->output(0) });
50 auto & x0 = GraphExport::Create(*exitVar0.output,
"x0");
51 auto & x1 = GraphExport::Create(*exitVar1.output,
"x1");
52 auto & x2 = GraphExport::Create(*exitVar2.output,
"x2");
57 const auto & tracedX0 = traceOutputIntraProcedurally(*x0.origin());
58 const auto & tracedX1 = traceOutputIntraProcedurally(*x1.origin());
59 const auto & tracedX2 = traceOutputIntraProcedurally(*x2.origin());
61 const auto & traceGammaEntry = traceOutputIntraProcedurally(*entryVar1.branchArgument[0]);
62 const auto & tracedNodeInput = traceOutputIntraProcedurally(*node->input(0)->origin());
65 EXPECT_EQ(&tracedX0, &i1);
66 EXPECT_EQ(&tracedX1, x1.origin());
67 EXPECT_EQ(&tracedX2, x2.origin());
68 EXPECT_EQ(&traceGammaEntry, &i1);
69 EXPECT_EQ(&tracedNodeInput, &i2);
75TEST(TraceTests, TestTraceOutputIntraProcedural_Theta)
80 const auto valueType = TestType::createValueType();
83 auto & i0 = GraphImport::Create(rvsdg, valueType,
"i0");
84 auto & i1 = GraphImport::Create(rvsdg, valueType,
"i1");
86 const auto thetaNode = ThetaNode::create(&rvsdg.
GetRootRegion());
88 auto loopVar0 = thetaNode->AddLoopVar(&i0);
89 auto loopVar1 = thetaNode->AddLoopVar(&i1);
91 auto node = TestOperation::createNode(thetaNode->subregion(), { loopVar1.pre }, { valueType });
92 loopVar1.post->divert_to(node->output(0));
94 auto & x0 = GraphExport::Create(*loopVar0.output,
"x0");
95 auto & x1 = GraphExport::Create(*loopVar1.output,
"x1");
100 const auto & tracedX0 = traceOutputIntraProcedurally(*x0.origin());
101 const auto & tracedX1 = traceOutputIntraProcedurally(*x1.origin());
102 const auto & traceLoopVar0Pre = traceOutputIntraProcedurally(*loopVar0.pre);
103 const auto & traceLoopVar1Pre = traceOutputIntraProcedurally(*loopVar1.pre);
104 const auto & tracedNodeInput = traceOutputIntraProcedurally(*node->input(0)->origin());
107 EXPECT_EQ(&tracedX0, &i0);
108 EXPECT_EQ(&tracedX1, x1.origin());
109 EXPECT_EQ(&traceLoopVar0Pre, &i0);
110 EXPECT_EQ(&traceLoopVar1Pre, loopVar1.pre);
111 EXPECT_EQ(&tracedNodeInput, loopVar1.pre);
117TEST(TraceTests, TestTraceNestedStructuralNodes)
122 const auto controlType = ControlType::Create(2);
123 const auto valueType = TestType::createValueType();
126 auto & i0 = GraphImport::Create(rvsdg, valueType,
"i0");
127 auto & i1 = GraphImport::Create(rvsdg, valueType,
"i1");
128 auto & i2 = GraphImport::Create(rvsdg, valueType,
"i2");
130 const auto thetaNode = ThetaNode::create(&rvsdg.
GetRootRegion());
132 auto loopVar0 = thetaNode->AddLoopVar(&i0);
133 auto loopVar1 = thetaNode->AddLoopVar(&i1);
134 auto loopVar2 = thetaNode->AddLoopVar(&i2);
139 const auto gammaNode = GammaNode::create(undefNode.output(0), 2);
140 auto entryVar0 = gammaNode->AddEntryVar(loopVar0.pre);
141 auto entryVar1 = gammaNode->AddEntryVar(loopVar1.pre);
143 gammaNode->AddExitVar({ entryVar0.branchArgument[0], entryVar0.branchArgument[1] });
145 gammaNode->AddExitVar({ entryVar1.branchArgument[0], entryVar1.branchArgument[1] });
149 loopVar0.post->divert_to(exitVar0.output);
150 loopVar1.post->divert_to(exitVar0.output);
152 auto & x0 = GraphExport::Create(*loopVar0.output,
"x0");
153 auto & x1 = GraphExport::Create(*loopVar1.output,
"x1");
154 auto & x2 = GraphExport::Create(*loopVar2.output,
"x2");
160 const auto & tracedX0 = traceOutputIntraProcedurally(*x0.origin());
161 const auto & tracedX1 = traceOutputIntraProcedurally(*x1.origin());
162 const auto & tracedX2 = traceOutputIntraProcedurally(*x2.origin());
163 const auto & traceExitVar0 = traceOutputIntraProcedurally(*exitVar0.output);
164 const auto & traceExitVar1 = traceOutputIntraProcedurally(*exitVar1.output);
165 const auto & traceBranchArgument0 = traceOutputIntraProcedurally(*entryVar0.branchArgument[0]);
166 const auto & traceBranchArgument1 = traceOutputIntraProcedurally(*entryVar1.branchArgument[1]);
167 const auto & traceLoopVar0Pre = traceOutputIntraProcedurally(*loopVar0.pre);
168 const auto & traceLoopVar1Pre = traceOutputIntraProcedurally(*loopVar1.pre);
169 const auto & traceLoopVar2Pre = traceOutputIntraProcedurally(*loopVar2.pre);
171 EXPECT_EQ(&tracedX0, &i0);
172 EXPECT_EQ(&tracedX1, loopVar1.output);
173 EXPECT_EQ(&tracedX2, &i2);
174 EXPECT_EQ(&traceExitVar0, &i0);
175 EXPECT_EQ(&traceExitVar1, loopVar1.pre);
176 EXPECT_EQ(&traceBranchArgument0, &i0);
177 EXPECT_EQ(&traceBranchArgument1, loopVar1.pre);
178 EXPECT_EQ(&traceLoopVar0Pre, &i0);
179 EXPECT_EQ(&traceLoopVar1Pre, loopVar1.pre);
180 EXPECT_EQ(&traceLoopVar2Pre, &i2);
186 constexpr bool enableCaching =
false;
190 const auto & tracedX0 = shallowTracer.
trace(*x0.origin());
191 const auto & tracedX1 = shallowTracer.
trace(*x1.origin());
192 const auto & tracedX2 = shallowTracer.
trace(*x2.origin());
193 const auto & traceExitVar0 = shallowTracer.
trace(*exitVar0.output);
194 const auto & traceExitVar1 = shallowTracer.
trace(*exitVar1.output);
195 const auto & traceBranchArgument0 = shallowTracer.
trace(*entryVar0.branchArgument[0]);
196 const auto & traceBranchArgument1 = shallowTracer.
trace(*entryVar1.branchArgument[1]);
197 const auto & traceLoopVar0Pre = shallowTracer.
trace(*loopVar0.pre);
198 const auto & traceLoopVar1Pre = shallowTracer.
trace(*loopVar1.pre);
199 const auto & traceLoopVar2Pre = shallowTracer.
trace(*loopVar2.pre);
201 EXPECT_EQ(&tracedX0, loopVar0.output);
202 EXPECT_EQ(&tracedX1, loopVar1.output);
203 EXPECT_EQ(&tracedX2, &i2);
204 EXPECT_EQ(&traceExitVar0, loopVar0.pre);
205 EXPECT_EQ(&traceExitVar1, loopVar1.pre);
206 EXPECT_EQ(&traceBranchArgument0, loopVar0.pre);
207 EXPECT_EQ(&traceBranchArgument1, loopVar1.pre);
208 EXPECT_EQ(&traceLoopVar0Pre, loopVar0.pre);
209 EXPECT_EQ(&traceLoopVar1Pre, loopVar1.pre);
210 EXPECT_EQ(&traceLoopVar2Pre, &i2);
219TEST(TraceTests, TestIndirectLoopInvariantOutput)
244 auto & c20 = BitConstantOperation::create(rvsdg.
GetRootRegion(), { 32, 20 });
245 auto & c40 = BitConstantOperation::create(rvsdg.
GetRootRegion(), { 32, 40 });
247 const auto thetaNode = ThetaNode::create(&rvsdg.
GetRootRegion());
248 auto invariantLoopVar = thetaNode->AddLoopVar(&c20);
249 auto indirectLoopVar = thetaNode->AddLoopVar(&c40);
252 auto user1 = TestOperation::createNode(thetaNode->subregion(), { indirectLoopVar.pre }, {});
255 indirectLoopVar.post->divert_to(invariantLoopVar.pre);
258 auto user2 = TestOperation::createNode(&rvsdg.
GetRootRegion(), { indirectLoopVar.output }, {});
263 const auto & tracedUser1 = traceOutputIntraProcedurally(*user1->input(0)->origin());
264 const auto & tracedUser2 = traceOutputIntraProcedurally(*user2->input(0)->origin());
267 EXPECT_TRUE(ThetaLoopVarIsInvariant(invariantLoopVar));
268 EXPECT_FALSE(ThetaLoopVarIsInvariant(indirectLoopVar));
269 EXPECT_EQ(&tracedUser1, indirectLoopVar.pre);
270 EXPECT_EQ(&tracedUser2, &c20);
277TEST(TraceTests, TestIndirectLoopInvariance)
302 auto & c20 = BitConstantOperation::create(rvsdg.
GetRootRegion(), { 32, 20 });
304 const auto thetaNode = ThetaNode::create(&rvsdg.
GetRootRegion());
305 auto invariantLoopVar = thetaNode->AddLoopVar(&c20);
306 auto indirectLoopVar = thetaNode->AddLoopVar(&c20);
309 auto user1 = TestOperation::createNode(thetaNode->subregion(), { indirectLoopVar.pre }, {});
312 indirectLoopVar.post->divert_to(invariantLoopVar.pre);
315 auto user2 = TestOperation::createNode(&rvsdg.
GetRootRegion(), { indirectLoopVar.output }, {});
320 const auto & tracedUser1 = traceOutputIntraProcedurally(*user1->input(0)->origin());
321 const auto & tracedUser2 = traceOutputIntraProcedurally(*user2->input(0)->origin());
324 EXPECT_TRUE(ThetaLoopVarIsInvariant(invariantLoopVar));
325 EXPECT_FALSE(ThetaLoopVarIsInvariant(indirectLoopVar));
326 EXPECT_EQ(&tracedUser1, &c20);
327 EXPECT_EQ(&tracedUser2, &c20);
330TEST(TraceTests, GammaCachingTest)
335 const auto controlType = ControlType::Create(2);
336 const auto valueType = TestType::createValueType();
340 auto & predicate = GraphImport::Create(rvsdg, controlType,
"predicate");
341 auto & i1 = GraphImport::Create(rvsdg, valueType,
"i1");
342 auto & i2 = GraphImport::Create(rvsdg, valueType,
"i2");
344 auto gammaNode = GammaNode::create(&predicate, 2);
345 auto i1EntryVar = gammaNode->AddEntryVar(&i1);
346 auto i2EntryVar = gammaNode->AddEntryVar(&i2);
349 gammaNode->AddExitVar({ i1EntryVar.branchArgument[0], i1EntryVar.branchArgument[1] });
351 auto & graphExport = GraphExport::Create(*exitVar.output,
"export");
353 constexpr bool enableCaching =
true;
358 auto traceResult = &tracer.
trace(*graphExport.origin());
359 assert(traceResult == &i1);
362 exitVar.branchResult[0]->divert_to(i2EntryVar.branchArgument[0]);
363 exitVar.branchResult[1]->divert_to(i2EntryVar.branchArgument[1]);
367 traceResult = &tracer.
trace(*graphExport.origin());
368 assert(traceResult == &i1);
372 traceResult = &tracer.
trace(*graphExport.origin());
373 assert(traceResult == &i2);
376TEST(TraceTests, ThetaCachingTest)
381 const auto controlType = ControlType::Create(2);
382 const auto valueType = TestType::createValueType();
386 auto & i1 = GraphImport::Create(rvsdg, valueType,
"i1");
387 auto & i2 = GraphImport::Create(rvsdg, valueType,
"i2");
390 auto loopVar1 = thetaNode->AddLoopVar(&i1);
391 auto loopVar2 = thetaNode->AddLoopVar(&i2);
393 auto & graphExport = GraphExport::Create(*loopVar1.output,
"export");
395 constexpr bool enableCaching =
true;
400 auto traceResult = &tracer.
trace(*graphExport.origin());
401 assert(traceResult == &i1);
404 loopVar1.post->divert_to(loopVar2.pre);
405 loopVar2.post->divert_to(loopVar1.pre);
409 traceResult = &tracer.
trace(*graphExport.origin());
410 assert(traceResult == &i1);
414 traceResult = &tracer.
trace(*graphExport.origin());
415 assert(traceResult == loopVar1.output);