Compare commits

...

16 Commits

Author SHA1 Message Date
Mukendi Mputu 15d236299d first draft pseudo code 2022-05-24 23:30:04 +02:00
Mukendi Mputu 2f682920f7 Merge commit '2ab71cf95df2fa3615909d24187b38715c20181d' 2022-05-24 21:56:35 +02:00
Nils Hölscher 2ab71cf95d Added Auto build badge to Readme.md 2022-05-24 11:07:32 +02:00
Nils Hölscher 13861282b4 . 2022-05-24 11:05:40 +02:00
Nils Hölscher 623818d49e moved Auto Build file 2022-05-24 10:54:18 +02:00
Nils Hölscher 841dbe1070 Automated builds and better UnitTEstNames for the Future. 2022-05-24 10:46:21 +02:00
Nils Hölscher 9dca6c2f67 More Unit Tests 2022-05-17 18:37:28 +02:00
Nils Hölscher 801831a2b5 fixed Bug in helper script 2022-05-17 08:20:52 +02:00
Nils Hölscher f818f3847a newer googletest suite 2022-05-16 14:05:04 +02:00
Nils Hölscher e40e6b7893 Added file Links in readme 2022-05-16 13:46:06 +02:00
Nils Hölscher 2cdcace84b Merge branch 'UnitTest' 2022-05-16 13:44:37 +02:00
Nils Hölscher 3264029256 Updated readme for UnitTests 2022-05-16 13:44:23 +02:00
Nils Hölscher 8ea0c571e4 Added some simple UnitTests 2022-05-16 13:38:48 +02:00
Nils Hölscher 0d09aa9e45 Merge branch 'master' into UnitTest 2022-05-16 11:58:33 +02:00
Nils Hölscher 7635fb52c7 Removed dbg option for loopunrolling. 2022-05-16 11:58:20 +02:00
Nils Hölscher e7ca0a68ef better exercise description in README.md 2022-05-16 11:55:40 +02:00
11 changed files with 408 additions and 92 deletions

11
.drone.yml Normal file
View File

@ -0,0 +1,11 @@
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

17
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,17 @@
{
"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
"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",

View File

@ -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/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
# 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)

View File

@ -56,7 +56,7 @@ struct CacheAnalysisPass : PassInfoMixin<CacheAnalysisPass> {
bool PrintEdgesPost = false;
bool DumpToDot = false;
bool DumpNodes = false;
bool LoopUnrolling = false;
bool LoopUnrolling = true;
// Assume a 4kB Cache
// 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) {
FunctionAnalysisManager &FAM =
MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
// FunctionAnalysisManager &FAM =
// MAM.getResult<FunctionAnalysisManagerModuleProxy>(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)

View File

@ -1,10 +1,18 @@
# 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.
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
@ -82,6 +90,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
@ -145,6 +154,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](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
Again if you work on a Pool PC use poolhelper.sh insted of the helper.sh script.

52
UnitTest/CMakeLists.txt Normal file
View File

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

174
UnitTest/UnitTest.cpp Normal file
View File

@ -0,0 +1,174 @@
#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
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! ===="
@ -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

View File

@ -1,4 +1,3 @@
#ifndef ABSTRACHTCACHESTATE_H
#define ABSTRACHTCACHESTATE_H
@ -11,9 +10,6 @@
#include <ostream>
#include <utility>
#include <llvm/IR/BasicBlock.h>
#include <llvm/Support/raw_ostream.h>
#include "AbstractState.h"
#include "Address.h"
#include "ConcreteState.h"
@ -92,7 +88,7 @@ public: // everything is public, because IDGAF
}
Visited[Visitor.first] = true;
}
return false;
return Ret;
}
/**
@ -104,8 +100,6 @@ public: // everything is public, because IDGAF
void removeNestedLoops(
std::list<unsigned int> LoopBodyIn,
std::map<unsigned int, unsigned int> OrigNodeToUnrolledNode) {
unsigned int LoopHead = LoopBodyIn.front();
unsigned int LoopTail = LoopBodyIn.back();
unsigned int NestLoopTail;
for (unsigned int NodeNr : LoopBodyIn) {
bool IsLoopHead = false;
@ -294,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";
}
}
}
@ -402,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";
}
}
@ -455,5 +449,6 @@ public: // everything is public, because IDGAF
Nodes[E.first].dump();
}
}
}; // namespace
#endif // ABSTRACHTCACHESTATE_H

View File

@ -12,8 +12,6 @@
#include <sstream>
#include <string>
#include <llvm/Support/raw_ostream.h>
#include "Address.h"
// Forward declarations
@ -103,8 +101,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(),
@ -139,34 +137,60 @@ public: // everything is public, because IDGAF
// TODO: Due date 08.06.2022
// Loop through all 16 sets
for (int Index; Index < 16; Index++) {
for (int Index = 0; Index < 16; Index++) {
// create a temporary set of associativity
struct Set temp_set;
struct Set current_set = Sets[Index];
struct Set incoming_set = In.Sets[Index];
// loop through all 4 Ages
for (int Age; Age < 4; Age++) {
struct Set current_set = Sets[Index];
struct Set incoming_set = In.Sets[Index];
//for (int Age = 0; Age < 4; Age++) {
// loop through current set and build list of all contained blocks
for (auto age: current_set.Associativity) {
std::cout << age.first
<< ":";
for (auto block : age.second.Blocks)
std::cout << block << std::endl;
}
// loop through incoming set and build list of all contained blocks
for (auto E2 : In.Sets[Index].Associativity[Age].Blocks) {
std::cout << "Block list in current set"
<< "[" << Index << "]" << std::endl;
// loop through current set and build list of all contained blocks
for (auto associativity_map : current_set.Associativity) {
}
int associativity_age = associativity_map.first;
std::list<unsigned int> associativity_block_list =
associativity_map.second.Blocks;
// 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);
}
Sets[Index] = temp_set;
std::cout << "Block list in incoming set"
<< "[" << Index << "]" << std::endl;
// loop through incoming set and build list of all contained blocks
for (auto associativity : incoming_set.Associativity) {
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;
}
}
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;
}
/**
* @brief Checks if Address Addr is in Cache
*
@ -228,46 +252,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";
}
llvm::outs() << "\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 << " ";
}
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
#endif // STATE_H