From e7ca0a68ef94b4bd512b13d22188abe9c21ed7dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Mon, 16 May 2022 11:55:40 +0200 Subject: [PATCH 01/12] better exercise description in README.md --- CacheAnalysisPass/CacheAnalysisPass.cpp | 8 ++++---- README.md | 10 ++++++++-- include/AbstractCache.h | 4 +--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CacheAnalysisPass/CacheAnalysisPass.cpp b/CacheAnalysisPass/CacheAnalysisPass.cpp index 97c4d2a..a438b86 100644 --- a/CacheAnalysisPass/CacheAnalysisPass.cpp +++ b/CacheAnalysisPass/CacheAnalysisPass.cpp @@ -215,15 +215,15 @@ struct CacheAnalysisPass : PassInfoMixin { } PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) { - FunctionAnalysisManager &FAM = - MAM.getResult(M).getManager(); + // FunctionAnalysisManager &FAM = + // MAM.getResult(M).getManager(); addressCollector(M); - Function *EntryFunction; + // Function *EntryFunction; for (Function &F : M.getFunctionList()) { // Start iterating through CFG from entry point if (F.getName().equals(EntryPoint)) { - EntryFunction = &F; + // EntryFunction = &F; initEdges(F); } if (PrintAddresses) diff --git a/README.md b/README.md index 15163a9..7c2eb29 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,16 @@ # RTSA-lab01-CacheAnalysis In this lab session you will learn how to implement a LRU cache in abstract representation. -The Goal is to implement an LRU must Join in include/AbstractState.h. -For this we assume a "Set-Associative LRU Cache", with 16 sets an associativity of 4 and a cacheline size of two times instruction size. + +## Exercise +Implement a LRU Must-Join as described in the lecture, WCET - Cache Analysis. +A 16 SetCache with an associativity of 4 Assumed, and cache lines can hold two memory words -> CacheSize 1024kB. +In order to do so, complete the function "mustJoin" inside [include/AbstractState.h:138](https://git.cs.tu-dortmund.de/nils.hoelscher/RTSA-lab01-CacheAnalysis/src/branch/master/include/AbstractState.h#L138). +The goal is to join the inbound state into the "this" state. + The Project can be build, tested and Evaluated with the "helper" script. +The Setup and some nice to knows are described in the following sections. ## Disclaimer diff --git a/include/AbstractCache.h b/include/AbstractCache.h index b4cf544..cbec453 100644 --- a/include/AbstractCache.h +++ b/include/AbstractCache.h @@ -92,7 +92,7 @@ public: // everything is public, because IDGAF } Visited[Visitor.first] = true; } - return false; + return Ret; } /** @@ -104,8 +104,6 @@ public: // everything is public, because IDGAF void removeNestedLoops( std::list LoopBodyIn, std::map OrigNodeToUnrolledNode) { - unsigned int LoopHead = LoopBodyIn.front(); - unsigned int LoopTail = LoopBodyIn.back(); unsigned int NestLoopTail; for (unsigned int NodeNr : LoopBodyIn) { bool IsLoopHead = false; From 7635fb52c7fe8aad0d5905ed70a0474a6689765b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Mon, 16 May 2022 11:58:20 +0200 Subject: [PATCH 02/12] Removed dbg option for loopunrolling. --- .vscode/launch.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index aa8dcd9..15b2235 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,21 +4,21 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "LLDB Unrolling", - "program": "/usr/bin/opt", - "args": [ - "-load-pass-plugin", - "${workspaceFolder}/build/libCacheAnalysisPass.so", - "-passes=lru-misses", - "${workspaceFolder}/test/cnt.ll", - "-o", - "/dev/null" - ], - "cwd": "${workspaceFolder}" - }, + // { + // "type": "lldb", + // "request": "launch", + // "name": "LLDB Unrolling", + // "program": "/usr/bin/opt", + // "args": [ + // "-load-pass-plugin", + // "${workspaceFolder}/build/libCacheAnalysisPass.so", + // "-passes=lru-misses", + // "${workspaceFolder}/test/cnt.ll", + // "-o", + // "/dev/null" + // ], + // "cwd": "${workspaceFolder}" + // }, { "type": "lldb", "request": "launch", From 8ea0c571e437d7ae7c3064d41ff5374c170e3d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Mon, 16 May 2022 13:38:48 +0200 Subject: [PATCH 03/12] Added some simple UnitTests --- CMakeLists.txt | 14 ++++++ UnitTest/CMakeLists.txt | 52 +++++++++++++++++++++ UnitTest/UnitTest.cpp | 101 ++++++++++++++++++++++++++++++++++++++++ helper.sh | 2 +- include/AbstractCache.h | 43 ++++++++--------- include/AbstractState.h | 64 ++++++++++++++----------- 6 files changed, 226 insertions(+), 50 deletions(-) create mode 100644 UnitTest/CMakeLists.txt create mode 100644 UnitTest/UnitTest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index bbc8701..a550b68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,19 @@ cmake_minimum_required(VERSION 3.13.4) project(RTSA-lab01-CacheAnalysis) +#=============================================================================== +# 0. Add GoogleTest +#=============================================================================== +include(FetchContent) +FetchContent_Declare( + googletest + URL + URL https://github.com/google/googletest/archive/05CC6081FCBD0071053DE78238E136B3.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + #=============================================================================== # 1. VERIFY LLVM INSTALLATION DIR # This is just a bit of a sanity checking. @@ -108,4 +121,5 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") # available for the sub-projects. #=============================================================================== add_subdirectory(CacheAnalysisPass) # Use your pass name here. +add_subdirectory(UnitTest) #add_subdirectory(lib) \ No newline at end of file diff --git a/UnitTest/CMakeLists.txt b/UnitTest/CMakeLists.txt new file mode 100644 index 0000000..ea179d5 --- /dev/null +++ b/UnitTest/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.13.4) +project(UnitTest) + +#=============================================================================== +# 1. LOAD LLVM CONFIGURATION +#=============================================================================== +# Set this to a valid LLVM installation dir +set(LT_LLVM_INSTALL_DIR "" CACHE PATH "LLVM installation directory") + +# Add the location of LLVMConfig.cmake to CMake search paths (so that +# find_package can locate it) +list(APPEND CMAKE_PREFIX_PATH "${LT_LLVM_INSTALL_DIR}/lib/cmake/llvm/") + +# FIXME: This is a warkaround for #25. Remove once resolved and use +# find_package(LLVM 11.0.0 REQUIRED CONFIG) instead. +find_package(LLVM REQUIRED CONFIG) + +# UnitTest includes headers from LLVM - update the include paths accordingly +include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}, "${CMAKE_CURRENT_SOURCE_DIR}/../include") + +#=============================================================================== +# 2. LLVM-TUTOR BUILD CONFIGURATION +#=============================================================================== +# Use the same C++ standard as LLVM does +set(CMAKE_CXX_STANDARD 14 CACHE STRING "") + +# LLVM is normally built without RTTI. Be consistent with that. +if(NOT LLVM_ENABLE_RTTI) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") +endif() + +#=============================================================================== +# 3. ADD THE TARGET +#=============================================================================== +enable_testing() + +add_executable(UnitTest + # List your source files here. + UnitTest.cpp +) + + +# Allow undefined symbols in shared objects on Darwin (this is the default +# behaviour on Linux) +target_link_libraries(UnitTest + "$<$:-undefined dynamic_lookup>") + target_link_libraries( + UnitTest + gtest_main +) +include(GoogleTest) +gtest_discover_tests(UnitTest) \ No newline at end of file diff --git a/UnitTest/UnitTest.cpp b/UnitTest/UnitTest.cpp new file mode 100644 index 0000000..1cd62e0 --- /dev/null +++ b/UnitTest/UnitTest.cpp @@ -0,0 +1,101 @@ +#include +#include + +#include "../include/AbstractCache.h" + +void fillSet(AbstractState &In, unsigned int Set) { + for (int I = 0; I < 4; I++) { + In.Sets[Set].Associativity[I].Blocks.push_front(I); + } +} + +// Joined Set should remain the same +TEST(UnitTest, MustJoinSameStates) { + AbstractCache AC; + AC.addEmptyNode(0); + fillSet(AC.Nodes[0], 0); + AC.addEmptyNode(1); + fillSet(AC.Nodes[1], 0); + + AC.Nodes[0].mustJoin(AC.Nodes[1]); + for (auto B : AC.Nodes[0].Sets[0].Associativity) { + uint Age = B.first; + EXPECT_EQ(AC.Nodes[0].Sets[0].Associativity[Age].Blocks.front(), + AC.Nodes[1].Sets[0].Associativity[Age].Blocks.front()); + } +} + +void counterFillSet(AbstractState &In, unsigned int Set) { + for (int I = 0; I < 4; I++) { + In.Sets[Set].Associativity[I].Blocks.push_front((I + 1) % 4); + } +} + +// Resulting state should be +// Set[0]: +// Age[0]: +// Age[1]: 1 +// Age[2]: 2 +// Age[3]: 0 3 +TEST(UnitTest, MustJoinDifferentStates) { + AbstractCache AC; + AC.addEmptyNode(0); + counterFillSet(AC.Nodes[0], 0); + AC.addEmptyNode(1); + fillSet(AC.Nodes[1], 0); + std::cout << "==Before:==\n"; + AC.Nodes[0].dumpSet(0); + AC.Nodes[1].dumpSet(0); + + AC.Nodes[0].mustJoin(AC.Nodes[1]); + std::cout << "\n==After:==\n"; + AC.Nodes[0].dumpSet(0); + for (auto B : AC.Nodes[0].Sets[0].Associativity) { + uint Age = B.first; + switch (Age) { + case 0: + EXPECT_TRUE(AC.Nodes[0].Sets[0].Associativity[Age].Blocks.empty()); + break; + case 1: + EXPECT_EQ(AC.Nodes[0].Sets[0].Associativity[Age].Blocks.front(), 1); + break; + case 2: + EXPECT_EQ(AC.Nodes[0].Sets[0].Associativity[Age].Blocks.front(), 2); + break; + case 3: + // this test is not very exact the Set 0 with age 3 should contain (0,3) + // in arbitrary order + EXPECT_EQ(AC.Nodes[0].Sets[0].Associativity[Age].Blocks.size(), 2); + break; + default: + // should never be reached! + EXPECT_TRUE(false); + } + } +} + +void fillSetHighNumbers(AbstractState &In, unsigned int Set) { + for (int I = 0; I < 4; I++) { + In.Sets[Set].Associativity[I].Blocks.push_front(10+I); + } +} + +// resulting state should be empty +TEST(UnitTest, MustJoinDisjunctStates) { + AbstractCache AC; + AC.addEmptyNode(0); + fillSetHighNumbers(AC.Nodes[0], 0); + AC.addEmptyNode(1); + fillSet(AC.Nodes[1], 0); + std::cout << "==Before:==\n"; + AC.Nodes[0].dumpSet(0); + AC.Nodes[1].dumpSet(0); + + AC.Nodes[0].mustJoin(AC.Nodes[1]); + std::cout << "\n==After:==\n"; + AC.Nodes[0].dumpSet(0); + for (auto B : AC.Nodes[0].Sets[0].Associativity) { + uint Age = B.first; + EXPECT_TRUE(AC.Nodes[0].Sets[0].Associativity[Age].Blocks.empty()); + } +} \ No newline at end of file diff --git a/helper.sh b/helper.sh index c4138d6..04e1414 100755 --- a/helper.sh +++ b/helper.sh @@ -11,7 +11,7 @@ config () { mkdir build cd build echo "==== Configuring cmake ====" - cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DLT_LLVM_INSTALL_DIR=$LLVM_DIR ../CacheAnalysisPass/ + cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DLT_LLVM_INSTALL_DIR=/usr .. cd .. cp build/compile_commands.json compile_commands.json echo "==== Done! ====" diff --git a/include/AbstractCache.h b/include/AbstractCache.h index cbec453..7829e23 100644 --- a/include/AbstractCache.h +++ b/include/AbstractCache.h @@ -1,4 +1,3 @@ - #ifndef ABSTRACHTCACHESTATE_H #define ABSTRACHTCACHESTATE_H @@ -11,9 +10,6 @@ #include #include -#include -#include - #include "AbstractState.h" #include "Address.h" #include "ConcreteState.h" @@ -292,34 +288,34 @@ public: // everything is public, because IDGAF removeNestedLoops(LoopBody, OrigNodeToUnrolledNode); if (Verbose && FoundLoopBody) { - llvm::outs() << "Found LoopHead @: " << NodeNr << "\n"; - llvm::outs() << "With LoopTail @: " << LoopTail << "\n"; - llvm::outs() << "With Body: {\n"; + std::cout << "Found LoopHead @: " << NodeNr << "\n"; + std::cout << "With LoopTail @: " << LoopTail << "\n"; + std::cout << "With Body: {\n"; int I = 1; for (auto Node : LoopBody) { - llvm::outs() << Node << ", "; + std::cout << Node << ", "; if (!(I++ % 5)) { - llvm::outs() << "\n"; + std::cout << "\n"; } } - llvm::outs() << "}\n"; - llvm::outs() << "Unrolled States: {\n"; + std::cout << "}\n"; + std::cout << "Unrolled States: {\n"; I = 1; for (auto Node : LoopBody) { - llvm::outs() << OrigNodeToUnrolledNode[Node] << ", "; + std::cout << OrigNodeToUnrolledNode[Node] << ", "; if (!(I++ % 5)) { - llvm::outs() << "\n"; + std::cout << "\n"; } } - llvm::outs() << "}\n"; + std::cout << "}\n"; I = 1; - llvm::outs() << "OrigNodeToUnrolledNode: {\n"; + std::cout << "OrigNodeToUnrolledNode: {\n"; for (auto Nr : OrigNodeToUnrolledNode) { - llvm::outs() << Nr.first << "->" << Nr.second << ", "; + std::cout << Nr.first << "->" << Nr.second << ", "; if (!(I++ % 3)) - llvm::outs() << "\n"; + std::cout << "\n"; } - llvm::outs() << "}\n"; + std::cout << "}\n"; } } } @@ -400,19 +396,19 @@ public: // everything is public, because IDGAF * */ void dumpEdges() { - llvm::outs() << "Dumping Edges:\n"; + std::cout << "Dumping Edges:\n"; for (auto const &E : Edges) { - llvm::outs() << E.first; + std::cout << E.first; bool FirstPrint = true; for (unsigned int To : E.second) { if (FirstPrint) { - llvm::outs() << " -> " << To; + std::cout << " -> " << To; FirstPrint = false; } else { - llvm::outs() << ", " << To; + std::cout << ", " << To; } } - llvm::outs() << "\n"; + std::cout << "\n"; } } @@ -453,5 +449,6 @@ public: // everything is public, because IDGAF Nodes[E.first].dump(); } } + }; // namespace #endif // ABSTRACHTCACHESTATE_H \ No newline at end of file diff --git a/include/AbstractState.h b/include/AbstractState.h index 46149d6..25214f8 100644 --- a/include/AbstractState.h +++ b/include/AbstractState.h @@ -12,8 +12,6 @@ #include #include -#include - #include "Address.h" // Forward declarations @@ -107,8 +105,8 @@ public: // everything is public, because IDGAF void setUnrolled(unsigned int In) { Unrolled = In; } bool operator==(AbstractState In) { - for (int Index; Index < 16; Index++) { - for (int Age; Age < 4; Age++) { + for (int Index = 0; Index < 16; Index++) { + for (int Age = 0; Age < 4; Age++) { for (auto E1 : Sets[Index].Associativity[Age].Blocks) { // find E1 in In States Set and Age. if (std::find(In.Sets[Index].Associativity[Age].Blocks.begin(), @@ -203,46 +201,60 @@ public: // everything is public, because IDGAF } } if (Verbose) { - llvm::outs() << "Before:\n"; + std::cout << "Before:\n"; this->dump(); } // update this with PreAddr this->update(PreAddr); if (Verbose) { - llvm::outs() << "Update Tag: " << PreAddr.Tag << "\n"; - llvm::outs() << "Update Set: " << PreAddr.Index << "\n"; - llvm::outs() << "After:\n"; + std::cout << "Update Tag: " << PreAddr.Tag << "\n"; + std::cout << "Update Set: " << PreAddr.Index << "\n"; + std::cout << "After:\n"; this->dump(); } } - void dump() { - llvm::outs() << Addr << " {\n"; - llvm::outs() << "Unrolled: " << Unrolled << "\n"; - llvm::outs() << "Computed: " << Computed << "\n"; - llvm::outs() << "Predecessors: "; - for (auto PreNr : Predecessors) { - llvm::outs() << PreNr << " "; - } - llvm::outs() << "\n"; + void dumpSet(unsigned int Set) { + std::cout << Addr << " {\n"; - llvm::outs() << "Successors: "; - for (auto SuccNr : Successors) { - llvm::outs() << SuccNr << " "; + std::cout << "Set[" << Set << "]: \n"; + for (auto EntryPair : this->Sets[Set].Associativity) { + std::cout << " Age[" << EntryPair.first << "]: "; + for (auto Block : EntryPair.second.Blocks) { + std::cout << Block << " "; + } + std::cout << "\n"; + } + std::cout << "}\n"; + } + + void dump() { + std::cout << Addr << " {\n"; + std::cout << "Unrolled: " << Unrolled << "\n"; + std::cout << "Computed: " << Computed << "\n"; + std::cout << "Predecessors: "; + for (auto PreNr : Predecessors) { + std::cout << PreNr << " "; } - llvm::outs() << "\n"; + std::cout << "\n"; + + std::cout << "Successors: "; + for (auto SuccNr : Successors) { + std::cout << SuccNr << " "; + } + std::cout << "\n"; for (auto SetPair : Sets) { - llvm::outs() << "Set[" << SetPair.first << "]: \n"; + std::cout << "Set[" << SetPair.first << "]: \n"; for (auto EntryPair : SetPair.second.Associativity) { - llvm::outs() << " Age[" << EntryPair.first << "]: "; + std::cout << " Age[" << EntryPair.first << "]: "; for (auto Block : EntryPair.second.Blocks) { - llvm::outs() << Block << " "; + std::cout << Block << " "; } - llvm::outs() << "\n"; + std::cout << "\n"; } } - llvm::outs() << "}\n"; + std::cout << "}\n"; } }; // namespace From 3264029256016e06256ecf56bd9ccd10b0c4fb8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Mon, 16 May 2022 13:44:23 +0200 Subject: [PATCH 04/12] Updated readme for UnitTests --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 7c2eb29..5a0e609 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ This is my personally preferred IDE setup for C/C++ and by no means needed to ac clangd, Clang-Format, CodeLLDB, +C++ TestMate, Docker and Remote Development @@ -151,6 +152,12 @@ You can also set the following variables in the CacheAnalysisPass/CacheAnalysisP Helpful to understand what the program does but not very so much for the actual exercise. +## UnitTest + +The best way to see what your function does is to use the UnitTest.cpp. +With "C++ TestMate" install you can simply run or debug the test from the side panel in VS Code (Flask Icon). +The "C++ TestMate" is not installed in the VM as I just added this feature now. +Please feel free to add more test cases to your liking in UnitTest.cpp. ## Use the Helper script Again if you work on a Pool PC use poolhelper.sh insted of the helper.sh script. From e40e6b789311657555041c50be880fd90ba5bd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Mon, 16 May 2022 13:46:06 +0200 Subject: [PATCH 05/12] Added file Links in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5a0e609..4ad41bb 100644 --- a/README.md +++ b/README.md @@ -154,10 +154,10 @@ Helpful to understand what the program does but not very so much for the actual ## UnitTest -The best way to see what your function does is to use the UnitTest.cpp. +The best way to see what your function does is to use the [UnitTest.cpp](https://git.cs.tu-dortmund.de/nils.hoelscher/RTSA-lab01-CacheAnalysis/src/branch/master/UnitTest/UnitTest.cpp). With "C++ TestMate" install you can simply run or debug the test from the side panel in VS Code (Flask Icon). The "C++ TestMate" is not installed in the VM as I just added this feature now. -Please feel free to add more test cases to your liking in UnitTest.cpp. +Please feel free to add more test cases to your liking in [UnitTest.cpp](https://git.cs.tu-dortmund.de/nils.hoelscher/RTSA-lab01-CacheAnalysis/src/branch/master/UnitTest/UnitTest.cpp). ## Use the Helper script Again if you work on a Pool PC use poolhelper.sh insted of the helper.sh script. From f818f3847a2ffd1b16f4ddca62cbe459b8a8fdb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Mon, 16 May 2022 14:05:04 +0200 Subject: [PATCH 06/12] newer googletest suite --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a550b68..9e6c2cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ include(FetchContent) FetchContent_Declare( googletest URL - URL https://github.com/google/googletest/archive/05CC6081FCBD0071053DE78238E136B3.zip + URL https://github.com/google/googletest/archive/refs/heads/main.zip ) # For Windows: Prevent overriding the parent project's compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) From 801831a2b5b6279949359910c07413cdb3a0a8bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Tue, 17 May 2022 08:20:52 +0200 Subject: [PATCH 07/12] fixed Bug in helper script --- helper.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper.sh b/helper.sh index 04e1414..1bb80ac 100755 --- a/helper.sh +++ b/helper.sh @@ -27,7 +27,7 @@ compile () { run () { echo "==== Running $1 ====" - opt -load-pass-plugin build/libCacheAnalysisPass.so \ + opt -load-pass-plugin build/lib/libCacheAnalysisPass.so \ -passes='lru-misses(function(loop-unroll-and-jam))' \ test/$1.ll -o /dev/null #llvm-dis < out.bc > out.ll From 9dca6c2f67105bc53f2c64d17f435638b5cde837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Tue, 17 May 2022 18:37:28 +0200 Subject: [PATCH 08/12] More Unit Tests --- UnitTest/UnitTest.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/UnitTest/UnitTest.cpp b/UnitTest/UnitTest.cpp index 1cd62e0..1828893 100644 --- a/UnitTest/UnitTest.cpp +++ b/UnitTest/UnitTest.cpp @@ -76,7 +76,7 @@ TEST(UnitTest, MustJoinDifferentStates) { void fillSetHighNumbers(AbstractState &In, unsigned int Set) { for (int I = 0; I < 4; I++) { - In.Sets[Set].Associativity[I].Blocks.push_front(10+I); + In.Sets[Set].Associativity[I].Blocks.push_front(10 + I); } } @@ -98,4 +98,77 @@ TEST(UnitTest, MustJoinDisjunctStates) { uint Age = B.first; EXPECT_TRUE(AC.Nodes[0].Sets[0].Associativity[Age].Blocks.empty()); } +} + +TEST(UnitTest, MustJoinDisjunctStatesAllSets) { + AbstractCache AC; + AC.addEmptyNode(0); + AC.addEmptyNode(1); + for (int I = 0; I < 16; I++) { + fillSetHighNumbers(AC.Nodes[0], I); + fillSet(AC.Nodes[1], I); + } + + std::cout << "==Before:==\n"; + AC.Nodes[0].dump(); + AC.Nodes[1].dump(); + + AC.Nodes[0].mustJoin(AC.Nodes[1]); + std::cout << "\n==After:==\n"; + AC.Nodes[0].dump(); + for (auto Set : AC.Nodes[0].Sets) { + for (auto B : Set.second.Associativity) { + EXPECT_TRUE(B.second.Blocks.empty()); + } + } +} + +TEST(UnitTest, MustJoinDifferentStatesAllSets) { + AbstractCache AC; + AC.addEmptyNode(0); + AC.addEmptyNode(1); + for (int I = 0; I < 16; I++) { + if (I % 2) + counterFillSet(AC.Nodes[0], I); + fillSet(AC.Nodes[1], I); + } + std::cout << "==Before:==\n"; + AC.Nodes[0].dump(); + AC.Nodes[1].dump(); + + AC.Nodes[0].mustJoin(AC.Nodes[1]); + + AC.Nodes[1].mustJoin(AC.Nodes[0]); + std::cout << "\n==After:==\n"; + AC.Nodes[1].dump(); + for (auto Set : AC.Nodes[1].Sets) { + for (auto B : Set.second.Associativity) { + uint SetNr = Set.first; + uint Age = B.first; + if (SetNr % 2) { + switch (Age) { + case 0: + EXPECT_TRUE(B.second.Blocks.empty()); + break; + case 1: + EXPECT_EQ(B.second.Blocks.front(), 1); + break; + case 2: + EXPECT_EQ(B.second.Blocks.front(), 2); + break; + case 3: + // this test is not very exact the Set 0 with age 3 should contain + // (0,3) in arbitrary order + EXPECT_EQ(B.second.Blocks.size(), 2); + break; + default: + // should never be reached! + EXPECT_TRUE(false); + } + } else { + EXPECT_TRUE(B.second.Blocks.empty()); + } + } + } + EXPECT_TRUE(AC.Nodes[1] == AC.Nodes[0]); } \ No newline at end of file From 841dbe107012844668308410a44dd38c9767bed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Tue, 24 May 2022 10:46:21 +0200 Subject: [PATCH 09/12] Automated builds and better UnitTEstNames for the Future. --- UnitTest/UnitTest.cpp | 10 +++++----- include/.drone.yml | 8 ++++++++ 2 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 include/.drone.yml diff --git a/UnitTest/UnitTest.cpp b/UnitTest/UnitTest.cpp index 1828893..4c825f3 100644 --- a/UnitTest/UnitTest.cpp +++ b/UnitTest/UnitTest.cpp @@ -10,7 +10,7 @@ void fillSet(AbstractState &In, unsigned int Set) { } // Joined Set should remain the same -TEST(UnitTest, MustJoinSameStates) { +TEST(MustJoinTests, MustJoinSameStates) { AbstractCache AC; AC.addEmptyNode(0); fillSet(AC.Nodes[0], 0); @@ -37,7 +37,7 @@ void counterFillSet(AbstractState &In, unsigned int Set) { // Age[1]: 1 // Age[2]: 2 // Age[3]: 0 3 -TEST(UnitTest, MustJoinDifferentStates) { +TEST(MustJoinTests, MustJoinDifferentStates) { AbstractCache AC; AC.addEmptyNode(0); counterFillSet(AC.Nodes[0], 0); @@ -81,7 +81,7 @@ void fillSetHighNumbers(AbstractState &In, unsigned int Set) { } // resulting state should be empty -TEST(UnitTest, MustJoinDisjunctStates) { +TEST(MustJoinTests, MustJoinDisjunctStates) { AbstractCache AC; AC.addEmptyNode(0); fillSetHighNumbers(AC.Nodes[0], 0); @@ -100,7 +100,7 @@ TEST(UnitTest, MustJoinDisjunctStates) { } } -TEST(UnitTest, MustJoinDisjunctStatesAllSets) { +TEST(MustJoinTests, MustJoinDisjunctStatesAllSets) { AbstractCache AC; AC.addEmptyNode(0); AC.addEmptyNode(1); @@ -123,7 +123,7 @@ TEST(UnitTest, MustJoinDisjunctStatesAllSets) { } } -TEST(UnitTest, MustJoinDifferentStatesAllSets) { +TEST(MustJoinTests, MustJoinDifferentStatesAllSets) { AbstractCache AC; AC.addEmptyNode(0); AC.addEmptyNode(1); diff --git a/include/.drone.yml b/include/.drone.yml new file mode 100644 index 0000000..8543b16 --- /dev/null +++ b/include/.drone.yml @@ -0,0 +1,8 @@ +kind: pipeline +type: docker +name: llvmta-build +steps: +- name: Build + image: ls12-nvm-oma1:5000/cppdev + commands: + - ./helper all \ No newline at end of file From 623818d49ee3fc7ccd15c5e605930addd23d6074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Tue, 24 May 2022 10:54:18 +0200 Subject: [PATCH 10/12] moved Auto Build file --- include/.drone.yml => .drone.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename include/.drone.yml => .drone.yml (100%) diff --git a/include/.drone.yml b/.drone.yml similarity index 100% rename from include/.drone.yml rename to .drone.yml From 13861282b4a21b77a7a11285c3decd4e9581acf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Tue, 24 May 2022 11:05:40 +0200 Subject: [PATCH 11/12] . --- .drone.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 8543b16..5c52e65 100644 --- a/.drone.yml +++ b/.drone.yml @@ -5,4 +5,7 @@ steps: - name: Build image: ls12-nvm-oma1:5000/cppdev commands: - - ./helper all \ No newline at end of file + - mkdir build + - cd build + - cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DLT_LLVM_INSTALL_DIR=/usr .. + - ninja -j 2 \ No newline at end of file From 2ab71cf95df2fa3615909d24187b38715c20181d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20H=C3=B6lscher?= Date: Tue, 24 May 2022 11:07:32 +0200 Subject: [PATCH 12/12] Added Auto build badge to Readme.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4ad41bb..0d1f103 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # RTSA-lab01-CacheAnalysis +[![Build Status](http://129.217.34.203/api/badges/nils.hoelscher/RTSA-lab01-CacheAnalysis/status.svg)](http://129.217.34.203/nils.hoelscher/RTSA-lab01-CacheAnalysis) + In this lab session you will learn how to implement a LRU cache in abstract representation. ## Exercise