33TEST(AggregateAllocaSplittingTests, getElementPtrTest)
40 auto bit32Type = BitType::Create(32);
41 auto bit64Type = BitType::Create(64);
42 const auto pointerType = PointerType::Create();
43 const auto memoryStateType = MemoryStateType::Create();
44 const auto structType = StructType::CreateIdentified({ bit32Type, bit64Type },
false);
45 const auto functionType = FunctionType::Create({}, { memoryStateType });
48 auto & rvsdg = rvsdgModule.Rvsdg();
50 auto lambdaNode = LambdaNode::Create(
51 rvsdg.GetRootRegion(),
52 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
54 auto & zero32Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 0);
55 auto & zero64Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 64, 0);
56 auto & one32Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 1);
57 auto & allocaNode = AllocaOperation::createNode(structType, *one32Node.output(0), 4);
59 auto & gepXNode = GetElementPtrOperation::createNode(
60 *allocaNode.output(0),
61 { zero32Node.output(0), zero32Node.output(0) },
63 auto & storeGepXNode = StoreNonVolatileOperation::CreateNode(
65 *zero32Node.output(0),
66 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
69 auto & gepYNode = GetElementPtrOperation::createNode(
70 *allocaNode.output(0),
71 { zero32Node.output(0), one32Node.output(0) },
73 auto & storeGepYNode = StoreNonVolatileOperation::CreateNode(
75 *zero64Node.output(0),
76 { storeGepXNode.output(0) },
79 auto lambdaOutput = lambdaNode->finalize({ storeGepYNode.output(0) });
80 GraphExport::Create(*lambdaOutput,
"f");
88 EXPECT_EQ(lambdaNode->subregion()->numNodes(), 8u);
95 auto [memoryMergeNode, memoryMergeOperation] =
96 TryGetSimpleNodeAndOptionalOp<MemoryStateMergeOperation>(
97 *StoreOperation::getMemoryStateInputs(storeGepXNode).begin()->origin());
98 EXPECT_TRUE(memoryMergeNode && memoryMergeOperation);
100 EXPECT_EQ(memoryMergeNode->ninputs(), 2u);
104TEST(AggregateAllocaSplittingTests, gammaTest)
111 auto bit16Type = BitType::Create(16);
112 auto bit32Type = BitType::Create(32);
113 auto bit64Type = BitType::Create(64);
114 const auto controlType = ControlType::Create(2);
115 const auto pointerType = PointerType::Create();
116 const auto memoryStateType = MemoryStateType::Create();
117 const auto structType = StructType::CreateIdentified({ bit16Type, bit32Type, bit64Type },
false);
118 const auto functionType = FunctionType::Create({ controlType }, { memoryStateType });
121 auto & rvsdg = rvsdgModule.Rvsdg();
123 auto lambdaNode = LambdaNode::Create(
124 rvsdg.GetRootRegion(),
125 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
126 auto controlArgument = lambdaNode->GetFunctionArguments()[0];
128 auto & zero = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 0);
129 auto & one = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 1);
130 auto & two = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 2);
131 auto & allocaNode = AllocaOperation::createNode(structType, *one.output(0), 4);
133 auto gammaNode = GammaNode::create(controlArgument, 2);
134 auto baseAddressEntryVar = gammaNode->AddEntryVar(&AllocaOperation::getPointerOutput(allocaNode));
135 auto memoryStateEntryVar =
136 gammaNode->AddEntryVar(&AllocaOperation::getMemoryStateOutput(allocaNode));
138 Node *storeGep0Node =
nullptr, *storeGep1Node =
nullptr;
141 auto & zero16Node = IntegerConstantOperation::Create(*gammaNode->subregion(0), 16, 0);
142 auto & zero32Node = IntegerConstantOperation::Create(*gammaNode->subregion(0), 32, 0);
144 auto & gep0Node = GetElementPtrOperation::createNode(
145 *baseAddressEntryVar.branchArgument[0],
146 { zero32Node.output(0), zero32Node.output(0) },
148 storeGep0Node = &StoreNonVolatileOperation::CreateNode(
150 *zero16Node.output(0),
151 { memoryStateEntryVar.branchArgument[0] },
157 auto & zero32Node = IntegerConstantOperation::Create(*gammaNode->subregion(1), 32, 0);
158 auto & one32Node = IntegerConstantOperation::Create(*gammaNode->subregion(1), 32, 1);
160 auto & gep1Node = GetElementPtrOperation::createNode(
161 *baseAddressEntryVar.branchArgument[1],
162 { zero32Node.output(0), one32Node.output(0) },
164 storeGep1Node = &StoreNonVolatileOperation::CreateNode(
166 *zero32Node.output(0),
167 { memoryStateEntryVar.branchArgument[1] },
170 auto baseAddressExitVar = gammaNode->AddExitVar(baseAddressEntryVar.branchArgument);
171 auto memoryStateExitVar =
172 gammaNode->AddExitVar({ storeGep0Node->
output(0), storeGep1Node->output(0) });
174 auto & gep2Node = GetElementPtrOperation::createNode(
175 *baseAddressExitVar.output,
176 { zero.output(0), two.output(0) },
179 auto & zero64Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 64, 0);
180 auto & storeGep2Node = StoreNonVolatileOperation::CreateNode(
182 *zero64Node.output(0),
183 { memoryStateExitVar.output },
186 auto lambdaOutput = lambdaNode->finalize({ storeGep2Node.output(0) });
187 GraphExport::Create(*lambdaOutput,
"f");
198 gammaNode->mapBranchArgumentToInput(*StoreOperation::AddressInput(*storeGep0Node).origin());
205 gammaNode->mapBranchArgumentToInput(*StoreOperation::AddressInput(*storeGep1Node).origin());
216 auto [memoryMergeNode, memoryMergeOperation] =
217 TryGetSimpleNodeAndOptionalOp<MemoryStateMergeOperation>(
218 *memoryStateEntryVar.input->origin());
219 EXPECT_TRUE(memoryMergeNode && memoryMergeOperation);
221 EXPECT_EQ(memoryMergeNode->ninputs(), 3u);
225TEST(AggregateAllocaSplittingTests, thetaTest)
232 auto bit16Type = BitType::Create(16);
233 auto bit32Type = BitType::Create(32);
234 const auto pointerType = PointerType::Create();
235 const auto memoryStateType = MemoryStateType::Create();
236 const auto structType = StructType::CreateIdentified({ bit16Type, bit32Type },
false);
237 const auto functionType = FunctionType::Create({}, { memoryStateType });
240 auto & rvsdg = rvsdgModule.Rvsdg();
242 auto lambdaNode = LambdaNode::Create(
243 rvsdg.GetRootRegion(),
244 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
246 auto & one = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 1);
247 auto & allocaNode = AllocaOperation::createNode(structType, *one.output(0), 4);
249 Node * storeGep0Node =
nullptr;
250 auto thetaNode = ThetaNode::create(lambdaNode->subregion());
251 auto addressLoopVar = thetaNode->AddLoopVar(&AllocaOperation::getPointerOutput(allocaNode));
252 auto memoryStateLoopVar =
253 thetaNode->AddLoopVar(&AllocaOperation::getMemoryStateOutput(allocaNode));
255 auto & zero16Node = IntegerConstantOperation::Create(*thetaNode->subregion(), 16, 0);
256 auto & zero32Node = IntegerConstantOperation::Create(*thetaNode->subregion(), 32, 0);
257 auto & gep0Node = GetElementPtrOperation::createNode(
259 { zero32Node.output(0), zero32Node.output(0) },
262 storeGep0Node = &StoreNonVolatileOperation::CreateNode(
264 *zero16Node.output(0),
265 { memoryStateLoopVar.pre },
268 memoryStateLoopVar.post->divert_to(storeGep0Node->
output(0));
271 auto & zero32Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 0);
272 auto & gep1Node = GetElementPtrOperation::createNode(
273 *addressLoopVar.output,
274 { zero32Node.output(0), one.output(0) },
276 auto & storeGep1Node = StoreNonVolatileOperation::CreateNode(
278 *zero32Node.output(0),
279 { memoryStateLoopVar.output },
282 auto lambdaOutput = lambdaNode->finalize({ storeGep1Node.output(0) });
283 GraphExport::Create(*lambdaOutput,
"f");
293 const auto & tracedOutput =
294 traceOutput(*StoreOperation::AddressInput(*storeGep0Node).origin(),
false);
300 const auto & tracedOutput =
301 traceOutput(*StoreOperation::AddressInput(storeGep1Node).origin(),
false);
307 auto [memoryMergeNode, memoryMergeOperation] =
308 TryGetSimpleNodeAndOptionalOp<MemoryStateMergeOperation>(
309 *memoryStateLoopVar.input->origin());
310 EXPECT_TRUE(memoryMergeNode && memoryMergeOperation);
312 EXPECT_EQ(memoryMergeNode->ninputs(), 2u);
316TEST(AggregateAllocaSplittingTest, nestedStructTest)
323 const auto memoryStateType = MemoryStateType::Create();
324 auto bit8Type = BitType::Create(8);
325 auto bit12Type = BitType::Create(12);
326 auto bit16Type = BitType::Create(16);
327 auto bit20Type = BitType::Create(20);
328 auto bit32Type = BitType::Create(32);
329 auto bit64Type = BitType::Create(64);
330 auto bit128Type = BitType::Create(128);
332 auto structSmall = StructType::CreateIdentified({ bit12Type, bit16Type },
false);
333 auto structBig = StructType::CreateIdentified({ bit32Type, bit64Type },
false);
334 auto structType = StructType::CreateIdentified(
335 { bit8Type, structSmall, bit20Type, structBig, bit128Type },
338 const auto functionType = FunctionType::Create({}, { memoryStateType });
341 auto & rvsdg = rvsdgModule.Rvsdg();
343 auto lambdaNode = LambdaNode::Create(
344 rvsdg.GetRootRegion(),
345 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
347 auto & zeroNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 0);
348 auto & oneNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 1);
349 auto & twoNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 2);
350 auto & threeNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 3);
351 auto & fourNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 4);
353 auto & allocaNode = AllocaOperation::createNode(structType, *oneNode.output(0), 4);
355 auto & gepBit8Node = GetElementPtrOperation::createNode(
356 AllocaOperation::getPointerOutput(allocaNode),
357 { zeroNode.output(0), zeroNode.output(0) },
359 auto & bit8ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 8, 8);
360 auto storeGepBit8Node = &StoreNonVolatileOperation::CreateNode(
361 *gepBit8Node.output(0),
362 *bit8ConstantNode.output(0),
363 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
366 auto & gepBit12Node = GetElementPtrOperation::createNode(
367 AllocaOperation::getPointerOutput(allocaNode),
368 { zeroNode.output(0), oneNode.output(0), zeroNode.output(0) },
370 auto & bit12ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 12, 12);
371 auto storeGepBit12Node = &StoreNonVolatileOperation::CreateNode(
372 *gepBit12Node.output(0),
373 *bit12ConstantNode.output(0),
374 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
377 auto & gepBit16Node = GetElementPtrOperation::createNode(
378 AllocaOperation::getPointerOutput(allocaNode),
379 { zeroNode.output(0), oneNode.output(0), oneNode.output(0) },
381 auto & bit16ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 16, 16);
382 auto storeGepBit16Node = &StoreNonVolatileOperation::CreateNode(
383 *gepBit16Node.output(0),
384 *bit16ConstantNode.output(0),
385 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
388 auto & gepBit20Node = GetElementPtrOperation::createNode(
389 AllocaOperation::getPointerOutput(allocaNode),
390 { zeroNode.output(0), twoNode.output(0) },
392 auto & bit20ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 20, 20);
393 auto storeGepBit20Node = &StoreNonVolatileOperation::CreateNode(
394 *gepBit20Node.output(0),
395 *bit20ConstantNode.output(0),
396 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
399 auto & gepBit32Node = GetElementPtrOperation::createNode(
400 AllocaOperation::getPointerOutput(allocaNode),
401 { zeroNode.output(0), threeNode.output(0), zeroNode.output(0) },
403 auto & bit32ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 32);
404 auto storeGepBit32Node = &StoreNonVolatileOperation::CreateNode(
405 *gepBit32Node.output(0),
406 *bit32ConstantNode.output(0),
407 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
410 auto & gepBit64Node = GetElementPtrOperation::createNode(
411 AllocaOperation::getPointerOutput(allocaNode),
412 { zeroNode.output(0), threeNode.output(0), oneNode.output(0) },
414 auto & bit64ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 64, 64);
415 auto storeGepBit64Node = &StoreNonVolatileOperation::CreateNode(
416 *gepBit64Node.output(0),
417 *bit64ConstantNode.output(0),
418 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
421 auto & gepBit128Node = GetElementPtrOperation::createNode(
422 AllocaOperation::getPointerOutput(allocaNode),
423 { zeroNode.output(0), fourNode.output(0) },
425 auto & bit128ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 128, 128);
426 auto storeGepBit128Node = &StoreNonVolatileOperation::CreateNode(
427 *gepBit128Node.output(0),
428 *bit128ConstantNode.output(0),
429 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
432 auto memoryStateMerge = MemoryStateMergeOperation::Create({ storeGepBit8Node->output(0),
433 storeGepBit12Node->output(0),
434 storeGepBit16Node->output(0),
435 storeGepBit20Node->output(0),
436 storeGepBit32Node->output(0),
437 storeGepBit64Node->output(0),
438 storeGepBit128Node->output(0) });
440 auto lambdaOutput = lambdaNode->finalize({ memoryStateMerge });
441 GraphExport::Create(*lambdaOutput,
"f");
451 const auto & tracedOutput =
452 traceOutput(*StoreOperation::AddressInput(*storeGepBit8Node).origin(),
false);
458 const auto & tracedOutput =
459 traceOutput(*StoreOperation::AddressInput(*storeGepBit12Node).origin(),
false);
465 const auto & tracedOutput =
466 traceOutput(*StoreOperation::AddressInput(*storeGepBit16Node).origin(),
false);
472 const auto & tracedOutput =
473 traceOutput(*StoreOperation::AddressInput(*storeGepBit20Node).origin(),
false);
479 const auto & tracedOutput =
480 traceOutput(*StoreOperation::AddressInput(*storeGepBit32Node).origin(),
false);
486 const auto & tracedOutput =
487 traceOutput(*StoreOperation::AddressInput(*storeGepBit64Node).origin(),
false);
493 const auto & tracedOutput =
494 traceOutput(*StoreOperation::AddressInput(*storeGepBit128Node).origin(),
false);
500 auto [memoryMergeNode, memoryMergeOperation] =
501 TryGetSimpleNodeAndOptionalOp<MemoryStateMergeOperation>(
502 *lambdaNode->GetFunctionResults()[0]->origin());
503 EXPECT_TRUE(memoryMergeNode && memoryMergeOperation);
505 EXPECT_EQ(memoryMergeNode->ninputs(), 7u);
509TEST(AggregateAllocaSplittingTests, allocaWithCountBiggerThanOne)
516 auto bit32Type = BitType::Create(32);
517 auto bit64Type = BitType::Create(64);
518 const auto pointerType = PointerType::Create();
519 const auto memoryStateType = MemoryStateType::Create();
520 const auto structType = StructType::CreateIdentified({ bit32Type, bit64Type },
false);
521 const auto functionType = FunctionType::Create({}, { memoryStateType });
524 auto & rvsdg = rvsdgModule.Rvsdg();
526 auto lambdaNode = LambdaNode::Create(
527 rvsdg.GetRootRegion(),
528 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
530 auto & zero32Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 0);
531 auto & zero64Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 64, 0);
532 auto & one32Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 1);
533 auto & two32Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 2);
534 auto & allocaNode = AllocaOperation::createNode(structType, *two32Node.output(0), 4);
536 auto & gepNode = GetElementPtrOperation::createNode(
537 *allocaNode.output(0),
538 { zero32Node.output(0), one32Node.output(0) },
540 auto & storeGepNode = StoreNonVolatileOperation::CreateNode(
542 *zero64Node.output(0),
543 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
546 auto lambdaOutput = lambdaNode->finalize({ storeGepNode.output(0) });
547 GraphExport::Create(*lambdaOutput,
"f");
557 EXPECT_TRUE(Region::containsOperation<GetElementPtrOperation>(*lambdaNode->subregion(),
false));