Skip to content

Commit edd5726

Browse files
committed
LLVMCodeBuilder: Implement add operator
1 parent f2e0457 commit edd5726

File tree

5 files changed

+94
-0
lines changed

5 files changed

+94
-0
lines changed

src/dev/engine/internal/icodebuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ICodeBuilder
2424
virtual void addVariableValue(Variable *variable) = 0;
2525
virtual void addListContents(List *list) = 0;
2626

27+
virtual void createAdd() = 0;
2728
virtual void beginIfStatement() = 0;
2829
virtual void beginElseBranch() = 0;
2930
virtual void endIf() = 0;

src/dev/engine/internal/llvmcodebuilder.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
8888
break;
8989
}
9090

91+
case Step::Type::Add: {
92+
assert(step.args.size() == 2);
93+
const auto &arg1 = step.args[0];
94+
const auto &arg2 = step.args[1];
95+
llvm::Value *num1 = removeNaN(castValue(arg1.second, arg1.first));
96+
llvm::Value *num2 = removeNaN(castValue(arg2.second, arg2.first));
97+
step.functionReturnReg->value = m_builder.CreateFAdd(num1, num2);
98+
break;
99+
}
100+
91101
case Step::Type::Yield:
92102
if (!m_warp) {
93103
freeHeap();
@@ -412,6 +422,11 @@ void LLVMCodeBuilder::addListContents(List *list)
412422
{
413423
}
414424

425+
void LLVMCodeBuilder::createAdd()
426+
{
427+
createOp(Step::Type::Add, 2);
428+
}
429+
415430
void LLVMCodeBuilder::beginIfStatement()
416431
{
417432
Step step(Step::Type::BeginIf);
@@ -785,6 +800,34 @@ llvm::Type *LLVMCodeBuilder::getType(Compiler::StaticType type)
785800
}
786801
}
787802

803+
llvm::Value *LLVMCodeBuilder::removeNaN(llvm::Value *num)
804+
{
805+
// Replace NaN with zero
806+
llvm::Value *isNaN = m_builder.CreateFCmpUNO(num, num);
807+
return m_builder.CreateSelect(isNaN, llvm::ConstantFP::get(m_ctx, llvm::APFloat(0.0)), num);
808+
}
809+
810+
void LLVMCodeBuilder::createOp(Step::Type type, size_t argCount)
811+
{
812+
Step step(type);
813+
814+
assert(m_tmpRegs.size() >= argCount);
815+
size_t j = 0;
816+
817+
for (size_t i = m_tmpRegs.size() - argCount; i < m_tmpRegs.size(); i++)
818+
step.args.push_back({ Compiler::StaticType::Number, m_tmpRegs[i] });
819+
820+
m_tmpRegs.erase(m_tmpRegs.end() - argCount, m_tmpRegs.end());
821+
822+
auto ret = std::make_shared<Register>(Compiler::StaticType::Number);
823+
ret->isRawValue = true;
824+
step.functionReturnReg = ret;
825+
m_regs[m_currentFunction].push_back(ret);
826+
m_tmpRegs.push_back(ret);
827+
828+
m_steps.push_back(step);
829+
}
830+
788831
llvm::FunctionCallee LLVMCodeBuilder::resolveFunction(const std::string name, llvm::FunctionType *type)
789832
{
790833
return m_module->getOrInsertFunction(name, type);

src/dev/engine/internal/llvmcodebuilder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class LLVMCodeBuilder : public ICodeBuilder
2626
void addVariableValue(Variable *variable) override;
2727
void addListContents(List *list) override;
2828

29+
void createAdd() override;
2930
void beginIfStatement() override;
3031
void beginElseBranch() override;
3132
void endIf() override;
@@ -58,6 +59,7 @@ class LLVMCodeBuilder : public ICodeBuilder
5859
enum class Type
5960
{
6061
FunctionCall,
62+
Add,
6163
Yield,
6264
BeginIf,
6365
BeginElse,
@@ -124,6 +126,9 @@ class LLVMCodeBuilder : public ICodeBuilder
124126
llvm::Value *castRawValue(std::shared_ptr<Register> reg, Compiler::StaticType targetType);
125127
llvm::Value *castConstValue(const Value &value, Compiler::StaticType targetType);
126128
llvm::Type *getType(Compiler::StaticType type);
129+
llvm::Value *removeNaN(llvm::Value *num);
130+
131+
void createOp(Step::Type type, size_t argCount);
127132

128133
llvm::FunctionCallee resolveFunction(const std::string name, llvm::FunctionType *type);
129134
llvm::FunctionCallee resolve_value_init();

test/dev/llvm/llvmcodebuilder_test.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,50 @@ TEST_F(LLVMCodeBuilderTest, RawValueCasting)
200200
ASSERT_EQ(testing::internal::GetCapturedStdout(), expected);
201201
}
202202

203+
TEST_F(LLVMCodeBuilderTest, Add)
204+
{
205+
std::string expected;
206+
207+
auto addOpTest = [this, &expected](Value v1, Value v2, double expectedResult) {
208+
m_builder->addConstValue(v1);
209+
m_builder->addConstValue(v2);
210+
m_builder->createAdd();
211+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
212+
213+
m_builder->addConstValue(v1);
214+
m_builder->addFunctionCall("test_const_number", Compiler::StaticType::Number, { Compiler::StaticType::Number });
215+
m_builder->addConstValue(v2);
216+
m_builder->addFunctionCall("test_const_number", Compiler::StaticType::Number, { Compiler::StaticType::Number });
217+
m_builder->createAdd();
218+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
219+
220+
std::string str = Value(expectedResult).toString() + '\n';
221+
expected += str;
222+
expected += str;
223+
};
224+
225+
createBuilder(true);
226+
227+
addOpTest(50, 25, 75);
228+
addOpTest(-500, 25, -475);
229+
addOpTest(-500, -25, -525);
230+
addOpTest("2.54", "6.28", 8.82);
231+
addOpTest(2.54, "-6.28", -3.74);
232+
addOpTest(true, true, 2);
233+
addOpTest("Infinity", "Infinity", std::numeric_limits<double>::infinity());
234+
addOpTest("Infinity", "-Infinity", std::numeric_limits<double>::quiet_NaN());
235+
addOpTest("-Infinity", "Infinity", std::numeric_limits<double>::quiet_NaN());
236+
addOpTest("-Infinity", "-Infinity", -std::numeric_limits<double>::infinity());
237+
addOpTest(1, "NaN", 1);
238+
239+
auto code = m_builder->finalize();
240+
auto ctx = code->createExecutionContext(&m_target);
241+
242+
testing::internal::CaptureStdout();
243+
code->run(ctx.get());
244+
ASSERT_EQ(testing::internal::GetCapturedStdout(), expected);
245+
}
246+
203247
TEST_F(LLVMCodeBuilderTest, Yield)
204248
{
205249
auto build = [this]() {

test/mocks/codebuildermock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class CodeBuilderMock : public ICodeBuilder
1414
MOCK_METHOD(void, addVariableValue, (Variable *), (override));
1515
MOCK_METHOD(void, addListContents, (List *), (override));
1616

17+
MOCK_METHOD(void, createAdd, (), (override));
1718
MOCK_METHOD(void, beginIfStatement, (), (override));
1819
MOCK_METHOD(void, beginElseBranch, (), (override));
1920
MOCK_METHOD(void, endIf, (), (override));

0 commit comments

Comments
 (0)