From 11202e89ed39befe8175a3d855e51dd66fe2e55d Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Tue, 16 Jul 2024 19:16:17 +0200 Subject: [PATCH 1/7] improve cast and const ptr support (#8) --- .github/workflows/build.yml | 2 +- nautilus/include/nautilus/val_ptr.hpp | 6 +++ .../backends/mlir/MLIRLoweringProvider.cpp | 13 ++--- .../test/execution-tests/ExecutionTest.cpp | 47 +++++++++++++++++-- .../test/execution-tests/PointerFunctions.hpp | 26 +++++++--- nautilus/test/execution-tests/TracingTest.cpp | 2 +- 6 files changed, 77 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e2e9ff9f..4407d5e6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,6 +66,6 @@ jobs: - name: test shell: bash run: | - cd nautilus && ctest --test-dir=nautilus --output-on-failure + ctest --test-dir nautilus --output-on-failure diff --git a/nautilus/include/nautilus/val_ptr.hpp b/nautilus/include/nautilus/val_ptr.hpp index 15ce6cc9..367e2fbb 100644 --- a/nautilus/include/nautilus/val_ptr.hpp +++ b/nautilus/include/nautilus/val_ptr.hpp @@ -108,6 +108,12 @@ template class val : public base_ptr_val { public: using base_ptr_val::base_ptr_val; + + // enable cast to type T + template + operator val() const { + return val((T*)this->value, this->state); + } }; template diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp index e339260a..edfa6495 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp @@ -405,12 +405,13 @@ void MLIRLoweringProvider::generateMLIR(ir::ConstIntOperation* constIntOp, Value } } -void MLIRLoweringProvider::generateMLIR(ir::ConstPtrOperation* , ValueFrame& ) { - //builder->create(getNameLoc("location"), mlir::LLVM::LLVMPointerType, constPtrOperation->getValue()); - - //frame.setValue(constPtrOperation->getIdentifier(), - // getConstInt("ConstantOp", constIntOp->getStamp(), constIntOp->getValue())); - +void MLIRLoweringProvider::generateMLIR(ir::ConstPtrOperation* constPtr, ValueFrame& frame) { + int64_t val = (int64_t) constPtr->getValue(); + auto constInt = builder->create(getNameLoc("location"), builder->getI64Type(), + builder->getIntegerAttr(builder->getI64Type(), val)); + auto elementAddress = builder->create(getNameLoc("fieldAccess"), + mlir::LLVM::LLVMPointerType::get(context), constInt); + frame.setValue(constPtr->getIdentifier(), elementAddress); } void MLIRLoweringProvider::generateMLIR(ir::ConstFloatOperation* constFloatOp, ValueFrame& frame) { diff --git a/nautilus/test/execution-tests/ExecutionTest.cpp b/nautilus/test/execution-tests/ExecutionTest.cpp index acbf1ccf..193e4879 100644 --- a/nautilus/test/execution-tests/ExecutionTest.cpp +++ b/nautilus/test/execution-tests/ExecutionTest.cpp @@ -483,6 +483,37 @@ void functionCallExecutionTest(engine::NautilusEngine& engine) { void pointerExecutionTest(engine::NautilusEngine& engine) { int* values = new int[10] {1, 2, 3, 4, 5, 6, 7, 8, 9}; // int* ptr = &values; + SECTION("castVoidInt8") { + auto f = engine.registerFunction(castPtrAndGetValue); + int x = 42; + REQUIRE(f((void*) &x) == (int8_t) 42); + } + SECTION("castVoidInt16") { + auto f = engine.registerFunction(castPtrAndGetValue); + int x = 42; + REQUIRE(f((void*) &x) == (int16_t) 42); + } + SECTION("castVoidInt32") { + auto f = engine.registerFunction(castPtrAndGetValue); + int x = 42; + REQUIRE(f((void*) &x) == (int32_t) 42); + } + SECTION("castVoidInt64") { + auto f = engine.registerFunction(castPtrAndGetValue); + int64_t x = 42; + REQUIRE(f((void*) &x) == *((int64_t*) &x)); + } + SECTION("castVoidFloat") { + auto f = engine.registerFunction(castPtrAndGetValue); + int64_t x = 42; + REQUIRE(f((void*) &x) == *((float*) &x)); + } + SECTION("castVoidFloat") { + auto f = engine.registerFunction(castPtrAndGetValue); + int64_t x = 42; + REQUIRE(f((void*) &x) == *((double*) &x)); + } + SECTION("load") { auto f = engine.registerFunction(load); @@ -490,7 +521,6 @@ void pointerExecutionTest(engine::NautilusEngine& engine) { REQUIRE(f(values, (int32_t) 1) == 2); REQUIRE(f(values, (int32_t) 8) == 9); } - /* SECTION("loadConst") { globalPtr = values[0]; auto f = engine.registerFunction(loadConst); @@ -500,7 +530,6 @@ void pointerExecutionTest(engine::NautilusEngine& engine) { globalPtr = values[2]; REQUIRE(f() == 3); } - */ SECTION("sumArray") { auto f = engine.registerFunction(sumArray); val r = f(values, (int32_t) 10); @@ -521,9 +550,17 @@ void pointerExecutionTest(engine::NautilusEngine& engine) { int x = 42; REQUIRE(f((void*) &x) == 42); } - SECTION("passCustomStruct") { - auto f = engine.registerFunction(passCustomStruct); - CustomStruct x = {.x = 42}; + SECTION("castCustomClass") { + auto f = engine.registerFunction(castCustomClass); + CustomClass x; + x.x = 42; + BaseClass* BaseClass = &x; + REQUIRE(f(BaseClass) == 42); + } + SECTION("passCustomClass") { + auto f = engine.registerFunction(passCustomClass); + CustomClass x; + x.x = 42; REQUIRE(f(&x) == 42); } SECTION("specializeType") { diff --git a/nautilus/test/execution-tests/PointerFunctions.hpp b/nautilus/test/execution-tests/PointerFunctions.hpp index 0ded4ec6..ec18d0d1 100644 --- a/nautilus/test/execution-tests/PointerFunctions.hpp +++ b/nautilus/test/execution-tests/PointerFunctions.hpp @@ -21,6 +21,12 @@ val castVoidPtr(val array) { return intPtr[0]; } +template +val castPtrAndGetValue(val array) { + auto intPtr = static_cast>(array); + return intPtr[0]; +} + val sumArray(val array, val length) { val sum = val(0); for (val i = 0; i < length; i = i + 1) { @@ -39,17 +45,25 @@ void addArray(val array, val array2, val length) { } } - void callMemcpy(val src, val dest) { memcpy(dest, src, 0); } -struct CustomStruct { +class BaseClass {}; + +class CustomClass : public BaseClass { +public: int x; }; -val passCustomStruct(val customStructPtr) { - return invoke<>(+[](CustomStruct* ptr) { return ptr->x; }, customStructPtr); +val passCustomClass(val customClassPtr) { + return invoke<>(+[](CustomClass* ptr) { return ptr->x; }, customClassPtr); +} + +val castCustomClass(val voidPtr) { + // cast base struct to custom struct + auto resultPtr = static_cast>(voidPtr); + return invoke<>(+[](CustomClass* ptr) { return ptr->x; }, resultPtr); } struct CustomStruct2 { @@ -68,8 +82,8 @@ class val : public base_ptr_val { } }; -val specializeType(val customStructPtr) { - return customStructPtr.getX(); +val specializeType(val customClassPtr) { + return customClassPtr.getX(); } class WrapperType { diff --git a/nautilus/test/execution-tests/TracingTest.cpp b/nautilus/test/execution-tests/TracingTest.cpp index d0784f96..8da9f3ee 100644 --- a/nautilus/test/execution-tests/TracingTest.cpp +++ b/nautilus/test/execution-tests/TracingTest.cpp @@ -206,7 +206,7 @@ TEST_CASE("Loop Trace Test") { {"addArrayInt32", details::createFunctionWrapper(addArray)}, {"simpleDirectCall", details::createFunctionWrapper(simpleDirectCall)}, {"loopDirectCall", details::createFunctionWrapper(loopDirectCall)}, - {"passCustomStruct", details::createFunctionWrapper(passCustomStruct)}, + {"passCustomStruct", details::createFunctionWrapper(passCustomClass)}, {"specializeType", details::createFunctionWrapper(specializeType)}, {"useWrapper", details::createFunctionWrapper(useWrapper)}, {"voidFuncCall", details::createFunctionWrapper(voidFuncCall)}}; From c712ed462af29b2188cea90e9b1c1c8f40c1c3b8 Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Sat, 20 Jul 2024 01:26:44 +0200 Subject: [PATCH 2/7] add support for std::function for compiling functions (#9) --- nautilus/include/nautilus/Engine.hpp | 82 ++++++++++++++----- nautilus/include/nautilus/val_enum.hpp | 2 +- .../backends/mlir/MLIRLoweringProvider.cpp | 4 +- .../phases/TraceToIRConversionPhase.cpp | 2 +- nautilus/test/data/ir/addArrayInt32.trace | 2 +- .../test/execution-tests/ExecutionTest.cpp | 73 +++++++++++++---- 6 files changed, 123 insertions(+), 42 deletions(-) diff --git a/nautilus/include/nautilus/Engine.hpp b/nautilus/include/nautilus/Engine.hpp index dc35b5e7..b77e79f9 100644 --- a/nautilus/include/nautilus/Engine.hpp +++ b/nautilus/include/nautilus/Engine.hpp @@ -6,6 +6,7 @@ #include "nautilus/config.hpp" #include "nautilus/core.hpp" #include "nautilus/options.hpp" +#include namespace nautilus::engine { @@ -55,40 +56,61 @@ template std::function createFunctionWrapper(R (*fnptr)(FunctionArguments...)) { return createFunctionWrapper(std::make_index_sequence {}, fnptr); } + +template +std::function createFunctionWrapper(std::index_sequence, std::function func) { + [[maybe_unused]] std::size_t args = sizeof...(FunctionArguments); + auto traceFunc = [=]() { + if constexpr (std::is_void_v) { + func(details::createTraceArgument()...); + tracing::traceReturnOperation(Type::v, tracing::value_ref()); + } else { + auto returnValue = func(details::createTraceArgument()...); + auto type = tracing::to_type(); + tracing::traceReturnOperation(type, returnValue.state); + } + }; + return traceFunc; +} + +template +std::function createFunctionWrapper(std::function func) { + return createFunctionWrapper(std::make_index_sequence {}, func); +} #endif } // namespace details template class CallableFunction { public: - explicit CallableFunction(void* func) : func(func), executable(nullptr) { + explicit CallableFunction(std::function func) : func(func), executable(nullptr) { } explicit CallableFunction(std::unique_ptr& executable) - : func(), executable(std::move(executable)) { - if (this->executable->hasInvocableFunctionPtr()) { - func = this->executable->getInvocableFunctionPtr("execute"); - } - } + : func(), executable(std::move(executable)) {} template requires std::is_void_v auto operator()(FunctionArgumentsRaw... args) { // function is called from an external context. - using FunctionType = void(FunctionArguments...); - auto fnptr = reinterpret_cast(func); - fnptr(details::transform((args))...); + // no executable is defined, call the underling function directly and convert all arguments to val objects + if (executable == nullptr) { + func(details::transform((args))...); + return; + } + auto callable = + this->executable->template getInvocableMember("execute"); + callable(args...); + return; } template requires(!std::is_void_v) auto operator()(FunctionArgumentsRaw... args) { // function is called from an external context. - + // no executable is defined, call the underling function directly and convert all arguments to val objects if (executable == nullptr) { - using FunctionType = R(FunctionArguments...); - auto fnptr = reinterpret_cast(func); - auto result = fnptr(details::transform((args))...); + auto result = func(details::transform((args))...); return nautilus::details::getRawValue(result); } auto callable = @@ -97,7 +119,7 @@ class CallableFunction { } private: - void* func; + std::function func; std::unique_ptr executable; }; @@ -117,17 +139,39 @@ class NautilusEngine { return CallableFunction, val...>(executable); } #endif - return CallableFunction, val...>((void*) fnptr); + std::function(val...)> inputWrapper = fnptr; + return CallableFunction, val...>(inputWrapper); } template auto registerFunction(void (*fnptr)(FunctionArguments...)) const { - // auto wrapper = createFunctionWrapper(fnptr); - // auto executable = jit->compile(wrapper); - // auto ptr = reinterpret_cast(executable); - return CallableFunction((void*) fnptr); +#ifdef ENABLE_TRACING + if (options.getOptionOrDefault("engine.Compilation", true)) { + auto wrapper = details::createFunctionWrapper(fnptr); + auto executable = jit.compile(wrapper); + return CallableFunction(executable); + } +#endif + std::function inputWrapper = fnptr; + return CallableFunction(inputWrapper); + } + + + template + auto registerFunction(std::function(val...)> func) const { +#ifdef ENABLE_TRACING + if (options.getOptionOrDefault("engine.Compilation", true)) { + auto wrapper = details::createFunctionWrapper(func); + auto executable = jit.compile(wrapper); + return CallableFunction, val...>(executable); + } +#endif + return CallableFunction, val...>(func); } + + + private: const compiler::JITCompiler jit; const Options options; diff --git a/nautilus/include/nautilus/val_enum.hpp b/nautilus/include/nautilus/val_enum.hpp index 8904162b..8201fd36 100644 --- a/nautilus/include/nautilus/val_enum.hpp +++ b/nautilus/include/nautilus/val_enum.hpp @@ -27,7 +27,7 @@ class val { val(val& t) : state(tracing::traceCopy(t.state)), value(t.value) {}; val(T val) : state(tracing::traceConstant((underlying_type_t) val)), value(val) {}; #else - val(val t) : value((T) t.value) {}; + val(val t) : value((T) details::getRawValue(t)) {}; val(val& t) : value(t.value) {}; val(T val) : value(val) {}; #endif diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp index edfa6495..17b14f5d 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp @@ -527,9 +527,7 @@ void MLIRLoweringProvider::generateMLIR(ir::ModOperation* divIntOp, ValueFrame& void MLIRLoweringProvider::generateMLIR(ir::StoreOperation* storeOp, ValueFrame& frame) { auto value = frame.getValue(storeOp->getValue()->getIdentifier()); auto address = frame.getValue(storeOp->getAddress()->getIdentifier()); - auto bitcast = builder->create(getNameLoc("Address Bitcasted"), - mlir::LLVM::LLVMPointerType::get(context), address); - builder->create(getNameLoc("outputStore"), value, bitcast); + builder->create(getNameLoc("outputStore"), value, address); } void MLIRLoweringProvider::generateMLIR(ir::ReturnOperation* returnOp, ValueFrame& frame) { diff --git a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp index 99b00a29..532ca88c 100644 --- a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp +++ b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp @@ -406,7 +406,7 @@ void TraceToIRConversionPhase::IRConversionContext::processStore(int32_t, ValueF TraceOperation& operation) { auto address = frame.getValue(createValueIdentifier(operation.resultRef)); auto value = frame.getValue(createValueIdentifier(operation.input[0])); - currentBlock->addOperation(address, value); + currentBlock->addOperation(value, address); } void TraceToIRConversionPhase::IRConversionContext::processCall(int32_t, ValueFrame& frame, BasicBlock* currentBlock, diff --git a/nautilus/test/data/ir/addArrayInt32.trace b/nautilus/test/data/ir/addArrayInt32.trace index 42d79c39..4e9cb28c 100644 --- a/nautilus/test/data/ir/addArrayInt32.trace +++ b/nautilus/test/data/ir/addArrayInt32.trace @@ -21,7 +21,7 @@ Block_1($3:i32, $4:i32, $1:ptr, $2:ptr): $25 = 4 :i32 $26 = $4 * $25 :i32 $27 = $1 + $26 :ptr - store($27, $21) :void + store($21, $27) :void $28 = 1 :i32 $29 = $4 + $28 :i32 br Block_3($29, $3, $1, $2) :void diff --git a/nautilus/test/execution-tests/ExecutionTest.cpp b/nautilus/test/execution-tests/ExecutionTest.cpp index 193e4879..0c5e6a10 100644 --- a/nautilus/test/execution-tests/ExecutionTest.cpp +++ b/nautilus/test/execution-tests/ExecutionTest.cpp @@ -522,13 +522,13 @@ void pointerExecutionTest(engine::NautilusEngine& engine) { REQUIRE(f(values, (int32_t) 8) == 9); } SECTION("loadConst") { - globalPtr = values[0]; - auto f = engine.registerFunction(loadConst); - REQUIRE(f() == 1); - globalPtr = values[1]; - REQUIRE(f() == 2); - globalPtr = values[2]; - REQUIRE(f() == 3); + globalPtr = values[0]; + auto f = engine.registerFunction(loadConst); + REQUIRE(f() == 1); + globalPtr = values[1]; + REQUIRE(f() == 2); + globalPtr = values[2]; + REQUIRE(f() == 3); } SECTION("sumArray") { auto f = engine.registerFunction(sumArray); @@ -576,8 +576,57 @@ void pointerExecutionTest(engine::NautilusEngine& engine) { } } +class Clazz{ +public: + val function(val arg){ + return arg + 20; + } + + val functionWithStateAccess(val arg){ + return arg + state; + } + + int state; +}; + +void registerFunctionTest(engine::NautilusEngine& engine) { + + SECTION("pureFunction") { + auto f = engine.registerFunction(std::function([](val arg) { return arg; })); + REQUIRE(f(42) == 42); + REQUIRE(f(1) == 1); + } + + SECTION("functionWithClosure") { + auto closure = 42; + auto f = engine.registerFunction(std::function([closure](val arg) { return arg + closure; })); + REQUIRE(f(42) == 84); + REQUIRE(f(1) == 43); + } + + SECTION("functionBindMember") { + auto clazz = Clazz(); + std::function(val)> bound = std::bind(&Clazz::function, &clazz, std::placeholders::_1); + auto f = engine.registerFunction(bound); + REQUIRE(f(42) == 62); + REQUIRE(f(1) == 21); + } + + SECTION("functionBindMember2") { + auto clazz = Clazz(); + clazz.state = 100; + std::function(val)> bound = std::bind(&Clazz::functionWithStateAccess, &clazz, std::placeholders::_1); + auto f = engine.registerFunction(bound); + REQUIRE(f(42) == 142); + REQUIRE(f(1) == 101); + } +} + void runAllTests(engine::NautilusEngine& engine) { + SECTION("registerFunctionTest") { + registerFunctionTest(engine); + } SECTION("expressionTest") { addTest(engine); } @@ -596,16 +645,6 @@ void runAllTests(engine::NautilusEngine& engine) { } TEST_CASE("Engine Interpreter Test") { - /* - std::cout << (is_arithmetic_value> && (is_arithmetic_value> || - convertible_to_fundamental>)) << std::endl; std::cout << (is_arithmetic_value>) << std::endl; - std::cout << (is_arithmetic_value>) << std::endl; - std::cout << std::is_arithmetic_v>::basic_type> << std::endl; - std::cout << "Is int is_value? " << is_val> << std::endl; - std::cout << "Is int is_value? " << is_val << std::endl; - std::cout << "Is int is_value? " << is_val << std::endl; - std::cout << "Is int is_value? " << is_traceable_value> << std::endl; - */ engine::Options options; options.setOption("engine.Compilation", false); auto engine = engine::NautilusEngine(options); From 3fc07b4bec4011a639538fe9fa21f7b1d6238471 Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Tue, 23 Jul 2024 10:16:26 +0200 Subject: [PATCH 3/7] Register lambda function (#11) --- nautilus/include/nautilus/Engine.hpp | 6 ++--- nautilus/include/nautilus/function.hpp | 1 + nautilus/include/nautilus/val.hpp | 2 +- .../tracing/phases/SSACreationPhase.cpp | 4 ++++ nautilus/test/data/tracing/voidFuncCall.trace | 2 -- .../test/execution-tests/ExecutionTest.cpp | 23 +++++++++++++++---- 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/nautilus/include/nautilus/Engine.hpp b/nautilus/include/nautilus/Engine.hpp index b77e79f9..9e4a2670 100644 --- a/nautilus/include/nautilus/Engine.hpp +++ b/nautilus/include/nautilus/Engine.hpp @@ -158,15 +158,15 @@ class NautilusEngine { template - auto registerFunction(std::function(val...)> func) const { + auto registerFunction(std::function...)> func) const { #ifdef ENABLE_TRACING if (options.getOptionOrDefault("engine.Compilation", true)) { auto wrapper = details::createFunctionWrapper(func); auto executable = jit.compile(wrapper); - return CallableFunction, val...>(executable); + return CallableFunction...>(executable); } #endif - return CallableFunction, val...>(func); + return CallableFunction...>(func); } diff --git a/nautilus/include/nautilus/function.hpp b/nautilus/include/nautilus/function.hpp index 0f525858..aa6ba2d8 100644 --- a/nautilus/include/nautilus/function.hpp +++ b/nautilus/include/nautilus/function.hpp @@ -105,6 +105,7 @@ class CallableRuntimeFunction { auto ptr = (void*) fnptr; auto functionArgumentReferences = getArgumentReferences("functionName", (void*) fnptr, args...); tracing::traceCall(functionName, ptr, Type::v, functionArgumentReferences); + return; } #endif fnptr(transform((args))...); diff --git a/nautilus/include/nautilus/val.hpp b/nautilus/include/nautilus/val.hpp index 9a4db48b..d0b1187b 100644 --- a/nautilus/include/nautilus/val.hpp +++ b/nautilus/include/nautilus/val.hpp @@ -618,7 +618,7 @@ auto inline operator&&(LHS left, RHS right) { } template -auto inline operator!(LHS left) { +auto inline operator!(val left) { return details::lNot(left); } diff --git a/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp b/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp index dfad9d60..4ffe2688 100644 --- a/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp +++ b/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp @@ -93,6 +93,10 @@ void SSACreationPhase::SSACreationPhaseContext::processBlock(Block& block) { } } } + + if (operation.op == STORE) { + processValueRef(block, operation.resultRef, operation.resultType, i); + } } processedBlocks.emplace(block.blockId); // Recursively process the predecessors of this block diff --git a/nautilus/test/data/tracing/voidFuncCall.trace b/nautilus/test/data/tracing/voidFuncCall.trace index ba6fc6da..27f886fa 100644 --- a/nautilus/test/data/tracing/voidFuncCall.trace +++ b/nautilus/test/data/tracing/voidFuncCall.trace @@ -4,6 +4,4 @@ B0() ASSIGN $5 $3 :i32 ASSIGN $6 $4 :i32 CALL $7 ($5,$6) :void - ASSIGN $8 $5 :i32 - ASSIGN $9 $6 :i32 RETURN $1 :i32 diff --git a/nautilus/test/execution-tests/ExecutionTest.cpp b/nautilus/test/execution-tests/ExecutionTest.cpp index 0c5e6a10..04969074 100644 --- a/nautilus/test/execution-tests/ExecutionTest.cpp +++ b/nautilus/test/execution-tests/ExecutionTest.cpp @@ -576,13 +576,13 @@ void pointerExecutionTest(engine::NautilusEngine& engine) { } } -class Clazz{ +class Clazz { public: - val function(val arg){ + val function(val arg) { return arg + 20; } - val functionWithStateAccess(val arg){ + val functionWithStateAccess(val arg) { return arg + state; } @@ -597,6 +597,20 @@ void registerFunctionTest(engine::NautilusEngine& engine) { REQUIRE(f(1) == 1); } + SECTION("pureFunctionWithPtr") { + auto f = engine.registerFunction(std::function([](val arg) -> val { return *arg; })); + int8_t val = 42; + REQUIRE(f(&val) == 42); + } + + SECTION("pureVoidFunctionWithPtr") { + auto f = engine.registerFunction(std::function([](val arg) -> void { *arg = 42; })); + int8_t val = 1; + REQUIRE(val == 1); + f(&val); + REQUIRE(val == 42); + } + SECTION("functionWithClosure") { auto closure = 42; auto f = engine.registerFunction(std::function([closure](val arg) { return arg + closure; })); @@ -615,7 +629,8 @@ void registerFunctionTest(engine::NautilusEngine& engine) { SECTION("functionBindMember2") { auto clazz = Clazz(); clazz.state = 100; - std::function(val)> bound = std::bind(&Clazz::functionWithStateAccess, &clazz, std::placeholders::_1); + std::function(val)> bound = + std::bind(&Clazz::functionWithStateAccess, &clazz, std::placeholders::_1); auto f = engine.registerFunction(bound); REQUIRE(f(42) == 142); REQUIRE(f(1) == 101); From f6bd701cbd8b488b84a90c83a74e6103b0070393 Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Wed, 24 Jul 2024 15:02:12 +0200 Subject: [PATCH 4/7] add dev container definition (#1) --- .devcontainer/devcontainer.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..afc99ed9 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,11 @@ +{ + "image": "mcr.microsoft.com/devcontainers/cpp:ubuntu-24.04", + "name": "Try Nautilus", + "customizations": { + "vscode": { + "extensions": [ + "matepek.vscode-catch2-test-adapter" + ] + } + } +} \ No newline at end of file From 65fb12e714afe30f061027d6bbdd191d871126b7 Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Fri, 26 Jul 2024 09:28:36 +0200 Subject: [PATCH 5/7] Extend bitwise op support (#12) --- nautilus/include/nautilus/Executable.hpp | 3 + nautilus/include/nautilus/common/traceing.hpp | 6 +- nautilus/include/nautilus/val.hpp | 10 +- .../compiler/backends/bc/BCInterpreter.cpp | 314 ++++++++++++++---- .../backends/bc/BCLoweringProvider.cpp | 251 +++++++++++++- .../backends/bc/BCLoweringProvider.hpp | 10 +- .../compiler/backends/bc/ByteCode.hpp | 90 ++++- .../backends/cpp/CPPLoweringProvider.cpp | 45 ++- .../backends/cpp/CPPLoweringProvider.hpp | 8 +- .../backends/mlir/MLIRLoweringProvider.cpp | 80 +++-- .../backends/mlir/MLIRLoweringProvider.hpp | 29 +- .../BinaryOperations/BinaryCompOperation.cpp | 29 +- .../BinaryOperations/BinaryCompOperation.hpp | 4 +- .../BinaryOperations/CMakeLists.txt | 1 + .../NegateOperation.cpp | 8 +- .../NegateOperation.hpp | 0 .../BinaryOperations/ShiftOperation.cpp | 8 +- .../BinaryOperations/ShiftOperation.hpp | 2 + .../LogicalOperations/CMakeLists.txt | 13 +- .../LogicalOperations/NotOperation.cpp | 25 ++ .../LogicalOperations/NotOperation.hpp | 20 ++ .../compiler/ir/operations/Operation.cpp | 2 +- .../compiler/ir/operations/Operation.hpp | 3 + .../src/nautilus/tracing/TraceContext.cpp | 19 ++ .../src/nautilus/tracing/TraceContext.hpp | 7 +- nautilus/src/nautilus/tracing/TracingUtil.cpp | 16 +- .../phases/TraceToIRConversionPhase.cpp | 19 +- .../phases/TraceToIRConversionPhase.hpp | 3 + .../test/execution-tests/CastFunctions.hpp | 179 ++++++++++ .../test/execution-tests/ExecutionTest.cpp | 62 +++- .../execution-tests/ExpressionFunctions.hpp | 49 +++ 31 files changed, 1148 insertions(+), 167 deletions(-) rename nautilus/src/nautilus/compiler/ir/operations/{LogicalOperations => BinaryOperations}/NegateOperation.cpp (57%) rename nautilus/src/nautilus/compiler/ir/operations/{LogicalOperations => BinaryOperations}/NegateOperation.hpp (100%) create mode 100644 nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.cpp create mode 100644 nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.hpp create mode 100644 nautilus/test/execution-tests/CastFunctions.hpp diff --git a/nautilus/include/nautilus/Executable.hpp b/nautilus/include/nautilus/Executable.hpp index ac5c974b..780f23b5 100644 --- a/nautilus/include/nautilus/Executable.hpp +++ b/nautilus/include/nautilus/Executable.hpp @@ -77,6 +77,9 @@ class Executable { if constexpr (!std::is_void_v) { std::vector inputs_ = {getGenericArg(arguments)...}; auto res = genericFunction->invokeGeneric(inputs_); + if (std::is_same_v) { + return std::any_cast(res); + } return std::any_cast(res); } else { std::vector inputs_ = {getGenericArg(arguments)...}; diff --git a/nautilus/include/nautilus/common/traceing.hpp b/nautilus/include/nautilus/common/traceing.hpp index 8e9f2f38..004f3fe3 100644 --- a/nautilus/include/nautilus/common/traceing.hpp +++ b/nautilus/include/nautilus/common/traceing.hpp @@ -42,6 +42,7 @@ enum Op : uint8_t { LSH, RSH, BOR, + BXOR, BAND, NEGATE, }; @@ -93,7 +94,7 @@ constexpr Type to_type() { using type = std::remove_cvref_t; if constexpr (std::is_same_v) { return Type::b; - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v || (std::is_same_v)) { return Type::i8; } else if constexpr (std::is_same_v) { return Type::i16; @@ -162,7 +163,8 @@ value_ref traceCast(value_ref state, Type resultType); std::array& getVarRefMap(); -value_ref traceCall(const std::string& functionName, void* fptn, Type resultType, std::vector arguments); +value_ref traceCall(const std::string& functionName, void* fptn, Type resultType, + std::vector arguments); std::ostream& operator<<(std::ostream& os, const Op& operation); diff --git a/nautilus/include/nautilus/val.hpp b/nautilus/include/nautilus/val.hpp index d0b1187b..6fee93c3 100644 --- a/nautilus/include/nautilus/val.hpp +++ b/nautilus/include/nautilus/val.hpp @@ -77,7 +77,7 @@ template auto shr(val& left, val& right); template -auto neg(val& val); +val neg(val& val); template tracing::value_ref getState(T&& value) { @@ -425,15 +425,17 @@ DEFINE_BINARY_OPERATOR_HELPER(&, bAnd, BAND, COMMON_RETURN_TYPE) DEFINE_BINARY_OPERATOR_HELPER(|, bOr, BOR, COMMON_RETURN_TYPE) -DEFINE_BINARY_OPERATOR_HELPER(^, bXOr, BOR, COMMON_RETURN_TYPE) +DEFINE_BINARY_OPERATOR_HELPER(^, bXOr, BXOR, COMMON_RETURN_TYPE) template -val inline neg(val& val) { +val neg(val& val) { +#ifdef ENABLE_TRACING if (tracing::inTracer()) { auto tc = traceUnaryOp(val.state); return tc; } - return ~val.value; +#endif + return ~getRawValue(val); } template diff --git a/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp b/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp index e746d9ac..8bf628a5 100644 --- a/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp +++ b/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp @@ -111,89 +111,265 @@ void dyncallCalld(const OpCode& op, RegisterFile& regs) { static Operation* OpTable[] = { (Operation*) regMov, // add - (Operation*) add, (Operation*) add, (Operation*) add, (Operation*) add, - (Operation*) add, (Operation*) add, (Operation*) add, (Operation*) add, - (Operation*) add, (Operation*) add, + (Operation*) add, + (Operation*) add, + (Operation*) add, + (Operation*) add, + (Operation*) add, + (Operation*) add, + (Operation*) add, + (Operation*) add, + (Operation*) add, + (Operation*) add, // sub - (Operation*) sub, (Operation*) sub, (Operation*) sub, (Operation*) sub, - (Operation*) sub, (Operation*) sub, (Operation*) sub, (Operation*) sub, - (Operation*) sub, (Operation*) sub, + (Operation*) sub, + (Operation*) sub, + (Operation*) sub, + (Operation*) sub, + (Operation*) sub, + (Operation*) sub, + (Operation*) sub, + (Operation*) sub, + (Operation*) sub, + (Operation*) sub, // mul - (Operation*) mul, (Operation*) mul, (Operation*) mul, (Operation*) mul, - (Operation*) mul, (Operation*) mul, (Operation*) mul, (Operation*) mul, - (Operation*) mul, (Operation*) mul, + (Operation*) mul, + (Operation*) mul, + (Operation*) mul, + (Operation*) mul, + (Operation*) mul, + (Operation*) mul, + (Operation*) mul, + (Operation*) mul, + (Operation*) mul, + (Operation*) mul, // div - (Operation*) div, (Operation*) div, (Operation*) div, (Operation*) div, - (Operation*) div, (Operation*) div, (Operation*) div, (Operation*) div, - (Operation*) div, (Operation*) div, + (Operation*) div, + (Operation*) div, + (Operation*) div, + (Operation*) div, + (Operation*) div, + (Operation*) div, + (Operation*) div, + (Operation*) div, + (Operation*) div, + (Operation*) div, // mod - (Operation*) mod, (Operation*) mod, (Operation*) mod, (Operation*) mod, - (Operation*) mod, (Operation*) mod, (Operation*) mod, (Operation*) mod, + (Operation*) mod, + (Operation*) mod, + (Operation*) mod, + (Operation*) mod, + (Operation*) mod, + (Operation*) mod, + (Operation*) mod, + (Operation*) mod, // equals - (Operation*) equals, (Operation*) equals, (Operation*) equals, - (Operation*) equals, (Operation*) equals, (Operation*) equals, - (Operation*) equals, (Operation*) equals, (Operation*) equals, - (Operation*) equals, (Operation*) equals, + (Operation*) equals, + (Operation*) equals, + (Operation*) equals, + (Operation*) equals, + (Operation*) equals, + (Operation*) equals, + (Operation*) equals, + (Operation*) equals, + (Operation*) equals, + (Operation*) equals, + (Operation*) equals, // less than - (Operation*) lessThan, (Operation*) lessThan, (Operation*) lessThan, - (Operation*) lessThan, (Operation*) lessThan, (Operation*) lessThan, - (Operation*) lessThan, (Operation*) lessThan, (Operation*) lessThan, + (Operation*) lessThan, + (Operation*) lessThan, + (Operation*) lessThan, + (Operation*) lessThan, + (Operation*) lessThan, + (Operation*) lessThan, + (Operation*) lessThan, + (Operation*) lessThan, + (Operation*) lessThan, (Operation*) lessThan, // less than equals - (Operation*) lessThanEquals, (Operation*) lessThanEquals, (Operation*) lessThanEquals, - (Operation*) lessThanEquals, (Operation*) lessThanEquals, (Operation*) lessThanEquals, - (Operation*) lessThanEquals, (Operation*) lessThanEquals, (Operation*) lessThanEquals, + (Operation*) lessThanEquals, + (Operation*) lessThanEquals, + (Operation*) lessThanEquals, + (Operation*) lessThanEquals, + (Operation*) lessThanEquals, + (Operation*) lessThanEquals, + (Operation*) lessThanEquals, + (Operation*) lessThanEquals, + (Operation*) lessThanEquals, (Operation*) lessThanEquals, // greater than - (Operation*) greaterThan, (Operation*) greaterThan, (Operation*) greaterThan, - (Operation*) greaterThan, (Operation*) greaterThan, (Operation*) greaterThan, - (Operation*) greaterThan, (Operation*) greaterThan, (Operation*) greaterThan, + (Operation*) greaterThan, + (Operation*) greaterThan, + (Operation*) greaterThan, + (Operation*) greaterThan, + (Operation*) greaterThan, + (Operation*) greaterThan, + (Operation*) greaterThan, + (Operation*) greaterThan, + (Operation*) greaterThan, (Operation*) greaterThan, // greater than equals - (Operation*) greaterThanEquals, (Operation*) greaterThanEquals, - (Operation*) greaterThanEquals, (Operation*) greaterThanEquals, - (Operation*) greaterThanEquals, (Operation*) greaterThanEquals, - (Operation*) greaterThanEquals, (Operation*) greaterThanEquals, - (Operation*) greaterThanEquals, (Operation*) greaterThanEquals, + (Operation*) greaterThanEquals, + (Operation*) greaterThanEquals, + (Operation*) greaterThanEquals, + (Operation*) greaterThanEquals, + (Operation*) greaterThanEquals, + (Operation*) greaterThanEquals, + (Operation*) greaterThanEquals, + (Operation*) greaterThanEquals, + (Operation*) greaterThanEquals, + (Operation*) greaterThanEquals, // not equals - (Operation*) notEquals, (Operation*) notEquals, (Operation*) notEquals, - (Operation*) notEquals, (Operation*) notEquals, (Operation*) notEquals, - (Operation*) notEquals, (Operation*) notEquals, (Operation*) notEquals, - (Operation*) notEquals, (Operation*) notEquals, + (Operation*) notEquals, + (Operation*) notEquals, + (Operation*) notEquals, + (Operation*) notEquals, + (Operation*) notEquals, + (Operation*) notEquals, + (Operation*) notEquals, + (Operation*) notEquals, + (Operation*) notEquals, + (Operation*) notEquals, + (Operation*) notEquals, // load - (Operation*) load, (Operation*) load, (Operation*) load, (Operation*) load, - (Operation*) load, (Operation*) load, (Operation*) load, (Operation*) load, - (Operation*) load, (Operation*) load, (Operation*) load, + (Operation*) load, + (Operation*) load, + (Operation*) load, + (Operation*) load, + (Operation*) load, + (Operation*) load, + (Operation*) load, + (Operation*) load, + (Operation*) load, + (Operation*) load, + (Operation*) load, // store - (Operation*) store, (Operation*) store, (Operation*) store, (Operation*) store, - (Operation*) store, (Operation*) store, (Operation*) store, - (Operation*) store, (Operation*) store, (Operation*) store, (Operation*) store, + (Operation*) store, + (Operation*) store, + (Operation*) store, + (Operation*) store, + (Operation*) store, + (Operation*) store, + (Operation*) store, + (Operation*) store, + (Operation*) store, + (Operation*) store, + (Operation*) store, // and - (Operation*) andOp, (Operation*) orOp, (Operation*) notOp, + (Operation*) andOp, + (Operation*) orOp, + (Operation*) notOp, // Casts // int to int - (Operation*) cast, (Operation*) cast, (Operation*) cast, - (Operation*) cast, (Operation*) cast, (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, // uint to int - (Operation*) cast, (Operation*) cast, (Operation*) cast, - (Operation*) cast, (Operation*) cast, (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, // uint to uint - (Operation*) cast, (Operation*) cast, (Operation*) cast, - (Operation*) cast, (Operation*) cast, (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, // int to uint - (Operation*) cast, (Operation*) cast, (Operation*) cast, - (Operation*) cast, (Operation*) cast, (Operation*) cast, - (Operation*) cast, (Operation*) cast, (Operation*) cast, - (Operation*) cast, (Operation*) cast, (Operation*) cast, - (Operation*) cast, (Operation*) cast, (Operation*) cast, - (Operation*) cast, (Operation*) cast, (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, + (Operation*) cast, (Operation*) cast, // FUNCTION CALLS - (Operation*) dyncallReset, (Operation*) dyncallArgB, (Operation*) dyncallArgI8, (Operation*) dyncallArgI16, - (Operation*) dyncallArgI32, (Operation*) dyncallArgI64, (Operation*) dyncallArgF, (Operation*) dyncallArgD, - (Operation*) dyncallArgPtr, (Operation*) dyncallCallV, (Operation*) dyncallCallB, (Operation*) dyncallCallI8, - (Operation*) dyncallCallI16, (Operation*) dyncallCallI32, (Operation*) dyncallCallI64, (Operation*) dyncallCallPtr, - (Operation*) dyncallCallf, (Operation*) dyncallCalld}; + (Operation*) dyncallReset, + (Operation*) dyncallArgB, + (Operation*) dyncallArgI8, + (Operation*) dyncallArgI16, + (Operation*) dyncallArgI32, + (Operation*) dyncallArgI64, + (Operation*) dyncallArgF, + (Operation*) dyncallArgD, + (Operation*) dyncallArgPtr, + (Operation*) dyncallCallV, + (Operation*) dyncallCallB, + (Operation*) dyncallCallI8, + (Operation*) dyncallCallI16, + (Operation*) dyncallCallI32, + (Operation*) dyncallCallI64, + (Operation*) dyncallCallPtr, + (Operation*) dyncallCallf, + (Operation*) dyncallCalld, + // BITWISE OPS + // band + (Operation*) bitwiseAnd, + (Operation*) bitwiseAnd, + (Operation*) bitwiseAnd, + (Operation*) bitwiseAnd, + (Operation*) bitwiseAnd, + (Operation*) bitwiseAnd, + (Operation*) bitwiseAnd, + (Operation*) bitwiseAnd, + // bor + (Operation*) bitwiseOr, + (Operation*) bitwiseOr, + (Operation*) bitwiseOr, + (Operation*) bitwiseOr, + (Operation*) bitwiseOr, + (Operation*) bitwiseOr, + (Operation*) bitwiseOr, + (Operation*) bitwiseOr, + // bxor + (Operation*) bitwiseXOr, + (Operation*) bitwiseXOr, + (Operation*) bitwiseXOr, + (Operation*) bitwiseXOr, + (Operation*) bitwiseXOr, + (Operation*) bitwiseXOr, + (Operation*) bitwiseXOr, + (Operation*) bitwiseXOr, + // blsh + (Operation*) bitwiseLSH, + (Operation*) bitwiseLSH, + (Operation*) bitwiseLSH, + (Operation*) bitwiseLSH, + (Operation*) bitwiseLSH, + (Operation*) bitwiseLSH, + (Operation*) bitwiseLSH, + (Operation*) bitwiseLSH, + // brsh + (Operation*) bitwiseRSH, + (Operation*) bitwiseRSH, + (Operation*) bitwiseRSH, + (Operation*) bitwiseRSH, + (Operation*) bitwiseRSH, + (Operation*) bitwiseRSH, + (Operation*) bitwiseRSH, + (Operation*) bitwiseRSH, + // bnot + (Operation*) bitwiseNot, + +}; FunctionCallTarget::FunctionCallTarget(std::vector> arguments, void* functionPtr) : arguments(std::move(arguments)), functionPtr(functionPtr) { @@ -252,6 +428,10 @@ std::any BCInterpreter::invokeGeneric(const std::vector& args) { writeReg<>(registerFile, code.arguments[i], *value); } else if (auto* value = std::any_cast(&args[i])) { writeReg<>(registerFile, code.arguments[i], *value); + } else if (auto* value = std::any_cast(&args[i])) { + writeReg<>(registerFile, code.arguments[i], *value); + } else if (auto* value = std::any_cast(&args[i])) { + writeReg<>(registerFile, code.arguments[i], *value); } else if (auto* value = std::any_cast(&args[i])) { auto val = (int64_t) *value; registerFile[code.arguments[i]] = val; @@ -338,24 +518,18 @@ std::ostream& operator<<(std::ostream& os, const CodeBlock& block) { // handle terminator if (const auto* res = std::get_if(&block.terminatorOp)) { - os << "\t" - << "BR " << res->nextBlock << "\n"; + os << "\t" << "BR " << res->nextBlock << "\n"; } else if (const auto* res = std::get_if(&block.terminatorOp)) { - os << "\t" - << "CMP " - << "r" << res->conditionalReg << " " << res->trueBlock << " " << res->falseBlock << "\n"; + os << "\t" << "CMP " << "r" << res->conditionalReg << " " << res->trueBlock << " " << res->falseBlock << "\n"; } else if (const auto* res = std::get_if(&block.terminatorOp)) { - os << "\t" - << "Return " - << "r" << res->resultReg << "\n"; + os << "\t" << "Return " << "r" << res->resultReg << "\n"; } return os; } std::ostream& operator<<(std::ostream& os, const OpCode& code) { // auto str = std::string(code.op); - os << "str" - << " r" << code.reg1; + os << "str" << " r" << code.reg1; if (code.reg2 != -1) { os << " r" << code.reg2; } diff --git a/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp index 2eb59098..0e64f129 100644 --- a/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp @@ -720,6 +720,228 @@ void BCLoweringProvider::LoweringContext::process(ir::StoreOperation* storeOp, s program.blocks[block].code.emplace_back(oc); } +void BCLoweringProvider::LoweringContext::process(ir::BinaryCompOperation* binaryCompOperation, short block, + RegisterFrame& frame) { + auto leftReg = frame.getValue(binaryCompOperation->getLeftInput()->getIdentifier()); + auto rightReg = frame.getValue(binaryCompOperation->getRightInput()->getIdentifier()); + auto resultReg = getResultRegister(binaryCompOperation, frame); + frame.setValue(binaryCompOperation->getIdentifier(), resultReg); + auto type = binaryCompOperation->getStamp(); + auto opType = binaryCompOperation->getType(); + ByteCode bc = ByteCode::BLSH_i8; + switch ((type)) { + case Type::i8: + switch (opType) { + case ir::BinaryCompOperation::BAND: + bc = ByteCode::BAND_i8; + break; + case ir::BinaryCompOperation::BOR: + bc = ByteCode::BOR_i8; + break; + case ir::BinaryCompOperation::XOR: + bc = ByteCode::BXOR_i8; + break; + } + break; + case Type::i16: + switch (opType) { + case ir::BinaryCompOperation::BAND: + bc = ByteCode::BAND_i16; + break; + case ir::BinaryCompOperation::BOR: + bc = ByteCode::BOR_i16; + break; + case ir::BinaryCompOperation::XOR: + bc = ByteCode::BXOR_i16; + break; + } + break; + case Type::i32: + switch (opType) { + case ir::BinaryCompOperation::BAND: + bc = ByteCode::BAND_i32; + break; + case ir::BinaryCompOperation::BOR: + bc = ByteCode::BOR_i32; + break; + case ir::BinaryCompOperation::XOR: + bc = ByteCode::BXOR_i32; + break; + } + break; + case Type::i64: + switch (opType) { + case ir::BinaryCompOperation::BAND: + bc = ByteCode::BAND_i64; + break; + case ir::BinaryCompOperation::BOR: + bc = ByteCode::BOR_i64; + break; + case ir::BinaryCompOperation::XOR: + bc = ByteCode::BXOR_i64; + break; + } + break; + case Type::ui8: + switch (opType) { + case ir::BinaryCompOperation::BAND: + bc = ByteCode::BAND_ui8; + break; + case ir::BinaryCompOperation::BOR: + bc = ByteCode::BOR_ui8; + break; + case ir::BinaryCompOperation::XOR: + bc = ByteCode::BXOR_ui8; + break; + } + break; + case Type::ui16: + switch (opType) { + case ir::BinaryCompOperation::BAND: + bc = ByteCode::BAND_ui16; + break; + case ir::BinaryCompOperation::BOR: + bc = ByteCode::BOR_ui16; + break; + case ir::BinaryCompOperation::XOR: + bc = ByteCode::BXOR_ui16; + break; + } + break; + case Type::ui32: + switch (opType) { + case ir::BinaryCompOperation::BAND: + bc = ByteCode::BAND_ui32; + break; + case ir::BinaryCompOperation::BOR: + bc = ByteCode::BOR_ui32; + break; + case ir::BinaryCompOperation::XOR: + bc = ByteCode::BXOR_ui32; + break; + } + break; + case Type::ui64: + switch (opType) { + case ir::BinaryCompOperation::BAND: + bc = ByteCode::BAND_ui64; + break; + case ir::BinaryCompOperation::BOR: + bc = ByteCode::BOR_ui64; + break; + case ir::BinaryCompOperation::XOR: + bc = ByteCode::BXOR_ui64; + break; + } + break; + default: { + throw NotImplementedException("This type is not supported."); + } + } + + OpCode oc = {bc, leftReg, rightReg, resultReg}; + program.blocks[block].code.emplace_back(oc); +} + +void BCLoweringProvider::LoweringContext::process(ir::ShiftOperation* shiftOperation, short block, + RegisterFrame& frame) { + auto leftReg = frame.getValue(shiftOperation->getLeftInput()->getIdentifier()); + auto rightReg = frame.getValue(shiftOperation->getRightInput()->getIdentifier()); + auto resultReg = getResultRegister(shiftOperation, frame); + frame.setValue(shiftOperation->getIdentifier(), resultReg); + auto type = shiftOperation->getStamp(); + auto opType = shiftOperation->getType(); + ByteCode bc = ByteCode::BLSH_i8; + switch ((type)) { + case Type::i8: + switch (opType) { + case ir::ShiftOperation::LS: + bc = ByteCode::BLSH_i8; + break; + case ir::ShiftOperation::RS: + bc = ByteCode::BRSH_i8; + break; + } + break; + case Type::i16: + switch (opType) { + case ir::ShiftOperation::LS: + bc = ByteCode::BLSH_i16; + break; + case ir::ShiftOperation::RS: + bc = ByteCode::BRSH_i16; + break; + } + break; + case Type::i32: + switch (opType) { + case ir::ShiftOperation::LS: + bc = ByteCode::BLSH_i32; + break; + case ir::ShiftOperation::RS: + bc = ByteCode::BRSH_i32; + break; + } + break; + case Type::i64: + switch (opType) { + case ir::ShiftOperation::LS: + bc = ByteCode::BLSH_i64; + break; + case ir::ShiftOperation::RS: + bc = ByteCode::BRSH_i64; + break; + } + break; + case Type::ui8: + switch (opType) { + case ir::ShiftOperation::LS: + bc = ByteCode::BLSH_ui8; + break; + case ir::ShiftOperation::RS: + bc = ByteCode::BRSH_ui8; + break; + } + break; + case Type::ui16: + switch (opType) { + case ir::ShiftOperation::LS: + bc = ByteCode::BLSH_ui16; + break; + case ir::ShiftOperation::RS: + bc = ByteCode::BRSH_ui16; + break; + } + break; + case Type::ui32: + switch (opType) { + case ir::ShiftOperation::LS: + bc = ByteCode::BLSH_ui32; + break; + case ir::ShiftOperation::RS: + bc = ByteCode::BRSH_ui32; + break; + } + break; + case Type::ui64: + switch (opType) { + case ir::ShiftOperation::LS: + bc = ByteCode::BLSH_ui64; + break; + case ir::ShiftOperation::RS: + bc = ByteCode::BRSH_ui64; + break; + } + break; + default: { + throw NotImplementedException("This type is not supported."); + } + } + + OpCode oc = {bc, leftReg, rightReg, resultReg}; + program.blocks[block].code.emplace_back(oc); +} + void BCLoweringProvider::LoweringContext::process(ir::BasicBlockInvocation& bi, short block, RegisterFrame& parentFrame) { auto blockInputArguments = bi.getArguments(); @@ -773,7 +995,7 @@ void BCLoweringProvider::LoweringContext::process(const std::unique_ptr(opt); auto defaultRegister = registerProvider.allocRegister(); - defaultRegisterFile[defaultRegister] = (int64_t)constPtr->getValue(); + defaultRegisterFile[defaultRegister] = (int64_t) constPtr->getValue(); auto targetRegister = registerProvider.allocRegister(); frame.setValue(constPtr->getIdentifier(), targetRegister); @@ -899,6 +1121,11 @@ void BCLoweringProvider::LoweringContext::process(const std::unique_ptr(opt); + process(call, block, frame); + return; + } case ir::Operation::OperationType::CastOp: { auto cast = as(opt); process(cast, block, frame); @@ -909,6 +1136,16 @@ void BCLoweringProvider::LoweringContext::process(const std::unique_ptr(opt); + process(cast, block, frame); + return; + } + case ir::Operation::OperationType::ShiftOp: { + auto cast = as(opt); + process(cast, block, frame); + return; + } default: { throw NotImplementedException("This type is not supported."); @@ -1040,7 +1277,7 @@ void BCLoweringProvider::LoweringContext::processDynamicCall(ir::ProxyCallOperat } } -void BCLoweringProvider::LoweringContext::process(ir::NegateOperation* negateOperation, short block, +void BCLoweringProvider::LoweringContext::process(ir::NotOperation* negateOperation, short block, RegisterFrame& frame) { auto input = frame.getValue(negateOperation->getInput()->getIdentifier()); auto resultReg = getResultRegister(negateOperation, frame); @@ -1050,6 +1287,16 @@ void BCLoweringProvider::LoweringContext::process(ir::NegateOperation* negateOpe program.blocks[block].code.emplace_back(oc); } +void BCLoweringProvider::LoweringContext::process(ir::NegateOperation* negateOperation, short block, + RegisterFrame& frame) { + auto input = frame.getValue(negateOperation->getInput()->getIdentifier()); + auto resultReg = getResultRegister(negateOperation, frame); + frame.setValue(negateOperation->getIdentifier(), resultReg); + ByteCode bc = ByteCode::BNEGATE_I64; + OpCode oc = {bc, input, -1, resultReg}; + program.blocks[block].code.emplace_back(oc); +} + void BCLoweringProvider::LoweringContext::process(ir::CastOperation* castOp, short block, RegisterFrame& frame) { auto input = frame.getValue(castOp->getInput()->getIdentifier()); auto resultReg = getResultRegister(castOp, frame); diff --git a/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.hpp b/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.hpp index 9297351d..3df71990 100644 --- a/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.hpp +++ b/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.hpp @@ -9,18 +9,21 @@ #include "nautilus/compiler/ir/operations/ArithmeticOperations/ModOperation.hpp" #include "nautilus/compiler/ir/operations/ArithmeticOperations/MulOperation.hpp" #include "nautilus/compiler/ir/operations/ArithmeticOperations/SubOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.hpp" #include "nautilus/compiler/ir/operations/BranchOperation.hpp" #include "nautilus/compiler/ir/operations/CastOperation.hpp" #include "nautilus/compiler/ir/operations/ConstBooleanOperation.hpp" #include "nautilus/compiler/ir/operations/ConstFloatOperation.hpp" -#include "nautilus/compiler/ir/operations/ConstPtrOperation.hpp" #include "nautilus/compiler/ir/operations/ConstIntOperation.hpp" +#include "nautilus/compiler/ir/operations/ConstPtrOperation.hpp" #include "nautilus/compiler/ir/operations/FunctionOperation.hpp" #include "nautilus/compiler/ir/operations/IfOperation.hpp" #include "nautilus/compiler/ir/operations/LoadOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/AndOperation.hpp" +#include "nautilus/compiler/ir/operations/LogicalOperations/NotOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.hpp" -#include "nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/OrOperation.hpp" #include "nautilus/compiler/ir/operations/Operation.hpp" #include "nautilus/compiler/ir/operations/ProxyCallOperation.hpp" @@ -98,8 +101,11 @@ class BCLoweringProvider { void process(ir::AndOperation* opt, short block, RegisterFrame& frame); void process(ir::NegateOperation* opt, short block, RegisterFrame& frame); + void process(ir::NotOperation* opt, short block, RegisterFrame& frame); void process(ir::CastOperation* opt, short block, RegisterFrame& frame); + void process(ir::BinaryCompOperation* opt, short block, RegisterFrame& frame); + void process(ir::ShiftOperation* opt, short block, RegisterFrame& frame); void processDynamicCall(ir::ProxyCallOperation* opt, short block, RegisterFrame& frame); diff --git a/nautilus/src/nautilus/compiler/backends/bc/ByteCode.hpp b/nautilus/src/nautilus/compiler/backends/bc/ByteCode.hpp index 7d959b63..7e8073d1 100644 --- a/nautilus/src/nautilus/compiler/backends/bc/ByteCode.hpp +++ b/nautilus/src/nautilus/compiler/backends/bc/ByteCode.hpp @@ -230,7 +230,54 @@ enum class ByteCode : short { DYNCALL_call_i64, DYNCALL_call_ptr, DYNCALL_call_f, - DYNCALL_call_d + DYNCALL_call_d, + // band + BAND_i8, + BAND_i16, + BAND_i32, + BAND_i64, + BAND_ui8, + BAND_ui16, + BAND_ui32, + BAND_ui64, + // bor + BOR_i8, + BOR_i16, + BOR_i32, + BOR_i64, + BOR_ui8, + BOR_ui16, + BOR_ui32, + BOR_ui64, + // bxor + BXOR_i8, + BXOR_i16, + BXOR_i32, + BXOR_i64, + BXOR_ui8, + BXOR_ui16, + BXOR_ui32, + BXOR_ui64, + // blsh + BLSH_i8, + BLSH_i16, + BLSH_i32, + BLSH_i64, + BLSH_ui8, + BLSH_ui16, + BLSH_ui32, + BLSH_ui64, + // brsh + BRSH_i8, + BRSH_i16, + BRSH_i32, + BRSH_i64, + BRSH_ui8, + BRSH_ui16, + BRSH_ui32, + BRSH_ui64, + // negate + BNEGATE_I64, }; /** @@ -499,6 +546,47 @@ void cast(const OpCode& c, RegisterFile& regs) { writeReg(regs, c.output, value); } +template +void bitwiseAnd(const OpCode& c, RegisterFile& regs) { + auto l = readReg(regs, c.reg1); + auto r = readReg(regs, c.reg2); + writeReg(regs, c.output, l & r); +} + +template +void bitwiseOr(const OpCode& c, RegisterFile& regs) { + auto l = readReg(regs, c.reg1); + auto r = readReg(regs, c.reg2); + writeReg(regs, c.output, l | r); +} + +template +void bitwiseXOr(const OpCode& c, RegisterFile& regs) { + auto l = readReg(regs, c.reg1); + auto r = readReg(regs, c.reg2); + writeReg(regs, c.output, l ^ r); +} + +template +void bitwiseLSH(const OpCode& c, RegisterFile& regs) { + auto l = readReg(regs, c.reg1); + auto r = readReg(regs, c.reg2); + writeReg(regs, c.output, l << r); +} + +template +void bitwiseRSH(const OpCode& c, RegisterFile& regs) { + auto l = readReg(regs, c.reg1); + auto r = readReg(regs, c.reg2); + writeReg(regs, c.output, l >> r); +} + +template +void bitwiseNot(const OpCode& c, RegisterFile& regs) { + auto l = readReg(regs, c.reg1); + writeReg(regs, c.output, ~l); +} + /** * @brief Defines a final branch terminator operation */ diff --git a/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp index 423524cd..da5a9c9b 100644 --- a/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp @@ -201,8 +201,7 @@ void CPPLoweringProvider::LoweringContext::process(ir::BasicBlockInvocation& bi, blockArguments << getType(blockTargetArguments[i]->getStamp()) << " " << var << ";\n"; } - blocks[blockIndex] << parentFrame.getValue(blockTargetArgument) << " = " - << "temp_" << i << ";\n"; + blocks[blockIndex] << parentFrame.getValue(blockTargetArgument) << " = " << "temp_" << i << ";\n"; } blocks[blockIndex] << "}\n"; } @@ -265,6 +264,30 @@ void CPPLoweringProvider::LoweringContext::process(const std::unique_ptr(opt, "%", blockIndex, frame); return; } + case ir::Operation::OperationType::ShiftOp: { + auto op = static_cast(opt.get()); + if (op->getType() == ir::ShiftOperation::LS) { + processBinary(opt, "<<", blockIndex, frame); + } else { + processBinary(opt, ">>", blockIndex, frame); + } + return; + } + case ir::Operation::OperationType::BinaryComp: { + auto op = static_cast(opt.get()); + switch (op->getType()) { + case ir::BinaryCompOperation::BAND: + processBinary(opt, "&", blockIndex, frame); + break; + case ir::BinaryCompOperation::BOR: + processBinary(opt, "|", blockIndex, frame); + break; + case ir::BinaryCompOperation::XOR: + processBinary(opt, "^", blockIndex, frame); + break; + } + return; + } case ir::Operation::OperationType::ReturnOp: { auto returnOpt = static_cast(opt.get()); if (returnOpt->hasReturnValue()) { @@ -322,6 +345,11 @@ void CPPLoweringProvider::LoweringContext::process(const std::unique_ptr(opt); + process(call, blockIndex, frame); + return; + } case ir::Operation::OperationType::CastOp: { auto cast = as(opt); process(cast, blockIndex, frame); @@ -351,8 +379,8 @@ void CPPLoweringProvider::LoweringContext::process(ir::ProxyCallOperation* opt, argTypes << getType(arg->getStamp()); } if (!functionNames.contains(opt->getFunctionSymbol())) { - functions << "auto " << opt->getFunctionSymbol() << " = " - << "(" << returnType << "(*)(" << argTypes.str() << "))" << opt->getFunctionPtr() << ";\n"; + functions << "auto " << opt->getFunctionSymbol() << " = " << "(" << returnType << "(*)(" << argTypes.str() + << "))" << opt->getFunctionPtr() << ";\n"; functionNames.emplace(opt->getFunctionSymbol()); } if (opt->getStamp() != Type::v) { @@ -370,6 +398,15 @@ void CPPLoweringProvider::LoweringContext::process(ir::NegateOperation* negateOp auto resultVar = getVariable(negateOperation->getIdentifier()); blockArguments << getType(negateOperation->getStamp()) << " " << resultVar << ";\n"; frame.setValue(negateOperation->getIdentifier(), resultVar); + blocks[blockIndex] << resultVar << "= ~" << input << ";\n"; +} + +void CPPLoweringProvider::LoweringContext::process(ir::NotOperation* notOperation, short blockIndex, + RegisterFrame& frame) { + auto input = frame.getValue(notOperation->getInput()->getIdentifier()); + auto resultVar = getVariable(notOperation->getIdentifier()); + blockArguments << getType(notOperation->getStamp()) << " " << resultVar << ";\n"; + frame.setValue(notOperation->getIdentifier(), resultVar); blocks[blockIndex] << resultVar << "= !" << input << ";\n"; } diff --git a/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.hpp b/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.hpp index bdefbf60..334e0f7e 100644 --- a/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.hpp +++ b/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.hpp @@ -8,6 +8,9 @@ #include "nautilus/compiler/ir/operations/ArithmeticOperations/ModOperation.hpp" #include "nautilus/compiler/ir/operations/ArithmeticOperations/MulOperation.hpp" #include "nautilus/compiler/ir/operations/ArithmeticOperations/SubOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.hpp" #include "nautilus/compiler/ir/operations/BranchOperation.hpp" #include "nautilus/compiler/ir/operations/CastOperation.hpp" #include "nautilus/compiler/ir/operations/ConstBooleanOperation.hpp" @@ -18,7 +21,7 @@ #include "nautilus/compiler/ir/operations/LoadOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/AndOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.hpp" -#include "nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.hpp" +#include "nautilus/compiler/ir/operations/LogicalOperations/NotOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/OrOperation.hpp" #include "nautilus/compiler/ir/operations/Operation.hpp" #include "nautilus/compiler/ir/operations/ProxyCallOperation.hpp" @@ -77,8 +80,11 @@ class CPPLoweringProvider { void process(ir::ProxyCallOperation* opt, short block, RegisterFrame& frame); void process(ir::NegateOperation* opt, short block, RegisterFrame& frame); + void process(ir::NotOperation* opt, short block, RegisterFrame& frame); void process(ir::CastOperation* opt, short block, RegisterFrame& frame); + void process(ir::BinaryCompOperation* opt, short block, RegisterFrame& frame); + void process(ir::ShiftOperation* opt, short block, RegisterFrame& frame); static std::string getVariable(const ir::OperationIdentifier& id); diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp index 17b14f5d..f1d9d742 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp @@ -275,12 +275,21 @@ void MLIRLoweringProvider::generateMLIR(const std::unique_ptr& op case ir::Operation::OperationType::NegateOp: generateMLIR(as(operation), frame); break; + case ir::Operation::OperationType::NotOp: + generateMLIR(as(operation), frame); + break; case ir::Operation::OperationType::CastOp: generateMLIR(as(operation), frame); break; case ir::Operation::OperationType::ConstBooleanOp: generateMLIR(as(operation), frame); break; + case ir::Operation::OperationType::BinaryComp: + generateMLIR(as(operation), frame); + break; + case ir::Operation::OperationType::ShiftOp: + generateMLIR(as(operation), frame); + break; default: { throw NotImplementedException(""); } @@ -289,14 +298,17 @@ void MLIRLoweringProvider::generateMLIR(const std::unique_ptr& op void MLIRLoweringProvider::generateMLIR(ir::NegateOperation* negateOperation, ValueFrame& frame) { auto input = frame.getValue(negateOperation->getInput()->getIdentifier()); - auto negate = builder->create(getNameLoc("comparison"), mlir::arith::CmpIPredicate::eq, input, - getConstBool("bool", false)); - frame.setValue(negateOperation-> - - getIdentifier(), - negate + auto constInt = builder->create(getNameLoc("location"), input.getType(), + builder->getIntegerAttr(input.getType(), ~0)); + auto negate = builder->create(getNameLoc("comparison"), input, constInt); + frame.setValue(negateOperation->getIdentifier(), negate); +} - ); +void MLIRLoweringProvider::generateMLIR(ir::NotOperation* notOperation, ValueFrame& frame) { + auto input = frame.getValue(notOperation->getInput()->getIdentifier()); + auto constInt = getConstBool("loc", true); + auto negate = builder->create(getNameLoc("comparison"), input, constInt); + frame.setValue(notOperation->getIdentifier(), negate); } void MLIRLoweringProvider::generateMLIR(ir::OrOperation* orOperation, ValueFrame& frame) { @@ -354,21 +366,8 @@ void MLIRLoweringProvider::generateMLIR(ir::FunctionOperation* functionOp, Value // Store references to function args in the valueMap map. auto valueMapIterator = mlirFunction.args_begin(); - for (int i = 0; - - i < (int) - - functionOp->getFunctionBasicBlock() - ->getArguments() - . - - size(); - - ++i) { - frame.setValue(functionOp->getFunctionBasicBlock()->getArguments().at(i)-> - - getIdentifier(), - valueMapIterator[i] + for (int i = 0; i < (int) functionOp->getFunctionBasicBlock()->getArguments().size(); ++i) { + frame.setValue(functionOp->getFunctionBasicBlock()->getArguments().at(i)->getIdentifier(), valueMapIterator[i] ); } @@ -727,6 +726,43 @@ void MLIRLoweringProvider::generateMLIR(ir::CastOperation* castOperation, MLIRLo } } +void MLIRLoweringProvider::generateMLIR(ir::BinaryCompOperation* binaryCompOperation, + nautilus::compiler::mlir::MLIRLoweringProvider::ValueFrame& frame) { + auto leftInput = frame.getValue(binaryCompOperation->getLeftInput()->getIdentifier()); + auto rightInput = frame.getValue(binaryCompOperation->getRightInput()->getIdentifier()); + + mlir::Value op; + switch (binaryCompOperation->getType()) { + case ir::BinaryCompOperation::BAND: + op = builder->create(getNameLoc("location"), leftInput, rightInput); + break; + case ir::BinaryCompOperation::BOR: + op = builder->create(getNameLoc("location"), leftInput, rightInput); + break; + case ir::BinaryCompOperation::XOR: + op = builder->create(getNameLoc("location"), leftInput, rightInput); + break; + } + frame.setValue(binaryCompOperation->getIdentifier(), op); +} + +void MLIRLoweringProvider::generateMLIR(ir::ShiftOperation* shiftOperation, + nautilus::compiler::mlir::MLIRLoweringProvider::ValueFrame& frame) { + auto leftInput = frame.getValue(shiftOperation->getLeftInput()->getIdentifier()); + auto rightInput = frame.getValue(shiftOperation->getRightInput()->getIdentifier()); + + mlir::Value op; + switch (shiftOperation->getType()) { + case ir::ShiftOperation::LS: + op = builder->create(getNameLoc("location"), leftInput, rightInput); + break; + case ir::ShiftOperation::RS: + op = builder->create(getNameLoc("location"), leftInput, rightInput); + break; + } + frame.setValue(shiftOperation->getIdentifier(), op); +} + void MLIRLoweringProvider::generateMLIR(ir::ConstBooleanOperation* constBooleanOp, MLIRLoweringProvider::ValueFrame& frame) { auto constOp = builder->create( diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.hpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.hpp index ed6c5623..80717cec 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.hpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.hpp @@ -10,6 +10,9 @@ #include "nautilus/compiler/ir/operations/ArithmeticOperations/ModOperation.hpp" #include "nautilus/compiler/ir/operations/ArithmeticOperations/MulOperation.hpp" #include "nautilus/compiler/ir/operations/ArithmeticOperations/SubOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.hpp" #include "nautilus/compiler/ir/operations/BranchOperation.hpp" #include "nautilus/compiler/ir/operations/CastOperation.hpp" #include "nautilus/compiler/ir/operations/ConstBooleanOperation.hpp" @@ -21,7 +24,7 @@ #include "nautilus/compiler/ir/operations/LoadOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/AndOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.hpp" -#include "nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.hpp" +#include "nautilus/compiler/ir/operations/LogicalOperations/NotOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/OrOperation.hpp" #include "nautilus/compiler/ir/operations/Operation.hpp" #include "nautilus/compiler/ir/operations/ProxyCallOperation.hpp" @@ -109,36 +112,24 @@ class MLIRLoweringProvider { void generateMLIR(ir::ConstPtrOperation* constPtrOperation, ValueFrame& frame); void generateMLIR(ir::AddOperation* addIntOp, ValueFrame& frame); - void generateMLIR(ir::SubOperation* subIntOp, ValueFrame& frame); - void generateMLIR(ir::MulOperation* mulIntOp, ValueFrame& frame); - void generateMLIR(ir::DivOperation* divFloatOp, ValueFrame& frame); - void generateMLIR(ir::ModOperation* divFloatOp, ValueFrame& frame); - void generateMLIR(ir::StoreOperation* storeOp, ValueFrame& frame); - void generateMLIR(ir::LoadOperation* loadOp, ValueFrame& frame); - void generateMLIR(ir::IfOperation* ifOp, ValueFrame& frame); - void generateMLIR(ir::CompareOperation* compareOp, ValueFrame& frame); - void generateMLIR(ir::BranchOperation* branchOp, ValueFrame& frame); - void generateMLIR(ir::ReturnOperation* returnOp, ValueFrame& frame); - void generateMLIR(ir::ProxyCallOperation* proxyCallOp, ValueFrame& frame); - - void generateMLIR(ir::OrOperation* yieldOperation, ValueFrame& frame); - - void generateMLIR(ir::AndOperation* yieldOperation, ValueFrame& frame); - - void generateMLIR(ir::NegateOperation* yieldOperation, ValueFrame& frame); - + void generateMLIR(ir::OrOperation* orOperation, ValueFrame& frame); + void generateMLIR(ir::AndOperation* andOperation, ValueFrame& frame); + void generateMLIR(ir::NegateOperation* negateOperation, ValueFrame& frame); + void generateMLIR(ir::NotOperation* notOperation, ValueFrame& frame); void generateMLIR(ir::CastOperation* castOperation, ValueFrame& frame); + void generateMLIR(ir::BinaryCompOperation* binaryCompOperation, ValueFrame& frame); + void generateMLIR(ir::ShiftOperation* shiftOperation, ValueFrame& frame); /** * @brief Generates a basic block inside of the current MLIR module. Used for control flow (if,loop). diff --git a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.cpp index e481676f..47a778da 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.cpp @@ -6,20 +6,33 @@ namespace nautilus::compiler::ir { BinaryCompOperation::BinaryCompOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput, Type type) - : BinaryOperation(OperationType::AddOp, identifier, leftInput->getStamp(), leftInput, rightInput), type(type) { + : BinaryOperation(OperationType::BinaryComp, identifier, leftInput->getStamp(), leftInput, rightInput), type(type) { } std::string BinaryCompOperation::toString() { - if (type == BOR) { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " | " + - getRightInput()->getIdentifier().toString(); - } else { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " & " + - getRightInput()->getIdentifier().toString(); + + std::string opSymbol; + switch (type) { + case BAND: + opSymbol = " & "; + break; + case BOR: + opSymbol = " | "; + break; + case XOR: + opSymbol = " ^ "; + break; } + + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + opSymbol + + getRightInput()->getIdentifier().toString(); +} + +BinaryCompOperation::Type BinaryCompOperation::getType() const { + return type; } bool BinaryCompOperation::classof(const Operation* Op) { - return Op->getOperationType() == OperationType::AddOp; + return Op->getOperationType() == OperationType::BinaryComp; } } // namespace nautilus::compiler::ir diff --git a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.hpp b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.hpp index b17101b3..d4926508 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.hpp +++ b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.hpp @@ -8,7 +8,7 @@ namespace nautilus::compiler::ir { class BinaryCompOperation final : public BinaryOperation { public: - enum Type { BAND, BOR }; + enum Type { BAND, BOR, XOR }; BinaryCompOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput, Type type); @@ -18,6 +18,8 @@ class BinaryCompOperation final : public BinaryOperation { bool classof(const Operation* Op); + Type getType() const; + private: Type type; }; diff --git a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/CMakeLists.txt b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/CMakeLists.txt index 3652fe98..affd8f2f 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/CMakeLists.txt +++ b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/CMakeLists.txt @@ -2,4 +2,5 @@ add_source_files(nautilus ShiftOperation.cpp BinaryCompOperation.cpp + NegateOperation.cpp ) diff --git a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.cpp similarity index 57% rename from nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.cpp rename to nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.cpp index 7dfb5547..279143e3 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.cpp @@ -1,18 +1,18 @@ -#include "nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.hpp" namespace nautilus::compiler::ir { NegateOperation::NegateOperation(OperationIdentifier identifier, Operation* input) - : Operation(OperationType::NegateOp, identifier, Type::b, {input}) { + : Operation(OperationType::NegateOp, identifier, input->getStamp(), {input}) { } std::string NegateOperation::toString() { - return identifier.toString() + "= not " + getInput()->getIdentifier().toString(); + return identifier.toString() + "= ~" + getInput()->getIdentifier().toString(); } bool NegateOperation::classof(const Operation* Op) { - return Op->getOperationType() == OperationType::AddOp; + return Op->getOperationType() == OperationType::NegateOp; } Operation* NegateOperation::getInput() { diff --git a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.hpp b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.hpp similarity index 100% rename from nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.hpp rename to nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.hpp diff --git a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.cpp index 4987ec31..80171af6 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.cpp @@ -6,7 +6,7 @@ namespace nautilus::compiler::ir { ShiftOperation::ShiftOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput, ShiftType type) - : BinaryOperation(OperationType::AddOp, identifier, leftInput->getStamp(), leftInput, rightInput), type(type) { + : BinaryOperation(OperationType::ShiftOp, identifier, leftInput->getStamp(), leftInput, rightInput), type(type) { } std::string ShiftOperation::toString() { @@ -19,7 +19,11 @@ std::string ShiftOperation::toString() { } } +ShiftOperation::ShiftType ShiftOperation::getType() const { + return type; +} + bool ShiftOperation::classof(const Operation* Op) { - return Op->getOperationType() == OperationType::AddOp; + return Op->getOperationType() == OperationType::ShiftOp; } } // namespace nautilus::compiler::ir diff --git a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.hpp b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.hpp index 2c90fced..44c69e36 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.hpp +++ b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.hpp @@ -17,6 +17,8 @@ class ShiftOperation final : public BinaryOperation { bool classof(const Operation* Op); + ShiftType getType() const; + private: ShiftType type; }; diff --git a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/CMakeLists.txt b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/CMakeLists.txt index 67882f35..c0b8cd58 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/CMakeLists.txt +++ b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/CMakeLists.txt @@ -1,18 +1,7 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# https://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. add_source_files(nautilus AndOperation.cpp OrOperation.cpp - NegateOperation.cpp + NotOperation.cpp CompareOperation.cpp ) diff --git a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.cpp new file mode 100644 index 00000000..aac63993 --- /dev/null +++ b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.cpp @@ -0,0 +1,25 @@ + +#include "nautilus/compiler/ir/operations/LogicalOperations/NotOperation.hpp" + +namespace nautilus::compiler::ir { + +NotOperation::NotOperation(OperationIdentifier identifier, Operation* input) + : Operation(OperationType::NotOp, identifier, Type::b, {input}) { +} + +std::string NotOperation::toString() { + return identifier.toString() + "= !" + getInput()->getIdentifier().toString(); +} + +bool NotOperation::classof(const Operation* Op) { + return Op->getOperationType() == OperationType::NotOp; +} + +Operation* NotOperation::getInput() { + return inputs[0]; +} + +void NotOperation::setInput(Operation* newInput) { + this->inputs[0] = newInput; +} +} // namespace nautilus::compiler::ir diff --git a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.hpp b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.hpp new file mode 100644 index 00000000..59c56c9f --- /dev/null +++ b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.hpp @@ -0,0 +1,20 @@ + +#include "nautilus/compiler/ir/operations/Operation.hpp" + +namespace nautilus::compiler::ir { + +class NotOperation : public Operation { +public: + NotOperation(OperationIdentifier identifier, Operation* input); + + ~NotOperation() override = default; + + Operation* getInput(); + + void setInput(Operation* newInput); + + std::string toString() override; + + bool classof(const Operation* Op); +}; +} // namespace nautilus::compiler::ir diff --git a/nautilus/src/nautilus/compiler/ir/operations/Operation.cpp b/nautilus/src/nautilus/compiler/ir/operations/Operation.cpp index 0f0ece19..7583ad7c 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/Operation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/Operation.cpp @@ -10,7 +10,7 @@ #include "nautilus/compiler/ir/operations/LoadOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/AndOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.hpp" -#include "nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/OrOperation.hpp" #include "nautilus/compiler/ir/operations/ProxyCallOperation.hpp" #include "nautilus/compiler/ir/operations/ReturnOperation.hpp" diff --git a/nautilus/src/nautilus/compiler/ir/operations/Operation.hpp b/nautilus/src/nautilus/compiler/ir/operations/Operation.hpp index 7b5325cd..12e5327c 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/Operation.hpp +++ b/nautilus/src/nautilus/compiler/ir/operations/Operation.hpp @@ -40,6 +40,7 @@ class Operation { enum class OperationType : uint8_t { AddOp, AndOp, + NotOp, BasicBlockArgument, BlockInvocation, BranchOp, @@ -63,6 +64,8 @@ class Operation { ReturnOp, StoreOp, SubOp, + BinaryComp, + ShiftOp, }; explicit Operation(OperationType opType, const OperationIdentifier& identifier, Type type, diff --git a/nautilus/src/nautilus/tracing/TraceContext.cpp b/nautilus/src/nautilus/tracing/TraceContext.cpp index f5c612e8..d04f7812 100644 --- a/nautilus/src/nautilus/tracing/TraceContext.cpp +++ b/nautilus/src/nautilus/tracing/TraceContext.cpp @@ -206,6 +206,25 @@ void TraceContext::traceReturnOperation(Type type, value_ref ref) { return; } +value_ref TraceContext::traceUnaryOperation(nautilus::tracing::Op op, Type resultType, + nautilus::tracing::value_ref& inputRef) { + if (isFollowing()) { + auto currentOperation = executionTrace->getCurrentOperation(); + executionTrace->nextOperation(); + assert(currentOperation.op == op); + return currentOperation.resultRef; + } + + auto tag = recordSnapshot(); + if (executionTrace->checkTag(tag)) { + auto inputVariant = InputVariant(inputRef); + auto resultRef = + executionTrace->addOperationWithResult(tag, op, resultType, std::vector {inputVariant}); + return resultRef; + } + throw TraceTerminationException(); +} + value_ref TraceContext::traceBinaryOperation(Op op, Type resultType, value_ref& leftRef, value_ref& rightRef) { // std::cout <variableBitset << std::endl; if (isFollowing()) { diff --git a/nautilus/src/nautilus/tracing/TraceContext.hpp b/nautilus/src/nautilus/tracing/TraceContext.hpp index 7b01d87d..07171764 100644 --- a/nautilus/src/nautilus/tracing/TraceContext.hpp +++ b/nautilus/src/nautilus/tracing/TraceContext.hpp @@ -76,9 +76,7 @@ class TraceContext { * @param inputRef reference to the input. * @param resultRef reference to the result. */ - value_ref traceUnaryOperation(const Op&, value_ref& inputRef) { - return inputRef; - } + value_ref traceUnaryOperation(Op op, Type resultType, value_ref& inputRef); /** * @brief Trace a binary operation, e.g., add, sub, div. @@ -102,7 +100,8 @@ class TraceContext { */ void traceAssignment(value_ref targetRef, value_ref sourceRef, Type resultType); - value_ref traceCall(const std::string& functionName, void* fptn, Type resultType, std::vector arguments); + value_ref traceCall(const std::string& functionName, void* fptn, Type resultType, + std::vector arguments); bool traceCmp(value_ref targetRef); diff --git a/nautilus/src/nautilus/tracing/TracingUtil.cpp b/nautilus/src/nautilus/tracing/TracingUtil.cpp index dea2b10e..a194f14d 100644 --- a/nautilus/src/nautilus/tracing/TracingUtil.cpp +++ b/nautilus/src/nautilus/tracing/TracingUtil.cpp @@ -67,7 +67,8 @@ value_ref traceCall(const std::string& functionName, void* fptn, Type resultType template [[maybe_unused]] value_ref traceUnaryOp(value_ref leftState) { - return TraceContext::get()->traceUnaryOperation(op, leftState); + auto type = to_type(); + return TraceContext::get()->traceUnaryOperation(op, type, leftState); } #if __APPLE__ @@ -255,6 +256,16 @@ template value_ref traceConstant(uint32_t* value); template value_ref traceConstant(uint64_t* value); +template value_ref traceUnaryOp(value_ref leftState); +template value_ref traceUnaryOp(value_ref leftState); +template value_ref traceUnaryOp(value_ref leftState); +template value_ref traceUnaryOp(value_ref leftState); +template value_ref traceUnaryOp(value_ref leftState); +template value_ref traceUnaryOp(value_ref leftState); +template value_ref traceUnaryOp(value_ref leftState); +template value_ref traceUnaryOp(value_ref leftState); +template value_ref traceUnaryOp(value_ref leftState); + #if __APPLE__ template value_ref traceConstant(size_t* value); @@ -347,6 +358,9 @@ std::ostream& operator<<(std::ostream& os, const Op& operation) { case BAND: os << "BAND"; break; + case BXOR: + os << "BXOR"; + break; case NEGATE: os << "NEGATE"; break; diff --git a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp index 532ca88c..b95aeeab 100644 --- a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp +++ b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp @@ -5,13 +5,13 @@ #include "nautilus/compiler/ir/operations/ArithmeticOperations/ModOperation.hpp" #include "nautilus/compiler/ir/operations/ArithmeticOperations/MulOperation.hpp" #include "nautilus/compiler/ir/operations/ArithmeticOperations/SubOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.hpp" #include "nautilus/compiler/ir/operations/CastOperation.hpp" #include "nautilus/compiler/ir/operations/ConstBooleanOperation.hpp" #include "nautilus/compiler/ir/operations/ConstPtrOperation.hpp" #include "nautilus/compiler/ir/operations/LoadOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/AndOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.hpp" -#include "nautilus/compiler/ir/operations/LogicalOperations/NegateOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/OrOperation.hpp" #include "nautilus/compiler/ir/operations/Operation.hpp" #include "nautilus/compiler/ir/operations/ProxyCallOperation.hpp" @@ -118,6 +118,10 @@ void TraceToIRConversionPhase::IRConversionContext::processOperation(int32_t sco processNegate(scope, frame, currentIrBlock, operation); return; }; + case Op::NOT: { + processNot(scope, frame, currentIrBlock, operation); + return; + }; case Op::AND: { processAnd(scope, frame, currentIrBlock, operation); return; @@ -168,8 +172,6 @@ void TraceToIRConversionPhase::IRConversionContext::processOperation(int32_t sco return; case FREE: break; - case NOT: - break; case MOD: processMod(scope, frame, currentIrBlock, operation); return; @@ -185,6 +187,9 @@ void TraceToIRConversionPhase::IRConversionContext::processOperation(int32_t sco case BAND: processBinaryComp(scope, frame, currentIrBlock, operation, compiler::ir::BinaryCompOperation::BAND); return; + case BXOR: + processBinaryComp(scope, frame, currentIrBlock, operation, compiler::ir::BinaryCompOperation::XOR); + return; } throw NotImplementedException("Type is not implemented."); @@ -335,6 +340,14 @@ void TraceToIRConversionPhase::IRConversionContext::processNegate(int32_t, Value frame.setValue(resultIdentifier, negateOperation); } +void TraceToIRConversionPhase::IRConversionContext::processNot(int32_t, ValueFrame& frame, BasicBlock* currentBlock, + TraceOperation& operation) { + auto input = frame.getValue(createValueIdentifier(operation.input[0])); + auto resultIdentifier = createValueIdentifier(operation.resultRef); + auto notOperation = currentBlock->addOperation(resultIdentifier, input); + frame.setValue(resultIdentifier, notOperation); +} + void TraceToIRConversionPhase::IRConversionContext::processLessThan(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { diff --git a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.hpp b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.hpp index 5d0fafd8..d5bea97f 100644 --- a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.hpp +++ b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.hpp @@ -14,6 +14,7 @@ #include "nautilus/compiler/ir/operations/FunctionOperation.hpp" #include "nautilus/compiler/ir/operations/IfOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.hpp" +#include "nautilus/compiler/ir/operations/LogicalOperations/NotOperation.hpp" #include "nautilus/compiler/ir/operations/Operation.hpp" #include "nautilus/compiler/ir/operations/ReturnOperation.hpp" #include "nautilus/tracing/Block.hpp" @@ -85,6 +86,8 @@ class TraceToIRConversionPhase { void processNegate(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); + void processNot(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, + TraceOperation& operation); void processAnd(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); diff --git a/nautilus/test/execution-tests/CastFunctions.hpp b/nautilus/test/execution-tests/CastFunctions.hpp new file mode 100644 index 00000000..a746efd7 --- /dev/null +++ b/nautilus/test/execution-tests/CastFunctions.hpp @@ -0,0 +1,179 @@ +#pragma once + +#include + +namespace nautilus::engine { + +val assignment1(val x) { + auto y = x; + return y; +} + +val assignment2(val x) { + auto y = x; + y = y + 1; + return y; +} + +val assignment3(val x) { + auto y = x; + y = y + 1; + return x; +} + +val assignment4(val x) { + val y = 42; + y = x + 1; + return y; +} + +val assignment5(val x) { + val y = 42; + y = x + 1; + return x; +} + +val int8AddExpression(val x) { + val y = (int8_t) 2; + return y + x; +} + +val int16AddExpression(val x) { + val y = (int16_t) 5; + return x + y; +} + +val int32AddExpression(val x) { + val y = 5; + return x + y; +} + +val int64AddExpression(val x) { + val y = (int64_t) 7; + return x + y; +} + +val floatAddExpression(val x) { + val y = 7.0f; + return x + y; +} + +val doubleAddExpression(val x) { + val y = 7.0; + return x + y; +} + +val castFloatToDoubleAddExpression(val x) { + val y = 7.0; + return x + y; +} + +val castInt8ToInt64AddExpression(val x) { + val y = (int64_t) 7; + return x + y; +} + +val castInt8ToInt64AddExpression2(val x) { + val y = (int64_t) 42; + return y + x; +} + +val lAnd(val a, val b) { + return a && b; +} + +val lOr(val a, val b) { + return a || b; +} + +val incrementPost(val x) { + auto y = x++; + return y + x; +} + +val incrementPre(val x) { + auto y = ++x; + return y + x; +} + +val decrementPost(val x) { + auto y = x--; + return y + x; +} + +val decrementPre(val x) { + auto y = --x; + return y + x; +} + +val assignAdd(val x) { + x += 5; + return x; +} + +val assignSub(val x) { + x -= 5; + return x; +} + +val assignMul(val x) { + x *= 5; + return x; +} + +val assignDiv(val x) { + x /= 5; + return x; +} + +val assignMod(val x) { + x %= 5; + return x; +} + +val assignAnd(val x) { + x &= 5; + return x; +} + +val assignOr(val x) { + x |= 5; + return x; +} + +val assignXor(val x) { + x ^= 5; + return x; +} + +val assignShl(val x) { + x <<= 5; + return x; +} + +val assignShr(val x) { + x >>= 5; + return x; +} + +template +val shiftLeft(val x, val y) { + return x << y; +} + +template +val shiftRight(val x, val y) { + return x >> y; +} + +template +val negate(val x) { + return ~x; +} + +template +val logicalNot(val x) { + return !x; +} + +} // namespace nautilus::engine diff --git a/nautilus/test/execution-tests/ExecutionTest.cpp b/nautilus/test/execution-tests/ExecutionTest.cpp index 04969074..ec673f02 100644 --- a/nautilus/test/execution-tests/ExecutionTest.cpp +++ b/nautilus/test/execution-tests/ExecutionTest.cpp @@ -12,6 +12,43 @@ namespace nautilus::engine { void addTest(engine::NautilusEngine& engine) { + SECTION("staticCast") { + auto f = engine.registerFunction(staticCastExpression); + REQUIRE(f((int8_t)34) == 34); + } + + + SECTION("logicalNot") { + auto f = engine.registerFunction(logicalNot); + REQUIRE(f(true) == false); + REQUIRE(f(false) == true); + } + + SECTION("intBitwiseNegate") { + auto f = engine.registerFunction(negate); + REQUIRE(f(0) == -1); + REQUIRE(f(1) == -2); + REQUIRE(f(INT_MAX) == INT_MIN); + REQUIRE(f(INT_MIN) == INT_MAX); + } + + SECTION("uintBitwiseNegate") { + auto f = engine.registerFunction(negate); + REQUIRE(f((uint32_t)0) == UINT_MAX); + REQUIRE(f((uint32_t)1) == UINT_MAX -1); + REQUIRE(f((uint32_t)INT_MAX) == (uint32_t)INT_MIN); + REQUIRE(f((uint32_t)INT_MIN) == (uint32_t)INT_MAX); + REQUIRE(f(UINT_MAX) == 0); + } + + SECTION("charBitwiseNegate") { + auto f = engine.registerFunction(negate); + REQUIRE(f((char)0) == (char)-1); + REQUIRE(f((char)1) == (char)-2); + REQUIRE(f((char)CHAR_MAX) == (char)CHAR_MIN); + REQUIRE(f((char)CHAR_MIN) == (char)CHAR_MAX); + } + SECTION("callEnumFunction") { auto f = engine.registerFunction(callEnumFunction); REQUIRE(f(Color::BLUE) == 42); @@ -24,6 +61,22 @@ void addTest(engine::NautilusEngine& engine) { REQUIRE(f(Color::GREEN) == 0); } + SECTION("lAnd") { + auto f = engine.registerFunction(lAnd); + REQUIRE(f(true, true) == true); + REQUIRE(f(true, false) == false); + REQUIRE(f(false, false) == false); + REQUIRE(f(false, true) == false); + } + + SECTION("lOr") { + auto f = engine.registerFunction(lOr); + REQUIRE(f(true, true) == true); + REQUIRE(f(true, false) == true); + REQUIRE(f(false, false) == false); + REQUIRE(f(false, true) == true); + } + SECTION("incrementPost") { auto f = engine.registerFunction(incrementPost); REQUIRE(f(1) == 3); @@ -69,7 +122,6 @@ void addTest(engine::NautilusEngine& engine) { REQUIRE(f(7) == 2); REQUIRE(f(5) == 0); } - /* SECTION("assignAnd") { auto f = engine.registerFunction(assignAnd); REQUIRE(f(7) == 5); @@ -79,11 +131,13 @@ void addTest(engine::NautilusEngine& engine) { auto f = engine.registerFunction(assignOr); REQUIRE(f(7) == 7); REQUIRE(f(5) == 5); - } SECTION("assignXor") { + } + SECTION("assignXor") { auto f = engine.registerFunction(assignXor); REQUIRE(f(7) == 2); REQUIRE(f(5) == 0); - }SECTION("assignShl") { + } + SECTION("assignShl") { auto f = engine.registerFunction(assignShl); REQUIRE(f(7) == 224); REQUIRE(f(5) == 160); @@ -91,7 +145,7 @@ void addTest(engine::NautilusEngine& engine) { auto f = engine.registerFunction(assignShr); REQUIRE(f(7) == 0); REQUIRE(f(5) == 0); - }*/ + } SECTION("assignment1") { auto f = engine.registerFunction(assignment1); REQUIRE(f(1) == 1); diff --git a/nautilus/test/execution-tests/ExpressionFunctions.hpp b/nautilus/test/execution-tests/ExpressionFunctions.hpp index ca9ca2e6..635ef0ee 100644 --- a/nautilus/test/execution-tests/ExpressionFunctions.hpp +++ b/nautilus/test/execution-tests/ExpressionFunctions.hpp @@ -4,6 +4,24 @@ namespace nautilus::engine { +template +val implicitCastExpression(val x) { + val y = x; + return y; +} + +template +val staticCastExpression(val x) { + val y = static_cast>(x); + return y; +} + +template +val dynamicCastExpression(val x) { + val y = dynamic_cast(x); + return y; +} + val assignment1(val x) { auto y = x; return y; @@ -63,6 +81,8 @@ val doubleAddExpression(val x) { return x + y; } + + val castFloatToDoubleAddExpression(val x) { val y = 7.0; return x + y; @@ -78,6 +98,14 @@ val castInt8ToInt64AddExpression2(val x) { return y + x; } +val lAnd(val a, val b) { + return a && b; +} + +val lOr(val a, val b) { + return a || b; +} + val incrementPost(val x) { auto y = x++; return y + x; @@ -147,4 +175,25 @@ val assignShr(val x) { x >>= 5; return x; } + +template +val shiftLeft(val x, val y) { + return x << y; +} + +template +val shiftRight(val x, val y) { + return x >> y; +} + +template +val negate(val x) { + return ~x; +} + +template +val logicalNot(val x) { + return !x; +} + } // namespace nautilus::engine From b9a90924ac7c47f6bfcc490b4fe362937ca8278b Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Sun, 28 Jul 2024 23:40:00 +0200 Subject: [PATCH 6/7] This PR extends the support of ptr operations on nautilus val objects (#13) --- .clang-format | 2 +- nautilus/include/nautilus/val_ptr.hpp | 67 ++++- .../src/nautilus/compiler/JITCompiler.cpp | 3 +- .../backends/amsjit/A64LoweringProvider.cpp | 3 +- .../compiler/backends/bc/BCInterpreter.cpp | 17 +- .../backends/bc/BCLoweringProvider.cpp | 24 +- .../backends/cpp/CPPLoweringProvider.cpp | 37 +-- .../compiler/backends/cpp/SharedLibrary.cpp | 3 +- .../compiler/backends/mlir/JITCompiler.cpp | 10 +- .../backends/mlir/LLVMIROptimizer.cpp | 10 +- .../backends/mlir/MLIRCompilationBackend.cpp | 3 +- .../backends/mlir/MLIRLoweringProvider.cpp | 152 +++++------ .../backends/mlir/MLIRPassManager.cpp | 4 +- .../compiler/backends/mlir/MLIRUtility.cpp | 6 +- .../nautilus/compiler/ir/IRDumpHandler.cpp | 17 +- .../compiler/ir/blocks/BasicBlock.cpp | 7 +- .../compiler/ir/blocks/BasicBlockArgument.cpp | 3 +- .../ArithmeticOperations/AddOperation.cpp | 6 +- .../ArithmeticOperations/DivOperation.cpp | 6 +- .../ArithmeticOperations/ModOperation.cpp | 6 +- .../ArithmeticOperations/MulOperation.cpp | 6 +- .../ArithmeticOperations/SubOperation.cpp | 6 +- .../BinaryOperations/BinaryCompOperation.cpp | 6 +- .../BinaryOperations/NegateOperation.cpp | 3 +- .../BinaryOperations/ShiftOperation.cpp | 10 +- .../compiler/ir/operations/CastOperation.cpp | 6 +- .../ir/operations/ConstBooleanOperation.cpp | 3 +- .../ir/operations/ConstFloatOperation.cpp | 3 +- .../ir/operations/ConstIntOperation.cpp | 3 +- .../ir/operations/ConstPtrOperation.cpp | 3 +- .../ir/operations/FunctionOperation.cpp | 8 +- .../compiler/ir/operations/IfOperation.cpp | 3 +- .../compiler/ir/operations/LoadOperation.cpp | 3 +- .../LogicalOperations/AndOperation.cpp | 6 +- .../LogicalOperations/CompareOperation.cpp | 9 +- .../LogicalOperations/NotOperation.cpp | 3 +- .../LogicalOperations/OrOperation.cpp | 6 +- .../compiler/ir/operations/Operation.cpp | 16 +- .../ir/operations/ProxyCallOperation.cpp | 10 +- .../ir/operations/ReturnOperation.cpp | 3 +- .../compiler/ir/operations/StoreOperation.cpp | 3 +- .../src/nautilus/tracing/ExecutionTrace.cpp | 18 +- .../src/nautilus/tracing/TraceContext.cpp | 22 +- .../src/nautilus/tracing/TraceOperation.cpp | 6 +- nautilus/src/nautilus/tracing/TracingUtil.cpp | 65 +++-- .../tracing/phases/SSACreationPhase.cpp | 15 +- .../phases/TraceToIRConversionPhase.cpp | 127 +++------ .../SymbolicExecutionContext.cpp | 3 +- .../execution-tests/BoolExecutionTest.cpp | 117 ++++++++ .../test/execution-tests/BoolOperations.hpp | 62 +++++ nautilus/test/execution-tests/CMakeLists.txt | 8 + .../test/execution-tests/ExecutionTest.cpp | 249 ++++++++++++++---- .../execution-tests/ExpressionFunctions.hpp | 7 - .../test/execution-tests/PointerFunctions.hpp | 40 +++ nautilus/test/execution-tests/TracingTest.cpp | 105 ++++---- .../test/val-tests/IntegerValTypeTest.cpp | 3 +- 56 files changed, 810 insertions(+), 542 deletions(-) create mode 100644 nautilus/test/execution-tests/BoolExecutionTest.cpp create mode 100644 nautilus/test/execution-tests/BoolOperations.hpp diff --git a/.clang-format b/.clang-format index 0a8f9164..7660ed5b 100644 --- a/.clang-format +++ b/.clang-format @@ -4,7 +4,7 @@ AccessModifierOffset: -4 AllowShortFunctionsOnASingleLine: false AllowShortLambdasOnASingleLine: Inline AlwaysBreakTemplateDeclarations: Yes -ColumnLimit: 120 +ColumnLimit: 240 CompactNamespaces: true IncludeBlocks: Merge IncludeCategories: diff --git a/nautilus/include/nautilus/val_ptr.hpp b/nautilus/include/nautilus/val_ptr.hpp index 367e2fbb..3fedb08e 100644 --- a/nautilus/include/nautilus/val_ptr.hpp +++ b/nautilus/include/nautilus/val_ptr.hpp @@ -112,7 +112,7 @@ class val : public base_ptr_val { // enable cast to type T template operator val() const { - return val((T*)this->value, this->state); + return val((T*) this->value, this->state); } }; @@ -200,39 +200,104 @@ auto inline operator-(val left, std::remove_pointer_t righ template requires std::is_pointer_v auto inline operator==(val left, val right) { + +#ifdef ENABLE_TRACING + if (tracing::inTracer()) { + auto tc = tracing::traceBinaryOp(left.state, right.state); + return val(tc); + } +#endif return val(left.value == right.value); } +template + requires std::is_pointer_v +auto inline operator==(val left, std::nullptr_t) { + auto nullVal = val(NULL); + return left == nullVal; +} + +template + requires std::is_pointer_v +auto inline operator==(std::nullptr_t, val right) { + auto nullVal = val(NULL); + return nullVal == right; +} + template requires std::is_pointer_v auto inline operator<=(val left, val right) { +#ifdef ENABLE_TRACING + if (tracing::inTracer()) { + auto tc = tracing::traceBinaryOp(left.state, right.state); + return val(tc); + } +#endif return val(left.value <= right.value); } template requires std::is_pointer_v auto inline operator<(val left, val right) { +#ifdef ENABLE_TRACING + if (tracing::inTracer()) { + auto tc = tracing::traceBinaryOp(left.state, right.state); + return val(tc); + } +#endif return val(left.value < right.value); } template requires std::is_pointer_v auto inline operator>(val left, val right) { +#ifdef ENABLE_TRACING + if (tracing::inTracer()) { + auto tc = tracing::traceBinaryOp(left.state, right.state); + return val(tc); + } +#endif return val(left.value > right.value); } template requires std::is_pointer_v auto inline operator>=(val left, val right) { +#ifdef ENABLE_TRACING + if (tracing::inTracer()) { + auto tc = tracing::traceBinaryOp(left.state, right.state); + return val(tc); + } +#endif return val(left.value >= right.value); } template requires std::is_pointer_v auto inline operator!=(val left, val right) { +#ifdef ENABLE_TRACING + if (tracing::inTracer()) { + auto tc = tracing::traceBinaryOp(left.state, right.state); + return val(tc); + } +#endif return val(left.value != right.value); } +template + requires std::is_pointer_v +auto inline operator!=(val left, std::nullptr_t) { + auto nullVal = val(NULL); + return left != nullVal; +} + +template + requires std::is_pointer_v +auto inline operator!=(std::nullptr_t, val right) { + auto nullVal = val(NULL); + return nullVal != right; +} + template <> class val { public: diff --git a/nautilus/src/nautilus/compiler/JITCompiler.cpp b/nautilus/src/nautilus/compiler/JITCompiler.cpp index 18156d45..7c28e51b 100644 --- a/nautilus/src/nautilus/compiler/JITCompiler.cpp +++ b/nautilus/src/nautilus/compiler/JITCompiler.cpp @@ -18,8 +18,7 @@ namespace nautilus::compiler { JITCompiler::JITCompiler() : options(), backends(std::make_unique()) { } -JITCompiler::JITCompiler(engine::Options options) - : options(std::move(options)), backends(std::make_unique()) { +JITCompiler::JITCompiler(engine::Options options) : options(std::move(options)), backends(std::make_unique()) { } JITCompiler::~JITCompiler() = default; diff --git a/nautilus/src/nautilus/compiler/backends/amsjit/A64LoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/amsjit/A64LoweringProvider.cpp index 4764bab4..7cd81fdb 100644 --- a/nautilus/src/nautilus/compiler/backends/amsjit/A64LoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/amsjit/A64LoweringProvider.cpp @@ -16,8 +16,7 @@ namespace nautilus::compiler::asmjit { using namespace ::asmjit; -A64LoweringProvider::LoweringContext::LoweringContext(std::shared_ptr ir, CodeHolder& code) - : cc(&code), ir(std::move(ir)) { +A64LoweringProvider::LoweringContext::LoweringContext(std::shared_ptr ir, CodeHolder& code) : cc(&code), ir(std::move(ir)) { } void* A64LoweringProvider::lower(std::shared_ptr ir, ::asmjit::JitRuntime& runtime) { diff --git a/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp b/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp index 8bf628a5..9e094cdf 100644 --- a/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp +++ b/nautilus/src/nautilus/compiler/backends/bc/BCInterpreter.cpp @@ -371,8 +371,7 @@ static Operation* OpTable[] = { }; -FunctionCallTarget::FunctionCallTarget(std::vector> arguments, void* functionPtr) - : arguments(std::move(arguments)), functionPtr(functionPtr) { +FunctionCallTarget::FunctionCallTarget(std::vector> arguments, void* functionPtr) : arguments(std::move(arguments)), functionPtr(functionPtr) { } BCInterpreter::BCInterpreter(Code code, RegisterFile registerFile) : code(std::move(code)), registerFile(registerFile) { @@ -518,18 +517,24 @@ std::ostream& operator<<(std::ostream& os, const CodeBlock& block) { // handle terminator if (const auto* res = std::get_if(&block.terminatorOp)) { - os << "\t" << "BR " << res->nextBlock << "\n"; + os << "\t" + << "BR " << res->nextBlock << "\n"; } else if (const auto* res = std::get_if(&block.terminatorOp)) { - os << "\t" << "CMP " << "r" << res->conditionalReg << " " << res->trueBlock << " " << res->falseBlock << "\n"; + os << "\t" + << "CMP " + << "r" << res->conditionalReg << " " << res->trueBlock << " " << res->falseBlock << "\n"; } else if (const auto* res = std::get_if(&block.terminatorOp)) { - os << "\t" << "Return " << "r" << res->resultReg << "\n"; + os << "\t" + << "Return " + << "r" << res->resultReg << "\n"; } return os; } std::ostream& operator<<(std::ostream& os, const OpCode& code) { // auto str = std::string(code.op); - os << "str" << " r" << code.reg1; + os << "str" + << " r" << code.reg1; if (code.reg2 != -1) { os << " r" << code.reg2; } diff --git a/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp index 0e64f129..59f9e02b 100644 --- a/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp @@ -324,6 +324,9 @@ void BCLoweringProvider::LoweringContext::process(ir::CompareOperation* cmpOp, s auto type = cmpOp->getLeftInput()->getStamp(); ByteCode bc; switch ((type)) { + case Type::b: + bc = ByteCode::EQ_b; + break; case Type::i8: bc = ByteCode::EQ_i8; break; @@ -720,8 +723,7 @@ void BCLoweringProvider::LoweringContext::process(ir::StoreOperation* storeOp, s program.blocks[block].code.emplace_back(oc); } -void BCLoweringProvider::LoweringContext::process(ir::BinaryCompOperation* binaryCompOperation, short block, - RegisterFrame& frame) { +void BCLoweringProvider::LoweringContext::process(ir::BinaryCompOperation* binaryCompOperation, short block, RegisterFrame& frame) { auto leftReg = frame.getValue(binaryCompOperation->getLeftInput()->getIdentifier()); auto rightReg = frame.getValue(binaryCompOperation->getRightInput()->getIdentifier()); auto resultReg = getResultRegister(binaryCompOperation, frame); @@ -843,8 +845,7 @@ void BCLoweringProvider::LoweringContext::process(ir::BinaryCompOperation* binar program.blocks[block].code.emplace_back(oc); } -void BCLoweringProvider::LoweringContext::process(ir::ShiftOperation* shiftOperation, short block, - RegisterFrame& frame) { +void BCLoweringProvider::LoweringContext::process(ir::ShiftOperation* shiftOperation, short block, RegisterFrame& frame) { auto leftReg = frame.getValue(shiftOperation->getLeftInput()->getIdentifier()); auto rightReg = frame.getValue(shiftOperation->getRightInput()->getIdentifier()); auto resultReg = getResultRegister(shiftOperation, frame); @@ -942,8 +943,7 @@ void BCLoweringProvider::LoweringContext::process(ir::ShiftOperation* shiftOpera program.blocks[block].code.emplace_back(oc); } -void BCLoweringProvider::LoweringContext::process(ir::BasicBlockInvocation& bi, short block, - RegisterFrame& parentFrame) { +void BCLoweringProvider::LoweringContext::process(ir::BasicBlockInvocation& bi, short block, RegisterFrame& parentFrame) { auto blockInputArguments = bi.getArguments(); auto& blockTargetArguments = bi.getBlock()->getArguments(); std::vector tempArgs; @@ -989,8 +989,7 @@ void BCLoweringProvider::LoweringContext::process(ir::BranchOperation* branchOp, program.blocks[block].terminatorOp = BranchOp {blockIndex}; } -void BCLoweringProvider::LoweringContext::process(const std::unique_ptr& opt, short block, - RegisterFrame& frame) { +void BCLoweringProvider::LoweringContext::process(const std::unique_ptr& opt, short block, RegisterFrame& frame) { switch (opt->getOperationType()) { case ir::Operation::OperationType::ConstPtrOp: { auto constPtr = as(opt); @@ -1160,8 +1159,7 @@ void BCLoweringProvider::LoweringContext::process(ir::ProxyCallOperation* opt, s processDynamicCall(opt, block, frame); } -void BCLoweringProvider::LoweringContext::processDynamicCall(ir::ProxyCallOperation* opt, short block, - RegisterFrame& frame) { +void BCLoweringProvider::LoweringContext::processDynamicCall(ir::ProxyCallOperation* opt, short block, RegisterFrame& frame) { auto& code = program.blocks[block].code; // NES_DEBUG("CREATE " << opt->toString() << " : " << opt->getStamp()->toString()) auto arguments = opt->getInputArguments(); @@ -1277,8 +1275,7 @@ void BCLoweringProvider::LoweringContext::processDynamicCall(ir::ProxyCallOperat } } -void BCLoweringProvider::LoweringContext::process(ir::NotOperation* negateOperation, short block, - RegisterFrame& frame) { +void BCLoweringProvider::LoweringContext::process(ir::NotOperation* negateOperation, short block, RegisterFrame& frame) { auto input = frame.getValue(negateOperation->getInput()->getIdentifier()); auto resultReg = getResultRegister(negateOperation, frame); frame.setValue(negateOperation->getIdentifier(), resultReg); @@ -1287,8 +1284,7 @@ void BCLoweringProvider::LoweringContext::process(ir::NotOperation* negateOperat program.blocks[block].code.emplace_back(oc); } -void BCLoweringProvider::LoweringContext::process(ir::NegateOperation* negateOperation, short block, - RegisterFrame& frame) { +void BCLoweringProvider::LoweringContext::process(ir::NegateOperation* negateOperation, short block, RegisterFrame& frame) { auto input = frame.getValue(negateOperation->getInput()->getIdentifier()); auto resultReg = getResultRegister(negateOperation, frame); frame.setValue(negateOperation->getIdentifier(), resultReg); diff --git a/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp index da5a9c9b..cd1cfc66 100644 --- a/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/cpp/CPPLoweringProvider.cpp @@ -128,8 +128,7 @@ std::string CPPLoweringProvider::LoweringContext::process(const ir::BasicBlock* } } -void CPPLoweringProvider::LoweringContext::process(ir::CompareOperation* cmpOp, short blockIndex, - RegisterFrame& frame) { +void CPPLoweringProvider::LoweringContext::process(ir::CompareOperation* cmpOp, short blockIndex, RegisterFrame& frame) { auto leftInput = frame.getValue(cmpOp->getLeftInput()->getIdentifier()); auto rightInput = frame.getValue(cmpOp->getRightInput()->getIdentifier()); auto resultVar = getVariable(cmpOp->getIdentifier()); @@ -138,8 +137,7 @@ void CPPLoweringProvider::LoweringContext::process(ir::CompareOperation* cmpOp, // we have to handle the special case that we want to do a null check. Currently, Nautilus IR just contains a x == // 0, thus we check if x is a ptr type. - if (cmpOp->isEquals() && cmpOp->getLeftInput()->getStamp() == Type::ptr && - isInteger(cmpOp->getRightInput()->getStamp())) { + if (cmpOp->isEquals() && cmpOp->getLeftInput()->getStamp() == Type::ptr && isInteger(cmpOp->getRightInput()->getStamp())) { blocks[blockIndex] << resultVar << " = " << leftInput << " == nullptr;\n"; return; } @@ -173,24 +171,21 @@ void CPPLoweringProvider::LoweringContext::process(ir::LoadOperation* loadOp, sh blocks[blockIndex] << resultVar << " = *reinterpret_cast<" << type << "*>(" << address << ");\n"; } -void CPPLoweringProvider::LoweringContext::process(ir::StoreOperation* storeOp, short blockIndex, - RegisterFrame& frame) { +void CPPLoweringProvider::LoweringContext::process(ir::StoreOperation* storeOp, short blockIndex, RegisterFrame& frame) { auto address = frame.getValue(storeOp->getAddress()->getIdentifier()); auto value = frame.getValue(storeOp->getValue()->getIdentifier()); auto type = getType(storeOp->getValue()->getStamp()); blocks[blockIndex] << "*reinterpret_cast<" << type << "*>(" << address << ") = " << value << ";\n"; } -void CPPLoweringProvider::LoweringContext::process(ir::BasicBlockInvocation& bi, short blockIndex, - RegisterFrame& parentFrame) { +void CPPLoweringProvider::LoweringContext::process(ir::BasicBlockInvocation& bi, short blockIndex, RegisterFrame& parentFrame) { auto blockInputArguments = bi.getArguments(); auto& blockTargetArguments = bi.getBlock()->getArguments(); blocks[blockIndex] << "// prepare block arguments\n"; blocks[blockIndex] << "{\n"; for (uint64_t i = 0; i < blockInputArguments.size(); i++) { auto blockArgument = blockInputArguments[i]->getIdentifier(); - blocks[blockIndex] << getType(blockTargetArguments[i]->getStamp()) << " temp_" << i << " = " - << parentFrame.getValue(blockArgument) << ";\n"; + blocks[blockIndex] << getType(blockTargetArguments[i]->getStamp()) << " temp_" << i << " = " << parentFrame.getValue(blockArgument) << ";\n"; } for (uint64_t i = 0; i < blockInputArguments.size(); i++) { auto blockTargetArgument = blockTargetArguments[i]->getIdentifier(); @@ -201,7 +196,8 @@ void CPPLoweringProvider::LoweringContext::process(ir::BasicBlockInvocation& bi, blockArguments << getType(blockTargetArguments[i]->getStamp()) << " " << var << ";\n"; } - blocks[blockIndex] << parentFrame.getValue(blockTargetArgument) << " = " << "temp_" << i << ";\n"; + blocks[blockIndex] << parentFrame.getValue(blockTargetArgument) << " = " + << "temp_" << i << ";\n"; } blocks[blockIndex] << "}\n"; } @@ -218,15 +214,13 @@ void CPPLoweringProvider::LoweringContext::process(ir::IfOperation* ifOpt, short blocks[blockIndex] << "goto " << falseBlock << ";}\n"; } -void CPPLoweringProvider::LoweringContext::process(ir::BranchOperation* branchOp, short blockIndex, - RegisterFrame& frame) { +void CPPLoweringProvider::LoweringContext::process(ir::BranchOperation* branchOp, short blockIndex, RegisterFrame& frame) { process(branchOp->getNextBlockInvocation(), blockIndex, frame); auto nextBlock = process(branchOp->getNextBlockInvocation().getBlock(), frame); blocks[blockIndex] << "goto " << nextBlock << ";\n"; } -void CPPLoweringProvider::LoweringContext::process(const std::unique_ptr& opt, short blockIndex, - RegisterFrame& frame) { +void CPPLoweringProvider::LoweringContext::process(const std::unique_ptr& opt, short blockIndex, RegisterFrame& frame) { switch (opt->getOperationType()) { case ir::Operation::OperationType::ConstBooleanOp: { processConst(opt, blockIndex, frame); @@ -362,8 +356,7 @@ void CPPLoweringProvider::LoweringContext::process(const std::unique_ptrgetStamp()); std::stringstream argTypes; @@ -379,8 +372,8 @@ void CPPLoweringProvider::LoweringContext::process(ir::ProxyCallOperation* opt, argTypes << getType(arg->getStamp()); } if (!functionNames.contains(opt->getFunctionSymbol())) { - functions << "auto " << opt->getFunctionSymbol() << " = " << "(" << returnType << "(*)(" << argTypes.str() - << "))" << opt->getFunctionPtr() << ";\n"; + functions << "auto " << opt->getFunctionSymbol() << " = " + << "(" << returnType << "(*)(" << argTypes.str() << "))" << opt->getFunctionPtr() << ";\n"; functionNames.emplace(opt->getFunctionSymbol()); } if (opt->getStamp() != Type::v) { @@ -392,8 +385,7 @@ void CPPLoweringProvider::LoweringContext::process(ir::ProxyCallOperation* opt, blocks[blockIndex] << opt->getFunctionSymbol() << "(" << args.str() << ");\n"; } -void CPPLoweringProvider::LoweringContext::process(ir::NegateOperation* negateOperation, short blockIndex, - RegisterFrame& frame) { +void CPPLoweringProvider::LoweringContext::process(ir::NegateOperation* negateOperation, short blockIndex, RegisterFrame& frame) { auto input = frame.getValue(negateOperation->getInput()->getIdentifier()); auto resultVar = getVariable(negateOperation->getIdentifier()); blockArguments << getType(negateOperation->getStamp()) << " " << resultVar << ";\n"; @@ -401,8 +393,7 @@ void CPPLoweringProvider::LoweringContext::process(ir::NegateOperation* negateOp blocks[blockIndex] << resultVar << "= ~" << input << ";\n"; } -void CPPLoweringProvider::LoweringContext::process(ir::NotOperation* notOperation, short blockIndex, - RegisterFrame& frame) { +void CPPLoweringProvider::LoweringContext::process(ir::NotOperation* notOperation, short blockIndex, RegisterFrame& frame) { auto input = frame.getValue(notOperation->getInput()->getIdentifier()); auto resultVar = getVariable(notOperation->getIdentifier()); blockArguments << getType(notOperation->getStamp()) << " " << resultVar << ";\n"; diff --git a/nautilus/src/nautilus/compiler/backends/cpp/SharedLibrary.cpp b/nautilus/src/nautilus/compiler/backends/cpp/SharedLibrary.cpp index 7107955b..82341b59 100644 --- a/nautilus/src/nautilus/compiler/backends/cpp/SharedLibrary.cpp +++ b/nautilus/src/nautilus/compiler/backends/cpp/SharedLibrary.cpp @@ -8,8 +8,7 @@ namespace nautilus::compiler::cpp { -SharedLibrary::SharedLibrary(void* shareLib, std::string soAbsolutePath) - : shareLib(shareLib), soAbsolutePath(std::move(soAbsolutePath)) { +SharedLibrary::SharedLibrary(void* shareLib, std::string soAbsolutePath) : shareLib(shareLib), soAbsolutePath(std::move(soAbsolutePath)) { } SharedLibrary::~SharedLibrary() { diff --git a/nautilus/src/nautilus/compiler/backends/mlir/JITCompiler.cpp b/nautilus/src/nautilus/compiler/backends/mlir/JITCompiler.cpp index 15aa4ed3..489b8ad2 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/JITCompiler.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/JITCompiler.cpp @@ -8,11 +8,8 @@ namespace nautilus::compiler::mlir { -std::unique_ptr<::mlir::ExecutionEngine> -JITCompiler::jitCompileModule(::mlir::OwningOpRef<::mlir::ModuleOp>& mlirModule, - const llvm::function_ref optPipeline, - const std::vector& jitProxyFunctionSymbols, - const std::vector& jitProxyFunctionTargetAddresses) { +std::unique_ptr<::mlir::ExecutionEngine> JITCompiler::jitCompileModule(::mlir::OwningOpRef<::mlir::ModuleOp>& mlirModule, const llvm::function_ref optPipeline, + const std::vector& jitProxyFunctionSymbols, const std::vector& jitProxyFunctionTargetAddresses) { // Register the translation from MLIR to LLVM IR, which must happen before we can JIT-compile. ::mlir::registerBuiltinDialectTranslation(*mlirModule->getContext()); @@ -48,8 +45,7 @@ JITCompiler::jitCompileModule(::mlir::OwningOpRef<::mlir::ModuleOp>& mlirModule, for (int i = 0; i < (int) jitProxyFunctionSymbols.size(); ++i) { auto address = jitProxyFunctionTargetAddresses.at(i); - symbolMap[interner(jitProxyFunctionSymbols.at(i))] = {llvm::orc::ExecutorAddr::fromPtr(address), - llvm::JITSymbolFlags::Exported}; + symbolMap[interner(jitProxyFunctionSymbols.at(i))] = {llvm::orc::ExecutorAddr::fromPtr(address), llvm::JITSymbolFlags::Exported}; } return symbolMap; }; diff --git a/nautilus/src/nautilus/compiler/backends/mlir/LLVMIROptimizer.cpp b/nautilus/src/nautilus/compiler/backends/mlir/LLVMIROptimizer.cpp index 1d5c8b7f..299d08ac 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/LLVMIROptimizer.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/LLVMIROptimizer.cpp @@ -24,13 +24,9 @@ std::function LLVMIROptimizer::getLLVMOptimizerPipel targetMachinePtr->setOptLevel(llvm::CodeGenOptLevel::Aggressive); // Add target-specific attributes to the 'execute' function. - llvmIRModule->getFunction("execute")->addAttributeAtIndex( - ~0, llvm::Attribute::get(llvmIRModule->getContext(), "target-cpu", targetMachinePtr->getTargetCPU())); - llvmIRModule->getFunction("execute")->addAttributeAtIndex( - ~0, llvm::Attribute::get(llvmIRModule->getContext(), "target-features", - targetMachinePtr->getTargetFeatureString())); - llvmIRModule->getFunction("execute")->addAttributeAtIndex( - ~0, llvm::Attribute::get(llvmIRModule->getContext(), "tune-cpu", targetMachinePtr->getTargetCPU())); + llvmIRModule->getFunction("execute")->addAttributeAtIndex(~0, llvm::Attribute::get(llvmIRModule->getContext(), "target-cpu", targetMachinePtr->getTargetCPU())); + llvmIRModule->getFunction("execute")->addAttributeAtIndex(~0, llvm::Attribute::get(llvmIRModule->getContext(), "target-features", targetMachinePtr->getTargetFeatureString())); + llvmIRModule->getFunction("execute")->addAttributeAtIndex(~0, llvm::Attribute::get(llvmIRModule->getContext(), "tune-cpu", targetMachinePtr->getTargetCPU())); llvm::SMDiagnostic Err; // Load LLVM IR module from proxy inlining input path (We assert that it exists in CompilationOptions). diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRCompilationBackend.cpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRCompilationBackend.cpp index 712bec2f..f5f896a1 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRCompilationBackend.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRCompilationBackend.cpp @@ -50,8 +50,7 @@ std::unique_ptr MLIRCompilationBackend::compile(std::shared_ptrgetJitProxyFunctionSymbols(), - loweringProvider->getJitProxyTargetAddresses()); + auto engine = JITCompiler::jitCompileModule(mlirModule, optPipeline, loweringProvider->getJitProxyFunctionSymbols(), loweringProvider->getJitProxyTargetAddresses()); // 5. Get execution function from engine. Create and return execution context. // timer.snapshot("MLIRComp"); diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp index f1d9d742..d26d68d6 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp @@ -70,8 +70,7 @@ mlir::Value MLIRLoweringProvider::getConstInt(const std::string& location, Type } mlir::Value MLIRLoweringProvider::getConstBool(const std::string& location, bool value) { - return builder->create(getNameLoc(location), builder->getI1Type(), - builder->getIntegerAttr(builder->getIndexType(), value)); + return builder->create(getNameLoc(location), builder->getI1Type(), builder->getIntegerAttr(builder->getIndexType(), value)); } // Todo Issue #3004: Currently, we are simply adding 'Query_1' as the FileLineLoc name. Moreover, @@ -140,6 +139,26 @@ mlir::arith::CmpFPredicate convertToFloatMLIRComparison(ir::CompareOperation::Co } } +mlir::LLVM::ICmpPredicate convertToLLVMComparison(ir::CompareOperation::Comparator comparisonType) { + switch (comparisonType) { + // the U in U(LT/LE/..) stands for unordered, not unsigned! Float comparisons are always signed. + case (ir::CompareOperation::Comparator::LT): + return mlir::LLVM::ICmpPredicate::ult; + case (ir::CompareOperation::Comparator::LE): + return mlir::LLVM::ICmpPredicate::ule; + case (ir::CompareOperation::Comparator::EQ): + return mlir::LLVM::ICmpPredicate::eq; + case (ir::CompareOperation::Comparator::GT): + return mlir::LLVM::ICmpPredicate::ugt; + case (ir::CompareOperation::Comparator::GE): + return mlir::LLVM::ICmpPredicate::uge; + case (ir::CompareOperation::Comparator::NE): + return mlir::LLVM::ICmpPredicate::ne; + default: + assert(false); + } +} + mlir::arith::CmpIPredicate convertToBooleanMLIRComparison(ir::CompareOperation::Comparator comparisonType) { switch (comparisonType) { // the U in U(LT/LE/..) stands for unordered, not unsigned! Float comparisons are always signed. @@ -160,9 +179,7 @@ mlir::arith::CmpIPredicate convertToBooleanMLIRComparison(ir::CompareOperation:: } } -mlir::FlatSymbolRefAttr MLIRLoweringProvider::insertExternalFunction(const std::string& name, void* functionPtr, - mlir::Type resultType, - std::vector argTypes, bool varArgs) { +mlir::FlatSymbolRefAttr MLIRLoweringProvider::insertExternalFunction(const std::string& name, void* functionPtr, mlir::Type resultType, std::vector argTypes, bool varArgs) { // Create function arg & result types (currently only int for result). mlir::LLVM::LLVMFunctionType llvmFnType = mlir::LLVM::LLVMFunctionType::get(resultType, argTypes, varArgs); @@ -298,8 +315,7 @@ void MLIRLoweringProvider::generateMLIR(const std::unique_ptr& op void MLIRLoweringProvider::generateMLIR(ir::NegateOperation* negateOperation, ValueFrame& frame) { auto input = frame.getValue(negateOperation->getInput()->getIdentifier()); - auto constInt = builder->create(getNameLoc("location"), input.getType(), - builder->getIntegerAttr(input.getType(), ~0)); + auto constInt = builder->create(getNameLoc("location"), input.getType(), builder->getIntegerAttr(input.getType(), ~0)); auto negate = builder->create(getNameLoc("comparison"), input, constInt); frame.setValue(negateOperation->getIdentifier(), negate); } @@ -389,36 +405,29 @@ void MLIRLoweringProvider::generateMLIR(ir::LoadOperation* loadOp, ValueFrame& f // auto bitcast = builder->create(getNameLoc("Bitcasted address"), // mlir::LLVM::LLVMPointerType::get(context), address); - auto mlirLoadOp = - builder->create(getNameLoc("loadedValue"), getMLIRType(loadOp->getStamp()), address); + auto mlirLoadOp = builder->create(getNameLoc("loadedValue"), getMLIRType(loadOp->getStamp()), address); frame.setValue(loadOp->getIdentifier(), mlirLoadOp); } void MLIRLoweringProvider::generateMLIR(ir::ConstIntOperation* constIntOp, ValueFrame& frame) { if (!frame.contains(constIntOp->getIdentifier())) { - frame.setValue(constIntOp->getIdentifier(), - getConstInt("ConstantOp", constIntOp->getStamp(), constIntOp->getValue())); + frame.setValue(constIntOp->getIdentifier(), getConstInt("ConstantOp", constIntOp->getStamp(), constIntOp->getValue())); } else { - frame.setValue(constIntOp->getIdentifier(), - getConstInt("ConstantOp", constIntOp->getStamp(), constIntOp->getValue())); + frame.setValue(constIntOp->getIdentifier(), getConstInt("ConstantOp", constIntOp->getStamp(), constIntOp->getValue())); } } void MLIRLoweringProvider::generateMLIR(ir::ConstPtrOperation* constPtr, ValueFrame& frame) { int64_t val = (int64_t) constPtr->getValue(); - auto constInt = builder->create(getNameLoc("location"), builder->getI64Type(), - builder->getIntegerAttr(builder->getI64Type(), val)); - auto elementAddress = builder->create(getNameLoc("fieldAccess"), - mlir::LLVM::LLVMPointerType::get(context), constInt); + auto constInt = builder->create(getNameLoc("location"), builder->getI64Type(), builder->getIntegerAttr(builder->getI64Type(), val)); + auto elementAddress = builder->create(getNameLoc("fieldAccess"), mlir::LLVM::LLVMPointerType::get(context), constInt); frame.setValue(constPtr->getIdentifier(), elementAddress); } void MLIRLoweringProvider::generateMLIR(ir::ConstFloatOperation* constFloatOp, ValueFrame& frame) { if (isFloat(constFloatOp->getStamp())) { auto floatType = (constFloatOp->getStamp() == Type::f32) ? builder->getF32Type() : builder->getF64Type(); - frame.setValue(constFloatOp->getIdentifier(), builder->create( - getNameLoc("constantFloat"), floatType, - builder->getFloatAttr(floatType, constFloatOp->getValue()))); + frame.setValue(constFloatOp->getIdentifier(), builder->create(getNameLoc("constantFloat"), floatType, builder->getFloatAttr(floatType, constFloatOp->getValue()))); } } @@ -430,14 +439,11 @@ void MLIRLoweringProvider::generateMLIR(ir::AddOperation* addOp, ValueFrame& fra auto rightInput = frame.getValue(addOp->getRightInput()->getIdentifier()); if (addOp->getLeftInput()->getStamp() == Type::ptr) { // if we add something to a ptr we have to use a llvm getelementptr - mlir::Value elementAddress = builder->create( - getNameLoc("fieldAccess"), mlir::LLVM::LLVMPointerType::get(context), builder->getI8Type(), leftInput, - mlir::ArrayRef({rightInput})); + mlir::Value elementAddress = builder->create(getNameLoc("fieldAccess"), mlir::LLVM::LLVMPointerType::get(context), builder->getI8Type(), leftInput, mlir::ArrayRef({rightInput})); frame.setValue(addOp->getIdentifier(), elementAddress); } else if (isFloat(addOp->getStamp())) { - auto mlirAddOp = builder->create(getNameLoc("binOpResult"), leftInput.getType(), leftInput, - rightInput, mlir::LLVM::FastmathFlags::fast); + auto mlirAddOp = builder->create(getNameLoc("binOpResult"), leftInput.getType(), leftInput, rightInput, mlir::LLVM::FastmathFlags::fast); frame.setValue(addOp->getIdentifier(), mlirAddOp); } else { if (!inductionVars.contains(addOp->getLeftInput()->getIdentifier())) { @@ -456,9 +462,7 @@ void MLIRLoweringProvider::generateMLIR(ir::SubOperation* subIntOp, ValueFrame& auto leftInput = frame.getValue(subIntOp->getLeftInput()->getIdentifier()); auto rightInput = frame.getValue(subIntOp->getRightInput()->getIdentifier()); if (isFloat(subIntOp->getStamp())) { - auto mlirSubOp = builder->create( - getNameLoc("binOpResult"), leftInput, rightInput, - mlir::LLVM::FastmathFlagsAttr::get(context, mlir::LLVM::FastmathFlags::fast)); + auto mlirSubOp = builder->create(getNameLoc("binOpResult"), leftInput, rightInput, mlir::LLVM::FastmathFlagsAttr::get(context, mlir::LLVM::FastmathFlags::fast)); frame.setValue(subIntOp->getIdentifier(), mlirSubOp); } else { auto mlirSubOp = builder->create(getNameLoc("binOpResult"), leftInput, rightInput); @@ -471,12 +475,10 @@ void MLIRLoweringProvider::generateMLIR(ir::MulOperation* mulOp, ValueFrame& fra auto rightInput = frame.getValue(mulOp->getRightInput()->getIdentifier()); auto resultType = leftInput.getType(); if (isFloat(mulOp->getStamp())) { - auto mlirMulOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, - rightInput, mlir::LLVM::FastmathFlags::fast); + auto mlirMulOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput, mlir::LLVM::FastmathFlags::fast); frame.setValue(mulOp->getIdentifier(), mlirMulOp); } else { - auto mlirMulOp = - builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput); + auto mlirMulOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput); frame.setValue(mulOp->getIdentifier(), mlirMulOp); } } @@ -486,17 +488,14 @@ void MLIRLoweringProvider::generateMLIR(ir::DivOperation* divIntOp, ValueFrame& auto rightInput = frame.getValue(divIntOp->getRightInput()->getIdentifier()); auto resultType = leftInput.getType(); if (isFloat(divIntOp->getStamp())) { - auto mlirDivOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, - rightInput, mlir::LLVM::FastmathFlags::fast); + auto mlirDivOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput, mlir::LLVM::FastmathFlags::fast); frame.setValue(divIntOp->getIdentifier(), mlirDivOp); } else { if (resultType.isSignedInteger()) { - auto mlirDivOp = - builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput); + auto mlirDivOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput); frame.setValue(divIntOp->getIdentifier(), mlirDivOp); } else { - auto mlirDivOp = - builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput); + auto mlirDivOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput); frame.setValue(divIntOp->getIdentifier(), mlirDivOp); } } @@ -507,17 +506,14 @@ void MLIRLoweringProvider::generateMLIR(ir::ModOperation* divIntOp, ValueFrame& auto rightInput = frame.getValue(divIntOp->getRightInput()->getIdentifier()); auto resultType = leftInput.getType(); if (isFloat(divIntOp->getStamp())) { - auto mlirDivOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, - rightInput, mlir::LLVM::FastmathFlags::fast); + auto mlirDivOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput, mlir::LLVM::FastmathFlags::fast); frame.setValue(divIntOp->getIdentifier(), mlirDivOp); } else { if (resultType.isSignedInteger()) { - auto mlirDivOp = - builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput); + auto mlirDivOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput); frame.setValue(divIntOp->getIdentifier(), mlirDivOp); } else { - auto mlirDivOp = - builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput); + auto mlirDivOp = builder->create(getNameLoc("binOpResult"), resultType, leftInput, rightInput); frame.setValue(divIntOp->getIdentifier(), mlirDivOp); } } @@ -534,8 +530,7 @@ void MLIRLoweringProvider::generateMLIR(ir::ReturnOperation* returnOp, ValueFram if (!returnOp->hasReturnValue()) { builder->create(getNameLoc("return"), mlir::ValueRange()); } else { - builder->create(getNameLoc("return"), - frame.getValue(returnOp->getReturnValue()->getIdentifier())); + builder->create(getNameLoc("return"), frame.getValue(returnOp->getReturnValue()->getIdentifier())); } } @@ -544,9 +539,7 @@ void MLIRLoweringProvider::generateMLIR(ir::ProxyCallOperation* proxyCallOp, Val if (theModule.lookupSymbol(proxyCallOp->getFunctionSymbol())) { functionRef = mlir::SymbolRefAttr::get(context, proxyCallOp->getFunctionSymbol()); } else { - functionRef = insertExternalFunction(proxyCallOp->getFunctionSymbol(), proxyCallOp->getFunctionPtr(), - getMLIRType(proxyCallOp->getStamp()), - getMLIRType(proxyCallOp->getInputArguments()), true); + functionRef = insertExternalFunction(proxyCallOp->getFunctionSymbol(), proxyCallOp->getFunctionPtr(), getMLIRType(proxyCallOp->getStamp()), getMLIRType(proxyCallOp->getInputArguments()), true); } std::vector functionArgs; @@ -554,8 +547,7 @@ void MLIRLoweringProvider::generateMLIR(ir::ProxyCallOperation* proxyCallOp, Val functionArgs.push_back(frame.getValue(arg->getIdentifier())); } if (proxyCallOp->getStamp() != Type::v) { - auto res = builder->create(getNameLoc("printFunc"), getMLIRType(proxyCallOp->getStamp()), - functionRef, functionArgs); + auto res = builder->create(getNameLoc("printFunc"), getMLIRType(proxyCallOp->getStamp()), functionRef, functionArgs); frame.setValue(proxyCallOp->getIdentifier(), res.getResult()); } else { builder->create(builder->getUnknownLoc(), mlir::TypeRange(), functionRef, functionArgs); @@ -569,9 +561,7 @@ void MLIRLoweringProvider::generateMLIR(ir::CompareOperation* compareOp, ValueFr if ((isInteger(leftStamp) && isFloat(rightStamp)) || ((isInteger(rightStamp) && isFloat(leftStamp)))) { // Avoid comparing integer to float throw NotImplementedException("Type missmatch: cannot compare"); - } else if (compareOp->getComparator() == ir::CompareOperation::EQ && - compareOp->getLeftInput()->getStamp() == Type::ptr && - isInteger(compareOp->getRightInput()->getStamp())) { + } else if (compareOp->getComparator() == ir::CompareOperation::EQ && compareOp->getLeftInput()->getStamp() == Type::ptr && isInteger(compareOp->getRightInput()->getStamp())) { // add null check throw NotImplementedException("Null check is not implemented"); // auto null = @@ -583,25 +573,24 @@ void MLIRLoweringProvider::generateMLIR(ir::CompareOperation* compareOp, ValueFr // frame.setValue(compareOp->getIdentifier(), cmpOp); } else if (isInteger(leftStamp) && isInteger(rightStamp)) { // handle integer - auto cmpOp = builder->create( - getNameLoc("comparison"), convertToIntMLIRComparison(compareOp->getComparator(), leftStamp), - frame.getValue(compareOp->getLeftInput()->getIdentifier()), - frame.getValue(compareOp->getRightInput()->getIdentifier())); + auto cmpOp = builder->create(getNameLoc("comparison"), convertToIntMLIRComparison(compareOp->getComparator(), leftStamp), frame.getValue(compareOp->getLeftInput()->getIdentifier()), + frame.getValue(compareOp->getRightInput()->getIdentifier())); frame.setValue(compareOp->getIdentifier(), cmpOp); } else if (isFloat(leftStamp) && isFloat(rightStamp)) { // handle float comparison - auto cmpOp = builder->create(getNameLoc("comparison"), - convertToFloatMLIRComparison(compareOp->getComparator()), - frame.getValue(compareOp->getLeftInput()->getIdentifier()), + auto cmpOp = builder->create(getNameLoc("comparison"), convertToFloatMLIRComparison(compareOp->getComparator()), frame.getValue(compareOp->getLeftInput()->getIdentifier()), frame.getValue(compareOp->getRightInput()->getIdentifier())); frame.setValue(compareOp->getIdentifier(), cmpOp); } else if (leftStamp == Type::b && rightStamp == Type::b) { // handle float comparison - auto cmpOp = builder->create(getNameLoc("comparison"), - convertToBooleanMLIRComparison(compareOp->getComparator()), - frame.getValue(compareOp->getLeftInput()->getIdentifier()), + auto cmpOp = builder->create(getNameLoc("comparison"), convertToBooleanMLIRComparison(compareOp->getComparator()), frame.getValue(compareOp->getLeftInput()->getIdentifier()), frame.getValue(compareOp->getRightInput()->getIdentifier())); frame.setValue(compareOp->getIdentifier(), cmpOp); + } else if (leftStamp == Type::ptr && rightStamp == Type::ptr) { + // handle float comparison + auto cmpOp = builder->create(getNameLoc("comparison"), convertToLLVMComparison(compareOp->getComparator()), frame.getValue(compareOp->getLeftInput()->getIdentifier()), + frame.getValue(compareOp->getRightInput()->getIdentifier())); + frame.setValue(compareOp->getIdentifier(), cmpOp); } else { throw NotImplementedException("Unknown type to compare"); } @@ -623,8 +612,7 @@ void MLIRLoweringProvider::generateMLIR(ir::IfOperation* ifOp, ValueFrame& frame } builder->restoreInsertionPoint(parentBlockInsertionPoint); - builder->create(getNameLoc("branch"), frame.getValue(ifOp->getValue()->getIdentifier()), - trueBlock, trueBlockArgs, elseBlock, elseBlockArgs); + builder->create(getNameLoc("branch"), frame.getValue(ifOp->getValue()->getIdentifier()), trueBlock, trueBlockArgs, elseBlock, elseBlockArgs); } void MLIRLoweringProvider::generateMLIR(ir::BranchOperation* branchOp, ValueFrame& frame) { @@ -665,9 +653,7 @@ mlir::Block* MLIRLoweringProvider::generateBasicBlock(ir::BasicBlockInvocation& return mlirBasicBlock; } -MLIRLoweringProvider::ValueFrame -MLIRLoweringProvider::createFrameFromParentBlock(MLIRLoweringProvider::ValueFrame& frame, - ir::BasicBlockInvocation& invocation) { +MLIRLoweringProvider::ValueFrame MLIRLoweringProvider::createFrameFromParentBlock(MLIRLoweringProvider::ValueFrame& frame, ir::BasicBlockInvocation& invocation) { auto invocationArguments = invocation.getArguments(); auto& childBlockArguments = invocation.getBlock()->getArguments(); // NES_ASSERT(invocationArguments.size() == childBlockArguments.size(), @@ -694,30 +680,25 @@ void MLIRLoweringProvider::generateMLIR(ir::CastOperation* castOperation, MLIRLo // we skip the cast if input bit width are the same. frame.setValue(castOperation->getIdentifier(), mlirInput); } else if (isSignedInteger(outputStamp)) { - auto mlirCast = - builder->create(getNameLoc("location"), getMLIRType(outputStamp), mlirInput); + auto mlirCast = builder->create(getNameLoc("location"), getMLIRType(outputStamp), mlirInput); frame.setValue(castOperation->getIdentifier(), mlirCast); } else { - auto mlirCast = - builder->create(getNameLoc("location"), getMLIRType(outputStamp), mlirInput); + auto mlirCast = builder->create(getNameLoc("location"), getMLIRType(outputStamp), mlirInput); frame.setValue(castOperation->getIdentifier(), mlirCast); } return; } else if (isFloat(inputStamp) && isFloat(outputStamp)) { auto mlirInput = frame.getValue(castOperation->getInput()->getIdentifier()); - auto mlirCast = - builder->create(getNameLoc("location"), getMLIRType(outputStamp), mlirInput); + auto mlirCast = builder->create(getNameLoc("location"), getMLIRType(outputStamp), mlirInput); frame.setValue(castOperation->getIdentifier(), mlirCast); return; } else if (isInteger(inputStamp) && isFloat(outputStamp)) { auto mlirInput = frame.getValue(castOperation->getInput()->getIdentifier()); if (isSignedInteger(inputStamp)) { - auto mlirCast = - builder->create(getNameLoc("location"), getMLIRType(outputStamp), mlirInput); + auto mlirCast = builder->create(getNameLoc("location"), getMLIRType(outputStamp), mlirInput); frame.setValue(castOperation->getIdentifier(), mlirCast); } else { - auto mlirCast = - builder->create(getNameLoc("location"), getMLIRType(outputStamp), mlirInput); + auto mlirCast = builder->create(getNameLoc("location"), getMLIRType(outputStamp), mlirInput); frame.setValue(castOperation->getIdentifier(), mlirCast); } return; @@ -726,8 +707,7 @@ void MLIRLoweringProvider::generateMLIR(ir::CastOperation* castOperation, MLIRLo } } -void MLIRLoweringProvider::generateMLIR(ir::BinaryCompOperation* binaryCompOperation, - nautilus::compiler::mlir::MLIRLoweringProvider::ValueFrame& frame) { +void MLIRLoweringProvider::generateMLIR(ir::BinaryCompOperation* binaryCompOperation, nautilus::compiler::mlir::MLIRLoweringProvider::ValueFrame& frame) { auto leftInput = frame.getValue(binaryCompOperation->getLeftInput()->getIdentifier()); auto rightInput = frame.getValue(binaryCompOperation->getRightInput()->getIdentifier()); @@ -746,8 +726,7 @@ void MLIRLoweringProvider::generateMLIR(ir::BinaryCompOperation* binaryCompOpera frame.setValue(binaryCompOperation->getIdentifier(), op); } -void MLIRLoweringProvider::generateMLIR(ir::ShiftOperation* shiftOperation, - nautilus::compiler::mlir::MLIRLoweringProvider::ValueFrame& frame) { +void MLIRLoweringProvider::generateMLIR(ir::ShiftOperation* shiftOperation, nautilus::compiler::mlir::MLIRLoweringProvider::ValueFrame& frame) { auto leftInput = frame.getValue(shiftOperation->getLeftInput()->getIdentifier()); auto rightInput = frame.getValue(shiftOperation->getRightInput()->getIdentifier()); @@ -763,11 +742,8 @@ void MLIRLoweringProvider::generateMLIR(ir::ShiftOperation* shiftOperation, frame.setValue(shiftOperation->getIdentifier(), op); } -void MLIRLoweringProvider::generateMLIR(ir::ConstBooleanOperation* constBooleanOp, - MLIRLoweringProvider::ValueFrame& frame) { - auto constOp = builder->create( - getNameLoc("location"), builder->getI1Type(), - builder->getIntegerAttr(builder->getI1Type(), constBooleanOp->getValue())); +void MLIRLoweringProvider::generateMLIR(ir::ConstBooleanOperation* constBooleanOp, MLIRLoweringProvider::ValueFrame& frame) { + auto constOp = builder->create(getNameLoc("location"), builder->getI1Type(), builder->getIntegerAttr(builder->getI1Type(), constBooleanOp->getValue())); frame.setValue(constBooleanOp->getIdentifier(), constOp); } diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRPassManager.cpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRPassManager.cpp index cb9974f2..35512cdc 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRPassManager.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRPassManager.cpp @@ -43,9 +43,7 @@ std::unique_ptr getMLIROptimizationPass(MLIRPassManager::Optimizatio throw NotImplementedException("pass is not supported"); } -int MLIRPassManager::lowerAndOptimizeMLIRModule(mlir::OwningOpRef& module, - const std::vector& loweringPasses, - const std::vector& optimizationPasses) { +int MLIRPassManager::lowerAndOptimizeMLIRModule(mlir::OwningOpRef& module, const std::vector& loweringPasses, const std::vector& optimizationPasses) { mlir::PassManager passManager(module->getContext()); // Apply optimization passes. diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRUtility.cpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRUtility.cpp index d2e3663e..c250919c 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRUtility.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRUtility.cpp @@ -46,8 +46,7 @@ int MLIRUtility::loadAndExecuteModuleFromString(const std::string& mlirString, c return 0; } -std::unique_ptr -MLIRUtility::compileNESIRToMachineCode(std::shared_ptr ir) { +std::unique_ptr MLIRUtility::compileNESIRToMachineCode(std::shared_ptr ir) { mlir::MLIRContext context; auto loweringProvider = std::make_unique(context); auto module = loweringProvider->generateModuleFromIR(ir); @@ -60,7 +59,6 @@ MLIRUtility::compileNESIRToMachineCode(std::shared_ptrgetJitProxyFunctionSymbols(), - loweringProvider->getJitProxyTargetAddresses()); + return MLIR::JITCompiler::jitCompileModule(module, optPipeline, loweringProvider->getJitProxyFunctionSymbols(), loweringProvider->getJitProxyTargetAddresses()); } } // namespace nautilus::compiler::mlir diff --git a/nautilus/src/nautilus/compiler/ir/IRDumpHandler.cpp b/nautilus/src/nautilus/compiler/ir/IRDumpHandler.cpp index 5b52b0f9..8977b775 100644 --- a/nautilus/src/nautilus/compiler/ir/IRDumpHandler.cpp +++ b/nautilus/src/nautilus/compiler/ir/IRDumpHandler.cpp @@ -17,16 +17,14 @@ std::shared_ptr NESIRDumpHandler::create(std::ostream& out) { return std::make_shared(out); } -const BasicBlock* NESIRDumpHandler::getNextLowerOrEqualLevelBasicBlock(const BasicBlock* thenBlock, - int ifParentBlockLevel) { +const BasicBlock* NESIRDumpHandler::getNextLowerOrEqualLevelBasicBlock(const BasicBlock* thenBlock, int ifParentBlockLevel) { auto& terminatorOp = thenBlock->getOperations().back(); if (terminatorOp->getOperationType() == Operation::OperationType::BranchOp) { auto branchOp = dynamic_cast(terminatorOp.get()); if (branchOp->getNextBlockInvocation().getBlock()->getScopeLevel() <= (uint32_t) ifParentBlockLevel) { return branchOp->getNextBlockInvocation().getBlock(); } else { - return getNextLowerOrEqualLevelBasicBlock(branchOp->getNextBlockInvocation().getBlock(), - ifParentBlockLevel); + return getNextLowerOrEqualLevelBasicBlock(branchOp->getNextBlockInvocation().getBlock(), ifParentBlockLevel); } } else if (terminatorOp->getOperationType() == Operation::OperationType::IfOp) { auto ifOp = dynamic_cast(terminatorOp.get()); @@ -49,9 +47,8 @@ void NESIRDumpHandler::dumpHelper(Operation* terminatorOp, int32_t) { } case Operation::OperationType::IfOp: { auto ifOp = static_cast(terminatorOp); - auto lastTerminatorOp = getNextLowerOrEqualLevelBasicBlock( - ifOp->getTrueBlockInvocation().getBlock(), - ifOp->getTrueBlockInvocation().getBlock()->getScopeLevel() - 1); // todo can lead to error #3234 + auto lastTerminatorOp = getNextLowerOrEqualLevelBasicBlock(ifOp->getTrueBlockInvocation().getBlock(), + ifOp->getTrueBlockInvocation().getBlock()->getScopeLevel() - 1); // todo can lead to error #3234 dumpHelper(ifOp->getTrueBlockInvocation().getBlock()); dumpHelper(ifOp->getFalseBlockInvocation().getBlock()); if (lastTerminatorOp) { @@ -72,11 +69,9 @@ void NESIRDumpHandler::dumpHelper(const BasicBlock* basicBlock) { visitedBlocks.emplace(basicBlock->getIdentifier()); out << '\n' << "Block_" << basicBlock->getIdentifier() << '('; if (basicBlock->getArguments().size() > 0) { - out << basicBlock->getArguments().at(0)->getIdentifier().toString() << ":" - << toString(basicBlock->getArguments().at(0)->getStamp()); + out << basicBlock->getArguments().at(0)->getIdentifier().toString() << ":" << toString(basicBlock->getArguments().at(0)->getStamp()); for (int i = 1; i < (int) basicBlock->getArguments().size(); ++i) { - out << ", " << basicBlock->getArguments().at(i)->getIdentifier().toString() << ":" - << toString(basicBlock->getArguments().at(i)->getStamp()); + out << ", " << basicBlock->getArguments().at(i)->getIdentifier().toString() << ":" << toString(basicBlock->getArguments().at(i)->getStamp()); } } out << "):" << '\n'; diff --git a/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.cpp b/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.cpp index 01464dbc..cc654017 100644 --- a/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.cpp +++ b/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.cpp @@ -7,11 +7,8 @@ #include namespace nautilus::compiler::ir { -BasicBlock::BasicBlock(const std::string& identifier, int32_t scopeLevel, - std::vector>& operations, - std::vector>& arguments) - : identifier(identifier), scopeLevel(scopeLevel), numLoopBackEdges(0), operations(std::move(operations)), - arguments(std::move(arguments)) { +BasicBlock::BasicBlock(const std::string& identifier, int32_t scopeLevel, std::vector>& operations, std::vector>& arguments) + : identifier(identifier), scopeLevel(scopeLevel), numLoopBackEdges(0), operations(std::move(operations)), arguments(std::move(arguments)) { } void BasicBlock::addNextBlock(BasicBlock* nextBlock, const std::vector& ops) { diff --git a/nautilus/src/nautilus/compiler/ir/blocks/BasicBlockArgument.cpp b/nautilus/src/nautilus/compiler/ir/blocks/BasicBlockArgument.cpp index 433763db..d849330e 100644 --- a/nautilus/src/nautilus/compiler/ir/blocks/BasicBlockArgument.cpp +++ b/nautilus/src/nautilus/compiler/ir/blocks/BasicBlockArgument.cpp @@ -2,8 +2,7 @@ #include "nautilus/compiler/ir/blocks/BasicBlockArgument.hpp" namespace nautilus::compiler::ir { -BasicBlockArgument::BasicBlockArgument(const OperationIdentifier identifier, Type stamp) - : Operation(OperationType::BasicBlockArgument, identifier, stamp) { +BasicBlockArgument::BasicBlockArgument(const OperationIdentifier identifier, Type stamp) : Operation(OperationType::BasicBlockArgument, identifier, stamp) { } std::ostream& operator<<(std::ostream& os, const BasicBlockArgument& argument) { diff --git a/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/AddOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/AddOperation.cpp index 8d51509c..4bdd59e0 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/AddOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/AddOperation.cpp @@ -3,13 +3,11 @@ namespace nautilus::compiler::ir { -AddOperation::AddOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) - : BinaryOperation(OperationType::AddOp, identifier, leftInput->getStamp(), leftInput, rightInput) { +AddOperation::AddOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) : BinaryOperation(OperationType::AddOp, identifier, leftInput->getStamp(), leftInput, rightInput) { } std::string AddOperation::toString() { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " + " + - getRightInput()->getIdentifier().toString(); + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " + " + getRightInput()->getIdentifier().toString(); } bool AddOperation::classof(const Operation* Op) { diff --git a/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/DivOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/DivOperation.cpp index 27723687..e268d13f 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/DivOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/DivOperation.cpp @@ -3,13 +3,11 @@ #include namespace nautilus::compiler::ir { -DivOperation::DivOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) - : BinaryOperation(OperationType::DivOp, identifier, leftInput->getStamp(), leftInput, rightInput) { +DivOperation::DivOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) : BinaryOperation(OperationType::DivOp, identifier, leftInput->getStamp(), leftInput, rightInput) { } std::string DivOperation::toString() { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " / " + - getRightInput()->getIdentifier().toString(); + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " / " + getRightInput()->getIdentifier().toString(); } bool DivOperation::classof(const Operation* Op) { diff --git a/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/ModOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/ModOperation.cpp index ad058c19..3a0e009a 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/ModOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/ModOperation.cpp @@ -4,13 +4,11 @@ #include namespace nautilus::compiler::ir { -ModOperation::ModOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) - : BinaryOperation(OperationType::ModOp, identifier, leftInput->getStamp(), leftInput, rightInput) { +ModOperation::ModOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) : BinaryOperation(OperationType::ModOp, identifier, leftInput->getStamp(), leftInput, rightInput) { } std::string ModOperation::toString() { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " % " + - getRightInput()->getIdentifier().toString(); + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " % " + getRightInput()->getIdentifier().toString(); } bool ModOperation::classof(const Operation* Op) { diff --git a/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/MulOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/MulOperation.cpp index 253317d3..c9ffc95c 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/MulOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/MulOperation.cpp @@ -4,13 +4,11 @@ #include namespace nautilus::compiler::ir { -MulOperation::MulOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) - : BinaryOperation(OperationType::MulOp, identifier, leftInput->getStamp(), leftInput, rightInput) { +MulOperation::MulOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) : BinaryOperation(OperationType::MulOp, identifier, leftInput->getStamp(), leftInput, rightInput) { } std::string MulOperation::toString() { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " * " + - getRightInput()->getIdentifier().toString(); + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " * " + getRightInput()->getIdentifier().toString(); } bool MulOperation::classof(const Operation* Op) { diff --git a/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/SubOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/SubOperation.cpp index d4f51010..6d6f8324 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/SubOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ArithmeticOperations/SubOperation.cpp @@ -3,13 +3,11 @@ #include namespace nautilus::compiler::ir { -SubOperation::SubOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) - : BinaryOperation(OperationType::SubOp, identifier, leftInput->getStamp(), leftInput, rightInput) { +SubOperation::SubOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) : BinaryOperation(OperationType::SubOp, identifier, leftInput->getStamp(), leftInput, rightInput) { } std::string SubOperation::toString() { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " - " + - getRightInput()->getIdentifier().toString(); + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " - " + getRightInput()->getIdentifier().toString(); } bool SubOperation::classof(const Operation* Op) { diff --git a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.cpp index 47a778da..6758f68b 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/BinaryCompOperation.cpp @@ -4,8 +4,7 @@ namespace nautilus::compiler::ir { -BinaryCompOperation::BinaryCompOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput, - Type type) +BinaryCompOperation::BinaryCompOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput, Type type) : BinaryOperation(OperationType::BinaryComp, identifier, leftInput->getStamp(), leftInput, rightInput), type(type) { } @@ -24,8 +23,7 @@ std::string BinaryCompOperation::toString() { break; } - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + opSymbol + - getRightInput()->getIdentifier().toString(); + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + opSymbol + getRightInput()->getIdentifier().toString(); } BinaryCompOperation::Type BinaryCompOperation::getType() const { diff --git a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.cpp index 279143e3..eaa795b8 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.cpp @@ -3,8 +3,7 @@ namespace nautilus::compiler::ir { -NegateOperation::NegateOperation(OperationIdentifier identifier, Operation* input) - : Operation(OperationType::NegateOp, identifier, input->getStamp(), {input}) { +NegateOperation::NegateOperation(OperationIdentifier identifier, Operation* input) : Operation(OperationType::NegateOp, identifier, input->getStamp(), {input}) { } std::string NegateOperation::toString() { diff --git a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.cpp index 80171af6..50f9b816 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/BinaryOperations/ShiftOperation.cpp @@ -4,18 +4,14 @@ namespace nautilus::compiler::ir { -ShiftOperation::ShiftOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput, - ShiftType type) - : BinaryOperation(OperationType::ShiftOp, identifier, leftInput->getStamp(), leftInput, rightInput), type(type) { +ShiftOperation::ShiftOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput, ShiftType type) : BinaryOperation(OperationType::ShiftOp, identifier, leftInput->getStamp(), leftInput, rightInput), type(type) { } std::string ShiftOperation::toString() { if (type == LS) { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " << " + - getRightInput()->getIdentifier().toString(); + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " << " + getRightInput()->getIdentifier().toString(); } else { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " >> " + - getRightInput()->getIdentifier().toString(); + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " >> " + getRightInput()->getIdentifier().toString(); } } diff --git a/nautilus/src/nautilus/compiler/ir/operations/CastOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/CastOperation.cpp index 4dfa2da4..9d539bda 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/CastOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/CastOperation.cpp @@ -3,8 +3,7 @@ namespace nautilus::compiler::ir { -CastOperation::CastOperation(OperationIdentifier identifier, Operation* input, Type targetStamp) - : Operation(OperationType::CastOp, identifier, targetStamp, {input}) { +CastOperation::CastOperation(OperationIdentifier identifier, Operation* input, Type targetStamp) : Operation(OperationType::CastOp, identifier, targetStamp, {input}) { } Operation* CastOperation::getInput() { @@ -16,8 +15,7 @@ void CastOperation::setInput(Operation* newInput) { } std::string CastOperation::toString() { - return identifier.toString() + " = " + getInput()->getIdentifier().toString() + " cast_to " + - nautilus::toString(getStamp()); + return identifier.toString() + " = " + getInput()->getIdentifier().toString() + " cast_to " + nautilus::toString(getStamp()); } } // namespace nautilus::compiler::ir diff --git a/nautilus/src/nautilus/compiler/ir/operations/ConstBooleanOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ConstBooleanOperation.cpp index 8f0da804..a26c59e4 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ConstBooleanOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ConstBooleanOperation.cpp @@ -5,8 +5,7 @@ namespace nautilus::compiler::ir { -ConstBooleanOperation::ConstBooleanOperation(OperationIdentifier identifier, bool constantValue) - : Operation(OperationType::ConstBooleanOp, identifier, Type::b), constantValue(constantValue) { +ConstBooleanOperation::ConstBooleanOperation(OperationIdentifier identifier, bool constantValue) : Operation(OperationType::ConstBooleanOp, identifier, Type::b), constantValue(constantValue) { } bool ConstBooleanOperation::getValue() { diff --git a/nautilus/src/nautilus/compiler/ir/operations/ConstFloatOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ConstFloatOperation.cpp index ca5ccce4..1b71f232 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ConstFloatOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ConstFloatOperation.cpp @@ -5,8 +5,7 @@ namespace nautilus::compiler::ir { -ConstFloatOperation::ConstFloatOperation(OperationIdentifier identifier, double constantValue, Type stamp) - : Operation(OperationType::ConstFloatOp, identifier, stamp), constantValue(constantValue) { +ConstFloatOperation::ConstFloatOperation(OperationIdentifier identifier, double constantValue, Type stamp) : Operation(OperationType::ConstFloatOp, identifier, stamp), constantValue(constantValue) { } double ConstFloatOperation::getValue() { diff --git a/nautilus/src/nautilus/compiler/ir/operations/ConstIntOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ConstIntOperation.cpp index 8aac281a..93f72eb5 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ConstIntOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ConstIntOperation.cpp @@ -6,8 +6,7 @@ namespace nautilus::compiler::ir { -ConstIntOperation::ConstIntOperation(OperationIdentifier identifier, int64_t constantValue, Type stamp) - : Operation(OperationType::ConstIntOp, identifier, stamp), constantValue(constantValue) { +ConstIntOperation::ConstIntOperation(OperationIdentifier identifier, int64_t constantValue, Type stamp) : Operation(OperationType::ConstIntOp, identifier, stamp), constantValue(constantValue) { } int64_t ConstIntOperation::getValue() { diff --git a/nautilus/src/nautilus/compiler/ir/operations/ConstPtrOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ConstPtrOperation.cpp index f6815f7b..f6034db6 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ConstPtrOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ConstPtrOperation.cpp @@ -6,8 +6,7 @@ namespace nautilus::compiler::ir { -ConstPtrOperation::ConstPtrOperation(OperationIdentifier identifier, void* constantValue) - : Operation(OperationType::ConstPtrOp, identifier, Type::ptr), constantValue(constantValue) { +ConstPtrOperation::ConstPtrOperation(OperationIdentifier identifier, void* constantValue) : Operation(OperationType::ConstPtrOp, identifier, Type::ptr), constantValue(constantValue) { } void* ConstPtrOperation::getValue() { diff --git a/nautilus/src/nautilus/compiler/ir/operations/FunctionOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/FunctionOperation.cpp index baad11a7..548e277c 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/FunctionOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/FunctionOperation.cpp @@ -4,12 +4,8 @@ namespace nautilus::compiler::ir { -FunctionOperation::FunctionOperation(std::string name, std::vector>& functionBasicBlocks, - std::vector inputArgs, std::vector inputArgNames, - Type outputArg) - : Operation(OperationType::FunctionOp, outputArg), name(std::move(name)), - functionBasicBlocks(std::move(functionBasicBlocks)), inputArgs(std::move(inputArgs)), - inputArgNames(std::move(inputArgNames)) { +FunctionOperation::FunctionOperation(std::string name, std::vector>& functionBasicBlocks, std::vector inputArgs, std::vector inputArgNames, Type outputArg) + : Operation(OperationType::FunctionOp, outputArg), name(std::move(name)), functionBasicBlocks(std::move(functionBasicBlocks)), inputArgs(std::move(inputArgs)), inputArgNames(std::move(inputArgNames)) { } const std::string& FunctionOperation::getName() const { diff --git a/nautilus/src/nautilus/compiler/ir/operations/IfOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/IfOperation.cpp index cc452bd8..7f095ce5 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/IfOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/IfOperation.cpp @@ -43,8 +43,7 @@ void IfOperation::setMergeBlock(BasicBlockPtr mergeBlock) { } std::string IfOperation::toString() { - std::string baseString = "if " + getValue()->getIdentifier().toString() + " ? Block_" + - trueBlockInvocation.getBlock()->getIdentifier() + '('; + std::string baseString = "if " + getValue()->getIdentifier().toString() + " ? Block_" + trueBlockInvocation.getBlock()->getIdentifier() + '('; // "if " + comparatorOp->getIdentifier() + " ? Block_" + trueBlockInvocation.getBlock()->getIdentifier() + '('; if (trueBlockInvocation.getArguments().size() > 0) { baseString += trueBlockInvocation.getArguments()[0]->getIdentifier().toString(); diff --git a/nautilus/src/nautilus/compiler/ir/operations/LoadOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/LoadOperation.cpp index a8d83b60..bb3f5de3 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/LoadOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/LoadOperation.cpp @@ -3,8 +3,7 @@ namespace nautilus::compiler::ir { -LoadOperation::LoadOperation(const OperationIdentifier& identifier, Operation* address, Type type) - : Operation(OperationType::LoadOp, identifier, type, {address}) { +LoadOperation::LoadOperation(const OperationIdentifier& identifier, Operation* address, Type type) : Operation(OperationType::LoadOp, identifier, type, {address}) { } const Operation* LoadOperation::getAddress() { diff --git a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/AndOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/AndOperation.cpp index cf5965ff..f5312ea3 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/AndOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/AndOperation.cpp @@ -3,13 +3,11 @@ namespace nautilus::compiler::ir { -AndOperation::AndOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) - : BinaryOperation(OperationType::AndOp, identifier, Type::b, leftInput, rightInput) { +AndOperation::AndOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) : BinaryOperation(OperationType::AndOp, identifier, Type::b, leftInput, rightInput) { } std::string AndOperation::toString() { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " and " + - getRightInput()->getIdentifier().toString(); + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " and " + getRightInput()->getIdentifier().toString(); } bool AndOperation::classof(const Operation* Op) { diff --git a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.cpp index 43d95a92..b1f7a89b 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.cpp @@ -3,10 +3,8 @@ #include "nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.hpp" namespace nautilus::compiler::ir { -CompareOperation::CompareOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput, - Comparator comparator) - : BinaryOperation(Operation::OperationType::CompareOp, identifier, Type::b, leftInput, rightInput), - comparator(comparator) { +CompareOperation::CompareOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput, Comparator comparator) + : BinaryOperation(Operation::OperationType::CompareOp, identifier, Type::b, leftInput, rightInput), comparator(comparator) { } CompareOperation::Comparator CompareOperation::getComparator() { @@ -64,8 +62,7 @@ std::string CompareOperation::getComparatorAsString() { } std::string CompareOperation::toString() { - return identifier.toString() + " = " + getLeftInput()->getIdentifier().toString() + " " + getComparatorAsString() + - " " + getRightInput()->getIdentifier().toString(); + return identifier.toString() + " = " + getLeftInput()->getIdentifier().toString() + " " + getComparatorAsString() + " " + getRightInput()->getIdentifier().toString(); } } // namespace nautilus::compiler::ir diff --git a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.cpp index aac63993..32d72405 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/NotOperation.cpp @@ -3,8 +3,7 @@ namespace nautilus::compiler::ir { -NotOperation::NotOperation(OperationIdentifier identifier, Operation* input) - : Operation(OperationType::NotOp, identifier, Type::b, {input}) { +NotOperation::NotOperation(OperationIdentifier identifier, Operation* input) : Operation(OperationType::NotOp, identifier, Type::b, {input}) { } std::string NotOperation::toString() { diff --git a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/OrOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/OrOperation.cpp index 858b864b..7147c80c 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/OrOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/LogicalOperations/OrOperation.cpp @@ -3,13 +3,11 @@ namespace nautilus::compiler::ir { -OrOperation::OrOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) - : BinaryOperation(OperationType::OrOp, identifier, Type::b, leftInput, rightInput) { +OrOperation::OrOperation(OperationIdentifier identifier, Operation* leftInput, Operation* rightInput) : BinaryOperation(OperationType::OrOp, identifier, Type::b, leftInput, rightInput) { } std::string OrOperation::toString() { - return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " or " + - getRightInput()->getIdentifier().toString(); + return getIdentifier().toString() + " = " + getLeftInput()->getIdentifier().toString() + " or " + getRightInput()->getIdentifier().toString(); ; } diff --git a/nautilus/src/nautilus/compiler/ir/operations/Operation.cpp b/nautilus/src/nautilus/compiler/ir/operations/Operation.cpp index 7583ad7c..d68f7261 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/Operation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/Operation.cpp @@ -4,13 +4,13 @@ #include "nautilus/compiler/ir/operations/ArithmeticOperations/DivOperation.hpp" #include "nautilus/compiler/ir/operations/ArithmeticOperations/MulOperation.hpp" #include "nautilus/compiler/ir/operations/ArithmeticOperations/SubOperation.hpp" +#include "nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.hpp" #include "nautilus/compiler/ir/operations/BranchOperation.hpp" #include "nautilus/compiler/ir/operations/CastOperation.hpp" #include "nautilus/compiler/ir/operations/IfOperation.hpp" #include "nautilus/compiler/ir/operations/LoadOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/AndOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.hpp" -#include "nautilus/compiler/ir/operations/BinaryOperations/NegateOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/OrOperation.hpp" #include "nautilus/compiler/ir/operations/ProxyCallOperation.hpp" #include "nautilus/compiler/ir/operations/ReturnOperation.hpp" @@ -18,13 +18,10 @@ #include namespace nautilus::compiler::ir { -Operation::Operation(OperationType opType, const OperationIdentifier& identifier, Type stamp, - const std::vector& inputs) - : opType(opType), identifier(identifier), stamp(stamp), inputs(inputs) { +Operation::Operation(OperationType opType, const OperationIdentifier& identifier, Type stamp, const std::vector& inputs) : opType(opType), identifier(identifier), stamp(stamp), inputs(inputs) { } -Operation::Operation(OperationType opType, Type stamp, const std::vector& inputs) - : opType(opType), identifier(0), stamp(stamp), inputs(inputs) { +Operation::Operation(OperationType opType, Type stamp, const std::vector& inputs) : opType(opType), identifier(0), stamp(stamp), inputs(inputs) { } Operation::~Operation() noexcept = default; @@ -80,13 +77,10 @@ bool OperationIdentifier::operator>=(const OperationIdentifier& rhs) const { } bool Operation::isConstOperation() const { - return opType == OperationType::ConstBooleanOp || opType == OperationType::ConstFloatOp || - opType == OperationType::ConstIntOp; + return opType == OperationType::ConstBooleanOp || opType == OperationType::ConstFloatOp || opType == OperationType::ConstIntOp; } -BinaryOperation::BinaryOperation(OperationType opType, const OperationIdentifier& identifier, Type type, - Operation* left, Operation* right) - : Operation(opType, identifier, type, {left, right}) { +BinaryOperation::BinaryOperation(OperationType opType, const OperationIdentifier& identifier, Type type, Operation* left, Operation* right) : Operation(opType, identifier, type, {left, right}) { } Operation* BinaryOperation::getLeftInput() { diff --git a/nautilus/src/nautilus/compiler/ir/operations/ProxyCallOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ProxyCallOperation.cpp index 7490d65d..d703f92e 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ProxyCallOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ProxyCallOperation.cpp @@ -3,15 +3,11 @@ #include namespace nautilus::compiler::ir { -ProxyCallOperation::ProxyCallOperation(OperationIdentifier identifier, const std::vector& inputArguments, - Type resultType) - : Operation(Operation::OperationType::ProxyCallOp, identifier, resultType, inputArguments) { +ProxyCallOperation::ProxyCallOperation(OperationIdentifier identifier, const std::vector& inputArguments, Type resultType) : Operation(Operation::OperationType::ProxyCallOp, identifier, resultType, inputArguments) { } -ProxyCallOperation::ProxyCallOperation(std::string functionSymbol, void* functionPtr, OperationIdentifier identifier, - std::vector inputArguments, Type resultType) - : Operation(Operation::OperationType::ProxyCallOp, identifier, resultType, std::move(inputArguments)), - mangedFunctionSymbol(std::move(functionSymbol)), functionPtr(functionPtr) { +ProxyCallOperation::ProxyCallOperation(std::string functionSymbol, void* functionPtr, OperationIdentifier identifier, std::vector inputArguments, Type resultType) + : Operation(Operation::OperationType::ProxyCallOp, identifier, resultType, std::move(inputArguments)), mangedFunctionSymbol(std::move(functionSymbol)), functionPtr(functionPtr) { } const std::vector& ProxyCallOperation::getInputArguments() const { diff --git a/nautilus/src/nautilus/compiler/ir/operations/ReturnOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/ReturnOperation.cpp index c4def18f..fd5d8409 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/ReturnOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/ReturnOperation.cpp @@ -7,8 +7,7 @@ namespace nautilus::compiler::ir { ReturnOperation::ReturnOperation() : Operation(Operation::OperationType::ReturnOp, Type::v) { } -ReturnOperation::ReturnOperation(Operation* returnValue) - : Operation(Operation::OperationType::ReturnOp, returnValue->getStamp(), {returnValue}) { +ReturnOperation::ReturnOperation(Operation* returnValue) : Operation(Operation::OperationType::ReturnOp, returnValue->getStamp(), {returnValue}) { } std::string ReturnOperation::toString() { diff --git a/nautilus/src/nautilus/compiler/ir/operations/StoreOperation.cpp b/nautilus/src/nautilus/compiler/ir/operations/StoreOperation.cpp index efddb22e..cc231d8f 100644 --- a/nautilus/src/nautilus/compiler/ir/operations/StoreOperation.cpp +++ b/nautilus/src/nautilus/compiler/ir/operations/StoreOperation.cpp @@ -4,8 +4,7 @@ namespace nautilus::compiler::ir { -StoreOperation::StoreOperation(Operation* value, Operation* address) - : Operation(OperationType::StoreOp, Type::v, {value, address}) { +StoreOperation::StoreOperation(Operation* value, Operation* address) : Operation(OperationType::StoreOp, Type::v, {value, address}) { } Operation* StoreOperation::getValue() { diff --git a/nautilus/src/nautilus/tracing/ExecutionTrace.cpp b/nautilus/src/nautilus/tracing/ExecutionTrace.cpp index 82dbb8d4..fd2c118b 100644 --- a/nautilus/src/nautilus/tracing/ExecutionTrace.cpp +++ b/nautilus/src/nautilus/tracing/ExecutionTrace.cpp @@ -49,8 +49,7 @@ void ExecutionTrace::addReturn(Snapshot& snapshot, Type type, value_ref ref) { returnRefs.emplace_back(operationIdentifier); } -void ExecutionTrace::addAssignmentOperation(Snapshot& snapshot, nautilus::tracing::value_ref targetRef, - nautilus::tracing::value_ref srcRef, Type resultType) { +void ExecutionTrace::addAssignmentOperation(Snapshot& snapshot, nautilus::tracing::value_ref targetRef, nautilus::tracing::value_ref srcRef, Type resultType) { // std::cout << "\n Add Assign:" << std::endl; // std::cout << targetRef.ref << " - " << srcRef.ref << std::endl; // std::cout << *this << std::endl; @@ -65,8 +64,7 @@ void ExecutionTrace::addAssignmentOperation(Snapshot& snapshot, nautilus::tracin addTag(snapshot, operationIdentifier); } -void ExecutionTrace::addOperation(Snapshot& snapshot, Op& operation, Type& resultType, - nautilus::tracing::value_ref targetRef, nautilus::tracing::value_ref srcRef) { +void ExecutionTrace::addOperation(Snapshot& snapshot, Op& operation, Type& resultType, nautilus::tracing::value_ref targetRef, nautilus::tracing::value_ref srcRef) { // std::cout << "\n Add Operation:" << operation << std::endl; // std::cout << targetRef.ref << " - " << srcRef.ref << std::endl; // std::cout << *this << std::endl; @@ -77,8 +75,7 @@ void ExecutionTrace::addOperation(Snapshot& snapshot, Op& operation, Type& resul operations.emplace_back(snapshot, operation, resultType, targetRef, std::vector {srcRef}); } -value_ref ExecutionTrace::addOperationWithResult(Snapshot& snapshot, Op& operation, Type& resultType, - std::vector&& inputs) { +value_ref ExecutionTrace::addOperationWithResult(Snapshot& snapshot, Op& operation, Type& resultType, std::vector&& inputs) { // std::cout << "\n Add Operation:" << operation << std::endl; // std::cout << *this << std::endl; if (blocks.empty()) { @@ -86,8 +83,7 @@ value_ref ExecutionTrace::addOperationWithResult(Snapshot& snapshot, Op& operati } auto& operations = blocks[currentBlockIndex].operations; - auto& to = operations.emplace_back(snapshot, operation, resultType, value_ref(getNextValueRef(), resultType), - std::forward>(inputs)); + auto& to = operations.emplace_back(snapshot, operation, resultType, value_ref(getNextValueRef(), resultType), std::forward>(inputs)); auto operationIdentifier = getNextOperationIdentifier(); addTag(snapshot, operationIdentifier); @@ -108,8 +104,7 @@ void ExecutionTrace::addCmpOperation(Snapshot& snapshot, nautilus::tracing::valu auto operationInputs = std::vector {inputs, BlockRef(trueBlock), BlockRef(falseBlock)}; auto& operations = blocks[currentBlockIndex].operations; - operations.emplace_back(snapshot, CMP, Type::v, value_ref(getNextValueRef(), Type::v), - std::forward>(operationInputs)); + operations.emplace_back(snapshot, CMP, Type::v, value_ref(getNextValueRef(), Type::v), std::forward>(operationInputs)); auto operationIdentifier = getNextOperationIdentifier(); addTag(snapshot, operationIdentifier); } @@ -183,8 +178,7 @@ Block& ExecutionTrace::processControlFlowMerge(operation_identifier oi) { } // remove content beyond opID - referenceBlock.operations.erase(referenceBlock.operations.begin() + oi.operationIndex, - referenceBlock.operations.end()); + referenceBlock.operations.erase(referenceBlock.operations.begin() + oi.operationIndex, referenceBlock.operations.end()); // add jump from referenced block to merge block auto mergeBlockRef = BlockRef(mergedBlockId); diff --git a/nautilus/src/nautilus/tracing/TraceContext.cpp b/nautilus/src/nautilus/tracing/TraceContext.cpp index d04f7812..3c04db80 100644 --- a/nautilus/src/nautilus/tracing/TraceContext.cpp +++ b/nautilus/src/nautilus/tracing/TraceContext.cpp @@ -23,9 +23,7 @@ void TraceContext::terminate() { traceContext = nullptr; } -TraceContext::TraceContext(TagRecorder& tagRecorder) - : tagRecorder(tagRecorder), executionTrace(std::make_unique()), - symbolicExecutionContext(std::make_unique()) { +TraceContext::TraceContext(TagRecorder& tagRecorder) : tagRecorder(tagRecorder), executionTrace(std::make_unique()), symbolicExecutionContext(std::make_unique()) { } value_ref TraceContext::registerFunctionArgument(Type type, size_t index) { @@ -128,8 +126,7 @@ value_ref TraceContext::traceCopy(nautilus::tracing::value_ref ref) { throw TraceTerminationException(); } -value_ref TraceContext::traceCall(const std::string& functionName, void* fptn, Type resultType, - std::vector arguments) { +value_ref TraceContext::traceCall(const std::string& functionName, void* fptn, Type resultType, std::vector arguments) { if (symbolicExecutionContext->getCurrentMode() == SymbolicExecutionContext::MODE::FOLLOW) { auto currentOperation = executionTrace->getCurrentOperation(); executionTrace->nextOperation(); @@ -146,8 +143,7 @@ value_ref TraceContext::traceCall(const std::string& functionName, void* fptn, T .arguments = arguments, }); auto op = Op::CALL; - auto resultRef = - executionTrace->addOperationWithResult(tag, op, resultType, std::vector {functionArguments}); + auto resultRef = executionTrace->addOperationWithResult(tag, op, resultType, std::vector {functionArguments}); // executionTrace->variableBitset[resultRef] = true; return resultRef; } @@ -186,8 +182,7 @@ value_ref TraceContext::traceCast(value_ref state, Type resultType) { if (executionTrace->checkTag(tag)) { auto leftIV = InputVariant(state); auto op = Op::CAST; - auto resultRef = - executionTrace->addOperationWithResult(tag, op, resultType, std::vector {leftIV}); + auto resultRef = executionTrace->addOperationWithResult(tag, op, resultType, std::vector {leftIV}); // executionTrace->variableBitset[resultRef] = true; return resultRef; } @@ -206,8 +201,7 @@ void TraceContext::traceReturnOperation(Type type, value_ref ref) { return; } -value_ref TraceContext::traceUnaryOperation(nautilus::tracing::Op op, Type resultType, - nautilus::tracing::value_ref& inputRef) { +value_ref TraceContext::traceUnaryOperation(nautilus::tracing::Op op, Type resultType, nautilus::tracing::value_ref& inputRef) { if (isFollowing()) { auto currentOperation = executionTrace->getCurrentOperation(); executionTrace->nextOperation(); @@ -218,8 +212,7 @@ value_ref TraceContext::traceUnaryOperation(nautilus::tracing::Op op, Type resul auto tag = recordSnapshot(); if (executionTrace->checkTag(tag)) { auto inputVariant = InputVariant(inputRef); - auto resultRef = - executionTrace->addOperationWithResult(tag, op, resultType, std::vector {inputVariant}); + auto resultRef = executionTrace->addOperationWithResult(tag, op, resultType, std::vector {inputVariant}); return resultRef; } throw TraceTerminationException(); @@ -239,8 +232,7 @@ value_ref TraceContext::traceBinaryOperation(Op op, Type resultType, value_ref& if (executionTrace->checkTag(tag)) { auto leftIV = InputVariant(leftRef); auto rightIV = InputVariant(rightRef); - auto resultRef = - executionTrace->addOperationWithResult(tag, op, resultType, std::vector {leftIV, rightIV}); + auto resultRef = executionTrace->addOperationWithResult(tag, op, resultType, std::vector {leftIV, rightIV}); return resultRef; } throw TraceTerminationException(); diff --git a/nautilus/src/nautilus/tracing/TraceOperation.cpp b/nautilus/src/nautilus/tracing/TraceOperation.cpp index a3a9142f..f91a626c 100644 --- a/nautilus/src/nautilus/tracing/TraceOperation.cpp +++ b/nautilus/src/nautilus/tracing/TraceOperation.cpp @@ -30,12 +30,10 @@ std::ostream& operator<<(std::ostream& os, const BlockRef& ref) { return os; } -TraceOperation::TraceOperation(Snapshot& tag, Op op, Type resultType, value_ref ref, std::vector&& input) - : tag(tag), op(op), resultType(resultType), resultRef(ref), input(input) { +TraceOperation::TraceOperation(Snapshot& tag, Op op, Type resultType, value_ref ref, std::vector&& input) : tag(tag), op(op), resultType(resultType), resultRef(ref), input(input) { } -TraceOperation::TraceOperation(Op op, std::vector&& input) - : tag(), op(op), resultType(Type::v), resultRef(), input(input) { +TraceOperation::TraceOperation(Op op, std::vector&& input) : tag(), op(op), resultType(Type::v), resultRef(), input(input) { } std::ostream& operator<<(std::ostream& os, const TraceOperation& operation) { diff --git a/nautilus/src/nautilus/tracing/TracingUtil.cpp b/nautilus/src/nautilus/tracing/TracingUtil.cpp index a194f14d..57bcdc04 100644 --- a/nautilus/src/nautilus/tracing/TracingUtil.cpp +++ b/nautilus/src/nautilus/tracing/TracingUtil.cpp @@ -56,8 +56,7 @@ value_ref traceConstant(Type type, std::any&& value) { return TraceContext::get() != nullptr; } -value_ref traceCall(const std::string& functionName, void* fptn, Type resultType, - std::vector arguments) { +value_ref traceCall(const std::string& functionName, void* fptn, Type resultType, std::vector arguments) { return TraceContext::get()->traceCall(functionName, fptn, resultType, arguments); } @@ -72,43 +71,43 @@ template } #if __APPLE__ -#define INSTANTIATE_TRACE_FUNC(OP) \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ +#define INSTANTIATE_TRACE_FUNC(OP) \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); #else -#define INSTANTIATE_TRACE_FUNC(OP) \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ - template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ +#define INSTANTIATE_TRACE_FUNC(OP) \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ + template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); \ template value_ref traceBinaryOp(value_ref leftState, value_ref rightState); #endif -#define INSTANTIATE_TRACE_UN_FUNC(OP) \ - template value_ref traceUnaryOp(value_ref leftState); \ - template value_ref traceUnaryOp(value_ref leftState); \ - template value_ref traceUnaryOp(value_ref leftState); \ - template value_ref traceUnaryOp(value_ref leftState); \ - template value_ref traceUnaryOp(value_ref leftState); \ - template value_ref traceUnaryOp(value_ref leftState); \ - template value_ref traceUnaryOp(value_ref leftState); \ - template value_ref traceUnaryOp(value_ref leftState); \ - template value_ref traceUnaryOp(value_ref leftState); \ +#define INSTANTIATE_TRACE_UN_FUNC(OP) \ + template value_ref traceUnaryOp(value_ref leftState); \ + template value_ref traceUnaryOp(value_ref leftState); \ + template value_ref traceUnaryOp(value_ref leftState); \ + template value_ref traceUnaryOp(value_ref leftState); \ + template value_ref traceUnaryOp(value_ref leftState); \ + template value_ref traceUnaryOp(value_ref leftState); \ + template value_ref traceUnaryOp(value_ref leftState); \ + template value_ref traceUnaryOp(value_ref leftState); \ + template value_ref traceUnaryOp(value_ref leftState); \ template value_ref traceUnaryOp(value_ref leftState); template value_ref traceUnaryOp(value_ref leftState); diff --git a/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp b/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp index 4ffe2688..95984c02 100644 --- a/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp +++ b/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp @@ -11,8 +11,7 @@ std::shared_ptr SSACreationPhase::apply(std::shared_ptr trace) - : trace(std::move(trace)) { +SSACreationPhase::SSACreationPhaseContext::SSACreationPhaseContext(std::shared_ptr trace) : trace(std::move(trace)) { } Block& SSACreationPhase::SSACreationPhaseContext::getReturnBlock() { @@ -32,8 +31,7 @@ Block& SSACreationPhase::SSACreationPhaseContext::getReturnBlock() { auto& returnOpBlock = trace->getBlock(returnOp.blockIndex); auto returnValue = returnOpBlock.operations[returnOp.operationIndex]; auto snap = Snapshot(); - returnOpBlock.operations[returnOp.operationIndex] = TraceOperation( - snap, ASSIGN, defaultReturnOp.resultType, defaultReturnOp.resultRef, {returnValue.resultRef}); + returnOpBlock.operations[returnOp.operationIndex] = TraceOperation(snap, ASSIGN, defaultReturnOp.resultType, defaultReturnOp.resultRef, {returnValue.resultRef}); returnOpBlock.addOperation({Op::JMP, std::vector {BlockRef(returnBlock.blockId)}}); returnBlock.predecessors.emplace_back(returnOp.blockIndex); } @@ -60,8 +58,7 @@ std::shared_ptr SSACreationPhase::SSACreationPhaseContext::proce return std::move(trace); } -bool SSACreationPhase::SSACreationPhaseContext::isLocalValueRef(Block& block, value_ref& ref, Type, - uint32_t operationIndex) { +bool SSACreationPhase::SSACreationPhaseContext::isLocalValueRef(Block& block, value_ref& ref, Type, uint32_t operationIndex) { // A value ref is defined in the local scope, if it is the result of an operation before the operationIndex for (uint32_t i = 0; i < operationIndex; i++) { auto& resOperation = block.operations[i]; @@ -110,8 +107,7 @@ void SSACreationPhase::SSACreationPhaseContext::processBlock(Block& block) { } } -void SSACreationPhase::SSACreationPhaseContext::processValueRef(Block& block, value_ref& ref, Type ref_type, - uint32_t operationIndex) { +void SSACreationPhase::SSACreationPhaseContext::processValueRef(Block& block, value_ref& ref, Type ref_type, uint32_t operationIndex) { if (isLocalValueRef(block, ref, ref_type, operationIndex)) { // variable is a local ref -> don't do anything as the value is defined in the current block } else { @@ -144,8 +140,7 @@ void SSACreationPhase::SSACreationPhaseContext::processValueRef(Block& block, va } } -void SSACreationPhase::SSACreationPhaseContext::processBlockRef(Block& block, BlockRef& blockRef, - uint32_t operationIndex) { +void SSACreationPhase::SSACreationPhaseContext::processBlockRef(Block& block, BlockRef& blockRef, uint32_t operationIndex) { // a block ref has a set of arguments, which are handled the same as all other value references. for (auto& input : blockRef.arguments) { processValueRef(block, input, input.type, operationIndex); diff --git a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp index b95aeeab..a579d487 100644 --- a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp +++ b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp @@ -34,10 +34,9 @@ std::shared_ptr TraceToIRConversionPhase::IRConversionContext::process( // trace->getBlock(trace->getReturn().front().blockIndex).operations.back(); auto returnStamp = returnType; - auto functionOperation = - std::make_unique("execute", currentBasicBlocks, - /*argumentTypes*/ std::vector {}, - /*arguments*/ std::vector {}, returnStamp); + auto functionOperation = std::make_unique("execute", currentBasicBlocks, + /*argumentTypes*/ std::vector {}, + /*arguments*/ std::vector {}, returnStamp); ir->addRootOperation(std::move(functionOperation)); return ir; @@ -69,9 +68,7 @@ BasicBlock* TraceToIRConversionPhase::IRConversionContext::processBlock(int32_t return irBasicBlockPtr; } -void TraceToIRConversionPhase::IRConversionContext::processOperation(int32_t scope, ValueFrame& frame, - Block& currentBlock, BasicBlock*& currentIrBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processOperation(int32_t scope, ValueFrame& frame, Block& currentBlock, BasicBlock*& currentIrBlock, TraceOperation& operation) { switch (operation.op) { case Op::ADD: { @@ -195,8 +192,7 @@ void TraceToIRConversionPhase::IRConversionContext::processOperation(int32_t sco throw NotImplementedException("Type is not implemented."); } -void TraceToIRConversionPhase::IRConversionContext::processJMP(int32_t scope, ValueFrame& frame, BasicBlock* block, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processJMP(int32_t scope, ValueFrame& frame, BasicBlock* block, TraceOperation& operation) { // NES_DEBUG("current block " << block->getIdentifier() << " " << operation); auto blockRef = get(operation.input[0]); BasicBlockInvocation blockInvocation; @@ -213,8 +209,7 @@ void TraceToIRConversionPhase::IRConversionContext::processJMP(int32_t scope, Va block->addNextBlock(resultTargetBlock, blockInvocation.getArguments()); } -void TraceToIRConversionPhase::IRConversionContext::processCMP(int32_t scope, ValueFrame& frame, Block&, - BasicBlock* currentIrBlock, TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processCMP(int32_t scope, ValueFrame& frame, Block&, BasicBlock* currentIrBlock, TraceOperation& operation) { auto valueRef = get(operation.input[0]); auto trueCaseBlockRef = get(operation.input[1]); @@ -246,9 +241,7 @@ std::vector TraceToIRConversionPhase::IRConversionContext:: return blockArgumentIdentifiers; } -void TraceToIRConversionPhase::IRConversionContext::createBlockArguments(ValueFrame& frame, - BasicBlockInvocation& blockInvocation, - BlockRef val) { +void TraceToIRConversionPhase::IRConversionContext::createBlockArguments(ValueFrame& frame, BasicBlockInvocation& blockInvocation, BlockRef val) { for (auto& arg : val.arguments) { auto valueIdentifier = createValueIdentifier(arg); blockInvocation.addArgument(frame.getValue(valueIdentifier)); @@ -263,9 +256,7 @@ OperationIdentifier TraceToIRConversionPhase::IRConversionContext::createValueId return OperationIdentifier(0); } -void TraceToIRConversionPhase::IRConversionContext::processAdd(int32_t, ValueFrame& frame, - compiler::ir::BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processAdd(int32_t, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -274,9 +265,7 @@ void TraceToIRConversionPhase::IRConversionContext::processAdd(int32_t, ValueFra currentBlock->addOperation(std::move(addOperation)); } -void TraceToIRConversionPhase::IRConversionContext::processSub(int32_t, ValueFrame& frame, - compiler::ir::BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processSub(int32_t, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -284,9 +273,7 @@ void TraceToIRConversionPhase::IRConversionContext::processSub(int32_t, ValueFra frame.setValue(resultIdentifier, subOperation); } -void TraceToIRConversionPhase::IRConversionContext::processMul(int32_t, ValueFrame& frame, - compiler::ir::BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processMul(int32_t, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -294,8 +281,7 @@ void TraceToIRConversionPhase::IRConversionContext::processMul(int32_t, ValueFra frame.setValue(resultIdentifier, mulOperation); } -void TraceToIRConversionPhase::IRConversionContext::processDiv(int32_t, ValueFrame& frame, BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processDiv(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -303,8 +289,7 @@ void TraceToIRConversionPhase::IRConversionContext::processDiv(int32_t, ValueFra frame.setValue(resultIdentifier, divOperation); } -void TraceToIRConversionPhase::IRConversionContext::processMod(int32_t, ValueFrame& frame, BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processMod(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -312,9 +297,8 @@ void TraceToIRConversionPhase::IRConversionContext::processMod(int32_t, ValueFra frame.setValue(resultIdentifier, divOperation); } -void TraceToIRConversionPhase::IRConversionContext::processBinaryComp( - int32_t, nautilus::tracing::TraceToIRConversionPhase::ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, - nautilus::tracing::TraceOperation& operation, compiler::ir::BinaryCompOperation::Type type) { +void TraceToIRConversionPhase::IRConversionContext::processBinaryComp(int32_t, nautilus::tracing::TraceToIRConversionPhase::ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, nautilus::tracing::TraceOperation& operation, + compiler::ir::BinaryCompOperation::Type type) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -322,9 +306,8 @@ void TraceToIRConversionPhase::IRConversionContext::processBinaryComp( frame.setValue(resultIdentifier, divOperation); } -void TraceToIRConversionPhase::IRConversionContext::processShift( - int32_t, nautilus::tracing::TraceToIRConversionPhase::ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, - nautilus::tracing::TraceOperation& operation, compiler::ir::ShiftOperation::ShiftType type) { +void TraceToIRConversionPhase::IRConversionContext::processShift(int32_t, nautilus::tracing::TraceToIRConversionPhase::ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, nautilus::tracing::TraceOperation& operation, + compiler::ir::ShiftOperation::ShiftType type) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -332,48 +315,38 @@ void TraceToIRConversionPhase::IRConversionContext::processShift( frame.setValue(resultIdentifier, divOperation); } -void TraceToIRConversionPhase::IRConversionContext::processNegate(int32_t, ValueFrame& frame, BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processNegate(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto input = frame.getValue(createValueIdentifier(operation.input[0])); auto resultIdentifier = createValueIdentifier(operation.resultRef); auto negateOperation = currentBlock->addOperation(resultIdentifier, input); frame.setValue(resultIdentifier, negateOperation); } -void TraceToIRConversionPhase::IRConversionContext::processNot(int32_t, ValueFrame& frame, BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processNot(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto input = frame.getValue(createValueIdentifier(operation.input[0])); auto resultIdentifier = createValueIdentifier(operation.resultRef); auto notOperation = currentBlock->addOperation(resultIdentifier, input); frame.setValue(resultIdentifier, notOperation); } -void TraceToIRConversionPhase::IRConversionContext::processLessThan(int32_t, ValueFrame& frame, - BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processLessThan(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto compareOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput, - CompareOperation::Comparator::LT); + auto compareOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput, CompareOperation::Comparator::LT); frame.setValue(resultIdentifier, compareOperation); } -void TraceToIRConversionPhase::IRConversionContext::processGreaterThan(int32_t, ValueFrame& frame, - BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processGreaterThan(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto compareOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput, - CompareOperation::Comparator::GT); + auto compareOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput, CompareOperation::Comparator::GT); frame.setValue(resultIdentifier, compareOperation); } -void TraceToIRConversionPhase::IRConversionContext::processEquals(int32_t, ValueFrame& frame, BasicBlock* currentBlock, - TraceOperation& operation, - CompareOperation::Comparator comp) { +void TraceToIRConversionPhase::IRConversionContext::processEquals(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation, CompareOperation::Comparator comp) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -381,8 +354,7 @@ void TraceToIRConversionPhase::IRConversionContext::processEquals(int32_t, Value frame.setValue(resultIdentifier, compareOperation); } -void TraceToIRConversionPhase::IRConversionContext::processAnd(int32_t, ValueFrame& frame, BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processAnd(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -390,8 +362,7 @@ void TraceToIRConversionPhase::IRConversionContext::processAnd(int32_t, ValueFra frame.setValue(resultIdentifier, andOperation); } -void TraceToIRConversionPhase::IRConversionContext::processOr(int32_t, ValueFrame& frame, BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processOr(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -399,8 +370,7 @@ void TraceToIRConversionPhase::IRConversionContext::processOr(int32_t, ValueFram frame.setValue(resultIdentifier, orOperation); } -void TraceToIRConversionPhase::IRConversionContext::processLoad(int32_t, ValueFrame& frame, BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processLoad(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { // TODO add load data type // auto constOperation = // std::make_shared(createValueIdentifier(operation.result), @@ -415,15 +385,13 @@ void TraceToIRConversionPhase::IRConversionContext::processLoad(int32_t, ValueFr currentBlock->addOperation(std::move(loadOperation)); } -void TraceToIRConversionPhase::IRConversionContext::processStore(int32_t, ValueFrame& frame, BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processStore(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto address = frame.getValue(createValueIdentifier(operation.resultRef)); auto value = frame.getValue(createValueIdentifier(operation.input[0])); currentBlock->addOperation(value, address); } -void TraceToIRConversionPhase::IRConversionContext::processCall(int32_t, ValueFrame& frame, BasicBlock* currentBlock, - TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processCall(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto inputArguments = std::vector {}; auto functionCallTarget = std::get(operation.input[0]); @@ -435,8 +403,7 @@ void TraceToIRConversionPhase::IRConversionContext::processCall(int32_t, ValueFr auto resultType = operation.resultType; auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto proxyCallOperation = currentBlock->addOperation( - functionCallTarget.functionName, functionCallTarget.ptr, resultIdentifier, inputArguments, resultType); + auto proxyCallOperation = currentBlock->addOperation(functionCallTarget.functionName, functionCallTarget.ptr, resultIdentifier, inputArguments, resultType); if (resultType != Type::v) { frame.setValue(resultIdentifier, proxyCallOperation); } @@ -466,46 +433,35 @@ bool TraceToIRConversionPhase::IRConversionContext::isBlockInLoop(uint32_t paren return false; } -void TraceToIRConversionPhase::IRConversionContext::processConst(int32_t, TraceToIRConversionPhase::ValueFrame& frame, - BasicBlock* currentBlock, TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processConst(int32_t, TraceToIRConversionPhase::ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto constant = &std::get(operation.input[0]); auto resultIdentifier = createValueIdentifier(operation.resultRef); auto resultType = (operation.resultType); Operation* constOperation; if (constant->type() == typeid(int8_t)) { - constOperation = - currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); + constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); } else if (constant->type() == typeid(int16_t)) { - constOperation = - currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); + constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); } else if (constant->type() == typeid(int32_t)) { - constOperation = - currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); + constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); } else if (constant->type() == typeid(int64_t)) { - constOperation = - currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); + constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); } else if (constant->type() == typeid(uint8_t)) { - constOperation = - currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); + constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); } else if (constant->type() == typeid(uint16_t)) { - constOperation = - currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); + constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); } else if (constant->type() == typeid(uint32_t)) { - constOperation = - currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); + constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); } else if (constant->type() == typeid(uint64_t)) { - constOperation = - currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); + constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); } else if (constant->type() == typeid(float)) { - constOperation = - currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); + constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); } else if (constant->type() == typeid(double)) { - constOperation = - currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); + constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant), resultType); } else if (constant->type() == typeid(bool)) { constOperation = currentBlock->addOperation(resultIdentifier, any_cast(*constant)); @@ -518,8 +474,7 @@ void TraceToIRConversionPhase::IRConversionContext::processConst(int32_t, TraceT frame.setValue(resultIdentifier, constOperation); } -void TraceToIRConversionPhase::IRConversionContext::processCast(int32_t, TraceToIRConversionPhase::ValueFrame& frame, - BasicBlock* currentBlock, TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processCast(int32_t, TraceToIRConversionPhase::ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto resultIdentifier = createValueIdentifier(operation.resultRef); auto input = frame.getValue(createValueIdentifier(operation.input[0])); diff --git a/nautilus/src/nautilus/tracing/symbolic_execution/SymbolicExecutionContext.cpp b/nautilus/src/nautilus/tracing/symbolic_execution/SymbolicExecutionContext.cpp index 8e060a47..ef556705 100644 --- a/nautilus/src/nautilus/tracing/symbolic_execution/SymbolicExecutionContext.cpp +++ b/nautilus/src/nautilus/tracing/symbolic_execution/SymbolicExecutionContext.cpp @@ -58,8 +58,7 @@ bool SymbolicExecutionContext::follow() { } bool SymbolicExecutionContext::shouldFollow() { - return currentMode == SymbolicExecutionContext::MODE::FOLLOW && - currentOperation < currentExecutionPath.getSize() - 1; + return currentMode == SymbolicExecutionContext::MODE::FOLLOW && currentOperation < currentExecutionPath.getSize() - 1; } bool SymbolicExecutionContext::shouldContinue() { diff --git a/nautilus/test/execution-tests/BoolExecutionTest.cpp b/nautilus/test/execution-tests/BoolExecutionTest.cpp new file mode 100644 index 00000000..cc0e1373 --- /dev/null +++ b/nautilus/test/execution-tests/BoolExecutionTest.cpp @@ -0,0 +1,117 @@ +#include "BoolOperations.hpp" +#include "nautilus/Engine.hpp" +#include "nautilus/val_concepts.hpp" +#include + +namespace nautilus::engine { + +void addTest(engine::NautilusEngine& engine) { + + SECTION("boolNot") { + auto f = engine.registerFunction(boolNot); + REQUIRE(f(true) == false); + REQUIRE(f(false) == true); + } + + SECTION("boolAnd") { + auto f = engine.registerFunction(boolAnd); + REQUIRE(f(true, true) == true); + REQUIRE(f(false, true) == false); + REQUIRE(f(false, false) == false); + REQUIRE(f(false, true) == false); + } + + SECTION("boolOr") { + auto f = engine.registerFunction(boolOr); + REQUIRE(f(true, true) == true); + REQUIRE(f(false, true) == true); + REQUIRE(f(false, false) == false); + REQUIRE(f(false, true) == true); + } + + SECTION("boolAssignment") { + auto f = engine.registerFunction(boolAssignment); + REQUIRE(f(true) == true); + REQUIRE(f(false) == false); + } + + SECTION("boolAssignmentOr") { + auto f = engine.registerFunction(boolAssignmentOr); + REQUIRE(f(true, true) == true); + REQUIRE(f(true, false) == true); + REQUIRE(f(false, true) == true); + REQUIRE(f(false, false) == false); + } + + SECTION("boolConst") { + auto f = engine.registerFunction(boolConst); + REQUIRE(f(true) == true); + REQUIRE(f(false) == false); + } + + SECTION("boolEquals") { + auto f = engine.registerFunction(boolEquals); + REQUIRE(f(true, true) == true); + REQUIRE(f(false, false) == true); + REQUIRE(f(false, true) == false); + REQUIRE(f(true, false) == false); + } + + SECTION("boolNotEquals") { + auto f = engine.registerFunction(boolNotEquals); + REQUIRE(f(true, true) == false); + REQUIRE(f(false, false) == false); + REQUIRE(f(false, true) == true); + REQUIRE(f(true, false) == true); + } + + SECTION("boolIfElse") { + auto f = engine.registerFunction(boolIfElse); + REQUIRE(f(true, true) == true); + REQUIRE(f(false, false) == false); + REQUIRE(f(false, true) == false); + REQUIRE(f(true, false) == false); + } + + SECTION("boolNestedFunction") { + auto f = engine.registerFunction(boolNestedFunction); + REQUIRE(f(true, true) == true); + REQUIRE(f(false, false) == true); + REQUIRE(f(false, true) == false); + REQUIRE(f(true, false) == false); + } +} + +TEST_CASE("Bool Interpreter Test") { + engine::Options options; + options.setOption("engine.Compilation", false); + auto engine = engine::NautilusEngine(options); + addTest(engine); +} + +#ifdef ENABLE_TRACING +TEST_CASE("Bool Compiler Test") { + std::vector backends = {}; +#ifdef ENABLE_MLIR_BACKEND + backends.emplace_back("mlir"); +#endif +#ifdef ENABLE_C_BACKEND + backends.emplace_back("cpp"); +#endif +#ifdef ENABLE_BC_BACKEND + backends.emplace_back("bc"); +#endif +#ifdef ENABLE_ASMJIT_BACKEND + backends.emplace_back("asmjit"); +#endif + for (auto& backend : backends) { + DYNAMIC_SECTION(backend) { + engine::Options options; + options.setOption("engine.backend", backend); + auto engine = engine::NautilusEngine(options); + addTest(engine); + } + } +} +#endif +} // namespace nautilus::engine diff --git a/nautilus/test/execution-tests/BoolOperations.hpp b/nautilus/test/execution-tests/BoolOperations.hpp new file mode 100644 index 00000000..2d5ed89e --- /dev/null +++ b/nautilus/test/execution-tests/BoolOperations.hpp @@ -0,0 +1,62 @@ +#pragma once + +#include + +namespace nautilus::engine { + +val boolNot(val x) { + return !x; +} + +val boolAnd(val a, val b) { + return a && b; +} + +val boolOr(val a, val b) { + return a || b; +} + +val boolAssignment(val x) { + auto z = x; + return z; +} + +val boolAssignmentOr(val x, val y) { + auto z = x; + x = y; + return z || y; +} + +val boolConst(val x) { + return x && true; +} + +val boolEquals(val x, val z) { + return x == z; +} + +val boolNotEquals(val x, val z) { + return x != z; +} + +val boolIfElse(val x, val z) { + if (x && z) { + return true; + } else { + return false; + } +} + +val eval(val x, val z) { + return x == z; +} + +val boolNestedFunction(val x, val z) { + if (eval(x, z)) { + return true; + } else { + return false; + } +} + +} // namespace nautilus::engine diff --git a/nautilus/test/execution-tests/CMakeLists.txt b/nautilus/test/execution-tests/CMakeLists.txt index b60debaa..7c887f2c 100644 --- a/nautilus/test/execution-tests/CMakeLists.txt +++ b/nautilus/test/execution-tests/CMakeLists.txt @@ -6,9 +6,17 @@ add_executable(nautilus-execution-tests ) target_link_libraries(nautilus-execution-tests PUBLIC nautilus Catch2::Catch2WithMain) + +add_executable(nautilus-bool-execution-tests + BoolExecutionTest.cpp +) + +target_link_libraries(nautilus-bool-execution-tests PUBLIC nautilus Catch2::Catch2WithMain) + list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras) catch_discover_tests(nautilus-execution-tests EXTRA_ARGS --allow-running-no-tests) +catch_discover_tests(nautilus-bool-execution-tests EXTRA_ARGS --allow-running-no-tests) if (ENABLE_TRACING AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")) # using Clang diff --git a/nautilus/test/execution-tests/ExecutionTest.cpp b/nautilus/test/execution-tests/ExecutionTest.cpp index ec673f02..331f9079 100644 --- a/nautilus/test/execution-tests/ExecutionTest.cpp +++ b/nautilus/test/execution-tests/ExecutionTest.cpp @@ -11,12 +11,40 @@ namespace nautilus::engine { void addTest(engine::NautilusEngine& engine) { - SECTION("staticCast") { auto f = engine.registerFunction(staticCastExpression); - REQUIRE(f((int8_t)34) == 34); + REQUIRE(f((int8_t) 34) == 34); + } + + SECTION("intBitwiseNegate") { + auto f = engine.registerFunction(negate); + REQUIRE(f(0) == -1); + REQUIRE(f(1) == -2); + REQUIRE(f(INT_MAX) == INT_MIN); + REQUIRE(f(INT_MIN) == INT_MAX); + } + + SECTION("uintBitwiseNegate") { + auto f = engine.registerFunction(negate); + REQUIRE(f((uint32_t) 0) == UINT_MAX); + REQUIRE(f((uint32_t) 1) == UINT_MAX - 1); + REQUIRE(f((uint32_t) INT_MAX) == (uint32_t) INT_MIN); + REQUIRE(f((uint32_t) INT_MIN) == (uint32_t) INT_MAX); + REQUIRE(f(UINT_MAX) == 0); + } + + SECTION("charBitwiseNegate") { + auto f = engine.registerFunction(negate); + REQUIRE(f((char) 0) == (char) -1); + REQUIRE(f((char) 1) == (char) -2); + REQUIRE(f((char) CHAR_MAX) == (char) CHAR_MIN); + REQUIRE(f((char) CHAR_MIN) == (char) CHAR_MAX); } + SECTION("staticCast") { + auto f = engine.registerFunction(staticCastExpression); + REQUIRE(f((int8_t) 34) == 34); + } SECTION("logicalNot") { auto f = engine.registerFunction(logicalNot); @@ -34,19 +62,19 @@ void addTest(engine::NautilusEngine& engine) { SECTION("uintBitwiseNegate") { auto f = engine.registerFunction(negate); - REQUIRE(f((uint32_t)0) == UINT_MAX); - REQUIRE(f((uint32_t)1) == UINT_MAX -1); - REQUIRE(f((uint32_t)INT_MAX) == (uint32_t)INT_MIN); - REQUIRE(f((uint32_t)INT_MIN) == (uint32_t)INT_MAX); + REQUIRE(f((uint32_t) 0) == UINT_MAX); + REQUIRE(f((uint32_t) 1) == UINT_MAX - 1); + REQUIRE(f((uint32_t) INT_MAX) == (uint32_t) INT_MIN); + REQUIRE(f((uint32_t) INT_MIN) == (uint32_t) INT_MAX); REQUIRE(f(UINT_MAX) == 0); } SECTION("charBitwiseNegate") { auto f = engine.registerFunction(negate); - REQUIRE(f((char)0) == (char)-1); - REQUIRE(f((char)1) == (char)-2); - REQUIRE(f((char)CHAR_MAX) == (char)CHAR_MIN); - REQUIRE(f((char)CHAR_MIN) == (char)CHAR_MAX); + REQUIRE(f((char) 0) == (char) -1); + REQUIRE(f((char) 1) == (char) -2); + REQUIRE(f((char) CHAR_MAX) == (char) CHAR_MIN); + REQUIRE(f((char) CHAR_MIN) == (char) CHAR_MAX); } SECTION("callEnumFunction") { @@ -61,22 +89,6 @@ void addTest(engine::NautilusEngine& engine) { REQUIRE(f(Color::GREEN) == 0); } - SECTION("lAnd") { - auto f = engine.registerFunction(lAnd); - REQUIRE(f(true, true) == true); - REQUIRE(f(true, false) == false); - REQUIRE(f(false, false) == false); - REQUIRE(f(false, true) == false); - } - - SECTION("lOr") { - auto f = engine.registerFunction(lOr); - REQUIRE(f(true, true) == true); - REQUIRE(f(true, false) == true); - REQUIRE(f(false, false) == false); - REQUIRE(f(false, true) == true); - } - SECTION("incrementPost") { auto f = engine.registerFunction(incrementPost); REQUIRE(f(1) == 3); @@ -123,28 +135,44 @@ void addTest(engine::NautilusEngine& engine) { REQUIRE(f(5) == 0); } SECTION("assignAnd") { - auto f = engine.registerFunction(assignAnd); - REQUIRE(f(7) == 5); - REQUIRE(f(5) == 5); + auto f = engine.registerFunction(assignAnd); + REQUIRE(f(7) == 5); + REQUIRE(f(5) == 5); } SECTION("assignOr") { - auto f = engine.registerFunction(assignOr); - REQUIRE(f(7) == 7); - REQUIRE(f(5) == 5); + auto f = engine.registerFunction(assignOr); + REQUIRE(f(7) == 7); + REQUIRE(f(5) == 5); + } + SECTION("assignXor") { + auto f = engine.registerFunction(assignXor); + REQUIRE(f(7) == 2); + REQUIRE(f(5) == 0); + } + SECTION("assignShl") { + auto f = engine.registerFunction(assignShl); + REQUIRE(f(7) == 224); + REQUIRE(f(5) == 160); + } + SECTION("assignShr") { + auto f = engine.registerFunction(assignShr); + REQUIRE(f(7) == 0); + REQUIRE(f(5) == 0); } SECTION("assignXor") { - auto f = engine.registerFunction(assignXor); - REQUIRE(f(7) == 2); - REQUIRE(f(5) == 0); + auto f = engine.registerFunction(assignXor); + REQUIRE(f(7) == 2); + REQUIRE(f(5) == 0); } SECTION("assignShl") { - auto f = engine.registerFunction(assignShl); - REQUIRE(f(7) == 224); - REQUIRE(f(5) == 160); - }SECTION("assignShr") { - auto f = engine.registerFunction(assignShr); - REQUIRE(f(7) == 0); - REQUIRE(f(5) == 0); + auto f = engine.registerFunction(assignShl); + REQUIRE(f(7) == 224); + REQUIRE(f(5) == 160); + } + SECTION("assignShr") { + auto f = engine.registerFunction(assignShr); + REQUIRE(f(7) == 0); + REQUIRE(f(5) == 0); } SECTION("assignment1") { auto f = engine.registerFunction(assignment1); @@ -536,6 +564,140 @@ void functionCallExecutionTest(engine::NautilusEngine& engine) { void pointerExecutionTest(engine::NautilusEngine& engine) { int* values = new int[10] {1, 2, 3, 4, 5, 6, 7, 8, 9}; + + SECTION("isNullptr") { + auto f = engine.registerFunction(isNullptr); + int x = 42; + int8_t* ptr = nullptr; + REQUIRE(f(&x) == false); + REQUIRE(f(ptr) == true); + + auto f2 = engine.registerFunction(isNullptr); + bool x2 = true; + bool* ptr2 = nullptr; + REQUIRE(f2(&x2) == false); + REQUIRE(f2(ptr2) == true); + + auto f3 = engine.registerFunction(isNullptr); + CustomStruct2* ptr3 = nullptr; + REQUIRE(f3(ptr3) == true); + } + + SECTION("isNotNullptr") { + auto f = engine.registerFunction(isNotNullptr); + int x = 42; + int8_t* ptr = nullptr; + REQUIRE(f(&x) == true); + REQUIRE(f(ptr) == false); + } + + SECTION("ptrEquals") { + { + auto f = engine.registerFunction(ptrEquals); + int8_t x = 42; + int8_t x2 = 42; + int8_t* nu = nullptr; + REQUIRE(f(&x, &x2) == false); + REQUIRE(f(&x, &x) == true); + REQUIRE(f(&x, nu) == false); + REQUIRE(f(nu, nu) == true); + } + { + auto f = engine.registerFunction(ptrEquals); + bool x = 42; + bool x2 = 42; + bool* nu = nullptr; + REQUIRE(f(&x, &x2) == false); + REQUIRE(f(&x, &x) == true); + REQUIRE(f(&x, nu) == false); + REQUIRE(f(nu, nu) == true); + } + { + auto f = engine.registerFunction(ptrEquals); + CustomStruct2 x; + CustomStruct2 x2; + bool* nu = nullptr; + REQUIRE(f(&x, &x2) == false); + REQUIRE(f(&x, &x) == true); + REQUIRE(f(&x, nu) == false); + REQUIRE(f(nu, nu) == true); + } + } + + SECTION("ptrNotEquals") { + { + auto f = engine.registerFunction(ptrNotEquals); + int8_t x = 42; + int8_t x2 = 42; + int8_t* nu = nullptr; + REQUIRE(f(&x, &x2) == true); + REQUIRE(f(&x, &x) == false); + REQUIRE(f(&x, nu) == true); + REQUIRE(f(nu, nu) == false); + } + { + auto f = engine.registerFunction(ptrNotEquals); + bool x = 42; + bool x2 = 42; + bool* nu = nullptr; + REQUIRE(f(&x, &x2) == true); + REQUIRE(f(&x, &x) == false); + REQUIRE(f(&x, nu) == true); + REQUIRE(f(nu, nu) == false); + } + { + auto f = engine.registerFunction(ptrNotEquals); + CustomStruct2 x; + CustomStruct2 x2; + bool* nu = nullptr; + REQUIRE(f(&x, &x2) == true); + REQUIRE(f(&x, &x) == false); + REQUIRE(f(&x, nu) == true); + REQUIRE(f(nu, nu) == false); + } + } + + SECTION("ptrLessThan") { + { + auto f = engine.registerFunction(ptrLessThan); + int8_t x = 42; + int8_t x2 = 42; + REQUIRE(f(&x, &x2) == (&x < &x2)); + REQUIRE(f(&x2, &x) == (&x2 < &x)); + } + } + + SECTION("ptrLessThanEquals") { + { + auto f = engine.registerFunction(ptrLessThanEquals); + int8_t x = 42; + int8_t x2 = 42; + REQUIRE(f(&x, &x2) == (&x <= &x2)); + REQUIRE(f(&x, &x) == (&x <= &x)); + REQUIRE(f(&x2, &x) == (&x2 <= &x)); + } + } + SECTION("ptrGreaterThan") { + { + auto f = engine.registerFunction(ptrGreaterThan); + int8_t x = 42; + int8_t x2 = 42; + REQUIRE(f(&x, &x2) == (&x > &x2)); + REQUIRE(f(&x, &x) == (&x > &x)); + REQUIRE(f(&x2, &x) == (&x2 > &x)); + } + } + + SECTION("ptrGreaterThanEquals") { + { + auto f = engine.registerFunction(ptrGreaterThanEquals); + int8_t x = 42; + int8_t x2 = 42; + REQUIRE(f(&x, &x2) == (&x >= &x2)); + REQUIRE(f(&x, &x) == (&x >= &x)); + REQUIRE(f(&x2, &x) == (&x2 >= &x)); + } + } // int* ptr = &values; SECTION("castVoidInt8") { auto f = engine.registerFunction(castPtrAndGetValue); @@ -683,8 +845,7 @@ void registerFunctionTest(engine::NautilusEngine& engine) { SECTION("functionBindMember2") { auto clazz = Clazz(); clazz.state = 100; - std::function(val)> bound = - std::bind(&Clazz::functionWithStateAccess, &clazz, std::placeholders::_1); + std::function(val)> bound = std::bind(&Clazz::functionWithStateAccess, &clazz, std::placeholders::_1); auto f = engine.registerFunction(bound); REQUIRE(f(42) == 142); REQUIRE(f(1) == 101); diff --git a/nautilus/test/execution-tests/ExpressionFunctions.hpp b/nautilus/test/execution-tests/ExpressionFunctions.hpp index 635ef0ee..5b3d5df6 100644 --- a/nautilus/test/execution-tests/ExpressionFunctions.hpp +++ b/nautilus/test/execution-tests/ExpressionFunctions.hpp @@ -98,13 +98,6 @@ val castInt8ToInt64AddExpression2(val x) { return y + x; } -val lAnd(val a, val b) { - return a && b; -} - -val lOr(val a, val b) { - return a || b; -} val incrementPost(val x) { auto y = x++; diff --git a/nautilus/test/execution-tests/PointerFunctions.hpp b/nautilus/test/execution-tests/PointerFunctions.hpp index ec18d0d1..9e74417c 100644 --- a/nautilus/test/execution-tests/PointerFunctions.hpp +++ b/nautilus/test/execution-tests/PointerFunctions.hpp @@ -21,6 +21,46 @@ val castVoidPtr(val array) { return intPtr[0]; } +template +val isNullptr(val ptr) { + return ptr == nullptr; +} + +template +val isNotNullptr(val ptr) { + return ptr != nullptr; +} + +template +val ptrEquals(val left, val right) { + return left == right; +} + +template +val ptrNotEquals(val left, val right) { + return left != right; +} + +template +val ptrLessThan(val left, val right) { + return left < right; +} + +template +val ptrLessThanEquals(val left, val right) { + return left <= right; +} + +template +val ptrGreaterThan(val left, val right) { + return left > right; +} + +template +val ptrGreaterThanEquals(val left, val right) { + return left >= right; +} + template val castPtrAndGetValue(val array) { auto intPtr = static_cast>(array); diff --git a/nautilus/test/execution-tests/TracingTest.cpp b/nautilus/test/execution-tests/TracingTest.cpp index 8da9f3ee..2dbc6539 100644 --- a/nautilus/test/execution-tests/TracingTest.cpp +++ b/nautilus/test/execution-tests/TracingTest.cpp @@ -128,23 +128,22 @@ void runTraceTests(std::vector>>& } TEST_CASE("Expression Trace Test") { - auto tests = std::vector>> { - {"assignShr", details::createFunctionWrapper(assignShr)}, - {"assignShl", details::createFunctionWrapper(assignShl)}, - {"assignment1", details::createFunctionWrapper(assignment1)}, - {"assignment2", details::createFunctionWrapper(assignment2)}, - {"assignment3", details::createFunctionWrapper(assignment3)}, - {"assignment4", details::createFunctionWrapper(assignment4)}, - {"assignment5", details::createFunctionWrapper(assignment5)}, - {"int8AddExpression", details::createFunctionWrapper(int8AddExpression)}, - {"int16AddExpression", details::createFunctionWrapper(int16AddExpression)}, - {"int32AddExpression", details::createFunctionWrapper(int32AddExpression)}, - {"int64AddExpression", details::createFunctionWrapper(int64AddExpression)}, - {"floatAddExpression", details::createFunctionWrapper(floatAddExpression)}, - {"doubleAddExpression", details::createFunctionWrapper(doubleAddExpression)}, - {"castFloatToDoubleAddExpression", details::createFunctionWrapper(castFloatToDoubleAddExpression)}, - {"castInt8ToInt64AddExpression", details::createFunctionWrapper(castInt8ToInt64AddExpression)}, - {"castInt8ToInt64AddExpression2", details::createFunctionWrapper(castInt8ToInt64AddExpression2)}}; + auto tests = std::vector>> {{"assignShr", details::createFunctionWrapper(assignShr)}, + {"assignShl", details::createFunctionWrapper(assignShl)}, + {"assignment1", details::createFunctionWrapper(assignment1)}, + {"assignment2", details::createFunctionWrapper(assignment2)}, + {"assignment3", details::createFunctionWrapper(assignment3)}, + {"assignment4", details::createFunctionWrapper(assignment4)}, + {"assignment5", details::createFunctionWrapper(assignment5)}, + {"int8AddExpression", details::createFunctionWrapper(int8AddExpression)}, + {"int16AddExpression", details::createFunctionWrapper(int16AddExpression)}, + {"int32AddExpression", details::createFunctionWrapper(int32AddExpression)}, + {"int64AddExpression", details::createFunctionWrapper(int64AddExpression)}, + {"floatAddExpression", details::createFunctionWrapper(floatAddExpression)}, + {"doubleAddExpression", details::createFunctionWrapper(doubleAddExpression)}, + {"castFloatToDoubleAddExpression", details::createFunctionWrapper(castFloatToDoubleAddExpression)}, + {"castInt8ToInt64AddExpression", details::createFunctionWrapper(castInt8ToInt64AddExpression)}, + {"castInt8ToInt64AddExpression2", details::createFunctionWrapper(castInt8ToInt64AddExpression2)}}; runTraceTests(tests); } TEST_CASE("Control-flow Trace Test") { @@ -180,47 +179,45 @@ TEST_CASE("Control-flow Trace Test") { } TEST_CASE("Loop Trace Test") { - auto tests = std::vector>> { - {"castVoidPtr", details::createFunctionWrapper(castVoidPtr)}, - {"ifInsideLoop", details::createFunctionWrapper(ifInsideLoop)}, - {"sumLoop", details::createFunctionWrapper(sumLoop)}, - {"nestedSumLoop", details::createFunctionWrapper(nestedSumLoop)}, - {"ifSumLoop", details::createFunctionWrapper(ifSumLoop)}, - {"ifElseSumLoop", details::createFunctionWrapper(ifElseSumLoop)}, - {"elseOnlySumLoop", details::createFunctionWrapper(elseOnlySumLoop)}, - {"nestedIfSumLoop", details::createFunctionWrapper(nestedIfSumLoop)}, - {"nestedIfElseSumLoop", details::createFunctionWrapper(nestedIfElseSumLoop)}, - {"nestedElseOnlySumLoop", details::createFunctionWrapper(nestedElseOnlySumLoop)}, - {"sumOfNumbers", details::createFunctionWrapper(sumOfNumbers)}, - {"factorial", details::createFunctionWrapper(factorial)}, - {"reverseNumber", details::createFunctionWrapper(reverseNumber)}, - {"fibonacci", details::createFunctionWrapper(fibonacci)}, - {"gcd", details::createFunctionWrapper(gcd)}, - {"decimalToBinary", details::createFunctionWrapper(decimalToBinary)}, - {"isPrime", details::createFunctionWrapper(isPrime)}, - {"collatz", details::createFunctionWrapper(collatz)}, - {"digitSum", details::createFunctionWrapper(digitSum)}, - {"sumOfSquares", details::createFunctionWrapper(sumOfSquares)}, - {"countDigits", details::createFunctionWrapper(countDigits)}, - {"sumArray", details::createFunctionWrapper(sumArray)}, - {"addArrayInt32", details::createFunctionWrapper(addArray)}, - {"simpleDirectCall", details::createFunctionWrapper(simpleDirectCall)}, - {"loopDirectCall", details::createFunctionWrapper(loopDirectCall)}, - {"passCustomStruct", details::createFunctionWrapper(passCustomClass)}, - {"specializeType", details::createFunctionWrapper(specializeType)}, - {"useWrapper", details::createFunctionWrapper(useWrapper)}, - {"voidFuncCall", details::createFunctionWrapper(voidFuncCall)}}; + auto tests = std::vector>> {{"castVoidPtr", details::createFunctionWrapper(castVoidPtr)}, + {"ifInsideLoop", details::createFunctionWrapper(ifInsideLoop)}, + {"sumLoop", details::createFunctionWrapper(sumLoop)}, + {"nestedSumLoop", details::createFunctionWrapper(nestedSumLoop)}, + {"ifSumLoop", details::createFunctionWrapper(ifSumLoop)}, + {"ifElseSumLoop", details::createFunctionWrapper(ifElseSumLoop)}, + {"elseOnlySumLoop", details::createFunctionWrapper(elseOnlySumLoop)}, + {"nestedIfSumLoop", details::createFunctionWrapper(nestedIfSumLoop)}, + {"nestedIfElseSumLoop", details::createFunctionWrapper(nestedIfElseSumLoop)}, + {"nestedElseOnlySumLoop", details::createFunctionWrapper(nestedElseOnlySumLoop)}, + {"sumOfNumbers", details::createFunctionWrapper(sumOfNumbers)}, + {"factorial", details::createFunctionWrapper(factorial)}, + {"reverseNumber", details::createFunctionWrapper(reverseNumber)}, + {"fibonacci", details::createFunctionWrapper(fibonacci)}, + {"gcd", details::createFunctionWrapper(gcd)}, + {"decimalToBinary", details::createFunctionWrapper(decimalToBinary)}, + {"isPrime", details::createFunctionWrapper(isPrime)}, + {"collatz", details::createFunctionWrapper(collatz)}, + {"digitSum", details::createFunctionWrapper(digitSum)}, + {"sumOfSquares", details::createFunctionWrapper(sumOfSquares)}, + {"countDigits", details::createFunctionWrapper(countDigits)}, + {"sumArray", details::createFunctionWrapper(sumArray)}, + {"addArrayInt32", details::createFunctionWrapper(addArray)}, + {"simpleDirectCall", details::createFunctionWrapper(simpleDirectCall)}, + {"loopDirectCall", details::createFunctionWrapper(loopDirectCall)}, + {"passCustomStruct", details::createFunctionWrapper(passCustomClass)}, + {"specializeType", details::createFunctionWrapper(specializeType)}, + {"useWrapper", details::createFunctionWrapper(useWrapper)}, + {"voidFuncCall", details::createFunctionWrapper(voidFuncCall)}}; runTraceTests(tests); } TEST_CASE("Static Trace Test") { - auto tests = std::vector>> { - {"staticLoop", details::createFunctionWrapper(staticLoop)}, - // {"staticLoopWithIf", details::createFunctionWrapper(staticLoopWithIf)}, - {"staticLoopWithDynamicLoop", details::createFunctionWrapper(staticLoopWithDynamicLoop)}, - // {"staticIterator", details::createFunctionWrapper(staticIterator)}, - {"staticLoopIncrement", details::createFunctionWrapper(staticLoopIncrement)}, - {"staticWhileLoopDecrement", details::createFunctionWrapper(staticWhileLoopDecrement)}}; + auto tests = std::vector>> {{"staticLoop", details::createFunctionWrapper(staticLoop)}, + // {"staticLoopWithIf", details::createFunctionWrapper(staticLoopWithIf)}, + {"staticLoopWithDynamicLoop", details::createFunctionWrapper(staticLoopWithDynamicLoop)}, + // {"staticIterator", details::createFunctionWrapper(staticIterator)}, + {"staticLoopIncrement", details::createFunctionWrapper(staticLoopIncrement)}, + {"staticWhileLoopDecrement", details::createFunctionWrapper(staticWhileLoopDecrement)}}; runTraceTests(tests); } } // namespace nautilus::engine diff --git a/nautilus/test/val-tests/IntegerValTypeTest.cpp b/nautilus/test/val-tests/IntegerValTypeTest.cpp index 4525ea51..3974e672 100644 --- a/nautilus/test/val-tests/IntegerValTypeTest.cpp +++ b/nautilus/test/val-tests/IntegerValTypeTest.cpp @@ -5,8 +5,7 @@ namespace nautilus { -TEMPLATE_TEST_CASE("Integer Val Operation Test", "[value][template]", int8_t, int16_t, int32_t, int64_t, uint8_t, - uint16_t, uint32_t, uint64_t) { +TEMPLATE_TEST_CASE("Integer Val Operation Test", "[value][template]", int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t) { SECTION("comparison operators") { SECTION("==") { auto f1 = val(static_cast(42)); From f512110e7b9125cb5b32b792408dfbfc6c8b18d0 Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Tue, 30 Jul 2024 23:46:26 +0200 Subject: [PATCH 7/7] add additional check to verify the number of arguments in SSA --- .../tracing/phases/SSACreationPhase.cpp | 7 ++ nautilus/test/data/after_ssa/staticLoop.trace | 44 ++++++------- .../data/after_ssa/staticLoopIncrement.trace | 44 ++++++------- nautilus/test/data/ir/staticLoop.trace | 44 ++++++------- .../test/data/ir/staticLoopIncrement.trace | 44 ++++++------- nautilus/test/data/tracing/staticLoop.trace | 64 +++++++++---------- .../data/tracing/staticLoopIncrement.trace | 64 +++++++++---------- .../test/execution-tests/ExecutionTest.cpp | 26 ++++++++ .../execution-tests/StaticLoopFunctions.hpp | 4 +- 9 files changed, 187 insertions(+), 154 deletions(-) diff --git a/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp b/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp index 95984c02..e4ded8ab 100644 --- a/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp +++ b/nautilus/src/nautilus/tracing/phases/SSACreationPhase.cpp @@ -1,4 +1,6 @@ +#include +#include #include #include #include @@ -53,6 +55,11 @@ std::shared_ptr SSACreationPhase::SSACreationPhaseContext::proce // As a result two blocks, can't use the same value references. makeBlockArgumentsUnique(); + // check arguments + if (trace->arguments.size() != trace->getBlocks().front().arguments.size()) { + throw RuntimeException(fmt::format("Wrong number of arguments in trace: expected {}, got {}\n", trace->arguments.size(), trace->getBlocks().front().arguments.size())); + } + // sort arguments std::sort(trace->getBlocks().front().arguments.begin(), trace->getBlocks().front().arguments.end()); return std::move(trace); diff --git a/nautilus/test/data/after_ssa/staticLoop.trace b/nautilus/test/data/after_ssa/staticLoop.trace index 23c9f0fc..6022c849 100644 --- a/nautilus/test/data/after_ssa/staticLoop.trace +++ b/nautilus/test/data/after_ssa/staticLoop.trace @@ -1,23 +1,23 @@ B0() - CONST $2 1 :i32 - CONST $3 10 :i32 - ADD $4 $2 $3 :i32 - CONST $5 10 :i32 - ADD $6 $4 $5 :i32 - CONST $7 10 :i32 - ADD $8 $6 $7 :i32 - CONST $9 10 :i32 - ADD $10 $8 $9 :i32 - CONST $11 10 :i32 - ADD $12 $10 $11 :i32 - CONST $13 10 :i32 - ADD $14 $12 $13 :i32 - CONST $15 10 :i32 - ADD $16 $14 $15 :i32 - CONST $17 10 :i32 - ADD $18 $16 $17 :i32 - CONST $19 10 :i32 - ADD $20 $18 $19 :i32 - CONST $21 10 :i32 - ADD $22 $20 $21 :i32 - RETURN $22 :i32 + CONST $1 1 :i32 + CONST $2 10 :i32 + ADD $3 $1 $2 :i32 + CONST $4 10 :i32 + ADD $5 $3 $4 :i32 + CONST $6 10 :i32 + ADD $7 $5 $6 :i32 + CONST $8 10 :i32 + ADD $9 $7 $8 :i32 + CONST $10 10 :i32 + ADD $11 $9 $10 :i32 + CONST $12 10 :i32 + ADD $13 $11 $12 :i32 + CONST $14 10 :i32 + ADD $15 $13 $14 :i32 + CONST $16 10 :i32 + ADD $17 $15 $16 :i32 + CONST $18 10 :i32 + ADD $19 $17 $18 :i32 + CONST $20 10 :i32 + ADD $21 $19 $20 :i32 + RETURN $21 :i32 diff --git a/nautilus/test/data/after_ssa/staticLoopIncrement.trace b/nautilus/test/data/after_ssa/staticLoopIncrement.trace index 23c9f0fc..6022c849 100644 --- a/nautilus/test/data/after_ssa/staticLoopIncrement.trace +++ b/nautilus/test/data/after_ssa/staticLoopIncrement.trace @@ -1,23 +1,23 @@ B0() - CONST $2 1 :i32 - CONST $3 10 :i32 - ADD $4 $2 $3 :i32 - CONST $5 10 :i32 - ADD $6 $4 $5 :i32 - CONST $7 10 :i32 - ADD $8 $6 $7 :i32 - CONST $9 10 :i32 - ADD $10 $8 $9 :i32 - CONST $11 10 :i32 - ADD $12 $10 $11 :i32 - CONST $13 10 :i32 - ADD $14 $12 $13 :i32 - CONST $15 10 :i32 - ADD $16 $14 $15 :i32 - CONST $17 10 :i32 - ADD $18 $16 $17 :i32 - CONST $19 10 :i32 - ADD $20 $18 $19 :i32 - CONST $21 10 :i32 - ADD $22 $20 $21 :i32 - RETURN $22 :i32 + CONST $1 1 :i32 + CONST $2 10 :i32 + ADD $3 $1 $2 :i32 + CONST $4 10 :i32 + ADD $5 $3 $4 :i32 + CONST $6 10 :i32 + ADD $7 $5 $6 :i32 + CONST $8 10 :i32 + ADD $9 $7 $8 :i32 + CONST $10 10 :i32 + ADD $11 $9 $10 :i32 + CONST $12 10 :i32 + ADD $13 $11 $12 :i32 + CONST $14 10 :i32 + ADD $15 $13 $14 :i32 + CONST $16 10 :i32 + ADD $17 $15 $16 :i32 + CONST $18 10 :i32 + ADD $19 $17 $18 :i32 + CONST $20 10 :i32 + ADD $21 $19 $20 :i32 + RETURN $21 :i32 diff --git a/nautilus/test/data/ir/staticLoop.trace b/nautilus/test/data/ir/staticLoop.trace index fd817e7e..1740c599 100644 --- a/nautilus/test/data/ir/staticLoop.trace +++ b/nautilus/test/data/ir/staticLoop.trace @@ -1,27 +1,27 @@ NESIR { execute() { Block_0(): - $2 = 1 :i32 - $3 = 10 :i32 - $4 = $2 + $3 :i32 - $5 = 10 :i32 - $6 = $4 + $5 :i32 - $7 = 10 :i32 - $8 = $6 + $7 :i32 - $9 = 10 :i32 - $10 = $8 + $9 :i32 - $11 = 10 :i32 - $12 = $10 + $11 :i32 - $13 = 10 :i32 - $14 = $12 + $13 :i32 - $15 = 10 :i32 - $16 = $14 + $15 :i32 - $17 = 10 :i32 - $18 = $16 + $17 :i32 - $19 = 10 :i32 - $20 = $18 + $19 :i32 - $21 = 10 :i32 - $22 = $20 + $21 :i32 - return ($22) :i32 + $1 = 1 :i32 + $2 = 10 :i32 + $3 = $1 + $2 :i32 + $4 = 10 :i32 + $5 = $3 + $4 :i32 + $6 = 10 :i32 + $7 = $5 + $6 :i32 + $8 = 10 :i32 + $9 = $7 + $8 :i32 + $10 = 10 :i32 + $11 = $9 + $10 :i32 + $12 = 10 :i32 + $13 = $11 + $12 :i32 + $14 = 10 :i32 + $15 = $13 + $14 :i32 + $16 = 10 :i32 + $17 = $15 + $16 :i32 + $18 = 10 :i32 + $19 = $17 + $18 :i32 + $20 = 10 :i32 + $21 = $19 + $20 :i32 + return ($21) :i32 } } //NESIR \ No newline at end of file diff --git a/nautilus/test/data/ir/staticLoopIncrement.trace b/nautilus/test/data/ir/staticLoopIncrement.trace index fd817e7e..1740c599 100644 --- a/nautilus/test/data/ir/staticLoopIncrement.trace +++ b/nautilus/test/data/ir/staticLoopIncrement.trace @@ -1,27 +1,27 @@ NESIR { execute() { Block_0(): - $2 = 1 :i32 - $3 = 10 :i32 - $4 = $2 + $3 :i32 - $5 = 10 :i32 - $6 = $4 + $5 :i32 - $7 = 10 :i32 - $8 = $6 + $7 :i32 - $9 = 10 :i32 - $10 = $8 + $9 :i32 - $11 = 10 :i32 - $12 = $10 + $11 :i32 - $13 = 10 :i32 - $14 = $12 + $13 :i32 - $15 = 10 :i32 - $16 = $14 + $15 :i32 - $17 = 10 :i32 - $18 = $16 + $17 :i32 - $19 = 10 :i32 - $20 = $18 + $19 :i32 - $21 = 10 :i32 - $22 = $20 + $21 :i32 - return ($22) :i32 + $1 = 1 :i32 + $2 = 10 :i32 + $3 = $1 + $2 :i32 + $4 = 10 :i32 + $5 = $3 + $4 :i32 + $6 = 10 :i32 + $7 = $5 + $6 :i32 + $8 = 10 :i32 + $9 = $7 + $8 :i32 + $10 = 10 :i32 + $11 = $9 + $10 :i32 + $12 = 10 :i32 + $13 = $11 + $12 :i32 + $14 = 10 :i32 + $15 = $13 + $14 :i32 + $16 = 10 :i32 + $17 = $15 + $16 :i32 + $18 = 10 :i32 + $19 = $17 + $18 :i32 + $20 = 10 :i32 + $21 = $19 + $20 :i32 + return ($21) :i32 } } //NESIR \ No newline at end of file diff --git a/nautilus/test/data/tracing/staticLoop.trace b/nautilus/test/data/tracing/staticLoop.trace index 404487f0..60c02701 100644 --- a/nautilus/test/data/tracing/staticLoop.trace +++ b/nautilus/test/data/tracing/staticLoop.trace @@ -1,33 +1,33 @@ B0() - CONST $2 1 :i32 - CONST $3 10 :i32 - ADD $4 $2 $3 :i32 - ASSIGN $2 $4 :i32 - CONST $5 10 :i32 - ADD $6 $2 $5 :i32 - ASSIGN $2 $6 :i32 - CONST $7 10 :i32 - ADD $8 $2 $7 :i32 - ASSIGN $2 $8 :i32 - CONST $9 10 :i32 - ADD $10 $2 $9 :i32 - ASSIGN $2 $10 :i32 - CONST $11 10 :i32 - ADD $12 $2 $11 :i32 - ASSIGN $2 $12 :i32 - CONST $13 10 :i32 - ADD $14 $2 $13 :i32 - ASSIGN $2 $14 :i32 - CONST $15 10 :i32 - ADD $16 $2 $15 :i32 - ASSIGN $2 $16 :i32 - CONST $17 10 :i32 - ADD $18 $2 $17 :i32 - ASSIGN $2 $18 :i32 - CONST $19 10 :i32 - ADD $20 $2 $19 :i32 - ASSIGN $2 $20 :i32 - CONST $21 10 :i32 - ADD $22 $2 $21 :i32 - ASSIGN $2 $22 :i32 - RETURN $2 :i32 + CONST $1 1 :i32 + CONST $2 10 :i32 + ADD $3 $1 $2 :i32 + ASSIGN $1 $3 :i32 + CONST $4 10 :i32 + ADD $5 $1 $4 :i32 + ASSIGN $1 $5 :i32 + CONST $6 10 :i32 + ADD $7 $1 $6 :i32 + ASSIGN $1 $7 :i32 + CONST $8 10 :i32 + ADD $9 $1 $8 :i32 + ASSIGN $1 $9 :i32 + CONST $10 10 :i32 + ADD $11 $1 $10 :i32 + ASSIGN $1 $11 :i32 + CONST $12 10 :i32 + ADD $13 $1 $12 :i32 + ASSIGN $1 $13 :i32 + CONST $14 10 :i32 + ADD $15 $1 $14 :i32 + ASSIGN $1 $15 :i32 + CONST $16 10 :i32 + ADD $17 $1 $16 :i32 + ASSIGN $1 $17 :i32 + CONST $18 10 :i32 + ADD $19 $1 $18 :i32 + ASSIGN $1 $19 :i32 + CONST $20 10 :i32 + ADD $21 $1 $20 :i32 + ASSIGN $1 $21 :i32 + RETURN $1 :i32 diff --git a/nautilus/test/data/tracing/staticLoopIncrement.trace b/nautilus/test/data/tracing/staticLoopIncrement.trace index 404487f0..60c02701 100644 --- a/nautilus/test/data/tracing/staticLoopIncrement.trace +++ b/nautilus/test/data/tracing/staticLoopIncrement.trace @@ -1,33 +1,33 @@ B0() - CONST $2 1 :i32 - CONST $3 10 :i32 - ADD $4 $2 $3 :i32 - ASSIGN $2 $4 :i32 - CONST $5 10 :i32 - ADD $6 $2 $5 :i32 - ASSIGN $2 $6 :i32 - CONST $7 10 :i32 - ADD $8 $2 $7 :i32 - ASSIGN $2 $8 :i32 - CONST $9 10 :i32 - ADD $10 $2 $9 :i32 - ASSIGN $2 $10 :i32 - CONST $11 10 :i32 - ADD $12 $2 $11 :i32 - ASSIGN $2 $12 :i32 - CONST $13 10 :i32 - ADD $14 $2 $13 :i32 - ASSIGN $2 $14 :i32 - CONST $15 10 :i32 - ADD $16 $2 $15 :i32 - ASSIGN $2 $16 :i32 - CONST $17 10 :i32 - ADD $18 $2 $17 :i32 - ASSIGN $2 $18 :i32 - CONST $19 10 :i32 - ADD $20 $2 $19 :i32 - ASSIGN $2 $20 :i32 - CONST $21 10 :i32 - ADD $22 $2 $21 :i32 - ASSIGN $2 $22 :i32 - RETURN $2 :i32 + CONST $1 1 :i32 + CONST $2 10 :i32 + ADD $3 $1 $2 :i32 + ASSIGN $1 $3 :i32 + CONST $4 10 :i32 + ADD $5 $1 $4 :i32 + ASSIGN $1 $5 :i32 + CONST $6 10 :i32 + ADD $7 $1 $6 :i32 + ASSIGN $1 $7 :i32 + CONST $8 10 :i32 + ADD $9 $1 $8 :i32 + ASSIGN $1 $9 :i32 + CONST $10 10 :i32 + ADD $11 $1 $10 :i32 + ASSIGN $1 $11 :i32 + CONST $12 10 :i32 + ADD $13 $1 $12 :i32 + ASSIGN $1 $13 :i32 + CONST $14 10 :i32 + ADD $15 $1 $14 :i32 + ASSIGN $1 $15 :i32 + CONST $16 10 :i32 + ADD $17 $1 $16 :i32 + ASSIGN $1 $17 :i32 + CONST $18 10 :i32 + ADD $19 $1 $18 :i32 + ASSIGN $1 $19 :i32 + CONST $20 10 :i32 + ADD $21 $1 $20 :i32 + ASSIGN $1 $21 :i32 + RETURN $1 :i32 diff --git a/nautilus/test/execution-tests/ExecutionTest.cpp b/nautilus/test/execution-tests/ExecutionTest.cpp index 331f9079..b669247a 100644 --- a/nautilus/test/execution-tests/ExecutionTest.cpp +++ b/nautilus/test/execution-tests/ExecutionTest.cpp @@ -10,7 +10,27 @@ namespace nautilus::engine { +struct RObject { + val a; + val b; +}; + +RObject returnObject(val a, val b) { + if (a > b) { + return {.a = a, .b = b}; + } + return {.a = 0, .b = 0}; +} + +val constructComplexReturnObject(val a, val b) { + auto r = returnObject(a, b); + auto t1 = r.a + 1; + auto t2 = r.b + 1; + return t1 + t2; +} + void addTest(engine::NautilusEngine& engine) { + SECTION("staticCast") { auto f = engine.registerFunction(staticCastExpression); REQUIRE(f((int8_t) 34) == 34); @@ -902,8 +922,14 @@ TEST_CASE("Engine Compiler Test") { options.setOption("engine.backend", backend); auto engine = engine::NautilusEngine(options); runAllTests(engine); + SECTION("constructComplexReturnObject") { + // we assume that this throws a runtime exception with + // wrong number of arguments after tracing" + REQUIRE_THROWS(engine.registerFunction(constructComplexReturnObject)); + } } } + } #endif } // namespace nautilus::engine diff --git a/nautilus/test/execution-tests/StaticLoopFunctions.hpp b/nautilus/test/execution-tests/StaticLoopFunctions.hpp index 26a0f7ba..b9aa4196 100644 --- a/nautilus/test/execution-tests/StaticLoopFunctions.hpp +++ b/nautilus/test/execution-tests/StaticLoopFunctions.hpp @@ -4,7 +4,7 @@ namespace nautilus::engine { -val staticLoop(val) { +val staticLoop() { val agg = val(1); for (static_val start = 0; start < 10; start = start + 1) { agg = agg + 10; @@ -47,7 +47,7 @@ val staticIterator(val ref) { return sum; } -val staticLoopIncrement(val) { +val staticLoopIncrement() { val agg = val(1); for (static_val start = 0; start < 10; start++) { agg = agg + 10;