Jlm
TypeTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2024, 2025 HÃ¥vard Krogstie <krogstie.havard@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <gtest/gtest.h>
7 
8 #include <jlm/llvm/ir/types.hpp>
10 #include <jlm/rvsdg/TestType.hpp>
11 
12 #include <cassert>
13 
14 TEST(TypeTests, TestIsOrContains)
15 {
16  using namespace jlm::llvm;
17 
18  auto valueType = jlm::rvsdg::TestType::createValueType();
19  auto pointerType = PointerType::Create();
20  auto memoryStateType = MemoryStateType::Create();
21  auto ioStateType = IOStateType::Create();
22 
23  // Direct checks
24  EXPECT_TRUE(IsOrContains<PointerType>(*pointerType));
25  EXPECT_FALSE(IsOrContains<PointerType>(*memoryStateType));
26  EXPECT_FALSE(IsOrContains<PointerType>(*ioStateType));
27 
28  // Check type kinds
29  EXPECT_EQ(pointerType->Kind(), jlm::rvsdg::TypeKind::Value);
30  EXPECT_EQ(memoryStateType->Kind(), jlm::rvsdg::TypeKind::State);
31  EXPECT_EQ(ioStateType->Kind(), jlm::rvsdg::TypeKind::State);
32 
33  // Function types are not aggregate types
34  auto functionType = jlm::rvsdg::FunctionType::Create(
37  EXPECT_FALSE(IsAggregateType(*functionType));
38  EXPECT_TRUE(IsOrContains<jlm::rvsdg::FunctionType>(*functionType));
39  EXPECT_FALSE(IsOrContains<PointerType>(*functionType));
40  EXPECT_EQ(functionType->Kind(), jlm::rvsdg::TypeKind::Value);
41 
42  // Struct types are aggregates that can contain other types
43  auto structType = StructType::CreateIdentified({ valueType, pointerType }, false);
44  EXPECT_TRUE(IsAggregateType(*structType));
45  EXPECT_TRUE(IsOrContains<StructType>(*structType));
46  EXPECT_TRUE(IsOrContains<PointerType>(*structType));
47  EXPECT_EQ(structType->Kind(), jlm::rvsdg::TypeKind::Value);
48 
49  // Create an array containing the atruct type
50  auto arrayType = ArrayType::Create(structType, 20);
51  EXPECT_TRUE(IsAggregateType(*arrayType));
52  EXPECT_TRUE(IsOrContains<ArrayType>(*arrayType));
53  EXPECT_TRUE(IsOrContains<StructType>(*arrayType));
54  EXPECT_TRUE(IsOrContains<PointerType>(*arrayType));
55  EXPECT_EQ(arrayType->Kind(), jlm::rvsdg::TypeKind::Value);
56 
57  // Vector types are weird, as LLVM does not consider them to be aggregate types,
58  // but they still contain other types
59  const auto vectorType = FixedVectorType::Create(structType, 20);
60  EXPECT_FALSE(IsAggregateType(*vectorType));
61  EXPECT_TRUE(IsOrContains<VectorType>(*vectorType));
62  EXPECT_TRUE(IsOrContains<StructType>(*vectorType));
63  EXPECT_TRUE(IsOrContains<PointerType>(*vectorType));
64  EXPECT_EQ(vectorType->Kind(), jlm::rvsdg::TypeKind::Value);
65 }
66 
67 TEST(TypeTests, TestGetTypeSizeAndAlignment)
68 {
69  using namespace jlm::llvm;
70 
71  auto pointerType = PointerType::Create();
72  EXPECT_EQ(GetTypeStoreSize(*pointerType), 8u);
73  EXPECT_EQ(GetTypeAllocSize(*pointerType), 8u);
74  EXPECT_EQ(GetTypeAlignment(*pointerType), 8u);
75 
76  auto bits32 = jlm::rvsdg::BitType::Create(32);
77  auto bits50 = jlm::rvsdg::BitType::Create(50);
78  EXPECT_EQ(GetTypeStoreSize(*bits32), 4u);
79  EXPECT_EQ(GetTypeAllocSize(*bits32), 4u);
80  EXPECT_EQ(GetTypeAlignment(*bits32), 4u);
81 
82  EXPECT_EQ(GetTypeStoreSize(*bits50), 7u);
83  EXPECT_EQ(GetTypeAllocSize(*bits50), 8u);
84  EXPECT_EQ(GetTypeAlignment(*bits50), 8u);
85 
86  auto floatType = FloatingPointType::Create(fpsize::fp128);
87  EXPECT_EQ(GetTypeStoreSize(*floatType), 16u);
88  EXPECT_EQ(GetTypeAllocSize(*floatType), 16u);
89  EXPECT_EQ(GetTypeAlignment(*floatType), 16u);
91  EXPECT_EQ(GetTypeStoreSize(*floatType), 2u);
92  EXPECT_EQ(GetTypeAllocSize(*floatType), 2u);
93  EXPECT_EQ(GetTypeAlignment(*floatType), 2u);
94 
95  auto arrayType = ArrayType::Create(bits32, 5);
96  unsigned int expectedArrayStoreSize = 4 * 5;
97  unsigned int expectedArrayAllocAize = 4 * 5;
98  EXPECT_EQ(GetTypeStoreSize(*arrayType), expectedArrayStoreSize);
99  EXPECT_EQ(GetTypeAllocSize(*arrayType), expectedArrayAllocAize);
100  EXPECT_EQ(GetTypeAlignment(*arrayType), 4u);
101 
102  // Vectors are always aligned up, so a <3 x i32> is 12 bytes of data and 4 bytes of padding.
103  // Vectors are also very aligned
104  auto vectorType = FixedVectorType::Create(bits32, 3);
105  EXPECT_EQ(GetTypeStoreSize(*vectorType), 12u);
106  EXPECT_EQ(GetTypeAllocSize(*vectorType), 16u);
107  EXPECT_EQ(GetTypeAlignment(*vectorType), 16u);
108 
109  auto structType = StructType::CreateIdentified(
110  "myStruct",
111  { bits32,
112  pointerType,
113  arrayType,
114  vectorType, // The most aligned type, 16 byte alignment
115  bits32 },
116  false);
117  EXPECT_EQ(structType->GetFieldOffset(0), 0u);
118  EXPECT_EQ(structType->GetFieldOffset(1), 8u); // Due to 4 bytes of padding after i32
119  EXPECT_EQ(structType->GetFieldOffset(2), 16u);
120  EXPECT_EQ(structType->GetFieldOffset(3), 48u); // 12 bytes of padding after array
121  EXPECT_EQ(structType->GetFieldOffset(4), 64u);
122  EXPECT_EQ(GetTypeStoreSize(*structType), 80u); // Struct ends with 12 bytes of padding
123  EXPECT_EQ(GetTypeAllocSize(*structType), 80u);
124  EXPECT_EQ(GetTypeAlignment(*structType), 16u);
125 
126  auto packedStructType = StructType::CreateIdentified(
127  "myPackedStruct",
128  { bits32,
129  pointerType,
130  arrayType,
131  vectorType, // The most aligned type, 16 byte alignment
132  bits32 },
133  true);
134  EXPECT_EQ(packedStructType->GetFieldOffset(0), 0u);
135  EXPECT_EQ(packedStructType->GetFieldOffset(1), 4u);
136  EXPECT_EQ(packedStructType->GetFieldOffset(2), 12u);
137  EXPECT_EQ(packedStructType->GetFieldOffset(3), 32u); // array is 20 bytes
138  EXPECT_EQ(packedStructType->GetFieldOffset(4), 48u); // vector is 16 bytes
139  EXPECT_EQ(GetTypeStoreSize(*packedStructType), 52u);
140  EXPECT_EQ(GetTypeAllocSize(*packedStructType), 52u);
141  EXPECT_EQ(GetTypeAlignment(*packedStructType), 1u);
142 }
TEST(TypeTests, TestIsOrContains)
Definition: TypeTests.cpp:14
static std::shared_ptr< const ArrayType > Create(std::shared_ptr< const Type > type, size_t nelements)
Definition: types.hpp:98
static std::shared_ptr< const FixedVectorType > Create(std::shared_ptr< const rvsdg::Type > type, size_t size)
Definition: types.hpp:413
static std::shared_ptr< const FloatingPointType > Create(fpsize size)
Definition: types.cpp:117
static std::shared_ptr< const IOStateType > Create()
Definition: types.cpp:343
static std::shared_ptr< const MemoryStateType > Create()
Definition: types.cpp:379
static std::shared_ptr< const PointerType > Create()
Definition: types.cpp:45
static std::shared_ptr< const StructType > CreateIdentified(const std::string &name, std::vector< std::shared_ptr< const Type >> types, bool isPacked)
Definition: types.hpp:307
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
Definition: type.cpp:45
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 std::shared_ptr< const TestType > createValueType()
Definition: TestType.cpp:67
Global memory state passed between functions.
size_t GetTypeAlignment(const rvsdg::Type &type)
Definition: types.cpp:485
size_t GetTypeAllocSize(const rvsdg::Type &type)
Definition: types.cpp:473
size_t GetTypeStoreSize(const rvsdg::Type &type)
Definition: types.cpp:386
bool IsAggregateType(const jlm::rvsdg::Type &type)
Definition: types.hpp:531
@ State
Designate a state type.
@ Value
Designate a value type.