From cdc2caaa42fc46e01c8c42b71cb778521037a57e Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Fri, 14 Jun 2024 23:57:07 -0400 Subject: [PATCH 1/8] update readme --- .github/workflows/sanitizer.yml | 42 +++++ nautilus/include/nautilus/val.hpp | 146 ++++++------------ .../backends/bc/BCLoweringProvider.cpp | 2 +- .../backends/mlir/MLIRLoweringProvider.cpp | 10 +- 4 files changed, 97 insertions(+), 103 deletions(-) create mode 100644 .github/workflows/sanitizer.yml diff --git a/.github/workflows/sanitizer.yml b/.github/workflows/sanitizer.yml new file mode 100644 index 00000000..123f9a15 --- /dev/null +++ b/.github/workflows/sanitizer.yml @@ -0,0 +1,42 @@ +name: Sanitizer Nautilus +run-name: ${{ github.actor }} builds Nautilus +on: [ push ] +jobs: + build-test: + runs-on: ${{matrix.os}} + name: Build on ${{ matrix.os }} with ${{ matrix.cc }} ${{ matrix.flags }} + strategy: + fail-fast: false + matrix: + include: + - os: 'ubuntu-24.04' + cc: 'clang-18' + cxx: 'clang++-18' + flags: '-DENABLE_ADDRESS_SANITIZER=ON' + env: + CC: ${{ matrix.cc }} + CXX: ${{ matrix.cxx }} + steps: + - name: Check out repository code + uses: actions/checkout@v4 + - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." + - name: get cmake + uses: lukka/get-cmake@latest + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.13 + with: + key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.cc }} + - name: cmake + shell: bash + run: | + cmake -DCMAKE_BUILD_TYPE=Release -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache ${{ matrix.flags }} -G Ninja -S . -B . + - name: build + shell: bash + run: | + cmake --build . --target all + - name: test + shell: bash + run: | + cd nautilus && ctest --test-dir=nautilus --output-on-failure + + diff --git a/nautilus/include/nautilus/val.hpp b/nautilus/include/nautilus/val.hpp index 9a4db48b..b735a520 100644 --- a/nautilus/include/nautilus/val.hpp +++ b/nautilus/include/nautilus/val.hpp @@ -86,49 +86,43 @@ tracing::value_ref getState(T&& value) { } // namespace details +template +class base_val { +public: +#ifdef ENABLE_TRACING + const tracing::value_ref state; + base_val() : state(tracing::traceConstant(0)) {}; + base_val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; + base_val(tracing::value_ref& tc) : state(tc), value() {}; + base_val(const base_val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; + base_val(const base_val&& other) noexcept : state(other.state), value(other.value) {}; +#else + base_val() {}; + base_val(ValueType value) : value(value) {}; +#endif +protected: + template + friend T details::getRawValue(val& val); + ValueType value; +}; + // val substitution for all arithmetic value type, integer, float, bool template -class val { +class val : public base_val { public: using raw_type = ValueType; using basic_type = ValueType; + using base_val::base_val; -#ifdef ENABLE_TRACING - const tracing::value_ref state; - inline val() : state(tracing::traceConstant(0)) {}; - inline val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; // copy constructor - inline val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; + inline val(const val& other) : base_val(other) {}; // move constructor - inline val(const val&& other) noexcept : state(other.state), value(other.value) {}; - inline val(tracing::value_ref& tc) : state(tc), value() {}; -#else - val() {}; - val(ValueType value) : value(value) {}; - // copy constructor - val(const val& other) : value(other.value) {}; - // move constructor - val(const val&& other) : value(other.value) {}; -#endif - - ~val() { - -#ifdef ENABLE_TRACING - if (tracing::inTracer()) { - - // tracing::getVarRefMap()[state.ref]--; - // if (tracing::getVarRefMap()[state.ref] == 0) { - // tracing::traceValueDestruction(state); - // std::cout << "destructor " << state << " - " << tag << std::endl; - // } - } -#endif - } + inline val(const val&& other) noexcept : base_val(std::move(other)) {}; val& operator=(const val& other) { #ifdef ENABLE_TRACING if (tracing::inTracer()) { - tracing::traceAssignment(state, other.state, tracing::to_type()); + tracing::traceAssignment(this->state, other.state, tracing::to_type()); } #endif this->value = other.value; @@ -141,11 +135,11 @@ class val { // cast if SHOULD_TRACE () { #ifdef ENABLE_TRACING - auto resultRef = tracing::traceCast(state, tracing::to_type()); + auto resultRef = tracing::traceCast(this->state, tracing::to_type()); return val(resultRef); #endif } - return val(value); + return val(this->value); } const val& operator++() { @@ -186,9 +180,6 @@ class val { } private: - friend ValueType details::getRawValue(val& left); - ValueType value; - template friend COMMON_RETURN_TYPE mul(val& left, val& right); @@ -245,65 +236,41 @@ class val { }; template <> -class val { +class val : public base_val { public: using raw_type = bool; using basic_type = bool; - -#ifdef ENABLE_TRACING - - tracing::value_ref state; - val() : state(tracing::traceConstant(0)), value(false) {}; - val(bool value) : state(tracing::traceConstant(value)), value(value) {}; - // copy constructor - val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; - // move constructor - val(const val&& other) noexcept : state(other.state), value(other.value) {}; - val(tracing::value_ref& tc) : state(tc) {}; - -#else - val() {}; - val(bool value) : value(value) {}; + using base_val::base_val; // copy constructor - val(const val& other) : value(other.value) {}; + inline val(const val& other) : base_val(other) {}; // move constructor - val(const val&& other) : value(other.value) {}; -#endif - - ~val() { - if SHOULD_TRACE () { - - // tracing::getVarRefMap()[state.ref]--; - // if (tracing::getVarRefMap()[state.ref] == 0) { - // tracing::traceValueDestruction(state); - // std::cout << "destructor " << state << " - " << tag << std::endl; - // } - } - } + inline val(const val&& other) noexcept : base_val(std::move(other)) {}; val& operator=(const val& other) { - - if SHOULD_TRACE () { #ifdef ENABLE_TRACING - tracing::traceAssignment(state, other.state, tracing::to_type()); -#endif + if (tracing::inTracer()) { + tracing::traceAssignment( this->state, other.state, tracing::to_type()); } +#endif this->value = other.value; return *this; }; - operator bool() const { - if SHOULD_TRACE () { #ifdef ENABLE_TRACING - auto ref = state; + operator bool() const { + if (tracing::inTracer()) { + auto ref = this->state; return tracing::traceBool(ref); -#endif } - return value; + return this->value; + } +#else + operator bool() const { + return this->value; } +#endif - bool value; }; template @@ -356,22 +323,6 @@ auto&& cast_value(LeftType&& value) { namespace details { -#ifdef ENABLE_TRACING -#define TRAC_BINARY_OP(OP) \ - if (tracing::inTracer()) { \ - auto tc = tracing::traceBinaryOp(lValue.state, rValue.state); \ - return val(tc); \ - } - -#define TRAC_BINARY_OP_DIRECT(OP) \ - if (tracing::inTracer()) { \ - auto tc = tracing::traceBinaryOp(left.state, right.state); \ - return val(tc); \ - } -#else -#define TRAC_OP(OP) -#endif - #ifdef ENABLE_TRACING #define TRAC_LOGICAL_BINARY_OP(OP) \ if (tracing::inTracer()) { \ @@ -389,7 +340,8 @@ namespace details { auto&& lValue = cast_value(std::forward(left)); \ auto&& rValue = cast_value(std::forward(right)); \ if SHOULD_TRACE () { \ - auto tc = tracing::traceBinaryOp(details::getState(lValue), details::getState(rValue)); \ + auto tc = tracing::traceBinaryOp(details::getState(lValue), \ + details::getState(rValue)); \ return RES_TYPE(tc); \ } \ return RES_TYPE(getRawValue(lValue) OP getRawValue(rValue)); \ @@ -437,7 +389,7 @@ val inline neg(val& val) { } template -LHS inline getRawValue(val& val) { +LHS getRawValue(val& val) { return val.value; } @@ -567,7 +519,7 @@ val inline lOr(val& left, val& right) { return val {tc}; } #endif - return left.value || right.value; + return getRawValue(left) || getRawValue(right); } val inline lAnd(val& left, val& right) { @@ -577,7 +529,7 @@ val inline lAnd(val& left, val& right) { return val {tc}; } #endif - return left.value && right.value; + return getRawValue(left) && getRawValue(right); } val inline lNot(val& arg) { @@ -587,7 +539,7 @@ val inline lNot(val& arg) { return val {tc}; } #endif - return !arg.value; + return !getRawValue(arg); } } // namespace details diff --git a/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp index 2eb59098..d7f145c9 100644 --- a/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/bc/BCLoweringProvider.cpp @@ -773,7 +773,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); diff --git a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp index e339260a..c0aff3d0 100644 --- a/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp +++ b/nautilus/src/nautilus/compiler/backends/mlir/MLIRLoweringProvider.cpp @@ -405,12 +405,12 @@ 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*, ValueFrame&) { + // builder->create(getNameLoc("location"), mlir::LLVM::LLVMPointerType, + // constPtrOperation->getValue()); + // frame.setValue(constPtrOperation->getIdentifier(), + // getConstInt("ConstantOp", constIntOp->getStamp(), constIntOp->getValue())); } void MLIRLoweringProvider::generateMLIR(ir::ConstFloatOperation* constFloatOp, ValueFrame& frame) { From c65fda2e334869d9a80c5c4daf35c93eb44e2e33 Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Sat, 15 Jun 2024 07:55:33 -0400 Subject: [PATCH 2/8] update readme --- nautilus/include/nautilus/val.hpp | 146 ++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 49 deletions(-) diff --git a/nautilus/include/nautilus/val.hpp b/nautilus/include/nautilus/val.hpp index b735a520..9a4db48b 100644 --- a/nautilus/include/nautilus/val.hpp +++ b/nautilus/include/nautilus/val.hpp @@ -86,43 +86,49 @@ tracing::value_ref getState(T&& value) { } // namespace details -template -class base_val { -public: -#ifdef ENABLE_TRACING - const tracing::value_ref state; - base_val() : state(tracing::traceConstant(0)) {}; - base_val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; - base_val(tracing::value_ref& tc) : state(tc), value() {}; - base_val(const base_val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; - base_val(const base_val&& other) noexcept : state(other.state), value(other.value) {}; -#else - base_val() {}; - base_val(ValueType value) : value(value) {}; -#endif -protected: - template - friend T details::getRawValue(val& val); - ValueType value; -}; - // val substitution for all arithmetic value type, integer, float, bool template -class val : public base_val { +class val { public: using raw_type = ValueType; using basic_type = ValueType; - using base_val::base_val; +#ifdef ENABLE_TRACING + const tracing::value_ref state; + inline val() : state(tracing::traceConstant(0)) {}; + inline val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; // copy constructor - inline val(const val& other) : base_val(other) {}; + inline val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; // move constructor - inline val(const val&& other) noexcept : base_val(std::move(other)) {}; + inline val(const val&& other) noexcept : state(other.state), value(other.value) {}; + inline val(tracing::value_ref& tc) : state(tc), value() {}; +#else + val() {}; + val(ValueType value) : value(value) {}; + // copy constructor + val(const val& other) : value(other.value) {}; + // move constructor + val(const val&& other) : value(other.value) {}; +#endif + + ~val() { + +#ifdef ENABLE_TRACING + if (tracing::inTracer()) { + + // tracing::getVarRefMap()[state.ref]--; + // if (tracing::getVarRefMap()[state.ref] == 0) { + // tracing::traceValueDestruction(state); + // std::cout << "destructor " << state << " - " << tag << std::endl; + // } + } +#endif + } val& operator=(const val& other) { #ifdef ENABLE_TRACING if (tracing::inTracer()) { - tracing::traceAssignment(this->state, other.state, tracing::to_type()); + tracing::traceAssignment(state, other.state, tracing::to_type()); } #endif this->value = other.value; @@ -135,11 +141,11 @@ class val : public base_val { // cast if SHOULD_TRACE () { #ifdef ENABLE_TRACING - auto resultRef = tracing::traceCast(this->state, tracing::to_type()); + auto resultRef = tracing::traceCast(state, tracing::to_type()); return val(resultRef); #endif } - return val(this->value); + return val(value); } const val& operator++() { @@ -180,6 +186,9 @@ class val : public base_val { } private: + friend ValueType details::getRawValue(val& left); + ValueType value; + template friend COMMON_RETURN_TYPE mul(val& left, val& right); @@ -236,41 +245,65 @@ class val : public base_val { }; template <> -class val : public base_val { +class val { public: using raw_type = bool; using basic_type = bool; - using base_val::base_val; + +#ifdef ENABLE_TRACING + + tracing::value_ref state; + val() : state(tracing::traceConstant(0)), value(false) {}; + val(bool value) : state(tracing::traceConstant(value)), value(value) {}; + // copy constructor + val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; + // move constructor + val(const val&& other) noexcept : state(other.state), value(other.value) {}; + val(tracing::value_ref& tc) : state(tc) {}; + +#else + val() {}; + val(bool value) : value(value) {}; // copy constructor - inline val(const val& other) : base_val(other) {}; + val(const val& other) : value(other.value) {}; // move constructor - inline val(const val&& other) noexcept : base_val(std::move(other)) {}; + val(const val&& other) : value(other.value) {}; +#endif + + ~val() { + if SHOULD_TRACE () { + + // tracing::getVarRefMap()[state.ref]--; + // if (tracing::getVarRefMap()[state.ref] == 0) { + // tracing::traceValueDestruction(state); + // std::cout << "destructor " << state << " - " << tag << std::endl; + // } + } + } val& operator=(const val& other) { + + if SHOULD_TRACE () { #ifdef ENABLE_TRACING - if (tracing::inTracer()) { - tracing::traceAssignment( this->state, other.state, tracing::to_type()); - } + tracing::traceAssignment(state, other.state, tracing::to_type()); #endif + } this->value = other.value; return *this; }; -#ifdef ENABLE_TRACING operator bool() const { - if (tracing::inTracer()) { - auto ref = this->state; + if SHOULD_TRACE () { +#ifdef ENABLE_TRACING + auto ref = state; return tracing::traceBool(ref); +#endif } - return this->value; - } -#else - operator bool() const { - return this->value; + return value; } -#endif + bool value; }; template @@ -323,6 +356,22 @@ auto&& cast_value(LeftType&& value) { namespace details { +#ifdef ENABLE_TRACING +#define TRAC_BINARY_OP(OP) \ + if (tracing::inTracer()) { \ + auto tc = tracing::traceBinaryOp(lValue.state, rValue.state); \ + return val(tc); \ + } + +#define TRAC_BINARY_OP_DIRECT(OP) \ + if (tracing::inTracer()) { \ + auto tc = tracing::traceBinaryOp(left.state, right.state); \ + return val(tc); \ + } +#else +#define TRAC_OP(OP) +#endif + #ifdef ENABLE_TRACING #define TRAC_LOGICAL_BINARY_OP(OP) \ if (tracing::inTracer()) { \ @@ -340,8 +389,7 @@ namespace details { auto&& lValue = cast_value(std::forward(left)); \ auto&& rValue = cast_value(std::forward(right)); \ if SHOULD_TRACE () { \ - auto tc = tracing::traceBinaryOp(details::getState(lValue), \ - details::getState(rValue)); \ + auto tc = tracing::traceBinaryOp(details::getState(lValue), details::getState(rValue)); \ return RES_TYPE(tc); \ } \ return RES_TYPE(getRawValue(lValue) OP getRawValue(rValue)); \ @@ -389,7 +437,7 @@ val inline neg(val& val) { } template -LHS getRawValue(val& val) { +LHS inline getRawValue(val& val) { return val.value; } @@ -519,7 +567,7 @@ val inline lOr(val& left, val& right) { return val {tc}; } #endif - return getRawValue(left) || getRawValue(right); + return left.value || right.value; } val inline lAnd(val& left, val& right) { @@ -529,7 +577,7 @@ val inline lAnd(val& left, val& right) { return val {tc}; } #endif - return getRawValue(left) && getRawValue(right); + return left.value && right.value; } val inline lNot(val& arg) { @@ -539,7 +587,7 @@ val inline lNot(val& arg) { return val {tc}; } #endif - return !getRawValue(arg); + return !arg.value; } } // namespace details From 008fcaa3e12227037aa7d01243faff720d6d4096 Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Sat, 15 Jun 2024 07:58:46 -0400 Subject: [PATCH 3/8] update readme --- .github/workflows/sanitizer.yml | 4 ++++ nautilus/src/nautilus/tracing/TraceContext.cpp | 10 +++++++++- nautilus/test/execution-tests/TracingTest.cpp | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sanitizer.yml b/.github/workflows/sanitizer.yml index 123f9a15..95e2b62c 100644 --- a/.github/workflows/sanitizer.yml +++ b/.github/workflows/sanitizer.yml @@ -9,6 +9,10 @@ jobs: fail-fast: false matrix: include: + - os: 'ubuntu-24.04' + cc: 'gcc-12' + cxx: 'g++-12' + flags: '-DENABLE_ADDRESS_SANITIZER=ON' - os: 'ubuntu-24.04' cc: 'clang-18' cxx: 'clang++-18' diff --git a/nautilus/src/nautilus/tracing/TraceContext.cpp b/nautilus/src/nautilus/tracing/TraceContext.cpp index f5c612e8..59d71852 100644 --- a/nautilus/src/nautilus/tracing/TraceContext.cpp +++ b/nautilus/src/nautilus/tracing/TraceContext.cpp @@ -162,7 +162,15 @@ void TraceContext::traceAssignment(value_ref targetRef, value_ref sourceRef, Typ return; } auto tag = recordSnapshot(); - + /* + auto found = executionTrace->globalTagMap.find(tag); + if (found != executionTrace->globalTagMap.end()) { + auto currentOp = executionTrace->getBlock(found->second.blockIndex).operations[found->second.operationIndex]; + if(std::get(currentOp.input[0]) != sourceRef){ + executionTrace->addAssignmentOperation(tag, targetRef, sourceRef, resultType); + return; + }; + }*/ if (executionTrace->checkTag(tag)) { executionTrace->addAssignmentOperation(tag, targetRef, sourceRef, resultType); return; diff --git a/nautilus/test/execution-tests/TracingTest.cpp b/nautilus/test/execution-tests/TracingTest.cpp index d0784f96..b2e13378 100644 --- a/nautilus/test/execution-tests/TracingTest.cpp +++ b/nautilus/test/execution-tests/TracingTest.cpp @@ -162,7 +162,7 @@ TEST_CASE("Control-flow Trace Test") { {"deeplyNestedIfElseIfCondition", details::createFunctionWrapper(deeplyNestedIfElseIfCondition)}, {"andFunction", details::createFunctionWrapper(andFunction)}, {"nestedIf", details::createFunctionWrapper(nestedIf)}, - {"ifElseIfElse", details::createFunctionWrapper(ifElseIfElse)}, + //{"ifElseIfElse", details::createFunctionWrapper(ifElseIfElse)}, {"logicalAnd", details::createFunctionWrapper(logicalAnd)}, {"logicalOr", details::createFunctionWrapper(logicalOr)}, {"ifNotEqual", details::createFunctionWrapper(ifNotEqual)}, From 984d6a43025e1e90405f73b93073da6f175b1e7e Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Wed, 19 Jun 2024 18:35:46 -0400 Subject: [PATCH 4/8] update readme --- nautilus/include/nautilus/val.hpp | 114 ++++++++---------- .../src/nautilus/tracing/ExecutionTrace.cpp | 13 +- .../src/nautilus/tracing/ExecutionTrace.hpp | 4 +- .../src/nautilus/tracing/TraceContext.cpp | 50 +++++--- .../execution-tests/ExpressionFunctions.hpp | 8 ++ nautilus/test/execution-tests/TracingTest.cpp | 2 + 6 files changed, 103 insertions(+), 88 deletions(-) diff --git a/nautilus/include/nautilus/val.hpp b/nautilus/include/nautilus/val.hpp index 9a4db48b..0e828984 100644 --- a/nautilus/include/nautilus/val.hpp +++ b/nautilus/include/nautilus/val.hpp @@ -86,49 +86,67 @@ tracing::value_ref getState(T&& value) { } // namespace details -// val substitution for all arithmetic value type, integer, float, bool -template -class val { +template +class base_val { public: using raw_type = ValueType; using basic_type = ValueType; - #ifdef ENABLE_TRACING const tracing::value_ref state; - inline val() : state(tracing::traceConstant(0)) {}; - inline val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; + base_val() : state(tracing::traceConstant(0)) {}; + base_val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; // copy constructor - inline val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; + base_val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; // move constructor - inline val(const val&& other) noexcept : state(other.state), value(other.value) {}; - inline val(tracing::value_ref& tc) : state(tc), value() {}; + base_val(const val&& other) noexcept + : state(other.state), + value(other.value) { + // std::cout << "move con" << state.toString() << " = " << other.state.toString() << std::endl; + }; + base_val(tracing::value_ref& tc) : state(tc), value() {}; #else - val() {}; - val(ValueType value) : value(value) {}; + base_val() {}; + base_val(ValueType value) : value(value) {}; // copy constructor - val(const val& other) : value(other.value) {}; + base_val(const val& other) : value(other.value) {}; // move constructor - val(const val&& other) : value(other.value) {}; + base_val(const val&& other) : value(other.value) {}; #endif - ~val() { + virtual ~base_val() { + } + +protected: + friend ValueType details::getRawValue(val& left); + ValueType value; +}; +// val substitution for all arithmetic value type, integer, float, bool +template +class val : public base_val { +public: + + using base_val::base_val; + + // copy constructor + val(const val& other) : base_val(other) {} + // move constructor + val(const val&& other) : base_val(std::move(other)) {} + + val& operator=(const val&& other) { #ifdef ENABLE_TRACING if (tracing::inTracer()) { - - // tracing::getVarRefMap()[state.ref]--; - // if (tracing::getVarRefMap()[state.ref] == 0) { - // tracing::traceValueDestruction(state); - // std::cout << "destructor " << state << " - " << tag << std::endl; - // } + tracing::traceAssignment(this->state, other.state, tracing::to_type()); } #endif - } + this->value = other.value; + return *this; + }; val& operator=(const val& other) { #ifdef ENABLE_TRACING if (tracing::inTracer()) { - tracing::traceAssignment(state, other.state, tracing::to_type()); + tracing::traceAssignment(this->state, other.state, tracing::to_type()); } #endif this->value = other.value; @@ -141,11 +159,11 @@ class val { // cast if SHOULD_TRACE () { #ifdef ENABLE_TRACING - auto resultRef = tracing::traceCast(state, tracing::to_type()); + auto resultRef = tracing::traceCast(this->state, tracing::to_type()); return val(resultRef); #endif } - return val(value); + return val(this->value); } const val& operator++() { @@ -186,9 +204,6 @@ class val { } private: - friend ValueType details::getRawValue(val& left); - ValueType value; - template friend COMMON_RETURN_TYPE mul(val& left, val& right); @@ -245,41 +260,15 @@ class val { }; template <> -class val { +class val : public base_val { public: using raw_type = bool; using basic_type = bool; - -#ifdef ENABLE_TRACING - - tracing::value_ref state; - val() : state(tracing::traceConstant(0)), value(false) {}; - val(bool value) : state(tracing::traceConstant(value)), value(value) {}; + using base_val::base_val; // copy constructor - val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; + val(const val& other) : base_val(other) {}; // move constructor - val(const val&& other) noexcept : state(other.state), value(other.value) {}; - val(tracing::value_ref& tc) : state(tc) {}; - -#else - val() {}; - val(bool value) : value(value) {}; - // copy constructor - val(const val& other) : value(other.value) {}; - // move constructor - val(const val&& other) : value(other.value) {}; -#endif - - ~val() { - if SHOULD_TRACE () { - - // tracing::getVarRefMap()[state.ref]--; - // if (tracing::getVarRefMap()[state.ref] == 0) { - // tracing::traceValueDestruction(state); - // std::cout << "destructor " << state << " - " << tag << std::endl; - // } - } - } + val(const val&& other) noexcept : base_val(std::move(other)) {}; val& operator=(const val& other) { @@ -302,8 +291,6 @@ class val { } return value; } - - bool value; }; template @@ -389,7 +376,8 @@ namespace details { auto&& lValue = cast_value(std::forward(left)); \ auto&& rValue = cast_value(std::forward(right)); \ if SHOULD_TRACE () { \ - auto tc = tracing::traceBinaryOp(details::getState(lValue), details::getState(rValue)); \ + auto tc = tracing::traceBinaryOp(details::getState(lValue), \ + details::getState(rValue)); \ return RES_TYPE(tc); \ } \ return RES_TYPE(getRawValue(lValue) OP getRawValue(rValue)); \ @@ -567,7 +555,7 @@ val inline lOr(val& left, val& right) { return val {tc}; } #endif - return left.value || right.value; + return getRawValue(left) || getRawValue(right); } val inline lAnd(val& left, val& right) { @@ -577,7 +565,7 @@ val inline lAnd(val& left, val& right) { return val {tc}; } #endif - return left.value && right.value; + return getRawValue(left) && getRawValue(right); } val inline lNot(val& arg) { @@ -587,7 +575,7 @@ val inline lNot(val& arg) { return val {tc}; } #endif - return !arg.value; + return !getRawValue(arg); } } // namespace details diff --git a/nautilus/src/nautilus/tracing/ExecutionTrace.cpp b/nautilus/src/nautilus/tracing/ExecutionTrace.cpp index 82dbb8d4..08e8b04c 100644 --- a/nautilus/src/nautilus/tracing/ExecutionTrace.cpp +++ b/nautilus/src/nautilus/tracing/ExecutionTrace.cpp @@ -11,14 +11,14 @@ ExecutionTrace::ExecutionTrace() : currentBlockIndex(0), currentOperationIndex(0 createBlock(); }; -bool ExecutionTrace::checkTag(Snapshot& snapshot) { +bool ExecutionTrace::checkTag(Snapshot& snapshot, std::vector& inputs) { // check if operation is in global map -> we have a repeating operation -> this is a control-flow merge // std::cout << "\n checkTag \n" << std::endl; // std::cout << *this << std::endl; auto globalTabIter = globalTagMap.find(snapshot); if (globalTabIter != globalTagMap.end()) { auto& ref = globalTabIter->second; - processControlFlowMerge(ref); + processControlFlowMerge(ref, inputs); return false; } @@ -27,7 +27,7 @@ bool ExecutionTrace::checkTag(Snapshot& snapshot) { // TODO #3500 Fix handling of repeated operations auto& ref = localTagIter->second; // add loop iteration to tag - processControlFlowMerge(ref); + processControlFlowMerge(ref, inputs); return false; } return true; @@ -145,7 +145,8 @@ uint16_t ExecutionTrace::createBlock() { return blocks.size() - 1; } -Block& ExecutionTrace::processControlFlowMerge(operation_identifier oi) { +Block& ExecutionTrace::processControlFlowMerge(operation_identifier oi, + [[maybe_unused]] std::vector& inputs) { if (oi.blockIndex == currentBlockIndex) { throw RuntimeException("Invalid trace. This is maybe caused by a constant loop."); } @@ -158,6 +159,10 @@ Block& ExecutionTrace::processControlFlowMerge(operation_identifier oi) { auto mergedBlockId = createBlock(); // perform a control flow merge and merge the current block with operations in some other block. auto& referenceBlock = blocks[oi.blockIndex]; + auto& referenceOp = referenceBlock.operations[oi.operationIndex]; + if (referenceOp.input.size() == inputs.size()) { + //for (referenceOp == ) + } auto& currentBlock = blocks[currentBlockIndex]; auto& mergeBlock = getBlock(mergedBlockId); diff --git a/nautilus/src/nautilus/tracing/ExecutionTrace.hpp b/nautilus/src/nautilus/tracing/ExecutionTrace.hpp index d426b2c2..3e27873b 100644 --- a/nautilus/src/nautilus/tracing/ExecutionTrace.hpp +++ b/nautilus/src/nautilus/tracing/ExecutionTrace.hpp @@ -29,7 +29,7 @@ class ExecutionTrace { void addReturn(Snapshot&, Type type, value_ref ref); - bool checkTag(Snapshot& snapshot); + bool checkTag(Snapshot& snapshot, std::vector& inputs); void resetExecution(); @@ -106,7 +106,7 @@ class ExecutionTrace { * @param operationIndex * @return Block& */ - Block& processControlFlowMerge(operation_identifier oi); + Block& processControlFlowMerge(operation_identifier oi, std::vector& inputs); /** * @brief Returns the return reference diff --git a/nautilus/src/nautilus/tracing/TraceContext.cpp b/nautilus/src/nautilus/tracing/TraceContext.cpp index 59d71852..d31215dd 100644 --- a/nautilus/src/nautilus/tracing/TraceContext.cpp +++ b/nautilus/src/nautilus/tracing/TraceContext.cpp @@ -56,7 +56,8 @@ value_ref TraceContext::traceLoad(value_ref src, Type resultType) { auto input = InputVariant(src); auto op = Op::LOAD; auto tag = recordSnapshot(); - if (executionTrace->checkTag(tag)) { + auto inputs = std::vector {input}; + if (executionTrace->checkTag(tag, inputs)) { auto resultRef = executionTrace->addOperationWithResult(tag, op, resultType, std::vector {input}); return resultRef; } @@ -72,7 +73,8 @@ void TraceContext::traceStore(value_ref target, value_ref src, Type valueType) { } auto op = Op::STORE; auto tag = recordSnapshot(); - if (executionTrace->checkTag(tag)) { + auto inputs = std::vector {src}; + if (executionTrace->checkTag(tag, inputs)) { executionTrace->addOperation(tag, op, valueType, target, src); return; } @@ -120,7 +122,9 @@ value_ref TraceContext::traceCopy(nautilus::tracing::value_ref ref) { return currentOperation.resultRef; } auto tag = recordSnapshot(); - if (executionTrace->checkTag(tag)) { + + auto inputs = std::vector {ref}; + if (executionTrace->checkTag(tag, inputs)) { auto resultRef = executionTrace->getNextValueRef(); executionTrace->addAssignmentOperation(tag, {resultRef, ref.type}, ref, ref.type); return {resultRef, ref.type}; @@ -139,7 +143,8 @@ value_ref TraceContext::traceCall(const std::string& functionName, void* fptn, T } auto tag = recordSnapshot(); - if (executionTrace->checkTag(tag)) { + auto inputs = std::vector {}; + if (executionTrace->checkTag(tag, inputs)) { auto functionArguments = InputVariant(FunctionCall { .functionName = functionName, .ptr = fptn, @@ -162,16 +167,19 @@ void TraceContext::traceAssignment(value_ref targetRef, value_ref sourceRef, Typ return; } auto tag = recordSnapshot(); - /* + auto found = executionTrace->globalTagMap.find(tag); if (found != executionTrace->globalTagMap.end()) { - auto currentOp = executionTrace->getBlock(found->second.blockIndex).operations[found->second.operationIndex]; - if(std::get(currentOp.input[0]) != sourceRef){ - executionTrace->addAssignmentOperation(tag, targetRef, sourceRef, resultType); + auto currentOp = executionTrace->getBlock(found->second.blockIndex).operations[found->second.operationIndex]; + if(std::get(currentOp.input[0]) != sourceRef){ + executionTrace->getCurrentBlock().operations.emplace_back(tag, ASSIGN, resultType, targetRef, std::vector {sourceRef}); return; - }; - }*/ - if (executionTrace->checkTag(tag)) { + //executionTrace->addAssignmentOperation(tag, targetRef, sourceRef, resultType); + //return; + }; + } + auto inputs = std::vector {sourceRef}; + if (executionTrace->checkTag(tag, inputs)) { executionTrace->addAssignmentOperation(tag, targetRef, sourceRef, resultType); return; } @@ -191,8 +199,10 @@ value_ref TraceContext::traceCast(value_ref state, Type resultType) { // we are in a know operation if the operation at the current block[currentOperationCounter] is equal to the // received operation. auto tag = recordSnapshot(); - if (executionTrace->checkTag(tag)) { - auto leftIV = InputVariant(state); + auto leftIV = InputVariant(state); + auto inputs = std::vector {leftIV}; + if (executionTrace->checkTag(tag, inputs)) { + auto op = Op::CAST; auto resultRef = executionTrace->addOperationWithResult(tag, op, resultType, std::vector {leftIV}); @@ -225,11 +235,12 @@ value_ref TraceContext::traceBinaryOperation(Op op, Type resultType, value_ref& } auto tag = recordSnapshot(); - if (executionTrace->checkTag(tag)) { - auto leftIV = InputVariant(leftRef); - auto rightIV = InputVariant(rightRef); - auto resultRef = - executionTrace->addOperationWithResult(tag, op, resultType, std::vector {leftIV, rightIV}); + + auto leftIV = InputVariant(leftRef); + auto rightIV = InputVariant(rightRef); + auto inputs = std::vector {leftIV, rightIV}; + if (executionTrace->checkTag(tag, inputs)) { + auto resultRef = executionTrace->addOperationWithResult(tag, op, resultType, std::move(inputs)); return resultRef; } throw TraceTerminationException(); @@ -244,7 +255,8 @@ bool TraceContext::traceCmp(value_ref targetRef) { } else { // record auto tag = recordSnapshot(); - if (executionTrace->checkTag(tag)) { + auto inputs = std::vector {}; + if (executionTrace->checkTag(tag, inputs)) { executionTrace->addCmpOperation(tag, targetRef); result = symbolicExecutionContext->record(tag); } else { diff --git a/nautilus/test/execution-tests/ExpressionFunctions.hpp b/nautilus/test/execution-tests/ExpressionFunctions.hpp index ca9ca2e6..40ae430b 100644 --- a/nautilus/test/execution-tests/ExpressionFunctions.hpp +++ b/nautilus/test/execution-tests/ExpressionFunctions.hpp @@ -33,6 +33,14 @@ val assignment5(val x) { return x; } +val assignmentSwap(val x) { + auto t = x; + x = 42; + x = t + x; + return x; +} + + val int8AddExpression(val x) { val y = (int8_t) 2; return y + x; diff --git a/nautilus/test/execution-tests/TracingTest.cpp b/nautilus/test/execution-tests/TracingTest.cpp index b2e13378..581c5334 100644 --- a/nautilus/test/execution-tests/TracingTest.cpp +++ b/nautilus/test/execution-tests/TracingTest.cpp @@ -136,6 +136,7 @@ TEST_CASE("Expression Trace Test") { {"assignment3", details::createFunctionWrapper(assignment3)}, {"assignment4", details::createFunctionWrapper(assignment4)}, {"assignment5", details::createFunctionWrapper(assignment5)}, + {"assignmentSwap", details::createFunctionWrapper(assignmentSwap)}, {"int8AddExpression", details::createFunctionWrapper(int8AddExpression)}, {"int16AddExpression", details::createFunctionWrapper(int16AddExpression)}, {"int32AddExpression", details::createFunctionWrapper(int32AddExpression)}, @@ -175,6 +176,7 @@ TEST_CASE("Control-flow Trace Test") { {"varyingComplexity", details::createFunctionWrapper(varyingComplexity)}, {"logicalXOR", details::createFunctionWrapper(logicalXOR)}, {"nestedIfElseDifferentLevels", details::createFunctionWrapper(nestedIfElseDifferentLevels)}, + }; runTraceTests(tests); } From 956cbd7974e295802a08b0bc49b0c49b3d37135b Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Wed, 19 Jun 2024 18:45:39 -0400 Subject: [PATCH 5/8] update readme --- nautilus/include/nautilus/val.hpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/nautilus/include/nautilus/val.hpp b/nautilus/include/nautilus/val.hpp index 0e828984..d73bb3f9 100644 --- a/nautilus/include/nautilus/val.hpp +++ b/nautilus/include/nautilus/val.hpp @@ -89,21 +89,19 @@ tracing::value_ref getState(T&& value) { template class base_val { public: - using raw_type = ValueType; - using basic_type = ValueType; #ifdef ENABLE_TRACING const tracing::value_ref state; - base_val() : state(tracing::traceConstant(0)) {}; - base_val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; + inline base_val() : state(tracing::traceConstant(0)) {}; + inline base_val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; // copy constructor - base_val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; + inline base_val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; // move constructor - base_val(const val&& other) noexcept + inline base_val(const val&& other) noexcept : state(other.state), value(other.value) { // std::cout << "move con" << state.toString() << " = " << other.state.toString() << std::endl; }; - base_val(tracing::value_ref& tc) : state(tc), value() {}; + inline base_val(tracing::value_ref& tc) : state(tc), value() {}; #else base_val() {}; base_val(ValueType value) : value(value) {}; @@ -125,13 +123,15 @@ class base_val { template class val : public base_val { public: - + using raw_type = ValueType; + using basic_type = ValueType; using base_val::base_val; // copy constructor - val(const val& other) : base_val(other) {} - // move constructor - val(const val&& other) : base_val(std::move(other)) {} + inline val(const val& other) : base_val(other) { + } // move constructor + inline val(const val&& other) noexcept : base_val(std::move(other)) { + } val& operator=(const val&& other) { #ifdef ENABLE_TRACING From 4aacd8896331ca424921380354de1674f5dbf29f Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Wed, 19 Jun 2024 18:51:21 -0400 Subject: [PATCH 6/8] Revert "update readme" This reverts commit 956cbd7974e295802a08b0bc49b0c49b3d37135b. --- nautilus/include/nautilus/val.hpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/nautilus/include/nautilus/val.hpp b/nautilus/include/nautilus/val.hpp index d73bb3f9..0e828984 100644 --- a/nautilus/include/nautilus/val.hpp +++ b/nautilus/include/nautilus/val.hpp @@ -89,19 +89,21 @@ tracing::value_ref getState(T&& value) { template class base_val { public: + using raw_type = ValueType; + using basic_type = ValueType; #ifdef ENABLE_TRACING const tracing::value_ref state; - inline base_val() : state(tracing::traceConstant(0)) {}; - inline base_val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; + base_val() : state(tracing::traceConstant(0)) {}; + base_val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; // copy constructor - inline base_val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; + base_val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; // move constructor - inline base_val(const val&& other) noexcept + base_val(const val&& other) noexcept : state(other.state), value(other.value) { // std::cout << "move con" << state.toString() << " = " << other.state.toString() << std::endl; }; - inline base_val(tracing::value_ref& tc) : state(tc), value() {}; + base_val(tracing::value_ref& tc) : state(tc), value() {}; #else base_val() {}; base_val(ValueType value) : value(value) {}; @@ -123,15 +125,13 @@ class base_val { template class val : public base_val { public: - using raw_type = ValueType; - using basic_type = ValueType; + using base_val::base_val; // copy constructor - inline val(const val& other) : base_val(other) { - } // move constructor - inline val(const val&& other) noexcept : base_val(std::move(other)) { - } + val(const val& other) : base_val(other) {} + // move constructor + val(const val&& other) : base_val(std::move(other)) {} val& operator=(const val&& other) { #ifdef ENABLE_TRACING From 5eea0cd40b7cd248a1dd59e39b5f302542af03c0 Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Wed, 19 Jun 2024 18:51:21 -0400 Subject: [PATCH 7/8] Revert "update readme" This reverts commit 984d6a43025e1e90405f73b93073da6f175b1e7e. --- nautilus/include/nautilus/val.hpp | 114 ++++++++++-------- .../src/nautilus/tracing/ExecutionTrace.cpp | 13 +- .../src/nautilus/tracing/ExecutionTrace.hpp | 4 +- .../src/nautilus/tracing/TraceContext.cpp | 50 +++----- .../execution-tests/ExpressionFunctions.hpp | 8 -- nautilus/test/execution-tests/TracingTest.cpp | 2 - 6 files changed, 88 insertions(+), 103 deletions(-) diff --git a/nautilus/include/nautilus/val.hpp b/nautilus/include/nautilus/val.hpp index 0e828984..9a4db48b 100644 --- a/nautilus/include/nautilus/val.hpp +++ b/nautilus/include/nautilus/val.hpp @@ -86,67 +86,49 @@ tracing::value_ref getState(T&& value) { } // namespace details -template -class base_val { +// val substitution for all arithmetic value type, integer, float, bool +template +class val { public: using raw_type = ValueType; using basic_type = ValueType; + #ifdef ENABLE_TRACING const tracing::value_ref state; - base_val() : state(tracing::traceConstant(0)) {}; - base_val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; + inline val() : state(tracing::traceConstant(0)) {}; + inline val(ValueType value) : state(tracing::traceConstant(value)), value(value) {}; // copy constructor - base_val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; + inline val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; // move constructor - base_val(const val&& other) noexcept - : state(other.state), - value(other.value) { - // std::cout << "move con" << state.toString() << " = " << other.state.toString() << std::endl; - }; - base_val(tracing::value_ref& tc) : state(tc), value() {}; + inline val(const val&& other) noexcept : state(other.state), value(other.value) {}; + inline val(tracing::value_ref& tc) : state(tc), value() {}; #else - base_val() {}; - base_val(ValueType value) : value(value) {}; + val() {}; + val(ValueType value) : value(value) {}; // copy constructor - base_val(const val& other) : value(other.value) {}; + val(const val& other) : value(other.value) {}; // move constructor - base_val(const val&& other) : value(other.value) {}; + val(const val&& other) : value(other.value) {}; #endif - virtual ~base_val() { - } - -protected: - friend ValueType details::getRawValue(val& left); - ValueType value; -}; + ~val() { -// val substitution for all arithmetic value type, integer, float, bool -template -class val : public base_val { -public: - - using base_val::base_val; - - // copy constructor - val(const val& other) : base_val(other) {} - // move constructor - val(const val&& other) : base_val(std::move(other)) {} - - val& operator=(const val&& other) { #ifdef ENABLE_TRACING if (tracing::inTracer()) { - tracing::traceAssignment(this->state, other.state, tracing::to_type()); + + // tracing::getVarRefMap()[state.ref]--; + // if (tracing::getVarRefMap()[state.ref] == 0) { + // tracing::traceValueDestruction(state); + // std::cout << "destructor " << state << " - " << tag << std::endl; + // } } #endif - this->value = other.value; - return *this; - }; + } val& operator=(const val& other) { #ifdef ENABLE_TRACING if (tracing::inTracer()) { - tracing::traceAssignment(this->state, other.state, tracing::to_type()); + tracing::traceAssignment(state, other.state, tracing::to_type()); } #endif this->value = other.value; @@ -159,11 +141,11 @@ class val : public base_val { // cast if SHOULD_TRACE () { #ifdef ENABLE_TRACING - auto resultRef = tracing::traceCast(this->state, tracing::to_type()); + auto resultRef = tracing::traceCast(state, tracing::to_type()); return val(resultRef); #endif } - return val(this->value); + return val(value); } const val& operator++() { @@ -204,6 +186,9 @@ class val : public base_val { } private: + friend ValueType details::getRawValue(val& left); + ValueType value; + template friend COMMON_RETURN_TYPE mul(val& left, val& right); @@ -260,15 +245,41 @@ class val : public base_val { }; template <> -class val : public base_val { +class val { public: using raw_type = bool; using basic_type = bool; - using base_val::base_val; + +#ifdef ENABLE_TRACING + + tracing::value_ref state; + val() : state(tracing::traceConstant(0)), value(false) {}; + val(bool value) : state(tracing::traceConstant(value)), value(value) {}; // copy constructor - val(const val& other) : base_val(other) {}; + val(const val& other) : state(tracing::traceCopy(other.state)), value(other.value) {}; // move constructor - val(const val&& other) noexcept : base_val(std::move(other)) {}; + val(const val&& other) noexcept : state(other.state), value(other.value) {}; + val(tracing::value_ref& tc) : state(tc) {}; + +#else + val() {}; + val(bool value) : value(value) {}; + // copy constructor + val(const val& other) : value(other.value) {}; + // move constructor + val(const val&& other) : value(other.value) {}; +#endif + + ~val() { + if SHOULD_TRACE () { + + // tracing::getVarRefMap()[state.ref]--; + // if (tracing::getVarRefMap()[state.ref] == 0) { + // tracing::traceValueDestruction(state); + // std::cout << "destructor " << state << " - " << tag << std::endl; + // } + } + } val& operator=(const val& other) { @@ -291,6 +302,8 @@ class val : public base_val { } return value; } + + bool value; }; template @@ -376,8 +389,7 @@ namespace details { auto&& lValue = cast_value(std::forward(left)); \ auto&& rValue = cast_value(std::forward(right)); \ if SHOULD_TRACE () { \ - auto tc = tracing::traceBinaryOp(details::getState(lValue), \ - details::getState(rValue)); \ + auto tc = tracing::traceBinaryOp(details::getState(lValue), details::getState(rValue)); \ return RES_TYPE(tc); \ } \ return RES_TYPE(getRawValue(lValue) OP getRawValue(rValue)); \ @@ -555,7 +567,7 @@ val inline lOr(val& left, val& right) { return val {tc}; } #endif - return getRawValue(left) || getRawValue(right); + return left.value || right.value; } val inline lAnd(val& left, val& right) { @@ -565,7 +577,7 @@ val inline lAnd(val& left, val& right) { return val {tc}; } #endif - return getRawValue(left) && getRawValue(right); + return left.value && right.value; } val inline lNot(val& arg) { @@ -575,7 +587,7 @@ val inline lNot(val& arg) { return val {tc}; } #endif - return !getRawValue(arg); + return !arg.value; } } // namespace details diff --git a/nautilus/src/nautilus/tracing/ExecutionTrace.cpp b/nautilus/src/nautilus/tracing/ExecutionTrace.cpp index 08e8b04c..82dbb8d4 100644 --- a/nautilus/src/nautilus/tracing/ExecutionTrace.cpp +++ b/nautilus/src/nautilus/tracing/ExecutionTrace.cpp @@ -11,14 +11,14 @@ ExecutionTrace::ExecutionTrace() : currentBlockIndex(0), currentOperationIndex(0 createBlock(); }; -bool ExecutionTrace::checkTag(Snapshot& snapshot, std::vector& inputs) { +bool ExecutionTrace::checkTag(Snapshot& snapshot) { // check if operation is in global map -> we have a repeating operation -> this is a control-flow merge // std::cout << "\n checkTag \n" << std::endl; // std::cout << *this << std::endl; auto globalTabIter = globalTagMap.find(snapshot); if (globalTabIter != globalTagMap.end()) { auto& ref = globalTabIter->second; - processControlFlowMerge(ref, inputs); + processControlFlowMerge(ref); return false; } @@ -27,7 +27,7 @@ bool ExecutionTrace::checkTag(Snapshot& snapshot, std::vector& inp // TODO #3500 Fix handling of repeated operations auto& ref = localTagIter->second; // add loop iteration to tag - processControlFlowMerge(ref, inputs); + processControlFlowMerge(ref); return false; } return true; @@ -145,8 +145,7 @@ uint16_t ExecutionTrace::createBlock() { return blocks.size() - 1; } -Block& ExecutionTrace::processControlFlowMerge(operation_identifier oi, - [[maybe_unused]] std::vector& inputs) { +Block& ExecutionTrace::processControlFlowMerge(operation_identifier oi) { if (oi.blockIndex == currentBlockIndex) { throw RuntimeException("Invalid trace. This is maybe caused by a constant loop."); } @@ -159,10 +158,6 @@ Block& ExecutionTrace::processControlFlowMerge(operation_identifier oi, auto mergedBlockId = createBlock(); // perform a control flow merge and merge the current block with operations in some other block. auto& referenceBlock = blocks[oi.blockIndex]; - auto& referenceOp = referenceBlock.operations[oi.operationIndex]; - if (referenceOp.input.size() == inputs.size()) { - //for (referenceOp == ) - } auto& currentBlock = blocks[currentBlockIndex]; auto& mergeBlock = getBlock(mergedBlockId); diff --git a/nautilus/src/nautilus/tracing/ExecutionTrace.hpp b/nautilus/src/nautilus/tracing/ExecutionTrace.hpp index 3e27873b..d426b2c2 100644 --- a/nautilus/src/nautilus/tracing/ExecutionTrace.hpp +++ b/nautilus/src/nautilus/tracing/ExecutionTrace.hpp @@ -29,7 +29,7 @@ class ExecutionTrace { void addReturn(Snapshot&, Type type, value_ref ref); - bool checkTag(Snapshot& snapshot, std::vector& inputs); + bool checkTag(Snapshot& snapshot); void resetExecution(); @@ -106,7 +106,7 @@ class ExecutionTrace { * @param operationIndex * @return Block& */ - Block& processControlFlowMerge(operation_identifier oi, std::vector& inputs); + Block& processControlFlowMerge(operation_identifier oi); /** * @brief Returns the return reference diff --git a/nautilus/src/nautilus/tracing/TraceContext.cpp b/nautilus/src/nautilus/tracing/TraceContext.cpp index d31215dd..59d71852 100644 --- a/nautilus/src/nautilus/tracing/TraceContext.cpp +++ b/nautilus/src/nautilus/tracing/TraceContext.cpp @@ -56,8 +56,7 @@ value_ref TraceContext::traceLoad(value_ref src, Type resultType) { auto input = InputVariant(src); auto op = Op::LOAD; auto tag = recordSnapshot(); - auto inputs = std::vector {input}; - if (executionTrace->checkTag(tag, inputs)) { + if (executionTrace->checkTag(tag)) { auto resultRef = executionTrace->addOperationWithResult(tag, op, resultType, std::vector {input}); return resultRef; } @@ -73,8 +72,7 @@ void TraceContext::traceStore(value_ref target, value_ref src, Type valueType) { } auto op = Op::STORE; auto tag = recordSnapshot(); - auto inputs = std::vector {src}; - if (executionTrace->checkTag(tag, inputs)) { + if (executionTrace->checkTag(tag)) { executionTrace->addOperation(tag, op, valueType, target, src); return; } @@ -122,9 +120,7 @@ value_ref TraceContext::traceCopy(nautilus::tracing::value_ref ref) { return currentOperation.resultRef; } auto tag = recordSnapshot(); - - auto inputs = std::vector {ref}; - if (executionTrace->checkTag(tag, inputs)) { + if (executionTrace->checkTag(tag)) { auto resultRef = executionTrace->getNextValueRef(); executionTrace->addAssignmentOperation(tag, {resultRef, ref.type}, ref, ref.type); return {resultRef, ref.type}; @@ -143,8 +139,7 @@ value_ref TraceContext::traceCall(const std::string& functionName, void* fptn, T } auto tag = recordSnapshot(); - auto inputs = std::vector {}; - if (executionTrace->checkTag(tag, inputs)) { + if (executionTrace->checkTag(tag)) { auto functionArguments = InputVariant(FunctionCall { .functionName = functionName, .ptr = fptn, @@ -167,19 +162,16 @@ void TraceContext::traceAssignment(value_ref targetRef, value_ref sourceRef, Typ return; } auto tag = recordSnapshot(); - + /* auto found = executionTrace->globalTagMap.find(tag); if (found != executionTrace->globalTagMap.end()) { - auto currentOp = executionTrace->getBlock(found->second.blockIndex).operations[found->second.operationIndex]; - if(std::get(currentOp.input[0]) != sourceRef){ - executionTrace->getCurrentBlock().operations.emplace_back(tag, ASSIGN, resultType, targetRef, std::vector {sourceRef}); + auto currentOp = executionTrace->getBlock(found->second.blockIndex).operations[found->second.operationIndex]; + if(std::get(currentOp.input[0]) != sourceRef){ + executionTrace->addAssignmentOperation(tag, targetRef, sourceRef, resultType); return; - //executionTrace->addAssignmentOperation(tag, targetRef, sourceRef, resultType); - //return; - }; - } - auto inputs = std::vector {sourceRef}; - if (executionTrace->checkTag(tag, inputs)) { + }; + }*/ + if (executionTrace->checkTag(tag)) { executionTrace->addAssignmentOperation(tag, targetRef, sourceRef, resultType); return; } @@ -199,10 +191,8 @@ value_ref TraceContext::traceCast(value_ref state, Type resultType) { // we are in a know operation if the operation at the current block[currentOperationCounter] is equal to the // received operation. auto tag = recordSnapshot(); - auto leftIV = InputVariant(state); - auto inputs = std::vector {leftIV}; - if (executionTrace->checkTag(tag, inputs)) { - + if (executionTrace->checkTag(tag)) { + auto leftIV = InputVariant(state); auto op = Op::CAST; auto resultRef = executionTrace->addOperationWithResult(tag, op, resultType, std::vector {leftIV}); @@ -235,12 +225,11 @@ value_ref TraceContext::traceBinaryOperation(Op op, Type resultType, value_ref& } auto tag = recordSnapshot(); - - auto leftIV = InputVariant(leftRef); - auto rightIV = InputVariant(rightRef); - auto inputs = std::vector {leftIV, rightIV}; - if (executionTrace->checkTag(tag, inputs)) { - auto resultRef = executionTrace->addOperationWithResult(tag, op, resultType, std::move(inputs)); + if (executionTrace->checkTag(tag)) { + auto leftIV = InputVariant(leftRef); + auto rightIV = InputVariant(rightRef); + auto resultRef = + executionTrace->addOperationWithResult(tag, op, resultType, std::vector {leftIV, rightIV}); return resultRef; } throw TraceTerminationException(); @@ -255,8 +244,7 @@ bool TraceContext::traceCmp(value_ref targetRef) { } else { // record auto tag = recordSnapshot(); - auto inputs = std::vector {}; - if (executionTrace->checkTag(tag, inputs)) { + if (executionTrace->checkTag(tag)) { executionTrace->addCmpOperation(tag, targetRef); result = symbolicExecutionContext->record(tag); } else { diff --git a/nautilus/test/execution-tests/ExpressionFunctions.hpp b/nautilus/test/execution-tests/ExpressionFunctions.hpp index 40ae430b..ca9ca2e6 100644 --- a/nautilus/test/execution-tests/ExpressionFunctions.hpp +++ b/nautilus/test/execution-tests/ExpressionFunctions.hpp @@ -33,14 +33,6 @@ val assignment5(val x) { return x; } -val assignmentSwap(val x) { - auto t = x; - x = 42; - x = t + x; - return x; -} - - val int8AddExpression(val x) { val y = (int8_t) 2; return y + x; diff --git a/nautilus/test/execution-tests/TracingTest.cpp b/nautilus/test/execution-tests/TracingTest.cpp index 581c5334..b2e13378 100644 --- a/nautilus/test/execution-tests/TracingTest.cpp +++ b/nautilus/test/execution-tests/TracingTest.cpp @@ -136,7 +136,6 @@ TEST_CASE("Expression Trace Test") { {"assignment3", details::createFunctionWrapper(assignment3)}, {"assignment4", details::createFunctionWrapper(assignment4)}, {"assignment5", details::createFunctionWrapper(assignment5)}, - {"assignmentSwap", details::createFunctionWrapper(assignmentSwap)}, {"int8AddExpression", details::createFunctionWrapper(int8AddExpression)}, {"int16AddExpression", details::createFunctionWrapper(int16AddExpression)}, {"int32AddExpression", details::createFunctionWrapper(int32AddExpression)}, @@ -176,7 +175,6 @@ TEST_CASE("Control-flow Trace Test") { {"varyingComplexity", details::createFunctionWrapper(varyingComplexity)}, {"logicalXOR", details::createFunctionWrapper(logicalXOR)}, {"nestedIfElseDifferentLevels", details::createFunctionWrapper(nestedIfElseDifferentLevels)}, - }; runTraceTests(tests); } From bac22f0c3512f13dc8803ad349d539f3db33754c Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Wed, 31 Jul 2024 14:05:46 +0200 Subject: [PATCH 8/8] Update sanitizer.yml --- .github/workflows/sanitizer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sanitizer.yml b/.github/workflows/sanitizer.yml index 95e2b62c..650ab44f 100644 --- a/.github/workflows/sanitizer.yml +++ b/.github/workflows/sanitizer.yml @@ -41,6 +41,6 @@ jobs: - name: test shell: bash run: | - cd nautilus && ctest --test-dir=nautilus --output-on-failure + cd nautilus && ctest --output-on-failure