Compare commits
21 Commits
Fix-and-Lo
...
master
Author | SHA1 | Date |
---|---|---|
Nils Hölscher | cf2907d1d9 | |
Nils Hölscher | 65c74a1883 | |
Nils Hölscher | 73e16bd797 | |
Nils Hölscher | 388103da3f | |
Nils Hölscher | 9146caf849 | |
Nils Hölscher | 0079b4f0e0 | |
Nils Hölscher | 2ab71cf95d | |
Nils Hölscher | 13861282b4 | |
Nils Hölscher | 623818d49e | |
Nils Hölscher | 841dbe1070 | |
Nils Hölscher | 9dca6c2f67 | |
Nils Hölscher | 801831a2b5 | |
Nils Hölscher | f818f3847a | |
Nils Hölscher | e40e6b7893 | |
Nils Hölscher | 2cdcace84b | |
Nils Hölscher | 3264029256 | |
Nils Hölscher | 8ea0c571e4 | |
Nils Hölscher | 0d09aa9e45 | |
Nils Hölscher | 7635fb52c7 | |
Nils Hölscher | e7ca0a68ef | |
Nils Hölscher | 1ae6af2eb6 |
|
@ -0,0 +1,12 @@
|
|||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.241.1/containers/ubuntu/.devcontainer/base.Dockerfile
|
||||
|
||||
# [Choice] Ubuntu version (use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon): ubuntu-22.04, ubuntu-20.04, ubuntu-18.04
|
||||
ARG VARIANT="jammy"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}
|
||||
|
||||
# [Optional] Uncomment this section to install additional OS packages.
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install --no-install-recommends \
|
||||
llvm llvm-dev clang lldb gcc gdb cmake make ninja-build
|
||||
|
||||
ENV LLVM_DIR=/usr/lib/llvm-14
|
|
@ -0,0 +1,33 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.241.1/containers/ubuntu
|
||||
{
|
||||
"name": "Ubuntu",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
// Update 'VARIANT' to pick an Ubuntu version: jammy / ubuntu-22.04, focal / ubuntu-20.04, bionic /ubuntu-18.04
|
||||
// Use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon.
|
||||
"args": { "VARIANT": "ubuntu-22.04" }
|
||||
},
|
||||
"extensions": ["llvm-vs-code-extensions.vscode-clangd",
|
||||
"matepek.vscode-catch2-test-adapter",
|
||||
"twxs.cmake",
|
||||
"vadimcn.vscode-lldb",
|
||||
"xaver.clang-format",
|
||||
"yzhang.markdown-all-in-one",
|
||||
"shd101wyy.markdown-preview-enhanced",
|
||||
"streetsidesoftware.code-spell-checker"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "uname -a",
|
||||
|
||||
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||
"remoteUser": "vscode",
|
||||
"features": {
|
||||
"git": "latest",
|
||||
"fish": "latest"
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -4,21 +4,6 @@
|
|||
// 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",
|
||||
|
@ -26,7 +11,7 @@
|
|||
"program": "/usr/bin/opt",
|
||||
"args": [
|
||||
"-load-pass-plugin",
|
||||
"${workspaceFolder}/build/libCacheAnalysisPass.so",
|
||||
"${workspaceFolder}/build/lib/libCacheAnalysisPass.so",
|
||||
"-passes=lru-misses",
|
||||
"${workspaceFolder}/test/fft1.ll",
|
||||
"-o",
|
||||
|
@ -34,36 +19,36 @@
|
|||
],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "gdb fft1",
|
||||
"type": "cppdbg",//Only Usable with C/C++ extension installed from Microsoft.
|
||||
"request": "launch",
|
||||
"program": "/usr/bin/opt",
|
||||
"args": [
|
||||
"-load-pass-plugin",
|
||||
"${fileDirname}/../build/libCacheAnalysisPass.so",
|
||||
"-passes='lru-misses'",
|
||||
"${fileDirname}/../test/fft1.ll",
|
||||
"-o",
|
||||
"/dev/null"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${fileDirname}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
// {
|
||||
// "name": "gdb fft1",
|
||||
// "type": "cppdbg",//Only Usable with C/C++ extension installed from Microsoft.
|
||||
// "request": "launch",
|
||||
// "program": "/usr/bin/opt",
|
||||
// "args": [
|
||||
// "-load-pass-plugin",
|
||||
// "${fileDirname}/../build/lib/libCacheAnalysisPass.so",
|
||||
// "-passes='lru-misses'",
|
||||
// "${fileDirname}/../test/fft1.ll",
|
||||
// "-o",
|
||||
// "/dev/null"
|
||||
// ],
|
||||
// "stopAtEntry": false,
|
||||
// "cwd": "${fileDirname}",
|
||||
// "environment": [],
|
||||
// "externalConsole": false,
|
||||
// "MIMode": "gdb",
|
||||
// "setupCommands": [
|
||||
// {
|
||||
// "description": "Enable pretty-printing for gdb",
|
||||
// "text": "-enable-pretty-printing",
|
||||
// "ignoreFailures": true
|
||||
// },
|
||||
// {
|
||||
// "description": "Set Disassembly Flavor to Intel",
|
||||
// "text": "-gdb-set disassembly-flavor intel",
|
||||
// "ignoreFailures": true
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
}
|
|
@ -3,10 +3,16 @@
|
|||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "config",
|
||||
"type": "shell",
|
||||
"command": "rm -r build ; rm complile_commands.json ; mkdir build ; cd build ; cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DLT_LLVM_INSTALL_DIR=$LLVM_DIR ..",
|
||||
"group": "build"
|
||||
},
|
||||
{
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"command": "./helper.sh all",
|
||||
"command": " cd build ; ninja ",
|
||||
"group": "build"
|
||||
},
|
||||
]
|
||||
|
|
|
@ -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.
|
||||
|
@ -46,10 +59,10 @@ endif()
|
|||
# `find_package(llvm)`. So there's no need to add it here.
|
||||
list(APPEND CMAKE_PREFIX_PATH "${LT_LLVM_INSTALL_DIR}/lib/cmake/llvm/")
|
||||
|
||||
find_package(LLVM 13.0.0 REQUIRED CONFIG)
|
||||
find_package(LLVM 14.0.0 REQUIRED CONFIG)
|
||||
|
||||
# Another sanity check
|
||||
if(NOT "13" VERSION_EQUAL "${LLVM_VERSION_MAJOR}")
|
||||
if(NOT "14" VERSION_EQUAL "${LLVM_VERSION_MAJOR}")
|
||||
message(FATAL_ERROR "Found LLVM ${LLVM_VERSION_MAJOR}, but need LLVM 13")
|
||||
endif()
|
||||
|
||||
|
@ -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)
|
|
@ -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)
|
||||
|
|
158
README.md
158
README.md
|
@ -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
|
||||
|
||||
|
@ -18,17 +26,74 @@ I am more than happy helping you install Linux on your machine.
|
|||
|
||||
## Setups
|
||||
|
||||
The easiest Way is to use the VM Image (pw:rtsa) provided here:
|
||||
### VS Code Docker dev container (recommended setup)
|
||||
|
||||
<https://tu-dortmund.sciebo.de/s/JbvtbtEADx92eEG/authenticate>
|
||||
1.) install docker and VS Code on your Distribution. Please keep in mind Dev containers are only supported by the native version of VS Code from Microsoft!
|
||||
|
||||
On this VM you can simply open VS Code from the desktop and start coding.
|
||||
<https://docs.docker.com/get-docker/>
|
||||
|
||||
Following are native setups and some other unrecommended Setups are at the end of this Readme.
|
||||
<https://code.visualstudio.com/>
|
||||
|
||||
Also read the VS Code setup, which might be interesting independent from your chosen Setup.
|
||||
For this setup you cannot use the OSS version of VS code or the version from Snap, as the remote development extensions will not work.
|
||||
|
||||
### Mac Setup
|
||||
2.) I recommend you install the following extensions in vs code
|
||||
|
||||
clangd,
|
||||
Clang-Format,
|
||||
CodeLLDB,
|
||||
Docker and
|
||||
Remote Development (Microsoft VS Code only!)
|
||||
|
||||
For a general C/C++ setup of VS Code (I consider good) see:
|
||||
<https://ahemery.dev/2020/08/24/c-cpp-vscode/>
|
||||
|
||||
3.) The project comes with a pre configured dev container and should prompt you to use it after opening the project. With this you have a running setup. If not please continue reading the manual points.
|
||||
|
||||
3.manual.) Use the helper script to build and run a Container.
|
||||
|
||||
```bash
|
||||
./helper.sh docker
|
||||
```
|
||||
|
||||
This will build a docker image and run a Docker container with the current directory mounted.
|
||||
|
||||
The Docker container can later be started from the Docker VS Code extension.
|
||||
|
||||
4.manual) Attach VS Code to the container, in the Docker Tab, and start developing
|
||||
|
||||
### VS Code native setup
|
||||
|
||||
This is my personally preferred IDE setup for C/C++ and by no means needed to accomplish this exercise.
|
||||
|
||||
1.) Install VS Code on your Distribution or get it from Microsoft.
|
||||
|
||||
<https://code.visualstudio.com/>
|
||||
|
||||
2.) I recommend you install the following extensions in vs code
|
||||
|
||||
clangd,
|
||||
Clang-Format,
|
||||
CodeLLDB,
|
||||
C++ TestMate,
|
||||
Docker and
|
||||
Remote Development (Microsoft VS Code only!)
|
||||
|
||||
For a general C/C++ setup of VS Code (I consider good) see:
|
||||
<https://ahemery.dev/2020/08/24/c-cpp-vscode/>
|
||||
|
||||
Most parts can be skipped, as they are already integrated in this Repo.
|
||||
|
||||
3.a.) Set the LLVM_DIR variable to your LLVM(14) installation.
|
||||
|
||||
```bash
|
||||
export LLVM_DIR=<path/to/your/llvm/installation>
|
||||
```
|
||||
|
||||
3.b.) You can auto config and build by hitting Ctr+Shift+B from the IDE or use the helper script.
|
||||
|
||||
4.) Pressing F5 will start a debug session, make sure to set halting points.
|
||||
|
||||
### Mac setup
|
||||
|
||||
I recommend using docker and VS Code for setup.
|
||||
Also check out the recommended extensions in the Docker section.
|
||||
|
@ -41,7 +106,7 @@ For Mac (tested on M1 Mac mini) you can also use:
|
|||
|
||||
But you will need brew installed and also have to use the poolhelper script instead of the normal helper script.
|
||||
|
||||
### Setup on a Pool PC
|
||||
### Setup on a pool PC
|
||||
|
||||
At first get an IRB account from the following link and log in:
|
||||
|
||||
|
@ -69,65 +134,7 @@ Now you have a llvm13 source build.
|
|||
|
||||
Remember to use the poolhelper.sh instead of the helper.sh.
|
||||
|
||||
### VS Code Setup
|
||||
|
||||
This is my personally preferred IDE setup for C/C++ and by no means needed to accomplish this exercise.
|
||||
|
||||
1.) Install VS Code on your Distribution or get it from Microsoft.
|
||||
|
||||
<https://code.visualstudio.com/>
|
||||
|
||||
2.) I recommend you install the following extensions in vs code
|
||||
|
||||
clangd,
|
||||
Clang-Format,
|
||||
CodeLLDB,
|
||||
Docker and
|
||||
Remote Development
|
||||
|
||||
For a general C/C++ setup of VS Code (I consider good) see:
|
||||
<https://ahemery.dev/2020/08/24/c-cpp-vscode/>
|
||||
|
||||
Most parts can be skipped, as they are already integrated in this Repo.
|
||||
|
||||
3.) You can auto build by hitting Strg+Shift+B from the IDE.
|
||||
|
||||
4.) Pressing F5 will start a debug session, make sure to set halting points.
|
||||
|
||||
### Setting up Docker
|
||||
|
||||
1.) install docker and VS Code on your Distribution.
|
||||
|
||||
<https://docs.docker.com/get-docker/>
|
||||
|
||||
<https://code.visualstudio.com/>
|
||||
|
||||
For this setup you cannot use the OSS version of VS code or the version from Snap, as the remote development extensions will not work.
|
||||
|
||||
2.) I recommend you install the following extensions in vs code
|
||||
|
||||
clangd,
|
||||
Clang-Format,
|
||||
CodeLLDB,
|
||||
Docker and
|
||||
Remote Development
|
||||
|
||||
For a general C/C++ setup of VS Code (I consider good) see:
|
||||
<https://ahemery.dev/2020/08/24/c-cpp-vscode/>
|
||||
|
||||
Most of the setup can be skipped
|
||||
|
||||
3.) Use the helper script to build and run a Container
|
||||
|
||||
```bash
|
||||
./helper.sh docker
|
||||
```
|
||||
|
||||
This will build a docker image and run a Docker container with the current directory mounted.
|
||||
|
||||
The Docker container can later be started from the Docker VS Code extension.
|
||||
|
||||
4.) Attach VS Code to the container, in the Docker Tab, and start developing
|
||||
|
||||
## Debugging
|
||||
|
||||
|
@ -145,11 +152,24 @@ 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.
|
||||
|
||||
## Use the Helper script
|
||||
## 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).
|
||||
|
||||
|
||||
## Configuring and building
|
||||
|
||||
The easiest way is to use the VS Code tasks in this project.
|
||||
By using CTR+Shift+B you can config and then build the project.
|
||||
|
||||
### Use the helper script
|
||||
|
||||
Again if you work on a Pool PC use poolhelper.sh insted of the helper.sh script.
|
||||
|
||||
### Initial Setup
|
||||
### Initial setup
|
||||
|
||||
```bash
|
||||
./helper.sh all
|
||||
|
|
|
@ -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)
|
|
@ -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]);
|
||||
}
|
12
helper.sh
12
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=$LLVM_DIR ..
|
||||
cd ..
|
||||
cp build/compile_commands.json compile_commands.json
|
||||
echo "==== Done! ===="
|
||||
|
@ -27,12 +27,16 @@ 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
|
||||
}
|
||||
|
||||
test () {
|
||||
./build/bin/UnitTest --gtest_brief=1
|
||||
}
|
||||
|
||||
allBenchs=( "adpcm"
|
||||
"bs"
|
||||
"bsort100"
|
||||
|
@ -103,6 +107,9 @@ case $1 in
|
|||
echo "==== Please provide name of the test as second argument! ===="
|
||||
fi
|
||||
;;
|
||||
t | test)
|
||||
test
|
||||
;;
|
||||
ra | runall)
|
||||
runall
|
||||
;;
|
||||
|
@ -157,6 +164,7 @@ case $1 in
|
|||
echo " r | run [name] Run pass on test/[name] from the test folder"
|
||||
echo " cr [name] Compile and run pass on test/[name] from the test folder"
|
||||
echo " ra | runall Run pass on all tests from the test folder"
|
||||
echo " t | test Execute Unit tests, only test that Fail are printed."
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -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
|
|
@ -12,8 +12,6 @@
|
|||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
|
||||
#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 << " ";
|
||||
}
|
||||
llvm::outs() << "\n";
|
||||
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 << " ";
|
||||
}
|
||||
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
|
||||
|
|
|
@ -36,13 +36,17 @@ run () {
|
|||
#llvm-dis < out.bc > out.ll
|
||||
}
|
||||
|
||||
test () {
|
||||
./build/bin/UnitTest --gtest_brief=1
|
||||
}
|
||||
|
||||
buildllvm() {
|
||||
mkdir llvm
|
||||
cd llvm
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.1/llvm-13.0.1.src.tar.xz
|
||||
tar -xf llvm-13.0.1.src.tar.xz
|
||||
rm llvm-13.0.1.src.tar.xz
|
||||
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DLLVM_TARGETS_TO_BUILD=host llvm-13.0.1.src/
|
||||
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DLLVM_INCLUDE_TESTS=FALSE -DLLVM_TARGETS_TO_BUILD=host llvm-13.0.1.src/
|
||||
make -j 4
|
||||
export LLVM_DIR=$(pwd) >> ~/.zshrc
|
||||
export LLVM_DIR=$(pwd) >> ~/.bashrc
|
||||
|
@ -137,6 +141,9 @@ case $1 in
|
|||
echo "==== Please provide name of the test as second argument! ===="
|
||||
fi
|
||||
;;
|
||||
t | test)
|
||||
test
|
||||
;;
|
||||
ra | runall)
|
||||
runall
|
||||
;;
|
||||
|
@ -194,6 +201,7 @@ case $1 in
|
|||
echo " r | run [name] Run pass on test/[name] from the test folder"
|
||||
echo " cr [name] Compile and run pass on test/[name] from the test folder"
|
||||
echo " ra | runall Run pass on all tests from the test folder"
|
||||
echo " t | test Execute Unit tests, only test that Fail are printed."
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
|
Loading…
Reference in New Issue