Jlm
Functions
StoreValueForwardingTests.cpp File Reference
#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>
Include dependency graph for StoreValueForwardingTests.cpp:

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)
 

Function Documentation

◆ RunStoreValueForwarding()

static void RunStoreValueForwarding ( jlm::llvm::LlvmRvsdgModule rvsdgModule)
static

Definition at line 27 of file StoreValueForwardingTests.cpp.

◆ TEST() [1/7]

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() [2/7]

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() [3/7]

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() [4/7]

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() [5/7]

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() [6/7]

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() [7/7]

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.