00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #ifndef opt_cfg_trans_INCLUDED
00063 #define opt_cfg_trans_INCLUDED "opt_cfg_trans.h"
00064
00065 #include <iterator>
00066 #include <set>
00067 #include <map>
00068 #include <functional>
00069
00070 #define USE_STANDARD_TYPE
00071 #include "opt_defs.h"
00072 #include <stdio.h>
00073
00074 typedef int vertex_id;
00075
00076 template <class Cluster_iterator>
00077 bool adjacent(Cluster_iterator c1, const Cluster_iterator c2) {
00078
00079 ++c1;
00080 while (c1 < c2) {
00081 if (c1->begin() != c1->end()) return false;
00082 ++c1;
00083 }
00084 return true;
00085 }
00086
00087
00088
00089
00090
00091 template <class Cluster_iterator, class Fast_iterator>
00092 class composite_iterator {
00093 public:
00094 typedef composite_iterator<Cluster_iterator, Fast_iterator> self;
00095 typedef forward_iterator_tag iterator_category;
00096 typedef typename std::iterator_traits<Fast_iterator>::value_type value_type;
00097 typedef typename std::iterator_traits<Fast_iterator>::difference_type
00098 difference_type;
00099 typedef typename std::iterator_traits<Fast_iterator>::pointer pointer;
00100 typedef typename std::iterator_traits<Fast_iterator>::reference reference;
00101
00102 Cluster_iterator ci;
00103 Fast_iterator fi;
00104
00105 inline void normalize_forward() {
00106 while (fi == (*ci).end()) {
00107 ++ci;
00108 fi = (*ci).begin();
00109 }
00110 }
00111 inline void normalize_backward() {
00112 while (fi == (*ci).begin()) {
00113 --ci;
00114 fi = (*ci).end();
00115 }
00116 }
00117
00118 public:
00119 value_type& operator*() {
00120 normalize_forward();
00121 return *fi;
00122 }
00123 self& operator++() {
00124 if (fi == (*ci).end())
00125 normalize_forward();
00126 ++fi;
00127 return *this;
00128 }
00129 self& operator--() {
00130 if (fi == (*ci).begin())
00131 normalize_backward();
00132 --fi;
00133 return *this;
00134 }
00135 self operator++(int) {
00136 self tmp = *this;
00137 if (fi == (*ci).end())
00138 normalize_forward();
00139 ++fi;
00140 return tmp;
00141 }
00142 self operator--(int) {
00143 self tmp = *this;
00144 if (fi == (*ci).begin())
00145 normalize_backward();
00146 --fi;
00147 return tmp;
00148 }
00149 self& operator+=(int distance) {
00150 while (distance > 0) {
00151 normalize_forward();
00152 int delta = min((*ci).end()-fi, distance);
00153
00154 fi += delta;
00155 distance -= delta;
00156 }
00157 return *this;
00158 }
00159 self operator-=(int distance) {
00160 while (distance > 0) {
00161 int delta = min(fi-(*ci).begin(), distance);
00162 fi -= delta;
00163 distance -= delta;
00164 if (distance > 0) {
00165
00166 normalize_backward();
00167 fi = (*ci).end();
00168 --fi;
00169 --distance;
00170 }
00171 }
00172 }
00173 friend bool adjacent(Cluster_iterator c1, const Cluster_iterator c2) {
00174
00175 ++c1;
00176 while (c1 < c2) {
00177 if (c1->begin() != c1->end()) return false;
00178 ++c1;
00179 }
00180 return true;
00181 }
00182 friend bool operator==(const self& x, const self& y) {
00183 if (x.ci == y.ci)
00184 return x.fi == y.fi;
00185 if (x.fi == (*x.ci).end())
00186 return y.fi == (*y.ci).begin() && adjacent(x.ci,y.ci);
00187 if (x.fi == (*x.ci).begin())
00188 return y.fi == (*y.ci).end() && adjacent(y.ci,x.ci);
00189 return false;
00190 }
00191
00192 Cluster_iterator cluster_iterator() const { return ci; }
00193 Fast_iterator fast_iterator() const { return fi; }
00194
00195 composite_iterator<Cluster_iterator, Fast_iterator>
00196 (Cluster_iterator t1, Fast_iterator t2):ci(t1),fi(t2){}
00197 };
00198
00199
00200
00201
00202
00203 template <class T, class IndexFunction>
00204 class cluster_vector {
00205 public:
00206 typedef typename IndexFunction::result_type cluster_id;
00207 typedef T value_type;
00208 typedef IndexFunction index_function;
00209 typedef cluster_vector<T, IndexFunction> self;
00210 typedef vector<value_type> cluster_type;
00211 typedef typename cluster_type::iterator fast_iterator;
00212 typedef typename cluster_type::size_type size_type;
00213 typedef vector<cluster_type> cluster_container;
00214 typedef typename cluster_container::iterator cluster_iterator;
00215 typedef composite_iterator<cluster_iterator, fast_iterator> iterator;
00216
00217 private:
00218 cluster_container cluster;
00219 index_function i_fun;
00220
00221 public:
00222 cluster_iterator cluster_begin() { return cluster.begin(); }
00223 cluster_iterator cluster_end() { return cluster.end(); }
00224 size_type size() const { return cluster.size(); }
00225 cluster_type& operator[](cluster_id id) {
00226 Is_True(id < cluster.size(), ("cluster_vector out-of-bound access."));
00227 return cluster[id];
00228 }
00229 cluster_id cluster_index(cluster_iterator ci) { return ci - cluster_begin(); }
00230
00231 void extend(cluster_id id) {
00232 if (id >= cluster.size())
00233 cluster.insert(cluster.end(), id - cluster.size() + 1, cluster_type());
00234 }
00235 iterator insert(const value_type& v) {
00236 cluster_id id = i_fun(v);
00237 if (id < cluster.size()) {
00238 cluster[id].push_back(v);
00239 return iterator(cluster.begin()+id, cluster[id].end()-1);
00240 }
00241
00242 extend(id);
00243 cluster[id].push_back(v);
00244 return iterator(cluster.begin()+id, cluster[id].end()-1);
00245 }
00246
00247 iterator begin() { return iterator(cluster_begin(), (*cluster_begin()).begin()); }
00248 iterator end() { return iterator(cluster_end()-1, (*(cluster_end()-1)).end()); }
00249
00250 cluster_vector() { cluster.push_back( cluster_type()); }
00251 };
00252
00253 #ifdef KEY // fix g++ 3.2 problems
00254 template <class C>
00255 bool operator!=(C x, C y) { return !(x == y); }
00256 #endif
00257
00258
00259 struct one_dimensional_container_tag {};
00260 struct two_dimensional_container_tag : public one_dimensional_container_tag {};
00261
00262 template <class Container>
00263 struct container_traits {
00264 typedef one_dimensional_container_tag container_category;
00265 };
00266
00267 template <class T, class Indexfunction>
00268 struct container_traits<cluster_vector<T, Indexfunction> > {
00269 typedef two_dimensional_container_tag container_category;
00270 };
00271
00272 template <class Container>
00273 inline typename container_traits<Container>::container_category
00274 container_category(const Container&) {
00275 typedef typename container_traits<Container>::container_category category;
00276 return category();
00277 }
00278
00279
00280
00281
00282
00283
00284
00285 template <class Graph, class Edge>
00286 Edge& add_edge(Graph& g, const Edge& e)
00287 {
00288 g.extend(first(e));
00289 g.extend(second(e));
00290 return *(g.insert(e));
00291 }
00292
00293 template <class Graph, class Forward_Iterator>
00294 void add_edge(Graph& g, Forward_Iterator first, Forward_Iterator last)
00295 {
00296 while (first != last) add_edge(g, *first++);
00297 }
00298
00299 template <class Graph, class Vertex>
00300 typename Graph::value_type *find_edge(Graph& g, Vertex from, Vertex to)
00301 {
00302 if (from >= g.size())
00303 return NULL;
00304 for (typename Graph::fast_iterator e2 = g[from].begin();
00305 e2 != g[from].end();
00306 ++e2) {
00307 if ((*e2).second == to) {
00308 return &(*e2);
00309 }
00310 }
00311 return NULL;
00312 }
00313
00314 template <class Graph, class Vertex>
00315 bool erase_edge(Graph& g, Vertex from, Vertex to)
00316 {
00317 if (from >= g.size())
00318 return false;
00319 for (typename Graph::fast_iterator e2 = g[from].begin();
00320 e2 != g[from].end();
00321 ++e2) {
00322 if ((*e2).second == to) {
00323 g[from].erase(e2);
00324 return true;
00325 }
00326 }
00327 return false;
00328 }
00329
00330
00331 template <class Graph_in, class Graph_out>
00332 void reverse_graph(Graph_in& in, Graph_out& out, one_dimensional_container_tag)
00333 {
00334
00335 for (typename Graph_in::iterator e = in.begin(); e != in.end(); ++e)
00336 add_edge(out, edge(second(*e), first(*e)));
00337 }
00338
00339 template <class Graph_in, class Graph_out>
00340 void reverse_graph(Graph_in& in, Graph_out& out, two_dimensional_container_tag)
00341 {
00342
00343 for (typename Graph_in::cluster_iterator ci = in.cluster_begin();
00344 ci != in.cluster_end();
00345 ++ci) {
00346 for (typename Graph_in::fast_iterator fi = (*ci).begin();
00347 fi != (*ci).end();
00348 ++ci)
00349 add_edge(out, edge(second(*fi), first(*fi)));
00350 }
00351 }
00352
00353
00354 template <class Graph_in, class Graph_out>
00355 inline void reverse_graph(Graph_in& in, Graph_out& out)
00356 {
00357 reverse_graph(in, out, container_category(in));
00358 }
00359
00360
00361 template <class Graph, class Vertex_id, class Insert_iterator, class Visited_set>
00362 void generate_post_order(Graph& g, Vertex_id v, Insert_iterator& ii, Visited_set& visited)
00363 {
00364 if (visited.find(v) != visited.end()) return;
00365 visited.insert(v);
00366 for (typename Graph::fast_iterator e = g[v].begin();
00367 e != g[v].end();
00368 ++e) {
00369 generate_post_order(g, second(*e), ii, visited);
00370 };
00371 *ii++ = v;
00372 }
00373
00374 typedef int vertex_id;
00375
00376 template <class Graph, class Vertex_id, class Container>
00377 void generate_post_order(Graph& g, Vertex_id root, Container& c)
00378 {
00379 c.erase(c.begin(), c.end());
00380 std::insert_iterator<Container> ii(c, c.begin());
00381 std::set<Vertex_id> visited;
00382 generate_post_order(g, root, ii, visited);
00383
00384 {
00385 typename Container::size_type middle = c.size();
00386
00387
00388 for (vertex_id i = 0; i < g.size(); ++i) {
00389 if (visited.find(i) == visited.end() && g[i].size() > 0) {
00390 generate_post_order(g, i, ii, visited);
00391 }
00392 }
00393
00394
00395 if (c.size() > middle)
00396 rotate(c.begin(), c.begin()+middle, c.end());
00397 }
00398 }
00399
00400
00401 template <class Graph, class Vertex_id>
00402 void find_reachable_vertex_set(Graph& g, Vertex_id v, vector<bool>& reachable)
00403 {
00404 if (reachable[v]) return;
00405 reachable[v] = true;
00406 for (typename Graph::fast_iterator e = g[v].begin();
00407 e != g[v].end();
00408 ++e) {
00409 find_reachable_vertex_set(g, second(*e), reachable);
00410 };
00411 }
00412
00413
00414 template <class Graph_in, class Graph_out>
00415 void subgraph(Graph_in& in, Graph_out& out, vector<bool>& vertex_set)
00416 {
00417 for (typename Graph_in::iterator e = in.begin(); e != in.end(); ++e)
00418 if (vertex_set[first(*e)] && vertex_set[second(*e)])
00419 add_edge(out, *e);
00420 }
00421
00422
00423 template <class Graph_in, class Graph_out>
00424 void copy(Graph_in& in, Graph_out& out)
00425 {
00426 for (typename Graph_in::iterator e = in.begin(); e != in.end(); ++e)
00427 add_edge(out, *e);
00428 }
00429
00430
00431 template <class Graph>
00432 void erase(Graph& g)
00433 {
00434 for (typename Graph::cluster_id i = 0; i < g.size(); ++i) {
00435 g[i].erase(g[i].begin(), g[i].end());
00436 }
00437 }
00438
00439
00440 template <class Graph, class Vertex_id, class Container>
00441 inline void generate_reverse_post_order(Graph& g, Vertex_id root, Container& c)
00442 {
00443 generate_post_order(g, root, c);
00444 reverse(c.begin(), c.end());
00445 Is_True(c[0] == root, ("generate_reverse_post_order: root is not first element"));
00446 }
00447
00448
00449
00450
00451 template <class Graph, class Vertex_id, class Container>
00452 inline void topological_sort(Graph& in, Vertex_id root, Container& out)
00453 {
00454 typedef typename Graph::value_type edge;
00455 typedef cluster_vector<edge, std::_Select1st<edge> > succ_graph;
00456 succ_graph g;
00457 copy(in, g);
00458 if (root < g.size())
00459 generate_reverse_post_order(g, root, out);
00460 }
00461
00462
00463 template <class Graph>
00464 void print_nodes(Graph& g, FILE *fp=stdout)
00465 {
00466 #ifdef KEY
00467 fprintf(fp, "number of nodes %ld: ", (long) g.size());
00468 #else
00469 fprintf(fp, "number of nodes %d: ", (INT)g.size());
00470 #endif
00471 for (typename Graph::cluster_iterator n = g.cluster_begin();
00472 n != g.cluster_end();
00473 ++n) {
00474 if ((*n).size() > 0)
00475 fprintf(fp, "%d ", g.cluster_index(n));
00476 }
00477 fprintf(fp, "\n");
00478 }
00479
00480
00481 template <class Graph>
00482 void print_edges(Graph& g, FILE *fp = stdout)
00483 {
00484 fprintf(fp, "edges: ");
00485 for (typename Graph::iterator e = g.begin(); e != g.end(); ++e)
00486 fprintf(fp, "(%d,%d) ", first(*e), second(*e));
00487 fprintf(fp, "\n");
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 struct vertex {
00503 vertex_id id;
00504 int bb_id;
00505 vertex(vertex_id v, vertex_id clone_from):id(v),bb_id(clone_from) {};
00506 };
00507
00508 struct edge {
00509 typedef edge self;
00510 typedef vertex_id first_type;
00511 typedef vertex_id second_type;
00512 vertex_id first;
00513 vertex_id second;
00514 bool must_fall_thru;
00515 friend bool operator<(const self& x, const self& y) {
00516 if (x.first < y.first) return true;
00517 if (x.first == y.first && x.second < y.second) return true;
00518 return false;
00519 }
00520 edge(vertex_id v, vertex_id w):first(v), second(w), must_fall_thru(false) {};
00521 edge(vertex_id v, vertex_id w, bool f):first(v), second(w), must_fall_thru(f) {};
00522 };
00523
00524
00525 #ifdef FUNCTION_PARTIAL_SPECIALIZATION_SUPPORT
00526
00527 template <class Edge>
00528 Edge& add_edge(vector<Edge>& g, const Edge& e)
00529 {
00530 g.push_back(e);
00531 return *(g.end()-1);
00532 }
00533
00534 #else
00535
00536
00537 inline edge& add_edge(vector<edge>& g, const edge& e)
00538 {
00539 g.push_back(e);
00540 return *(g.end()-1);
00541 }
00542
00543 #endif
00544
00545
00546 inline vertex_id first(edge e) { return e.first; }
00547 inline vertex_id second(edge e) { return e.second; }
00548
00549 typedef cluster_vector<edge, std::_Select1st<edge> > successor_graph;
00550 typedef cluster_vector<edge, std::_Select2nd<edge> > predecessor_graph;
00551
00552
00553 template <class T>
00554 struct fp_print : public std::unary_function<T, int> {
00555 FILE *fp;
00556 fp_print(FILE *f):fp(f) {}
00557 int operator()(const T& x) const { return x.print(fp); }
00558 };
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 static int unique_bb_count(vector<edge>& clone, vector<edge>& exit)
00600 {
00601 std::set<vertex_id> visited;
00602 int count = 0;
00603 int i;
00604 for (i = 0; i < clone.size(); ++i) {
00605 vertex_id target = second(clone[i]);
00606 if (visited.find(target) == visited.end()) {
00607 ++count;
00608 visited.insert(target);
00609 }
00610 }
00611 for (i = 0; i < exit.size(); ++i) {
00612 vertex_id target = first(exit[i]);
00613 if (visited.find(target) == visited.end()) {
00614 ++count;
00615 visited.insert(target);
00616 }
00617 }
00618 return count;
00619 }
00620
00621
00622 struct zone {
00623 typedef vector<edge> edge_container;
00624 typedef edge_container::iterator iterator;
00625 int id;
00626 int merged_into;
00627 bool skip;
00628 vertex_id loop_butterfly;
00629
00630 edge_container entry;
00631 edge_container clone;
00632 edge_container exit;
00633 edge_container side_entry;
00634
00635 int profit;
00636 int code_expansion_saved;
00637 int code_expansion() {
00638 if (code_expansion_saved == 0)
00639 code_expansion_saved = unique_bb_count(clone,exit);
00640 return code_expansion_saved;
00641 }
00642 double priority() {
00643 return ((double)profit)/code_expansion();
00644 }
00645 void canonicalize() {
00646 sort(entry.begin(), entry.end());
00647 sort(clone.begin(), clone.end());
00648 sort(exit.begin(), exit.end());
00649 sort(side_entry.begin(), side_entry.end());
00650 }
00651 void print(FILE *);
00652 zone(int i):
00653 id(i), merged_into(i), profit(1), code_expansion_saved(0),
00654 loop_butterfly(0), skip(false) {}
00655 };
00656
00657
00658 typedef vector<zone> zone_container;
00659 typedef zone_container::iterator zone_iterator;
00660
00661
00662
00663
00664
00665
00666 struct path_type {
00667 vector<int> bbs;
00668 double wt;
00669 vertex_id first_bb() const { return *(bbs.begin()); }
00670 vertex_id last_bb() const { return *(bbs.end()-1); }
00671 void add_bb(vertex_id v) { bbs.push_back(v); }
00672
00673 path_type() {}
00674 path_type(vertex_id v, double w):wt(w) { add_bb(v); }
00675 path_type(path_type& path):bbs(path.bbs),wt(path.wt) {}
00676 };
00677
00678 #ifndef KEY // workaround g++ 3.2 problem
00679 struct less<path_type*> {
00680 bool operator()(path_type *p1, path_type *p2) {
00681 return (*p1).wt < (*p2).wt;
00682 }
00683 };
00684 #endif
00685
00686 extern void print_path_type(path_type *, FILE *);
00687 extern void print_vertex_set(std::set<vertex_id> *, FILE *);
00688
00689
00690 class COMP_UNIT;
00691
00692
00693
00694 void generate_conditional_const_zones(COMP_UNIT *cu, successor_graph &g,
00695 zone_container& zones, bool trace);
00696 void generate_loop_butterfly_zones(COMP_UNIT *cu, successor_graph &g,
00697 zone_container& zones, int, bool trace);
00698
00699 #endif