Commit ab6d331c authored by Ballabriga Clément's avatar Ballabriga Clément
Browse files

il manque le join

parent 0827eee5
......@@ -2,7 +2,7 @@ CXXFLAGS=`otawa-config otawa/oslice --cflags`
LIBS=`otawa-config otawa/oslice --libs`
LIBS+=-lppl
CXXFLAGS+=-fPIC -Wall -DUSE_CLANG_COMPLETER -std=c++11 -march=native -O3
CXXFLAGS+=-fPIC -Wall -DUSE_CLANG_COMPLETER -std=c++11 -O0 -g
all: poly.so
......@@ -10,13 +10,13 @@ poly.so: poly_PolyAnalysis.o poly_PlugHook.o poly_PPLDomain.o poly_PPLManager.o
$(CC) -shared -o poly.so poly_PolyAnalysis.o poly_PlugHook.o poly_PPLDomain.o poly_PPLManager.o poly_PolyWrap.o $(LIBS)
poly_PolyAnalysis.o: poly_PolyAnalysis.cpp include/PolyAnalysis.h include/PPLDomain.h include/PPLManager.h include/PolyCommon.h include/MyHTable.h include/OrderedDriver.h
poly_PolyAnalysis.o: poly_PolyAnalysis.cpp include/PolyAnalysis.h include/PPLDomain.h include/PolyWrap.h include/PPLManager.h include/PolyCommon.h include/MyHTable.h include/OrderedDriver.h
$(CXX) $(CXXFLAGS) -c poly_PolyAnalysis.cpp -o poly_PolyAnalysis.o
poly_PPLManager.o: poly_PPLManager.cpp include/PolyAnalysis.h include/PPLDomain.h include/PPLManager.h include/PolyCommon.h include/MyHTable.h include/OrderedDriver.h
poly_PPLManager.o: poly_PPLManager.cpp include/PolyAnalysis.h include/PPLDomain.h include/PolyWrap.h include/PPLManager.h include/PolyCommon.h include/MyHTable.h include/OrderedDriver.h
$(CXX) $(CXXFLAGS) -c poly_PPLManager.cpp -o poly_PPLManager.o
poly_PPLDomain.o: poly_PPLDomain.cpp include/PolyAnalysis.h include/PPLDomain.h include/PPLManager.h include/PolyCommon.h include/MyHTable.h include/OrderedDriver.h
poly_PPLDomain.o: poly_PPLDomain.cpp include/PolyAnalysis.h include/PPLDomain.h include/PolyWrap.h include/PPLManager.h include/PolyCommon.h include/MyHTable.h include/OrderedDriver.h
$(CXX) $(CXXFLAGS) -c poly_PPLDomain.cpp -o poly_PPLDomain.o
poly_PlugHook.o: poly_PlugHook.cpp
......
......@@ -128,15 +128,98 @@ class PPLSummary {
return true;
}
};
// TODO make this a template and put in elm/whatever
class Mapping {
public:
bool includes(const Mapping &src) const {
for (MyHTable<Ident, guid_t, HashIdent>::PairIterator it(id2guid); it; it++) {
if (!src.id2guid.hasKey((*it).fst))
return false;
if (src.id2guid[(*it).fst] != (*it).snd)
return false;
}
for (MyHTable<guid_t, Ident>::PairIterator it(guid2id); it; it++) {
if (!src.guid2id.hasKey((*it).fst))
return false;
const Ident &id1 = (*it).snd;
const Ident &id2 = src.guid2id[(*it).fst];
if (id1 != id2)
return false;
}
return true;
}
bool operator==(const Mapping &src) const {
return this->includes(src) && src.includes(*this);
}
inline void add(const Ident &id, guid_t guid) {
if (id2guid.hasKey(id))
guid2id.remove(id2guid[id]);
if (guid2id.hasKey(guid))
id2guid.remove(guid2id[guid]);
id2guid[id] = guid;
guid2id[guid] = id;
}
inline guid_t find1(const Ident &id) const {
return id2guid[id];
}
inline const Ident& find2(guid_t guid) const {
return guid2id[guid];
}
inline void del1(const Ident &id) {
guid2id.remove(id2guid[id]);
id2guid.remove(id);
}
inline void del2(guid_t guid) {
id2guid.remove(guid2id[guid]);
guid2id.remove(guid);
}
inline bool has1(const Ident &id) const {
return id2guid.hasKey(id);
}
inline bool has2(guid_t guid) const {
return guid2id.hasKey(guid);
}
inline MyHTable<Ident, guid_t, HashIdent>::PairIterator getPairIter() const {
return MyHTable<Ident, guid_t, HashIdent>::PairIterator(id2guid);
}
inline MyHTable<Ident, guid_t, HashIdent>::MutableIter getMutableIter() {
return MyHTable<Ident, guid_t, HashIdent>::MutableIter(id2guid);
}
inline int count() const {
ASSERT(id2guid.count() == guid2id.count());
return id2guid.count();
}
private:
MyHTable<Ident, guid_t, HashIdent> id2guid;
MyHTable<guid_t, Ident> guid2id;
};
class PPLDomain {
private:
private:
/* Abstract state */
WPoly poly;
MyHTable<Ident, int, HashIdent>
id2axis; ///< Mapping from identifier (register/pointers) to polyhedron variable
genstruct::Vector<Ident> axis2id; ///< Reverse identifier mapping
Mapping idmap; ///< Mapping from identifiers (registers/pointers) to polyhedron variables
Vector<guid_t> victims; ///< Set of variables scheduled to be destroyed
Ident compare_reg; ///< Register holding the last comparison result
sem::cond_t compare_op; ///< Last comparison semantics
......@@ -144,8 +227,6 @@ class PPLDomain {
int mem_ref{}; ///< Highest pointer ID + 1
int num_axis; ///<Highest poly variable ID + 1
BitVector trash; ///< Bitvector representing the set of variables scheduled to be destroyed
Vector<bound_t> bounds;
Vector<PPLDomain> *linbounds = NULL;
......@@ -230,9 +311,8 @@ class PPLDomain {
/**
* Builds a bottom state
*/
inline PPLDomain() {
inline PPLDomain() : poly(true) {
num_axis = -1;
poly = WPoly(true);
compare_reg = Ident();
compare_op = sem::EQ;
_ws = nullptr;
......@@ -243,26 +323,23 @@ class PPLDomain {
* Builds a top state
* @param maxAxis Maximum number of variables this state can hold
*/
inline explicit PPLDomain(int maxAxis, WorkSpace *ws, PPLSummary *summary = nullptr) {
inline explicit PPLDomain(int maxAxis, WorkSpace *ws, PPLSummary *summary = nullptr) : poly(false) {
num_axis = 0;
mem_ref = 0;
trash = BitVector(maxAxis);
_ws = ws;
poly = WPoly(true);
compare_reg = Ident();
compare_op = sem::EQ;
_summary = summary;
}
inline PPLDomain(const PPLDomain &src) {
poly = src.poly;
inline PPLDomain(const PPLDomain &src) : poly(src.poly){
num_axis = src.num_axis;
id2axis = src.id2axis;
axis2id = src.axis2id;
idmap = src.idmap;
ASSERT(idmap == src.idmap);
mem_ref = src.mem_ref;
compare_reg = src.compare_reg;
compare_op = src.compare_op;
trash = src.trash;
victims = src.victims;
bounds = src.bounds;
if (src.linbounds != nullptr) {
linbounds = new Vector<PPLDomain>(*src.linbounds);
......@@ -280,12 +357,12 @@ class PPLDomain {
inline PPLDomain &operator=(const PPLDomain &dom) {
poly = dom.poly;
num_axis = dom.num_axis;
id2axis = dom.id2axis;
axis2id = dom.axis2id;
idmap = dom.idmap;
ASSERT(idmap == dom.idmap);
compare_reg = dom.compare_reg;
compare_op = dom.compare_op;
mem_ref = dom.mem_ref;
trash = dom.trash;
victims = dom.victims;
bounds = dom.bounds;
_ws = dom._ws;
if (linbounds != nullptr) {
......@@ -382,7 +459,7 @@ class PPLDomain {
*
* @return The space dimension count.
*/
inline int getVarIDCount() const { return poly.space_dimension(); }
inline int getVarIDCount() const { return poly.variable_count(); }
/**
* Gets the number of constraints in the current state
......@@ -632,7 +709,9 @@ class PPLDomain {
*
* @param id Target identifier
*/
inline void varKill(const Ident &id) { return _doFreeAxis(id2axis[id]); }
inline void varKill(const Ident &id) {
varKill(WVar(idmap.find1(id)));
}
/**
* Schedule a variable to be destroyed.
......@@ -640,7 +719,10 @@ class PPLDomain {
*
* @param v Target variable
*/
inline void varKill(const WVar &v) { return _doFreeAxis(v.guid()); }
inline void varKill(const WVar &v) {
idmap.del2(v.guid());
victims.add(v.guid());
}
/**
* Gets the variable associated with an identifier, creating a new variable if it doesn't exists (i.e. lookup).
......@@ -666,8 +748,7 @@ class PPLDomain {
* @return true if the variable is mapped to an identifier, false otherwise
*/
inline bool isVarMapped(const WVar &v) const {
return ((unsigned)axis2id.length() > v.guid()) && (axis2id[v.guid()].getType() != Ident::ID_INVALID) &&
id2axis.hasKey(axis2id[v.guid()]);
return idmap.has2(v.guid());
}
/**
......@@ -676,7 +757,7 @@ class PPLDomain {
* @param v The variable
* @return The identifier
*/
inline const Ident &getIdent(const WVar &v) const { return axis2id[v.guid()]; }
inline const Ident &getIdent(const WVar &v) const { return idmap.find2(v.guid()); }
/**
* Tests if an identifier exists
......@@ -765,8 +846,8 @@ class PPLDomain {
private:
/* Private helper functions. Subject to changes, and should not be used directly. */
int _doAllocAxis(const Ident & /*ident*/, bool allow_replace = false);
void _doFreeAxis(int axis);
// int _doAllocAxis(const Ident & /*ident*/, bool allow_replace = false);
// void _doFreeAxis(int axis);
#ifdef POLY_DEBUG
void _sanityChecks(bool allow_holes = false);
#else
......
......@@ -11,7 +11,7 @@
#include "MyHTable.h"
// #define POLY_DEBUG 1
#define POLY_DEBUG 1
namespace otawa {
namespace poly {
......
......@@ -3,6 +3,7 @@
#include <ppl.hh>
#include <elm/io/Output.h>
#include <elm/io/io.h>
namespace otawa {
namespace poly {
......@@ -23,6 +24,7 @@ output_t& operator<< (output_t& stream, const coef_t&);
output_t& operator<< (output_t& stream, const WLinExpr&);
output_t& operator<< (output_t& stream, const WCons&);
output_t& operator<< (output_t& stream, const WPoly&);
output_t& operator<< (output_t& stream, const WVar&);
WCons operator==(const WLinExpr &a, const WLinExpr &b);
bool operator==(const WPoly &a, const WPoly &b);
bool operator!=(const WPoly &a, const WPoly &b);
......@@ -47,8 +49,8 @@ class WVar {
inline guid_t guid() const { return _guid; }
inline guid_t id() const { return _guid; }
static guid_t _guid_generator; // TODO FIXME: public needed for gruikfix in memMerge()
private:
static guid_t _guid_generator;
guid_t _guid;
};
......@@ -68,21 +70,34 @@ class WLinExpr {
const PPL::Linear_Expression toPPL(WPoly &poly) const;
const PPL::Linear_Expression toPPL(const WPoly &poly) const;
inline coef_t inhomogeneous_term() { return cst; }
inline coef_t coefficient(const WVar &v) { return coefs[v.guid()]; }
inline guid_t space_dimension() {
std::cout << "warning: WLinExpr::space_dimension() is deprecated" << std::endl;
guid_t res = 0;
for (std::map<guid_t,coef_t>::const_iterator it=coefs.begin(); it!=coefs.end(); ++it) {
if (res < it->first)
res = it->first;
}
return res + 1;
}
inline coef_t inhomogeneous_term() const { return cst; }
inline coef_t coefficient(const WVar &v) const { return coefs.at(v.guid()); }
void print(output_t &out) const;
class TermIterator {
public:
inline TermIterator(const WLinExpr &le): _le(le), real_it(_le.coefs.begin()) { }
TermIterator(const WCons &c);
inline void operator++() {
++real_it;
}
inline void operator++(int) {
real_it++;
}
inline WVar operator*() const {
return WVar(real_it->first);
}
inline operator bool() const {
return real_it != _le.coefs.end();
}
private:
const WLinExpr &_le;
std::map<guid_t,coef_t>::const_iterator real_it;
};
private:
std::map<guid_t,coef_t> coefs;
coef_t cst;
......@@ -107,12 +122,12 @@ class WCons {
} else abort();
expr.print(out);
}
inline coef_t inhomogeneous_term() { return expr.inhomogeneous_term(); }
inline coef_t coefficient(const WVar &v) { return expr.coefficient(v); }
inline guid_t space_dimension() { return expr.space_dimension(); }
inline coef_t inhomogeneous_term() const { return expr.inhomogeneous_term(); }
inline coef_t coefficient(const WVar &v) const { return expr.coefficient(v); }
inline const WLinExpr& getLE() const { return expr; }
inline ctype_t getType() const { return ctype; }
inline bool is_equality() const { return ctype == CONS_EQ; }
typedef WLinExpr::TermIterator TermIterator;
private:
ctype_t ctype;
WLinExpr expr;
......@@ -124,11 +139,12 @@ class WPoly {
class Eliminator {
public:
inline Eliminator(const std::vector<PPL::dimension_type> &victims,
PPL::C_Polyhedron &p) : _victims(victims), _p(p) {
PPL::C_Polyhedron &p) : _victims(victims), _p(p), _dom(_p.space_dimension() - 1),
_codom(_dom - _victims.size()) {
}
inline PPL::dimension_type max_in_codomain() const { return _p.space_dimension() - 2; }
inline PPL::dimension_type max_in_domain() const { return _p.space_dimension() - 1; }
inline PPL::dimension_type max_in_codomain() const { return _codom; }
inline PPL::dimension_type max_in_domain() const { return _dom; }
inline bool maps(PPL::dimension_type i, PPL::dimension_type &j) const {
PPL::dimension_type k = 0;
for (std::vector<PPL::dimension_type>::const_iterator it = _victims.begin(); it != _victims.end(); it++) {
......@@ -144,6 +160,8 @@ class WPoly {
private:
const std::vector<PPL::dimension_type> &_victims;
const PPL::C_Polyhedron & _p;
const int _dom;
const int _codom;
};
class MapHash {
public:
......@@ -177,10 +195,9 @@ class WPoly {
public:
class const_iterator {
class ConsIterator {
public:
inline const_iterator(const WPoly &p): _p(p), sys(p.poly.minimized_constraints()), real_it(sys.begin()) {
}
inline ConsIterator(const WPoly &p): _p(p), sys(p.poly.minimized_constraints()), real_it(sys.begin()) { }
inline void operator++() {
++real_it;
}
......@@ -200,7 +217,29 @@ class WPoly {
PPL::Constraint_System::const_iterator real_it;
};
inline WPoly(bool empty = false) {
class VarIterator {
public:
inline VarIterator(const WPoly &p): _p(p), real_it(_p.adapter.begin()) { }
inline void operator++() {
++real_it;
}
inline void operator++(int) {
real_it++;
}
inline WVar operator*() const {
return WVar(real_it->first);
}
inline operator bool() const {
return real_it != _p.adapter.end();
}
private:
const WPoly &_p;
std::map<guid_t,dim_t>::const_iterator real_it;
};
inline WPoly(bool empty) {
poly = PPL::C_Polyhedron(0, empty ? PPL::EMPTY : PPL::UNIVERSE);
}
......@@ -211,6 +250,7 @@ class WPoly {
inline PPL::Variable translate(const guid_t g) {
if (adapter.find(g) == adapter.end()) {
// std::cout << "v" << g << " does not exists\n";
adapter[g] = next;
next++;
}
......@@ -230,24 +270,48 @@ class WPoly {
}
inline PPL::Constraint translate(const WCons &c) const {
// std::cout << "const\n";
PPL::Linear_Expression lexpr = translate(c.getLE());
PPL::Constraint ppl_c = (c.getType() == CONS_EQ) ? (lexpr == 0) : (lexpr >= 0);
return ppl_c;
}
inline PPL::Constraint translate(const WCons &c) {
// std::cout << "pas const\n";
PPL::Linear_Expression lexpr = translate(c.getLE());
PPL::Constraint ppl_c = (c.getType() == CONS_EQ) ? (lexpr == 0) : (lexpr >= 0);
if (poly.space_dimension() < next) {
poly.add_space_dimensions_and_embed(next - poly.space_dimension());
}
// std::cout << "new space dimension: " << poly.space_dimension() << "\n";
return ppl_c;
}
std::map<dim_t,guid_t> invMap() const;
void add_constraint(const WCons &c) {
poly.add_constraint(translate(c));
/*
elm::cout << "poly avant: \n";
print(elm::cout);
elm::cout << "\n\n";
*/
PPL::Constraint pplc = translate(c);
poly.add_constraint(pplc);
/*
elm::cout << "constraint added: " << c << "\ntranslated to: ";
pplc.print();
elm::cout << "\n";
std::map<dim_t,guid_t> inv = invMap();
for (dim_t i = 0; i < pplc.space_dimension(); i++) {
const PPL::Coefficient &coef = pplc.coefficient(PPL::Variable(i));
if (coef != 0) {
inv.at(i);
}
}
elm::cout << "poly apres: \n";
print(elm::cout);
elm::cout << "\n\n";
*/
}
WCons back_translate(const PPL::Constraint &c) const;
......@@ -281,10 +345,19 @@ class WPoly {
return poly.is_universe();
}
inline dim_t space_dimension() const {
inline dim_t variable_count() const {
return poly.space_dimension();
}
inline guid_t highest_guid() const {
guid_t highest = 0;
for (std::map<guid_t,dim_t>::const_iterator it=adapter.begin(); it!=adapter.end(); ++it) {
if (highest < it->first)
highest = it->first;
}
return highest;
}
// Mapping (projection)
template <class F> void map_vars(F pfunc);
......@@ -324,6 +397,8 @@ class WPoly {
template <class F> inline void map_with_dim(F pfunc) {
poly.map_space_dimensions(pfunc);
next = pfunc.max_in_codomain() + 1;
assert(next == poly.space_dimension());
map_adapter_dim(pfunc);
}
......@@ -357,6 +432,7 @@ template <class F> void WPoly::map_adapter_dim(F pfunc) {
}
template <class F> void WPoly::map_vars(F pfunc) {
// std::cout << "map vars!\n";
std::map<guid_t,dim_t> new_adapter;
std::vector<dim_t> victims;
for (std::map<guid_t,dim_t>::iterator it=adapter.begin(); it!=adapter.end(); ++it) {
......@@ -364,14 +440,19 @@ template <class F> void WPoly::map_vars(F pfunc) {
guid_t j = i;
bool b = pfunc.maps(i, j);
if (b) {
std::cout << "v" << i << " mapped to " << "v" << j << "\n";
new_adapter[j] = it->second;
} else {
std::cout << "v" << i << " removed\n";
victims.push_back(it->second);
}
}
adapter = new_adapter;
Eliminator el(victims, poly);
// elm::cout << "max_domain=" << el.max_in_domain() << " max_codomain=" << el.max_in_codomain() << "\n";
map_with_dim(el);
// elm::cout << "after remap: \n";
// print(elm::cout);
}
} // end namespace poly
......
This diff is collapsed.
......@@ -18,6 +18,7 @@ output_t& operator<< (output_t& stream, const WLinExpr& le) {
le.print(stream);
return stream;
}
output_t& operator<< (output_t& stream, const WCons& c) {
c.print(stream);
return stream;
......@@ -27,13 +28,12 @@ output_t& operator<< (output_t& stream, const WPoly& p) {
p.print(stream);
return stream;
}
/*
output_t& operator<< (output_t& stream, const WVar& p) {
stream << "v" << p.guid();
return stream;
}
*/
WLinExpr::TermIterator::TermIterator(const WCons &c): _le(c.getLE()), real_it(_le.coefs.begin()) { }
void WLinExpr::print(output_t &out) const {
bool first = true;
for (std::map<guid_t,coef_t>::const_iterator it=coefs.begin(); it!=coefs.end(); ++it) {
......@@ -52,12 +52,16 @@ void WLinExpr::print(output_t &out) const {
}
void WPoly::print(output_t &out) const {
poly.print();
out << endl;
for (std::map<guid_t,dim_t>::const_iterator it=adapter.begin(); it != adapter.end(); it++) {
out << it->first << " -> " << it->second << endl;
}
out << "[";
for (WPoly::const_iterator it(*this); it; it++) {
for (WPoly::ConsIterator it(*this); it; it++) {
out << (*it) << "; ";
}
out << "]" << endl;
poly.print();
out << endl;
}
......@@ -178,7 +182,7 @@ WCons WPoly::back_translate(const Constraint &c) const {
for (dimension_type i = 0; i < poly.space_dimension(); i++) {
const Coefficient &coef = c.coefficient(Variable(i));
if (coef != 0) {
le = le + coef*WVar(inv[i]);
le = le + coef*WVar(inv.at(i));
}
}
le = le + c.inhomogeneous_term();
......
......@@ -4,7 +4,7 @@ LIBS=`otawa-config otawa/poly otawa/oslice --libs`
all: poly
poly: poly.cpp
c++ -o poly poly.cpp $(CXXFLAGS) $(LIBS) -march=native -O3
c++ -o poly poly.cpp $(CXXFLAGS) $(LIBS) -O0 -g
clean:
rm -f *~ core* target poly *.o target.ffx *.dot *.orange `cat tests.txt` tmp
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment