Skip to content

Commit 736270d

Browse files
committed
Do not use pointers to LLVM IR constants
1 parent f3546e6 commit 736270d

File tree

8 files changed

+83
-118
lines changed

8 files changed

+83
-118
lines changed

src/dev/engine/internal/llvmcodebuilder.cpp

Lines changed: 23 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include <llvm/Support/TargetSelect.h>
44
#include <llvm/IR/Verifier.h>
55
#include <llvm/ExecutionEngine/Orc/LLJIT.h>
6-
#include <scratchcpp/value.h>
76

87
#include "llvmcodebuilder.h"
98
#include "llvmexecutablecode.h"
@@ -30,16 +29,6 @@ LLVMCodeBuilder::LLVMCodeBuilder(const std::string &id) :
3029
initTypes();
3130
}
3231

33-
LLVMCodeBuilder::~LLVMCodeBuilder()
34-
{
35-
for (const auto &values : m_constValues) {
36-
for (const auto &v : values) {
37-
if (v)
38-
value_free(v.get());
39-
}
40-
}
41-
}
42-
4332
std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
4433
{
4534
size_t functionIndex = 0;
@@ -291,15 +280,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
291280
std::cout << "==============" << std::endl << std::endl;
292281
#endif
293282

294-
std::vector<std::unique_ptr<ValueData>> constValues;
295-
296-
for (auto &values : m_constValues) {
297-
for (auto &v : values)
298-
constValues.push_back(std::move(v));
299-
}
300-
301-
m_constValues.clear();
302-
return std::make_shared<LLVMExecutableCode>(std::move(m_module), constValues);
283+
return std::make_shared<LLVMExecutableCode>(std::move(m_module));
303284
}
304285

305286
void LLVMCodeBuilder::addFunctionCall(const std::string &functionName, Compiler::StaticType returnType, const std::vector<Compiler::StaticType> &argTypes)
@@ -331,16 +312,10 @@ void LLVMCodeBuilder::addFunctionCall(const std::string &functionName, Compiler:
331312
void LLVMCodeBuilder::addConstValue(const Value &value)
332313
{
333314
auto reg = std::make_shared<Register>(TYPE_MAP[value.type()]);
334-
reg->isRawValue = false;
335315
reg->isConstValue = true;
336-
reg->constValueIndex = m_constValues[m_currentFunction].size();
316+
reg->constValue = value;
337317
m_regs[m_currentFunction].push_back(reg);
338318
m_tmpRegs.push_back(reg);
339-
340-
std::unique_ptr<ValueData> v = std::make_unique<ValueData>();
341-
value_init(v.get());
342-
value_assign_copy(v.get(), &value.data());
343-
m_constValues[m_currentFunction].push_back(std::move(v));
344319
}
345320

346321
void LLVMCodeBuilder::addVariableValue(Variable *variable)
@@ -448,35 +423,6 @@ llvm::Function *LLVMCodeBuilder::beginFunction(size_t index)
448423
llvm::BasicBlock *entry = llvm::BasicBlock::Create(m_ctx, "entry", func);
449424
m_builder.SetInsertPoint(entry);
450425

451-
// Add const value pointers
452-
const auto &constValues = m_constValues[index];
453-
std::vector<llvm::Value *> constPtrs;
454-
455-
for (size_t i = 0; i < constValues.size(); i++) {
456-
llvm::Value *intAddress = m_builder.getInt64((uintptr_t)constValues[i].get());
457-
llvm::Value *ptr = m_builder.CreateIntToPtr(intAddress, m_valueDataType->getPointerTo());
458-
constPtrs.push_back(ptr);
459-
}
460-
461-
// Add registers
462-
auto &regs = m_regs[index];
463-
size_t regIndex = 0;
464-
465-
for (auto &reg : regs) {
466-
if (reg->isConstValue) {
467-
// Do not allocate space for existing constant values
468-
reg->value = constPtrs[reg->constValueIndex];
469-
} else {
470-
/*const std::string name = "r" + std::to_string(regIndex);
471-
472-
llvm::Value *valueData = m_builder.CreateAlloca(m_valueDataType, nullptr, name);
473-
m_builder.CreateCall(resolve_value_init(), { valueData });
474-
475-
reg->value = valueData;
476-
regIndex++;*/
477-
}
478-
}
479-
480426
return func;
481427
}
482428

@@ -509,6 +455,9 @@ void LLVMCodeBuilder::freeHeap()
509455

510456
llvm::Value *LLVMCodeBuilder::castValue(std::shared_ptr<Register> reg, Compiler::StaticType targetType)
511457
{
458+
if (reg->isConstValue)
459+
return castConstValue(reg->constValue, targetType);
460+
512461
if (reg->isRawValue)
513462
return castRawValue(reg, targetType);
514463

@@ -655,6 +604,24 @@ llvm::Value *LLVMCodeBuilder::castRawValue(std::shared_ptr<Register> reg, Compil
655604
}
656605
}
657606

607+
llvm::Value *LLVMCodeBuilder::castConstValue(const Value &value, Compiler::StaticType targetType)
608+
{
609+
switch (targetType) {
610+
case Compiler::StaticType::Number:
611+
return llvm::ConstantFP::get(m_ctx, llvm::APFloat(value.toDouble()));
612+
613+
case Compiler::StaticType::Bool:
614+
return m_builder.getInt1(value.toBool());
615+
616+
case Compiler::StaticType::String:
617+
return m_builder.CreateGlobalStringPtr(value.toString());
618+
619+
default:
620+
assert(false);
621+
return nullptr;
622+
}
623+
}
624+
658625
llvm::Type *LLVMCodeBuilder::getType(Compiler::StaticType type)
659626
{
660627
switch (type) {

src/dev/engine/internal/llvmcodebuilder.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#pragma once
44

5-
#include <scratchcpp/valuedata.h>
5+
#include <scratchcpp/value.h>
66
#include <llvm/IR/LLVMContext.h>
77
#include <llvm/IR/Module.h>
88
#include <llvm/IR/IRBuilder.h>
@@ -18,7 +18,6 @@ class LLVMCodeBuilder : public ICodeBuilder
1818
{
1919
public:
2020
LLVMCodeBuilder(const std::string &id);
21-
~LLVMCodeBuilder();
2221

2322
std::shared_ptr<ExecutableCode> finalize() override;
2423

@@ -51,7 +50,7 @@ class LLVMCodeBuilder : public ICodeBuilder
5150
llvm::Value *value = nullptr;
5251
bool isRawValue = false;
5352
bool isConstValue = false;
54-
size_t constValueIndex = 0;
53+
Value constValue;
5554
};
5655

5756
struct Step
@@ -106,6 +105,7 @@ class LLVMCodeBuilder : public ICodeBuilder
106105
void freeHeap();
107106
llvm::Value *castValue(std::shared_ptr<Register> reg, Compiler::StaticType targetType);
108107
llvm::Value *castRawValue(std::shared_ptr<Register> reg, Compiler::StaticType targetType);
108+
llvm::Value *castConstValue(const Value &value, Compiler::StaticType targetType);
109109
llvm::Type *getType(Compiler::StaticType type);
110110

111111
llvm::FunctionCallee resolveFunction(const std::string name, llvm::FunctionType *type);
@@ -133,7 +133,7 @@ class LLVMCodeBuilder : public ICodeBuilder
133133

134134
std::vector<Step> m_steps;
135135
size_t m_currentFunction = 0;
136-
std::vector<std::vector<std::unique_ptr<ValueData>>> m_constValues;
136+
std::vector<Value> m_constValues;
137137
std::vector<std::vector<std::shared_ptr<Register>>> m_regs;
138138
std::vector<std::shared_ptr<Register>> m_tmpRegs;
139139

src/dev/engine/internal/llvmexecutablecode.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
using namespace libscratchcpp;
1212

13-
LLVMExecutableCode::LLVMExecutableCode(std::unique_ptr<llvm::Module> module, std::vector<std::unique_ptr<ValueData>> &constValues) :
13+
LLVMExecutableCode::LLVMExecutableCode(std::unique_ptr<llvm::Module> module) :
1414
m_ctx(std::make_unique<llvm::LLVMContext>()),
1515
m_jit(llvm::orc::LLJITBuilder().create())
1616
{
@@ -46,19 +46,6 @@ LLVMExecutableCode::LLVMExecutableCode(std::unique_ptr<llvm::Module> module, std
4646

4747
i++;
4848
}
49-
50-
// Move const value pointers (transfer ownership)
51-
for (auto &v : constValues)
52-
m_constValues.push_back(std::move(v));
53-
54-
constValues.clear();
55-
}
56-
57-
LLVMExecutableCode::~LLVMExecutableCode()
58-
{
59-
// Free memory used by const values
60-
for (const auto &v : m_constValues)
61-
value_free(v.get());
6249
}
6350

6451
void LLVMExecutableCode::run(ExecutionContext *context)

src/dev/engine/internal/llvmexecutablecode.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ class LLVMExecutionContext;
1616
class LLVMExecutableCode : public ExecutableCode
1717
{
1818
public:
19-
LLVMExecutableCode(std::unique_ptr<llvm::Module> module, std::vector<std::unique_ptr<libscratchcpp::ValueData>> &constValues);
20-
~LLVMExecutableCode();
19+
LLVMExecutableCode(std::unique_ptr<llvm::Module> module);
2120

2221
void run(ExecutionContext *context) override;
2322
void kill(libscratchcpp::ExecutionContext *context) override;
@@ -39,7 +38,6 @@ class LLVMExecutableCode : public ExecutableCode
3938
llvm::Expected<std::unique_ptr<llvm::orc::LLJIT>> m_jit;
4039

4140
std::vector<FunctionType> m_functions;
42-
std::vector<std::unique_ptr<ValueData>> m_constValues;
4341
};
4442

4543
} // namespace libscratchcpp

test/dev/llvm/llvmcodebuilder_test.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,37 @@ TEST_F(LLVMCodeBuilderTest, FunctionCalls)
5959
ASSERT_EQ(testing::internal::GetCapturedStdout(), expected);
6060
}
6161

62+
TEST_F(LLVMCodeBuilderTest, ConstCasting)
63+
{
64+
m_builder->addConstValue(5.2);
65+
m_builder->addFunctionCall("test_print_number", Compiler::StaticType::Void, { Compiler::StaticType::Number });
66+
m_builder->addConstValue(-24.156);
67+
m_builder->addFunctionCall("test_print_number", Compiler::StaticType::Void, { Compiler::StaticType::Number });
68+
69+
m_builder->addConstValue(true);
70+
m_builder->addFunctionCall("test_print_bool", Compiler::StaticType::Void, { Compiler::StaticType::Bool });
71+
72+
m_builder->addConstValue(false);
73+
m_builder->addFunctionCall("test_print_bool", Compiler::StaticType::Void, { Compiler::StaticType::Bool });
74+
75+
m_builder->addConstValue("hello world");
76+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
77+
78+
auto code = m_builder->finalize();
79+
auto ctx = code->createExecutionContext(&m_target);
80+
81+
static const std::string expected =
82+
"5.2\n"
83+
"-24.156\n"
84+
"1\n"
85+
"0\n"
86+
"hello world\n";
87+
88+
testing::internal::CaptureStdout();
89+
code->run(ctx.get());
90+
ASSERT_EQ(testing::internal::GetCapturedStdout(), expected);
91+
}
92+
6293
TEST_F(LLVMCodeBuilderTest, Yield)
6394
{
6495
m_builder->addFunctionCall("test_function_no_args", Compiler::StaticType::Void, {});

test/dev/llvm/llvmexecutablecode_test.cpp

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ class LLVMExecutableCodeTest : public testing::Test
6969

7070
TEST_F(LLVMExecutableCodeTest, CreateExecutionContext)
7171
{
72-
std::vector<std::unique_ptr<ValueData>> constValues;
73-
LLVMExecutableCode code(std::move(m_module), constValues);
72+
LLVMExecutableCode code(std::move(m_module));
7473
auto ctx = code.createExecutionContext(&m_target);
7574
ASSERT_TRUE(ctx);
7675
ASSERT_EQ(ctx->target(), &m_target);
@@ -79,8 +78,7 @@ TEST_F(LLVMExecutableCodeTest, CreateExecutionContext)
7978

8079
TEST_F(LLVMExecutableCodeTest, NoFunctions)
8180
{
82-
std::vector<std::unique_ptr<ValueData>> constValues;
83-
LLVMExecutableCode code(std::move(m_module), constValues);
81+
LLVMExecutableCode code(std::move(m_module));
8482
auto ctx = code.createExecutionContext(&m_target);
8583
ASSERT_TRUE(code.isFinished(ctx.get()));
8684

@@ -100,8 +98,7 @@ TEST_F(LLVMExecutableCodeTest, SingleFunction)
10098
addTestFunction(f);
10199
endFunction(0);
102100

103-
std::vector<std::unique_ptr<ValueData>> constValues;
104-
LLVMExecutableCode code(std::move(m_module), constValues);
101+
LLVMExecutableCode code(std::move(m_module));
105102
auto ctx = code.createExecutionContext(&m_target);
106103
ASSERT_FALSE(code.isFinished(ctx.get()));
107104

@@ -148,8 +145,7 @@ TEST_F(LLVMExecutableCodeTest, MultipleFunctions)
148145
endFunction(i);
149146
}
150147

151-
std::vector<std::unique_ptr<ValueData>> constValues;
152-
LLVMExecutableCode code(std::move(m_module), constValues);
148+
LLVMExecutableCode code(std::move(m_module));
153149
auto ctx = code.createExecutionContext(&m_target);
154150
ASSERT_FALSE(code.isFinished(ctx.get()));
155151

@@ -161,36 +157,3 @@ TEST_F(LLVMExecutableCodeTest, MultipleFunctions)
161157

162158
ASSERT_TRUE(code.isFinished(ctx.get()));
163159
}
164-
165-
TEST_F(LLVMExecutableCodeTest, ConstValues)
166-
{
167-
beginFunction(0);
168-
std::vector<std::unique_ptr<ValueData>> constValues;
169-
170-
for (int i = 0; i < 2; i++) {
171-
std::unique_ptr<ValueData> value = std::make_unique<ValueData>();
172-
value_init(value.get());
173-
value_assign_int(value.get(), i + 1);
174-
constValues.push_back(std::move(value));
175-
}
176-
177-
auto ptrType = llvm::PointerType::get(llvm::Type::getInt8Ty(m_ctx), 0);
178-
llvm::Value *intAddress = m_builder->getInt64((uintptr_t)constValues[0].get());
179-
llvm::Value *ptr1 = m_builder->CreateIntToPtr(intAddress, ptrType);
180-
181-
intAddress = m_builder->getInt64((uintptr_t)constValues[1].get());
182-
llvm::Value *ptr2 = m_builder->CreateIntToPtr(intAddress, ptrType);
183-
184-
addTestPrintFunction(ptr1, ptr2);
185-
endFunction(0);
186-
187-
LLVMExecutableCode code(std::move(m_module), constValues);
188-
auto ctx = code.createExecutionContext(&m_target);
189-
ASSERT_TRUE(constValues.empty());
190-
ASSERT_FALSE(code.isFinished(ctx.get()));
191-
192-
testing::internal::CaptureStdout();
193-
code.run(ctx.get());
194-
ASSERT_EQ(testing::internal::GetCapturedStdout(), "1 2\n");
195-
ASSERT_TRUE(code.isFinished(ctx.get()));
196-
}

test/dev/llvm/testfunctions.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,19 @@ extern "C"
107107
{
108108
return counter;
109109
}
110+
111+
void test_print_number(Target *target, double v)
112+
{
113+
std::cout << v << std::endl;
114+
}
115+
116+
void test_print_bool(Target *target, bool v)
117+
{
118+
std::cout << v << std::endl;
119+
}
120+
121+
void test_print_string(Target *target, const char *v)
122+
{
123+
std::cout << v << std::endl;
124+
}
110125
}

test/dev/llvm/testfunctions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ extern "C"
2929
void test_reset_counter(Target *target);
3030
void test_increment_counter(Target *target);
3131
double test_get_counter(Target *target);
32+
33+
void test_print_number(Target *target, double v);
34+
void test_print_bool(Target *target, bool v);
35+
void test_print_string(Target *target, const char *v);
3236
}
3337

3438
} // namespace libscratchcpp

0 commit comments

Comments
 (0)