|
Jlm
|
#include <gtest/gtest.h>#include <jlm/llvm/ir/operators/alloca.hpp>#include <jlm/llvm/ir/operators/GetElementPtr.hpp>#include <jlm/llvm/ir/operators/IntegerOperations.hpp>#include <jlm/llvm/ir/operators/lambda.hpp>#include <jlm/llvm/ir/operators/Load.hpp>#include <jlm/llvm/ir/operators/operators.hpp>#include <jlm/llvm/ir/operators/Store.hpp>#include <jlm/llvm/ir/RvsdgModule.hpp>#include <jlm/llvm/ir/Trace.hpp>#include <jlm/llvm/opt/StoreValueForwarding.hpp>#include <jlm/rvsdg/gamma.hpp>#include <jlm/rvsdg/simple-node.hpp>#include <jlm/rvsdg/TestType.hpp>#include <jlm/rvsdg/theta.hpp>#include <jlm/rvsdg/UnitType.hpp>#include <jlm/rvsdg/view.hpp>#include <jlm/util/Statistics.hpp>
Go to the source code of this file.
Functions | |
| static void | RunStoreValueForwarding (jlm::llvm::LlvmRvsdgModule &rvsdgModule) |
| TEST (StoreValueForwardingTests, NestedAllocas) | |
| TEST (StoreValueForwardingTests, GetElementPointerOffsets) | |
| TEST (StoreValueForwardingTests, RoutingIn) | |
| TEST (StoreValueForwardingTests, RouteOut) | |
| TEST (StoreValueForwardingTests, RouteAroundLoadLoop) | |
| TEST (StoreValueForwardingTests, RouteUninitialized) | |
| TEST (StoreValueForwardingTests, GepInLoop) | |
|
static |
Definition at line 27 of file StoreValueForwardingTests.cpp.
| TEST | ( | StoreValueForwardingTests | , |
| GepInLoop | |||
| ) |
Checks that StoreValueForwarding handles GetElementPointer operations, and is able to distinguish between different offsets into the same memory region.
Creates a function that looks like int func() { int a[4]; // Alloca of type int[4]
int* a2 = &a[2]; int* a3 = &a[3]; *a2 = 20; *a3 = 30;
do { int loaded = a2; int a1 = &a[1]; int* a22 = &a1[1]; *a22 = loaded + 1; *a1 = 10; } while(0);
return *a2 + *a3; }
After StoreValueForwarding, all loads should be removed, and the load of a3 should not go via the theta node at all.
Definition at line 709 of file StoreValueForwardingTests.cpp.
| TEST | ( | StoreValueForwardingTests | , |
| GetElementPointerOffsets | |||
| ) |
Create a function that looks like int func(io0, mem0) { a, memA0 = ALLOCA[bits32], 2 memA1 = STORE[bits32] a, 40, memA0 b = GetElementPointer a, bits32[1] memA2 = STORE[bits32] b, 20, memA1 l1, memA3 = LOAD[bits64] a , memA2 l2, memA4 = LOAD[bits32] a , memA3 c = GetElementPointer[byte] a, 4 l3, memA5 = LOAD[bits32] c, memA4 return l1, l2, l3, io0, mem0 }
After StoreValueForwarding, the LOAD of l2 and l3 should be gone, and be replaced by constant values 40 and 20, respectively
Definition at line 144 of file StoreValueForwardingTests.cpp.
| TEST | ( | StoreValueForwardingTests | , |
| NestedAllocas | |||
| ) |
Create a function that looks like int func(io0, mem0) { p, memP0 = ALLOCA[ptr] a, memA0 = ALLOCA[int] memP1, memA1 = STORE p, a, memP0, memA0 memP2, memA2 = STORE a, 20, memP1, memA1 a0, memP3, memA3 = LOAD p, memP2, memA2 v1, memP4, memA4 = LOAD a0, memP3, memA3 return v1, io0, mem0 }
After StoreValueForwarding, both ALLOCAs should be gone, and the return value should be 20
Definition at line 34 of file StoreValueForwardingTests.cpp.
| TEST | ( | StoreValueForwardingTests | , |
| RouteAroundLoadLoop | |||
| ) |
Checks that StoreValueForwarding avoids routing values through loops with no stores. The inner LOAD needs to have a loop variable created to provide the value, but the outer LOAD should be directly replaced by the constant 40.
Create a function that looks like int func(q[ptr], io0, mem0) { mem1 = STORE[bits32] q, 40, mem0 u1 = undef[bits32] _, mem4, l2 = theta q, mem1, u1 [q1, mem2, _] { pred = CTRL(0) l1, mem3 = LOAD[bits32], q1, mem2 }[pred, q1, mem3, l1] l3, mem5 = LOAD[bits32] q, mem4 add1 = ADD l2, l3 return add1, io0, mem5 }
Definition at line 512 of file StoreValueForwardingTests.cpp.
| TEST | ( | StoreValueForwardingTests | , |
| RouteOut | |||
| ) |
Create a function that looks like int func(q[ptr], io0, mem0) { mem1 = STORE[bits32] q, 40, mem0 _, mem7 = theta q, mem1 [q1, mem2] { pred = CTRL(0) mem6 = gamma pred, q1, mem2 [_, q2, mem3]{ mem4 = STORE[bits32] q2, 20, mem3 }[mem4] [_, _, mem5]{ // empty region }[mem5] }[pred, q1, mem6] l1, mem8 = LOAD[bits32] q, mem7 return l1, io0, mem8 }
After StoreValueForwarding, the LOAD should be gone. The function return value should be a loop output, which leads to a gamma output, which is a constant 20 in the 0th region, and invariant in the 1st region.
Definition at line 385 of file StoreValueForwardingTests.cpp.
| TEST | ( | StoreValueForwardingTests | , |
| RouteUninitialized | |||
| ) |
Checks that StoreValueForwarding creates Undef nodes when forwarding from memory that has not been stored to since it was allocated.
Create a function that looks like int func(io0, mem0) { a, mem1 = ALLOCA[bits32], 1 pred = CTRL(0) mem5 = gamma prec, a, mem1 [_, a1, mem2] { mem3 = STORE a1, 20, mem2 }[mem3] [_, a2, mem4] { // Nothing happens in this gamma branch }[mem4] ld, mem6 = LOAD[bits32] a, mem5 return ld, io0, mem0 }
After StoreValueForwarding, the returned value should originate from a gamma output, which provides a constant integer 20 in the left region, and an undef node in the right branch.
Definition at line 614 of file StoreValueForwardingTests.cpp.
| TEST | ( | StoreValueForwardingTests | , |
| RoutingIn | |||
| ) |
Create a function that looks like int func(q[ptr], io0, mem0) { mem1 = STORE[bits32] q, 40, mem0 _, mem7, l3 = theta q, mem1, undef [q1, mem2, _] { pred = CTRL(0) l2, mem6 = gamma pred, q1, mem2 [q2, mem3]{ l1, mem4 = LOAD[bits32] q2, mem3 }[l1, mem4] [q3, mem5]{ l2 = IntegerConstantOperation(70) }[l2, mem5] }[pred, q1, mem6, l2] return l3, io0, mem7 }
After StoreValueForwarding, the LOAD should be gone, and the 40 be routed in to the gamma
Definition at line 271 of file StoreValueForwardingTests.cpp.