Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit b45b9bf2 authored by Valentin Touzeau's avatar Valentin Touzeau Committed by EXT Valentin Touzeau
Browse files

WIP

parent bd2fad60
......@@ -14,8 +14,6 @@ set(SOURCES "src/exactlru.cpp"
"src/ClassificationBuilder.cpp"
"src/ZDD/ZDD.cpp"
"src/ZDD/ZDDManager.cpp"
"src/ZDD/ZDDMustDomain.cpp"
"src/ZDD/ZDDMayDomain.cpp"
)
add_subdirectory(ddlib)
......
diff -r -c extra20/Makefile extra20/Makefile
*** extra20/Makefile 2003-10-11 12:25:38.000000000 +0200
--- extra20/Makefile 2018-05-04 16:25:52.535788756 +0200
***************
*** 4,11 ****
.SILENT:
# modify these macros to point to your include and lib directory
! INCDIR = /u/alanmi/local/include/
! LIBDIR = /u/alanmi/local/lib/
# modify this line to compile with compilers other than g++
CC = gcc
--- 4,11 ----
.SILENT:
# modify these macros to point to your include and lib directory
! INCDIR = ../cudd-2.3.1/include/
! LIBDIR = ../cudd-2.3.1/extra/
# modify this line to compile with compilers other than g++
CC = gcc
***************
*** 25,31 ****
#CFLAGS = -c -O -D_UNIX -D_HP_
# these are compiler flags for SunOS
! CFLAGS = -c -O -D_UNIX
#LFLAGS = -pg -Wall
LFLAGS =
--- 25,32 ----
#CFLAGS = -c -O -D_UNIX -D_HP_
# these are compiler flags for SunOS
! #CFLAGS = -c -O -D_UNIX
! CFLAGS = -c -O -D_UNIX -fPIC
#LFLAGS = -pg -Wall
LFLAGS =
#ifndef GENERATORS_SET_H
#define GENERATORS_SET_H
#include <set>
#include <exactlru/Generator.h>
namespace exactlru
{
template <typename AbstractValuePolicy>
class GSAbstractValue : public AbstractValuePolicy
{
public:
using Block = Generator::Block;
using GeneratorsSet = std::set<Generator, LexicalOrder>;
using PartialOrder = typename AbstractValuePolicy::Comparator;
GeneratorsSet(const GeneratorsSet& g = {}) : _generators(g)
{
}
void update(const Block* block)
{
GeneratorsSet old(_generators);
_generators.clear();
for(const auto& g : old) {
Generator newGenerator(g);
newGenerator.update(block);
insert(newGenerator);
}
void join(const GeneratorsSet& rhs)
{
for(const auto& g : rhs._generators) {
insert(g);
}
}
inline bool operator==(const GeneratorsSet& rhs) const
{
return _generators == rhs._generators;
}
inline bool operator!=(const GeneratorsSet& rhs) const
{
return !(*this == rhs);
}
private:
void insert(const Generator& generator)
{
// Check if "generator" is subsumed.
for(const auto& g : _generators)
if(_less(g, generator))
return;
// Remove old generators that are subsumed
typename GeneratorsSet::const_iterator it = _generators.begin();
while(it != _generators.end()) {
if(_less(generator, *it))
it = _generators.erase(it);
else
++it;
}
_generators.insert(generator);
}
GeneratorsSet _generators;
PartialOrder _less;
};
class GSMayAbstractValuePolicy
{
public:
using Self = GSAbstractValue<GSMayAbstractValuePolicy>;
class Comparator
{
public:
inline bool operator()(const Generator& lhs, const Generator& rhs) const
{
return rhs.contains(lhs);
}
};
bool isAlwaysMiss() const
{
const Self& self = static_cast<const Self&>(*this);
for(const auto& g : self._generators) {
if(!g.isFocusedBlockEvicted())
return false;
}
return true;
}
};
class GSMustAbstractValuePolicy
{
public:
using Self = GSAbstractValue<GSMustAbstractValuePolicy>;
class Comparator
{
public:
inline bool operator()(const Generator& lhs, const Generator& rhs) const
{
return lhs.contains(rhs);
}
};
bool isAlwaysHit() const
{
const Self& self = static_cast<const Self&>(*this);
for(const auto& g : self._generators) {
if(g.isFocusedBlockEvicted())
return false;
}
return true;
}
};
} // namespace exactlru
#endif // MAY_GENERATORS_SET_H
#ifndef MAY_MANAGER_H
#define MAY_MANAGER_H
#include <exactlru/MayAnalysis/MayDomain.h>
namespace exactlru
{
......
......@@ -29,10 +29,10 @@
#include <otawa/icache/features.h>
#include <otawa/icat3/features.h>
#include <exactlru/features.h>
#include <exactlru/MayAnalysis/MayDomain.h>
#include "MayDomain.h"
#include <exactlru/MayAnalysis/MayManager.h>
#include "../ZDD/ZDDMayDomain.h"
#include "../ZDD/Domain.h"
using namespace otawa;
......@@ -42,8 +42,8 @@ namespace exactlru
class MayAdapter
{
public:
//typedef ZDDMayDomain domain_t;
typedef MayDomain domain_t;
typedef Domain<ZDDMayDomainPolicy> domain_t;
//typedef MayDomain domain_t;
typedef typename domain_t::t t;
typedef CompositeCFG graph_t;
typedef ai::ArrayStore<domain_t, graph_t> store_t;
......@@ -105,8 +105,8 @@ private:
class MayAnalysis : public Processor
{
public:
//using domain_t = ZDDMayDomain;
using domain_t = MayDomain;
using domain_t = Domain<ZDDMayDomainPolicy>;
//using domain_t = MayDomain;
static p::declare reg;
MayAnalysis(p::declare& r = reg) :
......
#include <exactlru/MayAnalysis/MayDomain.h>
#include "MayDomain.h"
#include <exactlru/features.h>
#include <otawa/icat3/features.h>
......
......@@ -27,10 +27,10 @@
#include <otawa/icache/features.h>
#include <otawa/icat3/features.h>
#include <exactlru/features.h>
#include <exactlru/MustAnalysis/MustDomain.h>
#include "MustDomain.h"
#include <exactlru/MustAnalysis/MustManager.h>
#include "../ZDD/ZDDMustDomain.h"
#include "../ZDD/Domain.h"
using namespace otawa;
......@@ -40,8 +40,8 @@ namespace exactlru
class MustAdapter
{
public:
typedef ZDDMustDomain domain_t;
//typedef MustDomain domain_t;
//typedef Domain<ZDDMustDomainPolicy> domain_t;
typedef MustDomain domain_t;
typedef typename domain_t::t t;
typedef CompositeCFG graph_t;
typedef ai::ArrayStore<domain_t, graph_t> store_t;
......@@ -103,8 +103,8 @@ private:
class MustAnalysis : public Processor
{
public:
using domain_t = ZDDMustDomain;
//using domain_t = MustDomain;
//using domain_t = Domain<ZDDMustDomainPolicy>;
using domain_t = MustDomain;
static p::declare reg;
MustAnalysis(p::declare& r = reg) :
......
#include <exactlru/MustAnalysis/MustDomain.h>
#include "MustDomain.h"
#include <exactlru/features.h>
#include <otawa/icat3/features.h>
......
#ifndef EXACTLRU_ZDD_DOMAIN_H_
#define EXACTLRU_ZDD_DOMAIN_H_
#include <otawa/icat3/features.h>
#include <otawa/icache/features.h>
#include "ZDDAbstractValue.h"
namespace exactlru
{
template<typename DomainPolicy>
class Domain : public DomainPolicy
{
public:
using AbstractValue = typename DomainPolicy::AbstractValue;
// This alias is needed by Otawa
using t = AbstractValue;
Domain(const otawa::icat3::LBlock* focus,
const otawa::icat3::LBlockCollection& coll,
int set,
const AbstractValue* init) :
DomainPolicy(focus, coll, set, init),
m_focus(focus),
m_bot(AbstractValue::Init::Bot),
m_top(AbstractValue::Init::Top),
m_set(set),
m_coll(coll),
m_init(init ? *init : m_top),
m_tmp(AbstractValue::Init::Top)
{
}
inline const AbstractValue& bot(void) const { return m_bot; }
inline const AbstractValue& top(void) const { return m_top; }
inline const AbstractValue& init(void) const { return m_init; }
inline void copy(AbstractValue& d, const AbstractValue& s) { d = s; }
inline bool equals(const AbstractValue& a, const AbstractValue& b) { return a == b; }
inline void join(AbstractValue& d, const AbstractValue& s) {d.join(s);}
void update(const otawa::icache::Access& access, AbstractValue& a)
{
switch(access.kind()) {
case otawa::icache::FETCH:
if(m_coll.cache()->set(access.address()) == m_set)
fetch(a, otawa::icat3::LBLOCK(access));
break;
case otawa::icache::PREFETCH:
if(m_coll.cache()->set(access.address()) == m_set) {
copy(m_tmp, a);
fetch(a, otawa::icat3::LBLOCK(access));
join(a, m_tmp);
}
break;
case otawa::icache::NONE:
break;
}
}
private:
void fetch(AbstractValue& a, const otawa::icat3::LBlock *lb)
{
DomainPolicy::fetch(a, lb, m_coll.A(), m_focus);
}
const otawa::icat3::LBlock* m_focus;
AbstractValue m_bot, m_top;
otawa::hard::Cache::set_t m_set;
const otawa::icat3::LBlockCollection& m_coll;
const AbstractValue& m_init;
AbstractValue m_tmp;
};
class ZDDMayDomainPolicy
{
public:
using ManagerPtr = std::shared_ptr<ZDDManager>;
using AbstractValue = ZDDAbstractValue<MayAbstractValuePolicy>;
ZDDMayDomainPolicy(const otawa::icat3::LBlock*,
const otawa::icat3::LBlockCollection& coll,
int set,
const AbstractValue*) :
m_manager(new ZDDManager(coll[set]))
{
}
void fetch(AbstractValue& a, const otawa::icat3::LBlock *lb, int k, const otawa::icat3::LBlock* focus)
{
a.update(m_manager, lb, k, focus);
}
bool isAlwaysMiss(const AbstractValue& a) const
{
return a.isAlwaysMiss(m_manager);
}
private:
ManagerPtr m_manager;
};
class ZDDMustDomainPolicy
{
public:
using ManagerPtr = std::shared_ptr<ZDDManager>;
using AbstractValue = ZDDAbstractValue<MustAbstractValuePolicy>;
ZDDMustDomainPolicy(const otawa::icat3::LBlock*,
const otawa::icat3::LBlockCollection& coll,
int set,
const AbstractValue*) :
m_manager(new ZDDManager(coll[set]))
{
}
void fetch(AbstractValue& a, const otawa::icat3::LBlock *lb, int k, const otawa::icat3::LBlock* focus)
{
a.update(m_manager, lb, k, focus);
}
bool isAlwaysHit(const AbstractValue& a) const
{
return a.isAlwaysHit();
}
private:
ManagerPtr m_manager;
};
} // namespace exactlru
#endif /* EXACTLRU_ZDD_DOMAIN_H_ */
......@@ -2,17 +2,16 @@
#include "ZDDManager.h"
extern "C"
{
#include <cudd.h>
#include <cuddInt.h>
#include <extra.h>
}
namespace exactlru
{
long int count = 0;
ZDD ZDD::one(ManagerPtr manager)
{
ASSERT(manager);
......@@ -45,6 +44,7 @@ ZDD::ZDD(const ZDD& other) : _manager(other._manager), _zdd(other._zdd)
ZDD::~ZDD()
{
++count;
if(_zdd != nullptr)
Cudd_RecursiveDerefZdd(_manager->getManager(), _zdd);
}
......@@ -130,56 +130,60 @@ ZDD ZDD::minDotProduct(const ZDD& other) const
DdNode* u = Extra_zddDotProduct(_manager->getManager(), _zdd, other._zdd);
Cudd_Ref(u);
DdNode* res = Extra_zddMinimal(_manager->getManager(), u);
Cudd_RecursiveDerefZdd(_manager->getManager(), u);
Cudd_Deref(u);
return ZDD(_manager, res);
}
// return true if zdd has changed (ie. if some set contains has cardinality at least k)
bool ZDD::boundCardinality(unsigned int k)
{
ASSERT((_zdd == nullptr) == (_manager == nullptr));
ASSERT(_manager != nullptr);
ASSERT(_zdd != nullptr);
DdManager* manager = _manager->getManager();
// TODO: Check failure
DdNode* t = _zdd;
_zdd = boundCardinality(_zdd, k);
switch(k) {
case 0:
_zdd = CardinalityHelper<0>::truncate(manager, _zdd);
break;
case 1:
_zdd = CardinalityHelper<1>::truncate(manager, _zdd);
break;
case 3:
_zdd = CardinalityHelper<3>::truncate(manager, _zdd);
break;
case 7:
_zdd = CardinalityHelper<7>::truncate(manager, _zdd);
break;
case 15:
_zdd = CardinalityHelper<15>::truncate(manager, _zdd);
break;
case 31:
_zdd = CardinalityHelper<31>::truncate(manager, _zdd);
break;
case 63:
_zdd = CardinalityHelper<63>::truncate(manager, _zdd);
break;
default:
ASSERT(false); // Associativity is to big or not a power of 2
}
Cudd_Ref(_zdd);
bool same = t == _zdd;
Cudd_RecursiveDerefZdd(_manager->getManager(), t);
ASSERT((_zdd == nullptr) == (_manager == nullptr));
return !same;
}
void ZDD::printDotToFile(char* filename, char* function) const
{
ASSERT((_zdd == nullptr) == (_manager == nullptr));
ASSERT(_manager != nullptr);
ASSERT(_zdd != nullptr);
_manager->printDotToFile(_zdd, filename, function);
}
DdNode* ZDD::boundCardinality(DdNode* zdd, int unsigned bound)
{
ASSERT(_manager != nullptr);
DdManager* manager = _manager->getManager();
if(zdd == DD_ZERO(manager))
return zdd;
if(zdd == DD_ONE(manager))
return zdd;
if(bound == 0)
return boundCardinality(Cudd_E(zdd), 0);
DdNode* q_t = boundCardinality(Cudd_T(zdd), bound - 1);
Cudd_Ref(q_t);
DdNode* q_e = boundCardinality(Cudd_E(zdd), bound);
Cudd_Ref(q_e);
DdNode* q = cuddZddGetNode(manager, zdd->index, q_t, q_e);
Cudd_Deref(q_t);
Cudd_Deref(q_e);
return q;
ASSERT((_zdd == nullptr) == (_manager == nullptr));
}
} // namespace exactlru
......
......@@ -6,13 +6,67 @@
#include <memory>
#include <util.h>
struct DdNode;
extern "C"
{
#include <cudd.h>
#include <cuddInt.h>
}
namespace exactlru
{
class ZDDManager;
template <unsigned int bound>
class CardinalityHelper
{
public:
static DdNode* truncate(DdManager* manager, DdNode* zdd)
{
if(zdd == DD_ZERO(manager))
return zdd;
if(zdd == DD_ONE(manager))
return zdd;
DdNode* res = cuddCacheLookup1Zdd(manager, CardinalityHelper<bound>::truncate, zdd);
if (res)
return res;
DdNode* q_t = CardinalityHelper<bound - 1>::truncate(manager, Cudd_T(zdd));
Cudd_Ref(q_t);
DdNode* q_e = CardinalityHelper<bound>::truncate(manager, Cudd_E(zdd));
Cudd_Ref(q_e);
DdNode* q = cuddZddGetNode(manager, zdd->index, q_t, q_e);
Cudd_Deref(q_t);
Cudd_Deref(q_e);
return q;
}
};
template <>
class CardinalityHelper<0>
{
public:
static DdNode* truncate(DdManager* manager, DdNode* zdd)
{
if(zdd == DD_ZERO(manager))
return zdd;
if(zdd == DD_ONE(manager))
return zdd;
DdNode* res = cuddCacheLookup1Zdd(manager, CardinalityHelper<0>::truncate, zdd);
if (res)
return res;
return truncate(manager, Cudd_E(zdd));
}
};
class ZDD
{
public:
......@@ -42,7 +96,6 @@ public:
ManagerPtr getManager() const {return _manager;}
private:
DdNode* boundCardinality(DdNode* zdd, int unsigned bound);
ManagerPtr _manager;
DdNode* _zdd;
......
......@@ -9,11 +9,11 @@
namespace exactlru
{
template <typename Strategy>
class ZDDAbstractValue : public Strategy
template <typename AbstractValuePolicy>
class ZDDAbstractValue : public AbstractValuePolicy
{
public:
friend Strategy;
friend AbstractValuePolicy;
using Block = otawa::icat3::LBlock;
using ManagerPtr = std::shared_ptr<ZDDManager>;
......@@ -42,7 +42,7 @@ public:
return;
}