75TEST(GammaConversionTests, WithoutMatchOperation)
77 auto valueType = TestType::createValueType();
79 FunctionType::Create({ ControlType::Create(2), valueType, valueType }, { valueType });
83 auto lambda = LambdaNode::Create(
84 rvsdgModule.Rvsdg().GetRootRegion(),
85 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
87 auto gamma = GammaNode::create(lambda->GetFunctionArguments()[0], 2);
88 auto entryVar1 = gamma->AddEntryVar(lambda->GetFunctionArguments()[1]);
89 auto entryVar2 = gamma->AddEntryVar(lambda->GetFunctionArguments()[2]);
90 auto exitVar = gamma->AddExitVar({ entryVar1.branchArgument[0], entryVar2.branchArgument[1] });
92 auto lambdaOutput = lambda->finalize({ exitVar.output });
93 GraphExport::Create(*lambdaOutput,
"");
98TEST(GammaConversionTests, NestedGammas)
100 auto controlType = ControlType::Create(2);
101 auto bit32Type = BitType::Create(32);
102 auto functionType = FunctionType::Create({ controlType }, { bit32Type });
106 auto lambda = LambdaNode::Create(
107 rvsdgModule.Rvsdg().GetRootRegion(),
108 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
110 auto & outerControlConstant =
112 auto outerGamma = GammaNode::create(lambda->GetFunctionArguments()[0], 2);
113 auto outerVar = outerGamma->AddEntryVar(&outerControlConstant);
115 auto & innerControlConstant =
117 auto innerGamma = GammaNode::create(&innerControlConstant, 2);
118 auto innerVar = innerGamma->AddEntryVar(outerVar.branchArgument[1]);
120 innerGamma->AddExitVar({ innerVar.branchArgument[0], innerVar.branchArgument[1] });
122 auto outerExit = outerGamma->AddExitVar({ outerVar.branchArgument[0], innerExit.output });
124 auto lambdaOutput = lambda->finalize({ outerExit.output });
125 GraphExport::Create(*lambdaOutput,
"");
130TEST(GammaConversionTests, MuxPredicateMapping)
132 auto valueType = TestType::createValueType();
133 auto bitType = BitType::Create(1);
134 auto functionType = FunctionType::Create({ bitType, valueType, valueType }, { valueType });
138 auto lambda = LambdaNode::Create(
139 rvsdgModule.Rvsdg().GetRootRegion(),
140 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
143 MatchOperation::CreateNode(*lambda->GetFunctionArguments()[0], { { 0, 0 } }, 1, 2);
145 auto gamma = GammaNode::create(matchNode.output(0), 2);
146 auto entryVar1 = gamma->AddEntryVar(lambda->GetFunctionArguments()[1]);
147 auto entryVar2 = gamma->AddEntryVar(lambda->GetFunctionArguments()[2]);
148 auto exitVar = gamma->AddExitVar({ entryVar1.branchArgument[0], entryVar2.branchArgument[1] });
150 auto lambdaOutput = lambda->finalize({ exitVar.output });
151 GraphExport::Create(*lambdaOutput,
"");
157 if (is<MuxOperation>(node->GetOperation()))
159 EXPECT_EQ(node->input(0)->origin(), matchNode.output(0));
164TEST(GammaConversionTests, MuxAlternativeSelection)
166 auto valueType = TestType::createValueType();
167 auto functionType = FunctionType::Create({ BitType::Create(2), valueType }, { valueType });
171 auto lambda = LambdaNode::Create(
172 rvsdgModule.Rvsdg().GetRootRegion(),
173 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
175 auto & matchNode = MatchOperation::CreateNode(
176 *lambda->GetFunctionArguments()[0],
177 { { 0, 0 }, { 1, 1 }, { 2, 2 } },
181 auto gamma = GammaNode::create(matchNode.output(0), 3);
182 auto entryVar1 = gamma->AddEntryVar(lambda->GetFunctionArguments()[1]);
183 auto exitVar = gamma->AddExitVar(
184 { entryVar1.branchArgument[0], entryVar1.branchArgument[1], entryVar1.branchArgument[2] });
186 auto lambdaOutput = lambda->finalize({ exitVar.output });
187 GraphExport::Create(*lambdaOutput,
"");
193 if (is<MuxOperation>(node->GetOperation()))
195 auto & muxOp =
static_cast<const MuxOperation &
>(node->GetOperation());
196 EXPECT_EQ(muxOp.narguments(), 4u);
197 EXPECT_EQ(node->ninputs(), 4u);
202TEST(GammaConversionTests, MuxControlPredicateMapping)
204 auto valueType = TestType::createValueType();
206 FunctionType::Create({ BitType::Create(1), valueType, valueType }, { valueType });
210 auto lambda = LambdaNode::Create(
211 rvsdgModule.Rvsdg().GetRootRegion(),
212 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
215 MatchOperation::CreateNode(*lambda->GetFunctionArguments()[0], { { 0, 0 } }, 1, 2);
217 auto gamma = GammaNode::create(matchNode.output(0), 2);
218 auto entryVar1 = gamma->AddEntryVar(lambda->GetFunctionArguments()[1]);
219 auto entryVar2 = gamma->AddEntryVar(lambda->GetFunctionArguments()[2]);
220 auto exitVar = gamma->AddExitVar({ entryVar1.branchArgument[0], entryVar2.branchArgument[1] });
222 auto lambdaOutput = lambda->finalize({ exitVar.output });
223 GraphExport::Create(*lambdaOutput,
"");
229 if (is<MuxOperation>(node->GetOperation()))
231 EXPECT_EQ(node->ninputs(), 3u);
233 auto * muxPredicate = node->input(0)->origin();
234 EXPECT_EQ(muxPredicate, matchNode.output(0));
239TEST(GammaConversionTests, SpeculativeConversionUsesDiscardingMux)
241 auto valueType = TestType::createValueType();
242 auto functionType = FunctionType::Create({ BitType::Create(2), valueType }, { valueType });
246 auto lambda = LambdaNode::Create(
247 rvsdgModule.Rvsdg().GetRootRegion(),
248 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
250 auto & matchNode = MatchOperation::CreateNode(
251 *lambda->GetFunctionArguments()[0],
252 { { 0, 0 }, { 1, 1 }, { 2, 2 } },
256 auto gamma = GammaNode::create(matchNode.output(0), 3);
257 auto entryVar1 = gamma->AddEntryVar(lambda->GetFunctionArguments()[1]);
258 auto exitVar = gamma->AddExitVar(
259 { entryVar1.branchArgument[0], entryVar1.branchArgument[1], entryVar1.branchArgument[2] });
261 auto lambdaOutput = lambda->finalize({ exitVar.output });
262 GraphExport::Create(*lambdaOutput,
"");
268 if (is<MuxOperation>(node->GetOperation()))
270 auto & muxOp =
static_cast<const MuxOperation &
>(node->GetOperation());
271 EXPECT_TRUE(muxOp.discarding);
276TEST(GammaConversionTests, NonSpeculativeModeUsesBranches)
278 auto valueType = TestType::createValueType();
279 auto stateType = TestType::createStateType();
281 FunctionType::Create({ BitType::Create(2), valueType, valueType, stateType }, { stateType });
285 auto lambda = LambdaNode::Create(
286 rvsdgModule.Rvsdg().GetRootRegion(),
287 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
289 auto & matchNode = MatchOperation::CreateNode(
290 *lambda->GetFunctionArguments()[0],
291 { { 0, 0 }, { 1, 1 }, { 2, 2 } },
295 auto gamma = GammaNode::create(matchNode.output(0), 3);
296 auto stateVar = gamma->AddEntryVar(lambda->GetFunctionArguments()[3]);
297 auto stateExit = gamma->AddExitVar(
298 { stateVar.branchArgument[0], stateVar.branchArgument[1], stateVar.branchArgument[2] });
300 auto lambdaOutput = lambda->finalize({ stateExit.output });
301 GraphExport::Create(*lambdaOutput,
"");
305 size_t branchCount = 0;
308 if (is<BranchOperation>(node->GetOperation()))
310 EXPECT_EQ(node->ninputs(), 2u);
314 EXPECT_GE(branchCount, 1u);
static std::unique_ptr< LlvmLambdaOperation > Create(std::shared_ptr< const jlm::rvsdg::FunctionType > type, std::string name, const jlm::llvm::Linkage &linkage, jlm::llvm::CallingConvention callingConvention, jlm::llvm::AttributeSet attributes)