Compare commits

..

No commits in common. "15d236299d66738131aa68595a7439927b26915e" and "42b533434bbff391847427d605b6a054d5f64411" have entirely different histories.

11 changed files with 88 additions and 404 deletions

View File

@ -1,11 +0,0 @@
kind: pipeline
type: docker
name: llvmta-build
steps:
- name: Build
image: ls12-nvm-oma1:5000/cppdev
commands:
- mkdir build
- cd build
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DLT_LLVM_INSTALL_DIR=/usr ..
- ninja -j 2

View File

@ -1,17 +0,0 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++14",
"intelliSenseMode": "linux-clang-x64",
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
}
],
"version": 4
}

30
.vscode/launch.json vendored
View File

@ -4,21 +4,21 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
// { {
// "type": "lldb", "type": "lldb",
// "request": "launch", "request": "launch",
// "name": "LLDB Unrolling", "name": "LLDB Unrolling",
// "program": "/usr/bin/opt", "program": "/usr/bin/opt",
// "args": [ "args": [
// "-load-pass-plugin", "-load-pass-plugin",
// "${workspaceFolder}/build/libCacheAnalysisPass.so", "${workspaceFolder}/build/libCacheAnalysisPass.so",
// "-passes=lru-misses", "-passes=lru-misses",
// "${workspaceFolder}/test/cnt.ll", "${workspaceFolder}/test/cnt.ll",
// "-o", "-o",
// "/dev/null" "/dev/null"
// ], ],
// "cwd": "${workspaceFolder}" "cwd": "${workspaceFolder}"
// }, },
{ {
"type": "lldb", "type": "lldb",
"request": "launch", "request": "launch",

View File

@ -1,19 +1,6 @@
cmake_minimum_required(VERSION 3.13.4) cmake_minimum_required(VERSION 3.13.4)
project(RTSA-lab01-CacheAnalysis) project(RTSA-lab01-CacheAnalysis)
#===============================================================================
# 0. Add GoogleTest
#===============================================================================
include(FetchContent)
FetchContent_Declare(
googletest
URL
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)
FetchContent_MakeAvailable(googletest)
#=============================================================================== #===============================================================================
# 1. VERIFY LLVM INSTALLATION DIR # 1. VERIFY LLVM INSTALLATION DIR
# This is just a bit of a sanity checking. # This is just a bit of a sanity checking.
@ -121,5 +108,4 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
# available for the sub-projects. # available for the sub-projects.
#=============================================================================== #===============================================================================
add_subdirectory(CacheAnalysisPass) # Use your pass name here. add_subdirectory(CacheAnalysisPass) # Use your pass name here.
add_subdirectory(UnitTest)
#add_subdirectory(lib) #add_subdirectory(lib)

View File

@ -56,7 +56,7 @@ struct CacheAnalysisPass : PassInfoMixin<CacheAnalysisPass> {
bool PrintEdgesPost = false; bool PrintEdgesPost = false;
bool DumpToDot = false; bool DumpToDot = false;
bool DumpNodes = false; bool DumpNodes = false;
bool LoopUnrolling = true; bool LoopUnrolling = false;
// Assume a 4kB Cache // Assume a 4kB Cache
// with 16 Sets, associativity of 4 and Cachelines fitting two times the instruction size // with 16 Sets, associativity of 4 and Cachelines fitting two times the instruction size
@ -215,15 +215,15 @@ struct CacheAnalysisPass : PassInfoMixin<CacheAnalysisPass> {
} }
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) { PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) {
// FunctionAnalysisManager &FAM = FunctionAnalysisManager &FAM =
// MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
addressCollector(M); addressCollector(M);
// Function *EntryFunction; Function *EntryFunction;
for (Function &F : M.getFunctionList()) { for (Function &F : M.getFunctionList()) {
// Start iterating through CFG from entry point // Start iterating through CFG from entry point
if (F.getName().equals(EntryPoint)) { if (F.getName().equals(EntryPoint)) {
// EntryFunction = &F; EntryFunction = &F;
initEdges(F); initEdges(F);
} }
if (PrintAddresses) if (PrintAddresses)

View File

@ -1,18 +1,10 @@
# RTSA-lab01-CacheAnalysis # 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. 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.
## Exercise 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.
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 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 ## Disclaimer
@ -90,7 +82,6 @@ This is my personally preferred IDE setup for C/C++ and by no means needed to ac
clangd, clangd,
Clang-Format, Clang-Format,
CodeLLDB, CodeLLDB,
C++ TestMate,
Docker and Docker and
Remote Development Remote Development
@ -154,12 +145,6 @@ 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. 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](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](https://git.cs.tu-dortmund.de/nils.hoelscher/RTSA-lab01-CacheAnalysis/src/branch/master/UnitTest/UnitTest.cpp).
## Use the Helper script ## Use the Helper script
Again if you work on a Pool PC use poolhelper.sh insted of the helper.sh script. Again if you work on a Pool PC use poolhelper.sh insted of the helper.sh script.

View File

@ -1,52 +0,0 @@
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
"$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>")
target_link_libraries(
UnitTest
gtest_main
)
include(GoogleTest)
gtest_discover_tests(UnitTest)

View File

@ -1,174 +0,0 @@
#include <gtest/gtest.h>
#include <sys/stat.h>
#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(MustJoinTests, 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(MustJoinTests, 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(MustJoinTests, 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());
}
}
TEST(MustJoinTests, 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(MustJoinTests, 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]);
}

View File

@ -11,7 +11,7 @@ config () {
mkdir build mkdir build
cd build cd build
echo "==== Configuring cmake ====" echo "==== Configuring cmake ===="
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DLT_LLVM_INSTALL_DIR=/usr .. cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DLT_LLVM_INSTALL_DIR=$LLVM_DIR ../CacheAnalysisPass/
cd .. cd ..
cp build/compile_commands.json compile_commands.json cp build/compile_commands.json compile_commands.json
echo "==== Done! ====" echo "==== Done! ===="
@ -27,7 +27,7 @@ compile () {
run () { run () {
echo "==== Running $1 ====" echo "==== Running $1 ===="
opt -load-pass-plugin build/lib/libCacheAnalysisPass.so \ opt -load-pass-plugin build/libCacheAnalysisPass.so \
-passes='lru-misses(function(loop-unroll-and-jam))' \ -passes='lru-misses(function(loop-unroll-and-jam))' \
test/$1.ll -o /dev/null test/$1.ll -o /dev/null
#llvm-dis < out.bc > out.ll #llvm-dis < out.bc > out.ll

View File

@ -1,3 +1,4 @@
#ifndef ABSTRACHTCACHESTATE_H #ifndef ABSTRACHTCACHESTATE_H
#define ABSTRACHTCACHESTATE_H #define ABSTRACHTCACHESTATE_H
@ -10,6 +11,9 @@
#include <ostream> #include <ostream>
#include <utility> #include <utility>
#include <llvm/IR/BasicBlock.h>
#include <llvm/Support/raw_ostream.h>
#include "AbstractState.h" #include "AbstractState.h"
#include "Address.h" #include "Address.h"
#include "ConcreteState.h" #include "ConcreteState.h"
@ -88,7 +92,7 @@ public: // everything is public, because IDGAF
} }
Visited[Visitor.first] = true; Visited[Visitor.first] = true;
} }
return Ret; return false;
} }
/** /**
@ -100,6 +104,8 @@ public: // everything is public, because IDGAF
void removeNestedLoops( void removeNestedLoops(
std::list<unsigned int> LoopBodyIn, std::list<unsigned int> LoopBodyIn,
std::map<unsigned int, unsigned int> OrigNodeToUnrolledNode) { std::map<unsigned int, unsigned int> OrigNodeToUnrolledNode) {
unsigned int LoopHead = LoopBodyIn.front();
unsigned int LoopTail = LoopBodyIn.back();
unsigned int NestLoopTail; unsigned int NestLoopTail;
for (unsigned int NodeNr : LoopBodyIn) { for (unsigned int NodeNr : LoopBodyIn) {
bool IsLoopHead = false; bool IsLoopHead = false;
@ -288,34 +294,34 @@ public: // everything is public, because IDGAF
removeNestedLoops(LoopBody, OrigNodeToUnrolledNode); removeNestedLoops(LoopBody, OrigNodeToUnrolledNode);
if (Verbose && FoundLoopBody) { if (Verbose && FoundLoopBody) {
std::cout << "Found LoopHead @: " << NodeNr << "\n"; llvm::outs() << "Found LoopHead @: " << NodeNr << "\n";
std::cout << "With LoopTail @: " << LoopTail << "\n"; llvm::outs() << "With LoopTail @: " << LoopTail << "\n";
std::cout << "With Body: {\n"; llvm::outs() << "With Body: {\n";
int I = 1; int I = 1;
for (auto Node : LoopBody) { for (auto Node : LoopBody) {
std::cout << Node << ", "; llvm::outs() << Node << ", ";
if (!(I++ % 5)) { if (!(I++ % 5)) {
std::cout << "\n"; llvm::outs() << "\n";
} }
} }
std::cout << "}\n"; llvm::outs() << "}\n";
std::cout << "Unrolled States: {\n"; llvm::outs() << "Unrolled States: {\n";
I = 1; I = 1;
for (auto Node : LoopBody) { for (auto Node : LoopBody) {
std::cout << OrigNodeToUnrolledNode[Node] << ", "; llvm::outs() << OrigNodeToUnrolledNode[Node] << ", ";
if (!(I++ % 5)) { if (!(I++ % 5)) {
std::cout << "\n"; llvm::outs() << "\n";
} }
} }
std::cout << "}\n"; llvm::outs() << "}\n";
I = 1; I = 1;
std::cout << "OrigNodeToUnrolledNode: {\n"; llvm::outs() << "OrigNodeToUnrolledNode: {\n";
for (auto Nr : OrigNodeToUnrolledNode) { for (auto Nr : OrigNodeToUnrolledNode) {
std::cout << Nr.first << "->" << Nr.second << ", "; llvm::outs() << Nr.first << "->" << Nr.second << ", ";
if (!(I++ % 3)) if (!(I++ % 3))
std::cout << "\n"; llvm::outs() << "\n";
} }
std::cout << "}\n"; llvm::outs() << "}\n";
} }
} }
} }
@ -396,19 +402,19 @@ public: // everything is public, because IDGAF
* *
*/ */
void dumpEdges() { void dumpEdges() {
std::cout << "Dumping Edges:\n"; llvm::outs() << "Dumping Edges:\n";
for (auto const &E : Edges) { for (auto const &E : Edges) {
std::cout << E.first; llvm::outs() << E.first;
bool FirstPrint = true; bool FirstPrint = true;
for (unsigned int To : E.second) { for (unsigned int To : E.second) {
if (FirstPrint) { if (FirstPrint) {
std::cout << " -> " << To; llvm::outs() << " -> " << To;
FirstPrint = false; FirstPrint = false;
} else { } else {
std::cout << ", " << To; llvm::outs() << ", " << To;
} }
} }
std::cout << "\n"; llvm::outs() << "\n";
} }
} }
@ -449,6 +455,5 @@ public: // everything is public, because IDGAF
Nodes[E.first].dump(); Nodes[E.first].dump();
} }
} }
}; // namespace }; // namespace
#endif // ABSTRACHTCACHESTATE_H #endif // ABSTRACHTCACHESTATE_H

View File

@ -12,6 +12,8 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <llvm/Support/raw_ostream.h>
#include "Address.h" #include "Address.h"
// Forward declarations // Forward declarations
@ -101,8 +103,8 @@ public: // everything is public, because IDGAF
void setUnrolled(unsigned int In) { Unrolled = In; } void setUnrolled(unsigned int In) { Unrolled = In; }
bool operator==(AbstractState In) { bool operator==(AbstractState In) {
for (int Index = 0; Index < 16; Index++) { for (int Index; Index < 16; Index++) {
for (int Age = 0; Age < 4; Age++) { for (int Age; Age < 4; Age++) {
for (auto E1 : Sets[Index].Associativity[Age].Blocks) { for (auto E1 : Sets[Index].Associativity[Age].Blocks) {
// find E1 in In States Set and Age. // find E1 in In States Set and Age.
if (std::find(In.Sets[Index].Associativity[Age].Blocks.begin(), if (std::find(In.Sets[Index].Associativity[Age].Blocks.begin(),
@ -137,58 +139,32 @@ public: // everything is public, because IDGAF
// TODO: Due date 08.06.2022 // TODO: Due date 08.06.2022
// Loop through all 16 sets // Loop through all 16 sets
for (int Index = 0; Index < 16; Index++) { for (int Index; Index < 16; Index++) {
// create a temporary set of associativity // create a temporary set of associativity
struct Set temp_set; struct Set temp_set;
// loop through all 4 Ages
for (int Age; Age < 4; Age++) {
struct Set current_set = Sets[Index]; struct Set current_set = Sets[Index];
struct Set incoming_set = In.Sets[Index]; struct Set incoming_set = In.Sets[Index];
// loop through all 4 Ages
//for (int Age = 0; Age < 4; Age++) {
std::cout << "Block list in current set"
<< "[" << Index << "]" << std::endl;
// loop through current set and build list of all contained blocks // loop through current set and build list of all contained blocks
for (auto associativity_map : current_set.Associativity) { for (auto age: current_set.Associativity) {
std::cout << age.first
int associativity_age = associativity_map.first; << ":";
std::list<unsigned int> associativity_block_list = for (auto block : age.second.Blocks)
associativity_map.second.Blocks; std::cout << block << std::endl;
// for every element of associativity_block_list
// if find equivalent in incoming_set.Associativity.block_list
// set new_age = max(associativity_age, age);
// temp_set.Associativity.insert(std::pair<unsigned int, struct Entry>(new_age, new_entry) )
print_block_list(associativity_age, associativity_block_list);
} }
std::cout << "Block list in incoming set"
<< "[" << Index << "]" << std::endl;
// loop through incoming set and build list of all contained blocks // loop through incoming set and build list of all contained blocks
for (auto associativity : incoming_set.Associativity) { for (auto E2 : In.Sets[Index].Associativity[Age].Blocks) {
int age = associativity.first;
std::list<unsigned int> block_list =
associativity.second.Blocks;
print_block_list(age, block_list);
} }
// for (auto E2 : In.Sets[Index].Associativity[Age].Blocks) { }
// }
//}
Sets[Index] = temp_set; Sets[Index] = temp_set;
}
}
void print_block_list(int age, std::list<unsigned int> list) { }
std::cout << "\t" << age << " -> {";
for (auto block : list)
std::cout << block << " ";
std::cout << "}" << std::endl;
} }
/** /**
@ -252,60 +228,46 @@ public: // everything is public, because IDGAF
} }
} }
if (Verbose) { if (Verbose) {
std::cout << "Before:\n"; llvm::outs() << "Before:\n";
this->dump(); this->dump();
} }
// update this with PreAddr // update this with PreAddr
this->update(PreAddr); this->update(PreAddr);
if (Verbose) { if (Verbose) {
std::cout << "Update Tag: " << PreAddr.Tag << "\n"; llvm::outs() << "Update Tag: " << PreAddr.Tag << "\n";
std::cout << "Update Set: " << PreAddr.Index << "\n"; llvm::outs() << "Update Set: " << PreAddr.Index << "\n";
std::cout << "After:\n"; llvm::outs() << "After:\n";
this->dump(); this->dump();
} }
} }
void dumpSet(unsigned int Set) {
std::cout << Addr << " {\n";
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() { void dump() {
std::cout << Addr << " {\n"; llvm::outs() << Addr << " {\n";
std::cout << "Unrolled: " << Unrolled << "\n"; llvm::outs() << "Unrolled: " << Unrolled << "\n";
std::cout << "Computed: " << Computed << "\n"; llvm::outs() << "Computed: " << Computed << "\n";
std::cout << "Predecessors: "; llvm::outs() << "Predecessors: ";
for (auto PreNr : Predecessors) { for (auto PreNr : Predecessors) {
std::cout << PreNr << " "; llvm::outs() << PreNr << " ";
} }
std::cout << "\n"; llvm::outs() << "\n";
std::cout << "Successors: "; llvm::outs() << "Successors: ";
for (auto SuccNr : Successors) { for (auto SuccNr : Successors) {
std::cout << SuccNr << " "; llvm::outs() << SuccNr << " ";
} }
std::cout << "\n"; llvm::outs() << "\n";
for (auto SetPair : Sets) { for (auto SetPair : Sets) {
std::cout << "Set[" << SetPair.first << "]: \n"; llvm::outs() << "Set[" << SetPair.first << "]: \n";
for (auto EntryPair : SetPair.second.Associativity) { for (auto EntryPair : SetPair.second.Associativity) {
std::cout << " Age[" << EntryPair.first << "]: "; llvm::outs() << " Age[" << EntryPair.first << "]: ";
for (auto Block : EntryPair.second.Blocks) { for (auto Block : EntryPair.second.Blocks) {
std::cout << Block << " "; llvm::outs() << Block << " ";
} }
std::cout << "\n"; llvm::outs() << "\n";
} }
} }
std::cout << "}\n"; llvm::outs() << "}\n";
} }
}; // namespace }; // namespace
#endif // STATE_H #endif // STATE_H