2022-04-19 10:56:42 +02:00
|
|
|
#ifndef ABSSTATE_H
|
|
|
|
#define ABSSTATE_H
|
|
|
|
|
2022-05-03 14:04:21 +02:00
|
|
|
#include <algorithm>
|
2022-04-19 10:56:42 +02:00
|
|
|
#include <cassert>
|
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdlib>
|
2022-05-25 14:20:06 +02:00
|
|
|
#include <iomanip>
|
2022-04-19 10:56:42 +02:00
|
|
|
#include <iostream>
|
|
|
|
#include <list>
|
|
|
|
#include <map>
|
|
|
|
#include <ostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include "Address.h"
|
|
|
|
// Forward declarations
|
|
|
|
|
|
|
|
namespace cacheAnaPass {
|
|
|
|
class AbstractState;
|
|
|
|
|
|
|
|
} // namespace cacheAnaPass
|
|
|
|
|
|
|
|
class AbstractState {
|
|
|
|
public: // everything is public, because IDGAF
|
|
|
|
std::list<unsigned int> Successors;
|
|
|
|
std::list<unsigned int> Predecessors;
|
|
|
|
|
|
|
|
unsigned int Addr;
|
2022-04-29 14:31:08 +02:00
|
|
|
unsigned int Unrolled;
|
2022-04-19 10:56:42 +02:00
|
|
|
|
2022-05-06 10:04:45 +02:00
|
|
|
int Computed = 0;
|
|
|
|
bool Filled = false;
|
2022-04-19 10:56:42 +02:00
|
|
|
|
|
|
|
// Only entries below this comment are needed for the exercise.
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Containing all Abstract Cache Tags.
|
|
|
|
* Key of the list has no Meaning.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
struct Entry {
|
|
|
|
std::list<unsigned int> Blocks;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Cache Set, Key is the Age of the Entries.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
struct Set {
|
|
|
|
// uInt in this map is the Age.
|
|
|
|
std::map<unsigned int, Entry> Associativity;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Cache Sets, key is the Set number [0-15], derived from Address.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
std::map<unsigned int, Set> Sets;
|
|
|
|
|
|
|
|
AbstractState(AbstractState const &Copy) {
|
2022-04-29 14:31:08 +02:00
|
|
|
Addr = Copy.Addr;
|
|
|
|
Unrolled = Copy.Unrolled;
|
2022-04-19 10:56:42 +02:00
|
|
|
for (auto S : Copy.Sets) {
|
|
|
|
unsigned int SetNr = S.first;
|
|
|
|
for (auto E : S.second.Associativity) {
|
|
|
|
unsigned int Age = E.first;
|
|
|
|
for (auto B : E.second.Blocks) {
|
|
|
|
Sets[SetNr].Associativity[Age].Blocks.push_back(B);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-03 14:04:21 +02:00
|
|
|
AbstractState(AbstractState const &Copy, Address Update) {
|
|
|
|
Addr = Copy.Addr;
|
|
|
|
Unrolled = Copy.Unrolled;
|
|
|
|
for (auto S : Copy.Sets) {
|
|
|
|
unsigned int SetNr = S.first;
|
|
|
|
for (auto E : S.second.Associativity) {
|
|
|
|
unsigned int Age = E.first;
|
|
|
|
for (auto B : E.second.Blocks) {
|
|
|
|
Sets[SetNr].Associativity[Age].Blocks.push_back(B);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this->update(Update);
|
|
|
|
}
|
|
|
|
|
2022-04-19 10:56:42 +02:00
|
|
|
AbstractState() {}
|
|
|
|
|
2022-04-29 14:31:08 +02:00
|
|
|
AbstractState(unsigned int AddressIn) {
|
|
|
|
Addr = AddressIn;
|
|
|
|
Unrolled = 0;
|
|
|
|
}
|
2022-04-19 10:56:42 +02:00
|
|
|
|
2022-04-29 14:31:08 +02:00
|
|
|
AbstractState(unsigned int AddressIn, unsigned int UnrolledIn) {
|
|
|
|
Addr = AddressIn;
|
|
|
|
Unrolled = UnrolledIn;
|
2022-04-20 13:36:41 +02:00
|
|
|
}
|
2022-04-19 10:56:42 +02:00
|
|
|
|
2022-04-29 14:31:08 +02:00
|
|
|
void setUnrolled(unsigned int In) { Unrolled = In; }
|
|
|
|
|
2022-05-03 14:04:21 +02:00
|
|
|
bool operator==(AbstractState In) {
|
2022-05-16 13:38:48 +02:00
|
|
|
for (int Index = 0; Index < 16; Index++) {
|
|
|
|
for (int Age = 0; Age < 4; Age++) {
|
2022-05-03 14:04:21 +02:00
|
|
|
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(),
|
|
|
|
In.Sets[Index].Associativity[Age].Blocks.end(),
|
|
|
|
E1) == In.Sets[Index].Associativity[Age].Blocks.end()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (auto E2 : In.Sets[Index].Associativity[Age].Blocks) {
|
|
|
|
// find E2 in This Set and Age.
|
|
|
|
if (std::find(Sets[Index].Associativity[Age].Blocks.begin(),
|
|
|
|
Sets[Index].Associativity[Age].Blocks.end(),
|
|
|
|
E2) == Sets[Index].Associativity[Age].Blocks.end()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-04-19 10:56:42 +02:00
|
|
|
/**
|
|
|
|
* @brief Executes an Must LRU Join on the AbstractCacheState
|
|
|
|
*
|
|
|
|
* @param In, AbstractState that gets joined into the State.
|
|
|
|
*/
|
|
|
|
void mustJoin(AbstractState In) {
|
2022-04-20 13:36:41 +02:00
|
|
|
/**
|
2022-05-25 14:20:06 +02:00
|
|
|
* TODO: Fill this function with an LRU must Join.
|
2022-04-20 13:36:41 +02:00
|
|
|
* For this you need to use Sets. Associativity and Blocks.
|
|
|
|
*/
|
2022-05-24 21:53:15 +02:00
|
|
|
|
|
|
|
// Loop through all 16 sets
|
2022-05-24 23:30:04 +02:00
|
|
|
for (int Index = 0; Index < 16; Index++) {
|
2022-05-24 21:53:15 +02:00
|
|
|
|
2022-05-24 23:30:04 +02:00
|
|
|
struct Set current_set = Sets[Index];
|
|
|
|
struct Set incoming_set = In.Sets[Index];
|
2022-05-24 21:53:15 +02:00
|
|
|
|
2022-06-02 21:08:36 +02:00
|
|
|
// create a temporary set of associativity
|
|
|
|
struct Set temp_set;
|
|
|
|
temp_set.Associativity = {{(unsigned int)0, {{}}},
|
|
|
|
{(unsigned int)1, {{}}},
|
|
|
|
{(unsigned int)2, {{}}},
|
|
|
|
{(unsigned int)3, {{}}}};
|
|
|
|
|
|
|
|
int new_age = 0;
|
|
|
|
|
2022-05-25 14:20:06 +02:00
|
|
|
// loop through all Ages
|
2022-06-02 21:08:36 +02:00
|
|
|
for (int current_age = 0; current_age < 4; current_age++) {
|
|
|
|
|
|
|
|
std::list<unsigned int> new_block_list;
|
|
|
|
|
|
|
|
auto current_age_entry = current_set.Associativity[current_age];
|
|
|
|
std::list<unsigned int> current_age_blocklist =
|
|
|
|
current_age_entry.Blocks;
|
2022-05-24 23:30:04 +02:00
|
|
|
|
|
|
|
// for every element of associativity_block_list
|
2022-06-02 21:08:36 +02:00
|
|
|
for (auto block : current_age_blocklist) {
|
|
|
|
// look through ALL incoming_set.Blocklists for occurrences
|
2022-05-25 14:20:06 +02:00
|
|
|
for (auto incoming_associativity : incoming_set.Associativity) {
|
2022-06-02 21:08:36 +02:00
|
|
|
int age = incoming_associativity.first;
|
2022-05-25 14:20:06 +02:00
|
|
|
struct Entry entry = incoming_associativity.second;
|
|
|
|
|
|
|
|
auto ret =
|
|
|
|
std::find(entry.Blocks.begin(), entry.Blocks.end(), block);
|
2022-06-02 21:08:36 +02:00
|
|
|
if (ret !=
|
|
|
|
entry.Blocks.end()) { // if current block found amongst incoming
|
2022-05-25 14:20:06 +02:00
|
|
|
|
2022-06-02 21:08:36 +02:00
|
|
|
// compare the ages and take the maximum age
|
|
|
|
new_age = std::max(current_age, age);
|
2022-05-25 14:20:06 +02:00
|
|
|
|
2022-06-02 21:08:36 +02:00
|
|
|
new_block_list.push_front((unsigned int)*ret);
|
2022-05-25 14:20:06 +02:00
|
|
|
}
|
|
|
|
}
|
2022-06-02 21:08:36 +02:00
|
|
|
// update the temporary
|
|
|
|
temp_set.Associativity[new_age].Blocks.merge(new_block_list);
|
2022-05-24 23:30:04 +02:00
|
|
|
|
2022-06-02 21:08:36 +02:00
|
|
|
Sets[Index] = temp_set;
|
|
|
|
}
|
2022-05-24 21:53:15 +02:00
|
|
|
}
|
2022-06-02 21:08:36 +02:00
|
|
|
// Here should be Sets[Index] = temp_set;
|
2022-05-24 21:53:15 +02:00
|
|
|
}
|
2022-04-19 10:56:42 +02:00
|
|
|
}
|
|
|
|
|
2022-04-20 13:36:41 +02:00
|
|
|
/**
|
2022-04-19 10:56:42 +02:00
|
|
|
* @brief Checks if Address Addr is in Cache
|
|
|
|
*
|
|
|
|
* @param Addr Address to check.
|
|
|
|
* @return true CacheState contains Address Addr
|
|
|
|
* @return false CacheState does not contain Address Addr
|
|
|
|
*/
|
|
|
|
bool isHit(Address Addr) {
|
|
|
|
for (auto E : Sets[Addr.Index].Associativity) {
|
|
|
|
for (auto B : E.second.Blocks) {
|
|
|
|
if (B == Addr.Tag)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Updates the AbstractState with given Address
|
|
|
|
*
|
|
|
|
* @param Addr , Address
|
|
|
|
*/
|
|
|
|
void update(Address Addr) {
|
2022-05-06 10:04:45 +02:00
|
|
|
// If Updated Address is of Age 0 do nothing
|
|
|
|
if (std::find(Sets[Addr.Index].Associativity[0].Blocks.begin(),
|
|
|
|
Sets[Addr.Index].Associativity[0].Blocks.end(),
|
|
|
|
Addr.Tag) != Sets[Addr.Index].Associativity[0].Blocks.end())
|
|
|
|
return;
|
2022-04-29 14:31:08 +02:00
|
|
|
// This loopages all entries by one. 3 <-2, 2<-1, 1<-0
|
2022-04-22 10:35:30 +02:00
|
|
|
for (int I = 3; I > 0; I--) {
|
|
|
|
Sets[Addr.Index].Associativity[I] = Sets[Addr.Index].Associativity[I - 1];
|
2022-05-03 14:04:21 +02:00
|
|
|
Sets[Addr.Index].Associativity[I].Blocks.remove(Addr.Tag);
|
2022-04-19 10:56:42 +02:00
|
|
|
}
|
2022-04-29 14:31:08 +02:00
|
|
|
// entry at age 0 is updated with current address.
|
2022-04-19 10:56:42 +02:00
|
|
|
Sets[Addr.Index].Associativity[0].Blocks = {Addr.Tag};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-04-29 14:31:08 +02:00
|
|
|
* @brief Fills the AbstractState PreState and updates with PreAddress.
|
2022-04-19 10:56:42 +02:00
|
|
|
*
|
|
|
|
* @param PreState, State that fills this state.
|
|
|
|
*
|
|
|
|
* @param PreAddr Address of PreState
|
|
|
|
*/
|
|
|
|
void fill(AbstractState PreState, Address PreAddr) {
|
2022-05-06 10:04:45 +02:00
|
|
|
bool Verbose = false;
|
2022-04-29 14:31:08 +02:00
|
|
|
// copy Pre State into this.
|
2022-04-19 10:56:42 +02:00
|
|
|
for (auto S : PreState.Sets) {
|
|
|
|
unsigned int Index = S.first;
|
|
|
|
for (auto E : S.second.Associativity) {
|
2022-04-29 14:31:08 +02:00
|
|
|
unsigned int Age = E.first;
|
2022-04-19 10:56:42 +02:00
|
|
|
// If updated age is greater 4 The Tag is no longer in Cache.
|
|
|
|
// Due to associativity of 4 per set.
|
|
|
|
if (Age >= 4)
|
|
|
|
break;
|
|
|
|
for (auto B : E.second.Blocks) {
|
|
|
|
Sets[Index].Associativity[Age].Blocks.push_back(B);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-05-06 10:04:45 +02:00
|
|
|
if (Verbose) {
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << "Before:\n";
|
2022-05-06 10:04:45 +02:00
|
|
|
this->dump();
|
|
|
|
}
|
2022-04-29 14:31:08 +02:00
|
|
|
// update this with PreAddr
|
|
|
|
this->update(PreAddr);
|
2022-05-06 10:04:45 +02:00
|
|
|
if (Verbose) {
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << "Update Tag: " << PreAddr.Tag << "\n";
|
|
|
|
std::cout << "Update Set: " << PreAddr.Index << "\n";
|
|
|
|
std::cout << "After:\n";
|
2022-05-06 10:04:45 +02:00
|
|
|
this->dump();
|
|
|
|
}
|
2022-04-19 10:56:42 +02:00
|
|
|
}
|
|
|
|
|
2022-05-24 23:30:04 +02:00
|
|
|
void dumpSet(unsigned int Set) {
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << Addr << " {\n";
|
|
|
|
|
2022-05-24 23:30:04 +02:00
|
|
|
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 << " ";
|
2022-05-16 13:38:48 +02:00
|
|
|
}
|
2022-05-24 23:30:04 +02:00
|
|
|
std::cout << "\n";
|
|
|
|
}
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << "}\n";
|
|
|
|
}
|
|
|
|
|
2022-04-19 10:56:42 +02:00
|
|
|
void dump() {
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << Addr << " {\n";
|
|
|
|
std::cout << "Unrolled: " << Unrolled << "\n";
|
|
|
|
std::cout << "Computed: " << Computed << "\n";
|
|
|
|
std::cout << "Predecessors: ";
|
2022-04-19 10:56:42 +02:00
|
|
|
for (auto PreNr : Predecessors) {
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << PreNr << " ";
|
2022-04-19 10:56:42 +02:00
|
|
|
}
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << "\n";
|
2022-04-19 10:56:42 +02:00
|
|
|
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << "Successors: ";
|
2022-04-19 10:56:42 +02:00
|
|
|
for (auto SuccNr : Successors) {
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << SuccNr << " ";
|
2022-04-19 10:56:42 +02:00
|
|
|
}
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << "\n";
|
2022-04-19 10:56:42 +02:00
|
|
|
|
|
|
|
for (auto SetPair : Sets) {
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << "Set[" << SetPair.first << "]: \n";
|
2022-04-19 10:56:42 +02:00
|
|
|
for (auto EntryPair : SetPair.second.Associativity) {
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << " Age[" << EntryPair.first << "]: ";
|
2022-04-19 10:56:42 +02:00
|
|
|
for (auto Block : EntryPair.second.Blocks) {
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << Block << " ";
|
2022-04-19 10:56:42 +02:00
|
|
|
}
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << "\n";
|
2022-04-19 10:56:42 +02:00
|
|
|
}
|
|
|
|
}
|
2022-05-16 13:38:48 +02:00
|
|
|
std::cout << "}\n";
|
2022-04-19 10:56:42 +02:00
|
|
|
}
|
|
|
|
}; // namespace
|
|
|
|
#endif // STATE_H
|