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 = traceOutput(*StoreOperation::AddressInput(*storeGep0Node).origin());
299 const auto & tracedOutput = traceOutput(*StoreOperation::AddressInput(storeGep1Node).origin());
305 auto [memoryMergeNode, memoryMergeOperation] =
306 TryGetSimpleNodeAndOptionalOp<MemoryStateMergeOperation>(
307 *memoryStateLoopVar.input->origin());
308 EXPECT_TRUE(memoryMergeNode && memoryMergeOperation);
310 EXPECT_EQ(memoryMergeNode->ninputs(), 2u);
314TEST(AggregateAllocaSplittingTest, nestedStructTest)
321 const auto memoryStateType = MemoryStateType::Create();
322 auto bit8Type = BitType::Create(8);
323 auto bit12Type = BitType::Create(12);
324 auto bit16Type = BitType::Create(16);
325 auto bit20Type = BitType::Create(20);
326 auto bit32Type = BitType::Create(32);
327 auto bit64Type = BitType::Create(64);
328 auto bit128Type = BitType::Create(128);
330 auto structSmall = StructType::CreateIdentified({ bit12Type, bit16Type },
false);
331 auto structBig = StructType::CreateIdentified({ bit32Type, bit64Type },
false);
332 auto structType = StructType::CreateIdentified(
333 { bit8Type, structSmall, bit20Type, structBig, bit128Type },
336 const auto functionType = FunctionType::Create({}, { memoryStateType });
339 auto & rvsdg = rvsdgModule.Rvsdg();
341 auto lambdaNode = LambdaNode::Create(
342 rvsdg.GetRootRegion(),
343 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
345 auto & zeroNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 0);
346 auto & oneNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 1);
347 auto & twoNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 2);
348 auto & threeNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 3);
349 auto & fourNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 4);
351 auto & allocaNode = AllocaOperation::createNode(structType, *oneNode.output(0), 4);
353 auto & gepBit8Node = GetElementPtrOperation::createNode(
354 AllocaOperation::getPointerOutput(allocaNode),
355 { zeroNode.output(0), zeroNode.output(0) },
357 auto & bit8ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 8, 8);
358 auto storeGepBit8Node = &StoreNonVolatileOperation::CreateNode(
359 *gepBit8Node.output(0),
360 *bit8ConstantNode.output(0),
361 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
364 auto & gepBit12Node = GetElementPtrOperation::createNode(
365 AllocaOperation::getPointerOutput(allocaNode),
366 { zeroNode.output(0), oneNode.output(0), zeroNode.output(0) },
368 auto & bit12ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 12, 12);
369 auto storeGepBit12Node = &StoreNonVolatileOperation::CreateNode(
370 *gepBit12Node.output(0),
371 *bit12ConstantNode.output(0),
372 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
375 auto & gepBit16Node = GetElementPtrOperation::createNode(
376 AllocaOperation::getPointerOutput(allocaNode),
377 { zeroNode.output(0), oneNode.output(0), oneNode.output(0) },
379 auto & bit16ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 16, 16);
380 auto storeGepBit16Node = &StoreNonVolatileOperation::CreateNode(
381 *gepBit16Node.output(0),
382 *bit16ConstantNode.output(0),
383 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
386 auto & gepBit20Node = GetElementPtrOperation::createNode(
387 AllocaOperation::getPointerOutput(allocaNode),
388 { zeroNode.output(0), twoNode.output(0) },
390 auto & bit20ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 20, 20);
391 auto storeGepBit20Node = &StoreNonVolatileOperation::CreateNode(
392 *gepBit20Node.output(0),
393 *bit20ConstantNode.output(0),
394 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
397 auto & gepBit32Node = GetElementPtrOperation::createNode(
398 AllocaOperation::getPointerOutput(allocaNode),
399 { zeroNode.output(0), threeNode.output(0), zeroNode.output(0) },
401 auto & bit32ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 32);
402 auto storeGepBit32Node = &StoreNonVolatileOperation::CreateNode(
403 *gepBit32Node.output(0),
404 *bit32ConstantNode.output(0),
405 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
408 auto & gepBit64Node = GetElementPtrOperation::createNode(
409 AllocaOperation::getPointerOutput(allocaNode),
410 { zeroNode.output(0), threeNode.output(0), oneNode.output(0) },
412 auto & bit64ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 64, 64);
413 auto storeGepBit64Node = &StoreNonVolatileOperation::CreateNode(
414 *gepBit64Node.output(0),
415 *bit64ConstantNode.output(0),
416 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
419 auto & gepBit128Node = GetElementPtrOperation::createNode(
420 AllocaOperation::getPointerOutput(allocaNode),
421 { zeroNode.output(0), fourNode.output(0) },
423 auto & bit128ConstantNode = IntegerConstantOperation::Create(*lambdaNode->subregion(), 128, 128);
424 auto storeGepBit128Node = &StoreNonVolatileOperation::CreateNode(
425 *gepBit128Node.output(0),
426 *bit128ConstantNode.output(0),
427 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
430 auto memoryStateMerge = MemoryStateMergeOperation::Create({ storeGepBit8Node->output(0),
431 storeGepBit12Node->output(0),
432 storeGepBit16Node->output(0),
433 storeGepBit20Node->output(0),
434 storeGepBit32Node->output(0),
435 storeGepBit64Node->output(0),
436 storeGepBit128Node->output(0) });
438 auto lambdaOutput = lambdaNode->finalize({ memoryStateMerge });
439 GraphExport::Create(*lambdaOutput,
"f");
449 const auto & tracedOutput =
450 traceOutput(*StoreOperation::AddressInput(*storeGepBit8Node).origin());
456 const auto & tracedOutput =
457 traceOutput(*StoreOperation::AddressInput(*storeGepBit12Node).origin());
463 const auto & tracedOutput =
464 traceOutput(*StoreOperation::AddressInput(*storeGepBit16Node).origin());
470 const auto & tracedOutput =
471 traceOutput(*StoreOperation::AddressInput(*storeGepBit20Node).origin());
477 const auto & tracedOutput =
478 traceOutput(*StoreOperation::AddressInput(*storeGepBit32Node).origin());
484 const auto & tracedOutput =
485 traceOutput(*StoreOperation::AddressInput(*storeGepBit64Node).origin());
491 const auto & tracedOutput =
492 traceOutput(*StoreOperation::AddressInput(*storeGepBit128Node).origin());
498 auto [memoryMergeNode, memoryMergeOperation] =
499 TryGetSimpleNodeAndOptionalOp<MemoryStateMergeOperation>(
500 *lambdaNode->GetFunctionResults()[0]->origin());
501 EXPECT_TRUE(memoryMergeNode && memoryMergeOperation);
503 EXPECT_EQ(memoryMergeNode->ninputs(), 7u);
507TEST(AggregateAllocaSplittingTests, allocaWithCountBiggerThanOne)
514 auto bit32Type = BitType::Create(32);
515 auto bit64Type = BitType::Create(64);
516 const auto pointerType = PointerType::Create();
517 const auto memoryStateType = MemoryStateType::Create();
518 const auto structType = StructType::CreateIdentified({ bit32Type, bit64Type },
false);
519 const auto functionType = FunctionType::Create({}, { memoryStateType });
522 auto & rvsdg = rvsdgModule.Rvsdg();
524 auto lambdaNode = LambdaNode::Create(
525 rvsdg.GetRootRegion(),
526 LlvmLambdaOperation::Create(functionType,
"f", Linkage::externalLinkage));
528 auto & zero32Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 0);
529 auto & zero64Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 64, 0);
530 auto & one32Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 1);
531 auto & two32Node = IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 2);
532 auto & allocaNode = AllocaOperation::createNode(structType, *two32Node.output(0), 4);
534 auto & gepNode = GetElementPtrOperation::createNode(
535 *allocaNode.output(0),
536 { zero32Node.output(0), one32Node.output(0) },
538 auto & storeGepNode = StoreNonVolatileOperation::CreateNode(
540 *zero64Node.output(0),
541 { &AllocaOperation::getMemoryStateOutput(allocaNode) },
544 auto lambdaOutput = lambdaNode->finalize({ storeGepNode.output(0) });
545 GraphExport::Create(*lambdaOutput,
"f");
555 EXPECT_TRUE(Region::containsOperation<GetElementPtrOperation>(*lambdaNode->subregion(),
false));