7 #include <gtest/gtest.h>
30 static std::unique_ptr<jlm::util::Statistics>
36 fctinline.
Run(rm, collector);
38 EXPECT_EQ(collector.NumCollectedStatistics(), 1u);
42 TEST(FunctionInliningTests, testSimpleInlining)
82 auto & graph = rm.
Rvsdg();
83 auto vt = TestType::createValueType();
88 Region * gammaRegion0 =
nullptr;
97 graph.GetRootRegion(),
99 lambda->AddContextVar(*i);
101 auto t = TestOperation::createNode(
103 { lambda->GetFunctionArguments()[0] },
106 return lambda->finalize(
107 { t->output(0), lambda->GetFunctionArguments()[1], lambda->GetFunctionArguments()[2] });
121 graph.GetRootRegion(),
123 auto d = lambda->AddContextVar(*f1).inner;
124 auto controlArgument = lambda->GetFunctionArguments()[0];
125 auto valueArgument = lambda->GetFunctionArguments()[1];
126 auto iOStateArgument = lambda->GetFunctionArguments()[2];
127 auto memoryStateArgument = lambda->GetFunctionArguments()[3];
130 gammaRegion0 = gamma->subregion(0);
131 auto gammaInputF1 = gamma->AddEntryVar(d);
132 auto gammaInputValue = gamma->AddEntryVar(valueArgument);
133 auto gammaInputIoState = gamma->AddEntryVar(iOStateArgument);
134 auto gammaInputMemoryState = gamma->AddEntryVar(memoryStateArgument);
137 gammaInputF1.branchArgument[0],
138 jlm::rvsdg::AssertGetOwnerNode<jlm::rvsdg::LambdaNode>(*f1).GetOperation().Type(),
139 { gammaInputValue.branchArgument[0],
140 gammaInputIoState.branchArgument[0],
141 gammaInputMemoryState.branchArgument[0] });
143 auto gammaOutputValue =
144 gamma->AddExitVar({ callResults[0], gammaInputValue.branchArgument[1] });
145 auto gammaOutputIoState =
146 gamma->AddExitVar({ callResults[1], gammaInputIoState.branchArgument[1] });
147 auto gammaOutputMemoryState =
148 gamma->AddExitVar({ callResults[2], gammaInputMemoryState.branchArgument[1] });
150 return lambda->finalize(
151 { gammaOutputValue.output, gammaOutputIoState.output, gammaOutputMemoryState.output });
155 auto f2 = SetupF2(f1);
157 GraphExport::Create(*f2,
"f2");
168 EXPECT_FALSE(Region::ContainsOperation<CallOperation>(graph.GetRootRegion(),
true));
169 EXPECT_TRUE(Region::ContainsOperation<TestOperation>(*gammaRegion0,
true));
172 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#Functions"), 2u);
173 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#InlineableFunctions"), 2u);
174 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#FunctionCalls"), 1u);
175 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#InlinableCalls"), 1u);
176 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#CallsInlined"), 1u);
179 TEST(FunctionInliningTests, testInliningWithAlloca)
221 auto & graph = rm.
Rvsdg();
222 auto vt = TestType::createValueType();
227 Region * gammaRegion0 =
nullptr;
228 Region * f2Region =
nullptr;
237 graph.GetRootRegion(),
239 lambda->AddContextVar(*i);
240 auto lambdaArgs = lambda->GetFunctionArguments();
246 return lambda->finalize({ lambdaArgs[1], store[0] });
260 graph.GetRootRegion(),
262 auto d = lambda->AddContextVar(*f1).inner;
263 auto controlArgument = lambda->GetFunctionArguments()[0];
264 auto valueArgument = lambda->GetFunctionArguments()[1];
265 auto iOStateArgument = lambda->GetFunctionArguments()[2];
266 auto memoryStateArgument = lambda->GetFunctionArguments()[3];
267 f2Region = lambda->subregion();
270 gammaRegion0 = gamma->subregion(0);
271 auto gammaInputF1 = gamma->AddEntryVar(d);
272 auto gammaInputValue = gamma->AddEntryVar(valueArgument);
273 auto gammaInputIoState = gamma->AddEntryVar(iOStateArgument);
274 auto gammaInputMemoryState = gamma->AddEntryVar(memoryStateArgument);
277 gammaInputF1.branchArgument[0],
278 jlm::rvsdg::AssertGetOwnerNode<jlm::rvsdg::LambdaNode>(*f1).GetOperation().Type(),
279 { gammaInputValue.branchArgument[0],
280 gammaInputIoState.branchArgument[0],
281 gammaInputMemoryState.branchArgument[0] });
283 auto gammaOutputIoState =
284 gamma->AddExitVar({ callResults[0], gammaInputIoState.branchArgument[1] });
285 auto gammaOutputMemoryState =
286 gamma->AddExitVar({ callResults[1], gammaInputMemoryState.branchArgument[1] });
288 return lambda->finalize({ gammaOutputIoState.output, gammaOutputMemoryState.output });
292 auto f2 = SetupF2(f1);
294 GraphExport::Create(*f2,
"f2");
305 EXPECT_FALSE(Region::ContainsOperation<CallOperation>(graph.GetRootRegion(),
true));
307 EXPECT_TRUE(Region::ContainsOperation<StoreNonVolatileOperation>(*gammaRegion0,
true));
309 EXPECT_FALSE(Region::ContainsOperation<AllocaOperation>(*gammaRegion0,
true));
311 EXPECT_TRUE(Region::ContainsOperation<AllocaOperation>(*f2Region,
false));
314 TEST(FunctionInliningTests, testIndirectCall)
326 auto vt = TestType::createValueType();
340 auto & graph = rm.Rvsdg();
343 auto SetupF1 = [&](
const std::shared_ptr<const jlm::rvsdg::FunctionType> & functionType)
346 graph.GetRootRegion(),
348 return lambda->finalize(
349 { lambda->GetFunctionArguments()[1], lambda->GetFunctionArguments()[2] });
359 graph.GetRootRegion(),
361 auto cvi = lambda->AddContextVar(*i).inner;
362 auto cvf1 = lambda->AddContextVar(*f1).inner;
363 auto iOStateArgument = lambda->GetFunctionArguments()[0];
364 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
369 return lambda->finalize(callResults);
372 auto f1 = SetupF1(functionType1);
374 jlm::rvsdg::CreateOpNode<FunctionToPointerOperation>({ f1 }, functionType1).output(0));
376 GraphExport::Create(*f2,
"f2");
387 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#Functions"), 2u);
388 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#InlineableFunctions"), 2u);
389 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#FunctionCalls"), 1u);
390 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#InlinableCalls"), 0u);
391 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#CallsInlined"), 0u);
398 TEST(FunctionInliningTests, testFunctionWithDisqualifyingAlloca)
404 auto vt = TestType::createValueType();
409 auto & graph = rm.
Rvsdg();
413 auto functionType = FunctionType::Create(
418 graph.GetRootRegion(),
420 auto theta = ThetaNode::create(lambda->subregion());
425 return lambda->finalize(
426 { lambda->GetFunctionArguments()[0], lambda->GetFunctionArguments()[1] });
434 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#Functions"), 1u);
436 EXPECT_EQ(statistics->GetMeasurementValue<uint64_t>(
"#InlineableFunctions"), 0u);
static std::unique_ptr< jlm::util::Statistics > runInlining(jlm::llvm::LlvmRvsdgModule &rm)
TEST(FunctionInliningTests, testSimpleInlining)
static std::vector< rvsdg::Output * > create(std::shared_ptr< const rvsdg::Type > allocatedType, rvsdg::Output *count, const size_t alignment)
static std::vector< rvsdg::Output * > Create(rvsdg::Output *function, std::shared_ptr< const rvsdg::FunctionType > functionType, const std::vector< rvsdg::Output * > &arguments)
Performs function inlining on functions that are determined to be good candidates,...
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
static std::shared_ptr< const IOStateType > Create()
static rvsdg::Node & Create(rvsdg::Region ®ion, IntegerValueRepresentation representation)
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)
static std::shared_ptr< const MemoryStateType > Create()
static std::shared_ptr< const PointerType > Create()
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *value, const Variable *state, size_t alignment)
static std::shared_ptr< const ControlType > Create(std::size_t nalternatives)
Instantiates control type.
static std::shared_ptr< const FunctionType > Create(std::vector< std::shared_ptr< const jlm::rvsdg::Type >> argumentTypes, std::vector< std::shared_ptr< const jlm::rvsdg::Type >> resultTypes)
static GammaNode * create(jlm::rvsdg::Output *predicate, size_t nalternatives)
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
Represent acyclic RVSDG subgraphs.
Global memory state passed between functions.