summaryrefslogtreecommitdiff
path: root/src/loop_basic.cc
diff options
context:
space:
mode:
authorTuowen Zhao <ztuowen@gmail.com>2016-09-22 15:12:54 -0600
committerTuowen Zhao <ztuowen@gmail.com>2016-09-22 15:12:54 -0600
commit1929ac1a60615ee86779790c46e04e53de75462f (patch)
tree35566b4f04184a9aed98fdc9dda74507075a7890 /src/loop_basic.cc
parentf27e01a039195c379fd6716c4870858789941365 (diff)
downloadchill-1929ac1a60615ee86779790c46e04e53de75462f.tar.gz
chill-1929ac1a60615ee86779790c46e04e53de75462f.tar.bz2
chill-1929ac1a60615ee86779790c46e04e53de75462f.zip
add CHILL_DEBUG_PRINT & CHILL_DEBUG_BEGIN & CHILL_DEBUG_END
Diffstat (limited to 'src/loop_basic.cc')
-rw-r--r--src/loop_basic.cc1839
1 files changed, 0 insertions, 1839 deletions
diff --git a/src/loop_basic.cc b/src/loop_basic.cc
deleted file mode 100644
index a058598..0000000
--- a/src/loop_basic.cc
+++ /dev/null
@@ -1,1839 +0,0 @@
-/*
- * loop_basic.cc
- *
- * Created on: Nov 12, 2012
- * Author: anand
- */
-
-#include "loop.hh"
-#include "chill_error.hh"
-#include <omega.h>
-#include "omegatools.hh"
-#include <string.h>
-
-#include <code_gen/CG_utils.h>
-
-using namespace omega;
-
-void Loop::permute(const std::vector<int> &pi) {
- std::set<int> active;
- for (int i = 0; i < stmt.size(); i++)
- active.insert(i);
-
- permute(active, pi);
-}
-
-void Loop::original() {
- std::set<int> active;
- for (int i = 0; i < stmt.size(); i++)
- active.insert(i);
- setLexicalOrder(0, active);
- //apply_xform();
-}
-void Loop::permute(int stmt_num, int level, const std::vector<int> &pi) {
- // check for sanity of parameters
- int starting_order;
- if (stmt_num < 0 || stmt_num >= stmt.size())
- throw std::invalid_argument(
- "invalid statement number " + to_string(stmt_num));
- std::set<int> active;
- if (level < 0 || level > stmt[stmt_num].loop_level.size())
- throw std::invalid_argument("3invalid loop level " + to_string(level));
- else if (level == 0) {
- for (int i = 0; i < stmt.size(); i++)
- active.insert(i);
- level = 1;
- starting_order = 0;
- } else {
- std::vector<int> lex = getLexicalOrder(stmt_num);
- active = getStatements(lex, 2 * level - 2);
- starting_order = lex[2 * level - 2];
- lex[2 * level - 2]++;
- shiftLexicalOrder(lex, 2 * level - 2, active.size() - 1);
- }
- std::vector<int> pi_inverse(pi.size(), 0);
- for (int i = 0; i < pi.size(); i++) {
- if (pi[i] >= level + pi.size() || pi[i] < level
- || pi_inverse[pi[i] - level] != 0)
- throw std::invalid_argument("invalid permuation");
- pi_inverse[pi[i] - level] = level + i;
- }
- for (std::set<int>::iterator i = active.begin(); i != active.end(); i++)
- if (level + pi.size() - 1 > stmt[*i].loop_level.size())
- throw std::invalid_argument(
- "invalid permutation for statement " + to_string(*i));
-
- // invalidate saved codegen computation
- delete last_compute_cgr_;
- last_compute_cgr_ = NULL;
- delete last_compute_cg_;
- last_compute_cg_ = NULL;
-
- // Update transformation relations
- for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
- int n = stmt[*i].xform.n_out();
- Relation mapping(n, n);
- F_And *f_root = mapping.add_and();
- for (int j = 1; j <= 2 * level - 2; j++) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(mapping.output_var(j), 1);
- h.update_coef(mapping.input_var(j), -1);
- }
- for (int j = level; j <= level + pi.size() - 1; j++) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(mapping.output_var(2 * j), 1);
- h.update_coef(mapping.input_var(2 * pi[j - level]), -1);
- }
- for (int j = level; j <= level + pi.size() - 1; j++) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(mapping.output_var(2 * j - 1), 1);
- h.update_coef(mapping.input_var(2 * j - 1), -1);
- }
- for (int j = 2 * (level + pi.size() - 1) + 1; j <= n; j++) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(mapping.output_var(j), 1);
- h.update_coef(mapping.input_var(j), -1);
- }
- stmt[*i].xform = Composition(mapping, stmt[*i].xform);
- stmt[*i].xform.simplify();
- }
-
- // get the permuation for dependence vectors
- std::vector<int> t;
- for (int i = 0; i < pi.size(); i++)
- if (stmt[stmt_num].loop_level[pi[i] - 1].type == LoopLevelOriginal)
- t.push_back(stmt[stmt_num].loop_level[pi[i] - 1].payload);
- int max_dep_dim = -1;
- int min_dep_dim = dep.num_dim();
- for (int i = 0; i < t.size(); i++) {
- if (t[i] > max_dep_dim)
- max_dep_dim = t[i];
- if (t[i] < min_dep_dim)
- min_dep_dim = t[i];
- }
- if (min_dep_dim > max_dep_dim)
- return;
- if (max_dep_dim - min_dep_dim + 1 != t.size())
- throw loop_error("cannot update the dependence graph after permuation");
- std::vector<int> dep_pi(dep.num_dim());
- for (int i = 0; i < min_dep_dim; i++)
- dep_pi[i] = i;
- for (int i = min_dep_dim; i <= max_dep_dim; i++)
- dep_pi[i] = t[i - min_dep_dim];
- for (int i = max_dep_dim + 1; i < dep.num_dim(); i++)
- dep_pi[i] = i;
-
- dep.permute(dep_pi, active);
-
- // update the dependence graph
- DependenceGraph g(dep.num_dim());
- for (int i = 0; i < dep.vertex.size(); i++)
- g.insert();
- for (int i = 0; i < dep.vertex.size(); i++)
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[i].second.begin(); j != dep.vertex[i].second.end();
- j++) {
- if ((active.find(i) != active.end()
- && active.find(j->first) != active.end())) {
- std::vector<DependenceVector> dv = j->second;
- for (int k = 0; k < dv.size(); k++) {
- switch (dv[k].type) {
- case DEP_W2R:
- case DEP_R2W:
- case DEP_W2W:
- case DEP_R2R: {
- std::vector<coef_t> lbounds(dep.num_dim());
- std::vector<coef_t> ubounds(dep.num_dim());
- for (int d = 0; d < dep.num_dim(); d++) {
- lbounds[d] = dv[k].lbounds[dep_pi[d]];
- ubounds[d] = dv[k].ubounds[dep_pi[d]];
- }
- dv[k].lbounds = lbounds;
- dv[k].ubounds = ubounds;
- break;
- }
- case DEP_CONTROL: {
- break;
- }
- default:
- throw loop_error("unknown dependence type");
- }
- }
- g.connect(i, j->first, dv);
- } else if (active.find(i) == active.end()
- && active.find(j->first) == active.end()) {
- std::vector<DependenceVector> dv = j->second;
- g.connect(i, j->first, dv);
- } else {
- std::vector<DependenceVector> dv = j->second;
- for (int k = 0; k < dv.size(); k++)
- switch (dv[k].type) {
- case DEP_W2R:
- case DEP_R2W:
- case DEP_W2W:
- case DEP_R2R: {
- for (int d = 0; d < dep.num_dim(); d++)
- if (dep_pi[d] != d) {
- dv[k].lbounds[d] = -posInfinity;
- dv[k].ubounds[d] = posInfinity;
- }
- break;
- }
- case DEP_CONTROL:
- break;
- default:
- throw loop_error("unknown dependence type");
- }
- g.connect(i, j->first, dv);
- }
- }
- dep = g;
-
- // update loop level information
- for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
- int cur_dep_dim = min_dep_dim;
- std::vector<LoopLevel> new_loop_level(stmt[*i].loop_level.size());
- for (int j = 1; j <= stmt[*i].loop_level.size(); j++)
- if (j >= level && j < level + pi.size()) {
- switch (stmt[*i].loop_level[pi_inverse[j - level] - 1].type) {
- case LoopLevelOriginal:
- new_loop_level[j - 1].type = LoopLevelOriginal;
- new_loop_level[j - 1].payload = cur_dep_dim++;
- new_loop_level[j - 1].parallel_level =
- stmt[*i].loop_level[pi_inverse[j - level] - 1].parallel_level;
- break;
- case LoopLevelTile: {
- new_loop_level[j - 1].type = LoopLevelTile;
- int ref_level = stmt[*i].loop_level[pi_inverse[j - level]
- - 1].payload;
- if (ref_level >= level && ref_level < level + pi.size())
- new_loop_level[j - 1].payload = pi_inverse[ref_level
- - level];
- else
- new_loop_level[j - 1].payload = ref_level;
- new_loop_level[j - 1].parallel_level = stmt[*i].loop_level[j
- - 1].parallel_level;
- break;
- }
- default:
- throw loop_error(
- "unknown loop level information for statement "
- + to_string(*i));
- }
- } else {
- switch (stmt[*i].loop_level[j - 1].type) {
- case LoopLevelOriginal:
- new_loop_level[j - 1].type = LoopLevelOriginal;
- new_loop_level[j - 1].payload =
- stmt[*i].loop_level[j - 1].payload;
- new_loop_level[j - 1].parallel_level = stmt[*i].loop_level[j
- - 1].parallel_level;
- break;
- case LoopLevelTile: {
- new_loop_level[j - 1].type = LoopLevelTile;
- int ref_level = stmt[*i].loop_level[j - 1].payload;
- if (ref_level >= level && ref_level < level + pi.size())
- new_loop_level[j - 1].payload = pi_inverse[ref_level
- - level];
- else
- new_loop_level[j - 1].payload = ref_level;
- new_loop_level[j - 1].parallel_level = stmt[*i].loop_level[j
- - 1].parallel_level;
- break;
- }
- default:
- throw loop_error(
- "unknown loop level information for statement "
- + to_string(*i));
- }
- }
- stmt[*i].loop_level = new_loop_level;
- }
-
- setLexicalOrder(2 * level - 2, active, starting_order);
-}
-void Loop::permute(const std::set<int> &active, const std::vector<int> &pi) {
- if (active.size() == 0 || pi.size() == 0)
- return;
-
- // check for sanity of parameters
- int level = pi[0];
- for (int i = 1; i < pi.size(); i++)
- if (pi[i] < level)
- level = pi[i];
- if (level < 1)
- throw std::invalid_argument("invalid permuation");
- std::vector<int> reverse_pi(pi.size(), 0);
- for (int i = 0; i < pi.size(); i++)
- if (pi[i] >= level + pi.size())
- throw std::invalid_argument("invalid permutation");
- else
- reverse_pi[pi[i] - level] = i + level;
- for (int i = 0; i < reverse_pi.size(); i++)
- if (reverse_pi[i] == 0)
- throw std::invalid_argument("invalid permuation");
- int ref_stmt_num;
- std::vector<int> lex;
- for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
- if (*i < 0 || *i >= stmt.size())
- throw std::invalid_argument("invalid statement " + to_string(*i));
- if (i == active.begin()) {
- ref_stmt_num = *i;
- lex = getLexicalOrder(*i);
- } else {
- if (level + pi.size() - 1 > stmt[*i].loop_level.size())
- throw std::invalid_argument("invalid permuation");
- std::vector<int> lex2 = getLexicalOrder(*i);
- for (int j = 0; j < 2 * level - 3; j += 2)
- if (lex[j] != lex2[j])
- throw std::invalid_argument(
- "statements to permute must be in the same subloop");
- for (int j = 0; j < pi.size(); j++)
- if (!(stmt[*i].loop_level[level + j - 1].type
- == stmt[ref_stmt_num].loop_level[level + j - 1].type
- && stmt[*i].loop_level[level + j - 1].payload
- == stmt[ref_stmt_num].loop_level[level + j - 1].payload))
- throw std::invalid_argument(
- "permuted loops must have the same loop level types");
- }
- }
- // invalidate saved codegen computation
- delete last_compute_cgr_;
- last_compute_cgr_ = NULL;
- delete last_compute_cg_;
- last_compute_cg_ = NULL;
-
- // Update transformation relations
- for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
- int n = stmt[*i].xform.n_out();
- Relation mapping(n, n);
- F_And *f_root = mapping.add_and();
- for (int j = 1; j <= n; j += 2) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(mapping.output_var(j), 1);
- h.update_coef(mapping.input_var(j), -1);
- }
- for (int j = 0; j < pi.size(); j++) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(mapping.output_var(2 * (level + j)), 1);
- h.update_coef(mapping.input_var(2 * pi[j]), -1);
- }
- for (int j = 1; j < level; j++) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(mapping.output_var(2 * j), 1);
- h.update_coef(mapping.input_var(2 * j), -1);
- }
- for (int j = level + pi.size(); j <= stmt[*i].loop_level.size(); j++) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(mapping.output_var(2 * j), 1);
- h.update_coef(mapping.input_var(2 * j), -1);
- }
-
- stmt[*i].xform = Composition(mapping, stmt[*i].xform);
- stmt[*i].xform.simplify();
- }
-
- // get the permuation for dependence vectors
- std::vector<int> t;
- for (int i = 0; i < pi.size(); i++)
- if (stmt[ref_stmt_num].loop_level[pi[i] - 1].type == LoopLevelOriginal)
- t.push_back(stmt[ref_stmt_num].loop_level[pi[i] - 1].payload);
- int max_dep_dim = -1;
- int min_dep_dim = num_dep_dim;
- for (int i = 0; i < t.size(); i++) {
- if (t[i] > max_dep_dim)
- max_dep_dim = t[i];
- if (t[i] < min_dep_dim)
- min_dep_dim = t[i];
- }
- if (min_dep_dim > max_dep_dim)
- return;
- if (max_dep_dim - min_dep_dim + 1 != t.size())
- throw loop_error("cannot update the dependence graph after permuation");
- std::vector<int> dep_pi(num_dep_dim);
- for (int i = 0; i < min_dep_dim; i++)
- dep_pi[i] = i;
- for (int i = min_dep_dim; i <= max_dep_dim; i++)
- dep_pi[i] = t[i - min_dep_dim];
- for (int i = max_dep_dim + 1; i < num_dep_dim; i++)
- dep_pi[i] = i;
-
- dep.permute(dep_pi, active);
-
- // update the dependence graph
- DependenceGraph g(dep.num_dim());
- for (int i = 0; i < dep.vertex.size(); i++)
- g.insert();
- for (int i = 0; i < dep.vertex.size(); i++)
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[i].second.begin(); j != dep.vertex[i].second.end();
- j++) { //
- if ((active.find(i) != active.end()
- && active.find(j->first) != active.end())) {
- std::vector<DependenceVector> dv = j->second;
- for (int k = 0; k < dv.size(); k++) {
- switch (dv[k].type) {
- case DEP_W2R:
- case DEP_R2W:
- case DEP_W2W:
- case DEP_R2R: {
- std::vector<coef_t> lbounds(num_dep_dim);
- std::vector<coef_t> ubounds(num_dep_dim);
- for (int d = 0; d < num_dep_dim; d++) {
- lbounds[d] = dv[k].lbounds[dep_pi[d]];
- ubounds[d] = dv[k].ubounds[dep_pi[d]];
- }
- dv[k].lbounds = lbounds;
- dv[k].ubounds = ubounds;
- break;
- }
- case DEP_CONTROL: {
- break;
- }
- default:
- throw loop_error("unknown dependence type");
- }
- }
- g.connect(i, j->first, dv);
- } else if (active.find(i) == active.end()
- && active.find(j->first) == active.end()) {
- std::vector<DependenceVector> dv = j->second;
- g.connect(i, j->first, dv);
- } else {
- std::vector<DependenceVector> dv = j->second;
- for (int k = 0; k < dv.size(); k++)
- switch (dv[k].type) {
- case DEP_W2R:
- case DEP_R2W:
- case DEP_W2W:
- case DEP_R2R: {
- for (int d = 0; d < num_dep_dim; d++)
- if (dep_pi[d] != d) {
- dv[k].lbounds[d] = -posInfinity;
- dv[k].ubounds[d] = posInfinity;
- }
- break;
- }
- case DEP_CONTROL:
- break;
- default:
- throw loop_error("unknown dependence type");
- }
- g.connect(i, j->first, dv);
- }
- }
- dep = g;
-
- // update loop level information
- for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
- int cur_dep_dim = min_dep_dim;
- std::vector<LoopLevel> new_loop_level(stmt[*i].loop_level.size());
- for (int j = 1; j <= stmt[*i].loop_level.size(); j++)
- if (j >= level && j < level + pi.size()) {
- switch (stmt[*i].loop_level[reverse_pi[j - level] - 1].type) {
- case LoopLevelOriginal:
- new_loop_level[j - 1].type = LoopLevelOriginal;
- new_loop_level[j - 1].payload = cur_dep_dim++;
- new_loop_level[j - 1].parallel_level =
- stmt[*i].loop_level[reverse_pi[j - level] - 1].parallel_level;
- break;
- case LoopLevelTile: {
- new_loop_level[j - 1].type = LoopLevelTile;
- int ref_level = stmt[*i].loop_level[reverse_pi[j - level]-1].payload;
- if (ref_level >= level && ref_level < level + pi.size())
- new_loop_level[j - 1].payload = reverse_pi[ref_level
- - level];
- else
- new_loop_level[j - 1].payload = ref_level;
- new_loop_level[j - 1].parallel_level =
- stmt[*i].loop_level[reverse_pi[j - level] - 1].parallel_level;
- break;
- }
- default:
- throw loop_error(
- "unknown loop level information for statement "
- + to_string(*i));
- }
- } else {
- switch (stmt[*i].loop_level[j - 1].type) {
- case LoopLevelOriginal:
- new_loop_level[j - 1].type = LoopLevelOriginal;
- new_loop_level[j - 1].payload =
- stmt[*i].loop_level[j - 1].payload;
- new_loop_level[j - 1].parallel_level = stmt[*i].loop_level[j
- - 1].parallel_level;
- break;
- case LoopLevelTile: {
- new_loop_level[j - 1].type = LoopLevelTile;
- int ref_level = stmt[*i].loop_level[j - 1].payload;
- if (ref_level >= level && ref_level < level + pi.size())
- new_loop_level[j - 1].payload = reverse_pi[ref_level
- - level];
- else
- new_loop_level[j - 1].payload = ref_level;
- new_loop_level[j - 1].parallel_level = stmt[*i].loop_level[j
- - 1].parallel_level;
- break;
- }
- default:
- throw loop_error(
- "unknown loop level information for statement "
- + to_string(*i));
- }
- }
- stmt[*i].loop_level = new_loop_level;
- }
-
- setLexicalOrder(2 * level - 2, active);
-}
-
-
-void Loop::set_array_size(std::string name, int size ){
- array_dims.insert(std::pair<std::string, int >(name, size));
-}
-
-
-std::set<int> Loop::split(int stmt_num, int level, const Relation &cond) {
- // check for sanity of parameters
- if (stmt_num < 0 || stmt_num >= stmt.size())
- throw std::invalid_argument("invalid statement " + to_string(stmt_num));
- if (level <= 0 || level > stmt[stmt_num].loop_level.size())
- throw std::invalid_argument("4invalid loop level " + to_string(level));
-
- std::set<int> result;
- int dim = 2 * level - 1;
- std::vector<int> lex = getLexicalOrder(stmt_num);
- std::set<int> same_loop = getStatements(lex, dim - 1);
-
- Relation cond2 = copy(cond);
- cond2.simplify();
- cond2 = EQs_to_GEQs(cond2);
- Conjunct *c = cond2.single_conjunct();
- int cur_lex = lex[dim - 1];
-
- for (GEQ_Iterator gi(c->GEQs()); gi; gi++) {
- int max_level = (*gi).max_tuple_pos();
- Relation single_cond(max_level);
- single_cond.and_with_GEQ(*gi);
-
- // TODO: should decide where to place newly created statements with
- // complementary split condition from dependence graph.
- bool place_after;
- if (max_level == 0)
- place_after = true;
- else if ((*gi).get_coef(cond2.set_var(max_level)) < 0)
- place_after = true;
- else
- place_after = false;
-
- bool temp_place_after; // = place_after;
- bool assigned = false;
- int part1_to_part2;
- int part2_to_part1;
- // original statements with split condition,
- // new statements with complement of split condition
- int old_num_stmt = stmt.size();
- std::map<int, int> what_stmt_num;
- apply_xform(same_loop);
- for (std::set<int>::iterator i = same_loop.begin();
- i != same_loop.end(); i++) {
- int n = stmt[*i].IS.n_set();
- Relation part1, part2;
- if (max_level > n) {
- part1 = copy(stmt[*i].IS);
- part2 = Relation::False(0);
- } else {
- part1 = Intersection(copy(stmt[*i].IS),
- Extend_Set(copy(single_cond), n - max_level));
- part2 = Intersection(copy(stmt[*i].IS),
- Extend_Set(Complement(copy(single_cond)),
- n - max_level));
- }
-
- //split dependence check
-
- if (max_level > level) {
-
- DNF_Iterator di1(stmt[*i].IS.query_DNF());
- DNF_Iterator di2(part1.query_DNF());
- for (; di1 && di2; di1++, di2++) {
- //printf("In next conjunct,\n");
- EQ_Iterator ei1 = (*di1)->EQs();
- EQ_Iterator ei2 = (*di2)->EQs();
- for (; ei1 && ei2; ei1++, ei2++) {
- //printf(" In next equality constraint,\n");
- Constr_Vars_Iter cvi1(*ei1);
- Constr_Vars_Iter cvi2(*ei2);
- int dimension = (*cvi1).var->get_position();
- int same = 0;
- bool identical = false;
- if (identical = !strcmp((*cvi1).var->char_name(),
- (*cvi2).var->char_name())) {
-
- for (; cvi1 && cvi2; cvi1++, cvi2++) {
-
- if (((*cvi1).coef != (*cvi2).coef
- || (*ei1).get_const()
- != (*ei2).get_const())
- || (strcmp((*cvi1).var->char_name(),
- (*cvi2).var->char_name()))) {
-
- same++;
- }
- }
- }
- if ((same != 0) || !identical) {
-
- dimension = dimension - 1;
-
- while (stmt[*i].loop_level[dimension].type
- == LoopLevelTile)
- dimension =
- stmt[*i].loop_level[dimension].payload;
-
- dimension = stmt[*i].loop_level[dimension].payload;
-
- for (int i = 0; i < stmt.size(); i++) {
- std::vector<std::pair<int, DependenceVector> > D;
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[i].second.begin();
- j != dep.vertex[i].second.end(); j++) {
- for (int k = 0; k < j->second.size(); k++) {
- DependenceVector dv = j->second[k];
- if (dv.type != DEP_CONTROL)
- if (dv.hasNegative(dimension)
- && !dv.quasi)
- throw loop_error(
- "loop error: Split is illegal, dependence violation!");
-
- }
- }
- }
-
- }
-
- GEQ_Iterator gi1 = (*di1)->GEQs();
- GEQ_Iterator gi2 = (*di2)->GEQs();
-
- for (; gi1 && gi2; gi++, gi2++) {
-
- Constr_Vars_Iter cvi1(*gi1);
- Constr_Vars_Iter cvi2(*gi2);
- int dimension = (*cvi1).var->get_position();
- int same = 0;
- bool identical = false;
- if (identical = !strcmp((*cvi1).var->char_name(),
- (*cvi2).var->char_name())) {
-
- for (; cvi1 && cvi2; cvi1++, cvi2++) {
-
- if (((*cvi1).coef != (*cvi2).coef
- || (*gi1).get_const()
- != (*gi2).get_const())
- || (strcmp((*cvi1).var->char_name(),
- (*cvi2).var->char_name()))) {
-
- same++;
- }
- }
- }
- if ((same != 0) || !identical) {
- dimension = dimension - 1;
-
- while (stmt[*i].loop_level[dimension].type
- == LoopLevelTile)
- stmt[*i].loop_level[dimension].payload;
-
- dimension =
- stmt[*i].loop_level[dimension].payload;
-
- for (int i = 0; i < stmt.size(); i++) {
- std::vector<std::pair<int, DependenceVector> > D;
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[i].second.begin();
- j != dep.vertex[i].second.end();
- j++) {
- for (int k = 0; k < j->second.size();
- k++) {
- DependenceVector dv = j->second[k];
- if (dv.type != DEP_CONTROL)
- if (dv.hasNegative(dimension)
- && !dv.quasi)
-
- throw loop_error(
- "loop error: Split is illegal, dependence violation!");
-
- }
- }
- }
-
- }
-
- }
-
- }
-
- }
-
- DNF_Iterator di3(stmt[*i].IS.query_DNF());
- DNF_Iterator di4(part2.query_DNF()); //
- for (; di3 && di4; di3++, di4++) {
- EQ_Iterator ei1 = (*di3)->EQs();
- EQ_Iterator ei2 = (*di4)->EQs();
- for (; ei1 && ei2; ei1++, ei2++) {
- Constr_Vars_Iter cvi1(*ei1);
- Constr_Vars_Iter cvi2(*ei2);
- int dimension = (*cvi1).var->get_position();
- int same = 0;
- bool identical = false;
- if (identical = !strcmp((*cvi1).var->char_name(),
- (*cvi2).var->char_name())) {
-
- for (; cvi1 && cvi2; cvi1++, cvi2++) {
-
- if (((*cvi1).coef != (*cvi2).coef
- || (*ei1).get_const()
- != (*ei2).get_const())
- || (strcmp((*cvi1).var->char_name(),
- (*cvi2).var->char_name()))) {
-
- same++;
- }
- }
- }
- if ((same != 0) || !identical) {
- dimension = dimension - 1;
-
- while (stmt[*i].loop_level[dimension].type
- == LoopLevelTile)
- stmt[*i].loop_level[dimension].payload;
-
- dimension = stmt[*i].loop_level[dimension].payload;
-
- for (int i = 0; i < stmt.size(); i++) {
- std::vector<std::pair<int, DependenceVector> > D;
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[i].second.begin();
- j != dep.vertex[i].second.end(); j++) {
- for (int k = 0; k < j->second.size(); k++) {
- DependenceVector dv = j->second[k];
- if (dv.type != DEP_CONTROL)
- if (dv.hasNegative(dimension)
- && !dv.quasi)
-
- throw loop_error(
- "loop error: Split is illegal, dependence violation!");
-
- }
- }
- }
-
- }
-
- }
- GEQ_Iterator gi1 = (*di3)->GEQs();
- GEQ_Iterator gi2 = (*di4)->GEQs();
-
- for (; gi1 && gi2; gi++, gi2++) {
- Constr_Vars_Iter cvi1(*gi1);
- Constr_Vars_Iter cvi2(*gi2);
- int dimension = (*cvi1).var->get_position();
- int same = 0;
- bool identical = false;
- if (identical = !strcmp((*cvi1).var->char_name(),
- (*cvi2).var->char_name())) {
-
- for (; cvi1 && cvi2; cvi1++, cvi2++) {
-
- if (((*cvi1).coef != (*cvi2).coef
- || (*gi1).get_const()
- != (*gi2).get_const())
- || (strcmp((*cvi1).var->char_name(),
- (*cvi2).var->char_name()))) {
-
- same++;
- }
- }
- }
- if ((same != 0) || !identical) {
- dimension = dimension - 1;
-
- while (stmt[*i].loop_level[dimension].type //
- == LoopLevelTile)
- stmt[*i].loop_level[dimension].payload;
-
- dimension = stmt[*i].loop_level[dimension].payload;
-
- for (int i = 0; i < stmt.size(); i++) {
- std::vector<std::pair<int, DependenceVector> > D;
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[i].second.begin();
- j != dep.vertex[i].second.end(); j++) {
- for (int k = 0; k < j->second.size(); k++) {
- DependenceVector dv = j->second[k];
- if (dv.type != DEP_CONTROL)
- if (dv.hasNegative(dimension)
- && !dv.quasi)
-
- throw loop_error(
- "loop error: Split is illegal, dependence violation!");
-
- }
- }
- }
-
- }
-
- }
-
- }
-
- }
-
- stmt[*i].IS = part1;
-
- int n1 = part2.n_set();
- int m = this->known.n_set();
- Relation test;
- if(m > n1)
- test = Intersection(copy(this->known),
- Extend_Set(copy(part2), m - part2.n_set()));
- else
- test = Intersection(copy(part2),
- Extend_Set(copy(this->known), n1 - this->known.n_set()));
-
- if (test.is_upper_bound_satisfiable()) {
- Statement new_stmt;
- new_stmt.code = stmt[*i].code->clone();
- new_stmt.IS = part2;
- new_stmt.xform = copy(stmt[*i].xform);
- new_stmt.ir_stmt_node = NULL;
- new_stmt.loop_level = stmt[*i].loop_level;
-
- new_stmt.has_inspector = stmt[*i].has_inspector;
- new_stmt.reduction = stmt[*i].reduction;
- new_stmt.reductionOp = stmt[*i].reductionOp;
-
- stmt_nesting_level_.push_back(stmt_nesting_level_[*i]);
-
-
- if (place_after)
- assign_const(new_stmt.xform, dim - 1, cur_lex + 1);
- else
- assign_const(new_stmt.xform, dim - 1, cur_lex - 1);
-
- fprintf(stderr, "loop_basic.cc L828 adding stmt %d\n", stmt.size());
- stmt.push_back(new_stmt);
-
- uninterpreted_symbols.push_back(uninterpreted_symbols[stmt_num]);
- uninterpreted_symbols_stringrepr.push_back(uninterpreted_symbols_stringrepr[stmt_num]);
- dep.insert();
- what_stmt_num[*i] = stmt.size() - 1;
- if (*i == stmt_num)
- result.insert(stmt.size() - 1);
- }
-
- }
- // make adjacent lexical number available for new statements
- if (place_after) {
- lex[dim - 1] = cur_lex + 1;
- shiftLexicalOrder(lex, dim - 1, 1);
- } else {
- lex[dim - 1] = cur_lex - 1;
- shiftLexicalOrder(lex, dim - 1, -1);
- }
- // update dependence graph
- int dep_dim = get_dep_dim_of(stmt_num, level);
- for (int i = 0; i < old_num_stmt; i++) {
- std::vector<std::pair<int, std::vector<DependenceVector> > > D;
-
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[i].second.begin();
- j != dep.vertex[i].second.end(); j++) {
- if (same_loop.find(i) != same_loop.end()) {
- if (same_loop.find(j->first) != same_loop.end()) {
- if (what_stmt_num.find(i) != what_stmt_num.end()
- && what_stmt_num.find(j->first)
- != what_stmt_num.end())
- dep.connect(what_stmt_num[i],
- what_stmt_num[j->first], j->second);
- if (place_after
- && what_stmt_num.find(j->first)
- != what_stmt_num.end()) {
- std::vector<DependenceVector> dvs;
- for (int k = 0; k < j->second.size(); k++) {
- DependenceVector dv = j->second[k];
- if (dv.is_data_dependence() && dep_dim != -1) {
- dv.lbounds[dep_dim] = -posInfinity;
- dv.ubounds[dep_dim] = posInfinity;
- }
- dvs.push_back(dv);
- }
- if (dvs.size() > 0)
- D.push_back(
- std::make_pair(what_stmt_num[j->first],
- dvs));
- } else if (!place_after
- && what_stmt_num.find(i)
- != what_stmt_num.end()) {
- std::vector<DependenceVector> dvs;
- for (int k = 0; k < j->second.size(); k++) {
- DependenceVector dv = j->second[k];
- if (dv.is_data_dependence() && dep_dim != -1) {
- dv.lbounds[dep_dim] = -posInfinity;
- dv.ubounds[dep_dim] = posInfinity;
- }
- dvs.push_back(dv);
- }
- if (dvs.size() > 0)
- dep.connect(what_stmt_num[i], j->first, dvs);
-
- }
- } else {
- if (what_stmt_num.find(i) != what_stmt_num.end())
- dep.connect(what_stmt_num[i], j->first, j->second);
- }
- } else if (same_loop.find(j->first) != same_loop.end()) {
- if (what_stmt_num.find(j->first) != what_stmt_num.end())
- D.push_back(
- std::make_pair(what_stmt_num[j->first],
- j->second));
- }
- }
-
- for (int j = 0; j < D.size(); j++)
- dep.connect(i, D[j].first, D[j].second);
- }
-
- }
-
- return result;
-}
-
-void Loop::skew(const std::set<int> &stmt_nums, int level,
- const std::vector<int> &skew_amount) {
- if (stmt_nums.size() == 0)
- return;
-
- // check for sanity of parameters
- int ref_stmt_num = *(stmt_nums.begin());
- for (std::set<int>::const_iterator i = stmt_nums.begin();
- i != stmt_nums.end(); i++) {
- if (*i < 0 || *i >= stmt.size())
- throw std::invalid_argument(
- "invalid statement number " + to_string(*i));
- if (level < 1 || level > stmt[*i].loop_level.size())
- throw std::invalid_argument(
- "5invalid loop level " + to_string(level));
- for (int j = stmt[*i].loop_level.size(); j < skew_amount.size(); j++)
- if (skew_amount[j] != 0)
- throw std::invalid_argument("invalid skewing formula");
- }
-
- // invalidate saved codegen computation
- delete last_compute_cgr_;
- last_compute_cgr_ = NULL;
- delete last_compute_cg_;
- last_compute_cg_ = NULL;
-
- // set trasformation relations
- for (std::set<int>::const_iterator i = stmt_nums.begin();
- i != stmt_nums.end(); i++) {
- int n = stmt[*i].xform.n_out();
- Relation r(n, n);
- F_And *f_root = r.add_and();
- for (int j = 1; j <= n; j++)
- if (j != 2 * level) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(r.input_var(j), 1);
- h.update_coef(r.output_var(j), -1);
- }
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(r.output_var(2 * level), -1);
- for (int j = 0; j < skew_amount.size(); j++)
- if (skew_amount[j] != 0)
- h.update_coef(r.input_var(2 * (j + 1)), skew_amount[j]);
-
- stmt[*i].xform = Composition(r, stmt[*i].xform);
- stmt[*i].xform.simplify();
- }
-
- // update dependence graph
- if (stmt[ref_stmt_num].loop_level[level - 1].type == LoopLevelOriginal) {
- int dep_dim = stmt[ref_stmt_num].loop_level[level - 1].payload;
- for (std::set<int>::const_iterator i = stmt_nums.begin();
- i != stmt_nums.end(); i++)
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[*i].second.begin();
- j != dep.vertex[*i].second.end(); j++)
- if (stmt_nums.find(j->first) != stmt_nums.end()) {
- // dependence between skewed statements
- std::vector<DependenceVector> dvs = j->second;
- for (int k = 0; k < dvs.size(); k++) {
- DependenceVector &dv = dvs[k];
- if (dv.is_data_dependence()) {
- coef_t lb = 0;
- coef_t ub = 0;
- for (int kk = 0; kk < skew_amount.size(); kk++) {
- int cur_dep_dim = get_dep_dim_of(*i, kk + 1);
- if (skew_amount[kk] > 0) {
- if (lb != -posInfinity
- && stmt[*i].loop_level[kk].type == LoopLevelOriginal
- && dv.lbounds[cur_dep_dim] != -posInfinity)
- lb += skew_amount[kk] * dv.lbounds[cur_dep_dim];
- else {
- if (cur_dep_dim != -1
- && !(dv.lbounds[cur_dep_dim] == 0
- && dv.ubounds[cur_dep_dim]== 0))
- lb = -posInfinity;
- }
- if (ub != posInfinity
- && stmt[*i].loop_level[kk].type == LoopLevelOriginal
- && dv.ubounds[cur_dep_dim] != posInfinity)
- ub += skew_amount[kk] * dv.ubounds[cur_dep_dim];
- else {
- if (cur_dep_dim != -1
- && !(dv.lbounds[cur_dep_dim] == 0
- && dv.ubounds[cur_dep_dim] == 0))
- ub = posInfinity;
- }
- } else if (skew_amount[kk] < 0) {
- if (lb != -posInfinity
- && stmt[*i].loop_level[kk].type == LoopLevelOriginal
- && dv.ubounds[cur_dep_dim] != posInfinity)
- lb += skew_amount[kk] * dv.ubounds[cur_dep_dim];
- else {
- if (cur_dep_dim != -1
- && !(dv.lbounds[cur_dep_dim] == 0
- && dv.ubounds[cur_dep_dim] == 0))
- lb = -posInfinity;
- }
- if (ub != posInfinity
- && stmt[*i].loop_level[kk].type == LoopLevelOriginal
- && dv.lbounds[cur_dep_dim] != -posInfinity)
- ub += skew_amount[kk] * dv.lbounds[cur_dep_dim];
- else {
- if (cur_dep_dim != -1
- && !(dv.lbounds[cur_dep_dim] == 0
- && dv.ubounds[cur_dep_dim] == 0))
- ub = posInfinity;
- }
- }
- }
- dv.lbounds[dep_dim] = lb;
- dv.ubounds[dep_dim] = ub;
- if ((dv.isCarried(dep_dim) && dv.hasPositive(dep_dim))
- && dv.quasi)
- dv.quasi = false;
-
- if ((dv.isCarried(dep_dim) && dv.hasNegative(dep_dim))
- && !dv.quasi)
- throw loop_error(
- "loop error: Skewing is illegal, dependence violation!");
- dv.lbounds[dep_dim] = lb;
- dv.ubounds[dep_dim] = ub;
- if ((dv.isCarried(dep_dim)
- && dv.hasPositive(dep_dim)) && dv.quasi)
- dv.quasi = false;
-
- if ((dv.isCarried(dep_dim)
- && dv.hasNegative(dep_dim)) && !dv.quasi)
- throw loop_error(
- "loop error: Skewing is illegal, dependence violation!");
- }
- }
- j->second = dvs;
- } else {
- // dependence from skewed statement to unskewed statement becomes jumbled,
- // put distance value at skewed dimension to unknown
- std::vector<DependenceVector> dvs = j->second;
- for (int k = 0; k < dvs.size(); k++) {
- DependenceVector &dv = dvs[k];
- if (dv.is_data_dependence()) {
- dv.lbounds[dep_dim] = -posInfinity;
- dv.ubounds[dep_dim] = posInfinity;
- }
- }
- j->second = dvs;
- }
- for (int i = 0; i < dep.vertex.size(); i++)
- if (stmt_nums.find(i) == stmt_nums.end())
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[i].second.begin();
- j != dep.vertex[i].second.end(); j++)
- if (stmt_nums.find(j->first) != stmt_nums.end()) {
- // dependence from unskewed statement to skewed statement becomes jumbled,
- // put distance value at skewed dimension to unknown
- std::vector<DependenceVector> dvs = j->second;
- for (int k = 0; k < dvs.size(); k++) {
- DependenceVector &dv = dvs[k];
- if (dv.is_data_dependence()) {
- dv.lbounds[dep_dim] = -posInfinity;
- dv.ubounds[dep_dim] = posInfinity;
- }
- }
- j->second = dvs;
- }
- }
-}
-
-
-void Loop::shift(const std::set<int> &stmt_nums, int level, int shift_amount) {
- if (stmt_nums.size() == 0)
- return;
-
- // check for sanity of parameters
- int ref_stmt_num = *(stmt_nums.begin());
- for (std::set<int>::const_iterator i = stmt_nums.begin();
- i != stmt_nums.end(); i++) {
- if (*i < 0 || *i >= stmt.size())
- throw std::invalid_argument(
- "invalid statement number " + to_string(*i));
- if (level < 1 || level > stmt[*i].loop_level.size())
- throw std::invalid_argument(
- "6invalid loop level " + to_string(level));
- }
-
- // do nothing
- if (shift_amount == 0)
- return;
-
- // invalidate saved codegen computation
- delete last_compute_cgr_;
- last_compute_cgr_ = NULL;
- delete last_compute_cg_;
- last_compute_cg_ = NULL;
-
- // set trasformation relations
- for (std::set<int>::const_iterator i = stmt_nums.begin();
- i != stmt_nums.end(); i++) {
- int n = stmt[*i].xform.n_out();
-
- Relation r(n, n);
- F_And *f_root = r.add_and();
- for (int j = 1; j <= n; j++) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(r.input_var(j), 1);
- h.update_coef(r.output_var(j), -1);
- if (j == 2 * level)
- h.update_const(shift_amount);
- }
-
- stmt[*i].xform = Composition(r, stmt[*i].xform);
- stmt[*i].xform.simplify();
- }
-
- // update dependence graph
- if (stmt[ref_stmt_num].loop_level[level - 1].type == LoopLevelOriginal) {
- int dep_dim = stmt[ref_stmt_num].loop_level[level - 1].payload;
- for (std::set<int>::const_iterator i = stmt_nums.begin();
- i != stmt_nums.end(); i++)
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[*i].second.begin();
- j != dep.vertex[*i].second.end(); j++)
- if (stmt_nums.find(j->first) == stmt_nums.end()) {
- // dependence from shifted statement to unshifted statement
- std::vector<DependenceVector> dvs = j->second;
- for (int k = 0; k < dvs.size(); k++) {
- DependenceVector &dv = dvs[k];
- if (dv.is_data_dependence()) {
- if (dv.lbounds[dep_dim] != -posInfinity)
- dv.lbounds[dep_dim] -= shift_amount;
- if (dv.ubounds[dep_dim] != posInfinity)
- dv.ubounds[dep_dim] -= shift_amount;
- }
- }
- j->second = dvs;
- }
- for (int i = 0; i < dep.vertex.size(); i++)
- if (stmt_nums.find(i) == stmt_nums.end())
- for (DependenceGraph::EdgeList::iterator j =
- dep.vertex[i].second.begin();
- j != dep.vertex[i].second.end(); j++)
- if (stmt_nums.find(j->first) != stmt_nums.end()) {
- // dependence from unshifted statement to shifted statement
- std::vector<DependenceVector> dvs = j->second;
- for (int k = 0; k < dvs.size(); k++) {
- DependenceVector &dv = dvs[k];
- if (dv.is_data_dependence()) {
- if (dv.lbounds[dep_dim] != -posInfinity)
- dv.lbounds[dep_dim] += shift_amount;
- if (dv.ubounds[dep_dim] != posInfinity)
- dv.ubounds[dep_dim] += shift_amount;
- }
- }
- j->second = dvs;
- }
- }
-}
-
-void Loop::scale(const std::set<int> &stmt_nums, int level, int scale_amount) {
- std::vector<int> skew_amount(level, 0);
- skew_amount[level - 1] = scale_amount;
- skew(stmt_nums, level, skew_amount);
-}
-
-void Loop::reverse(const std::set<int> &stmt_nums, int level) {
- scale(stmt_nums, level, -1);
-}
-
-void Loop::fuse(const std::set<int> &stmt_nums, int level) {
- if (stmt_nums.size() == 0 || stmt_nums.size() == 1)
- return;
-
- // invalidate saved codegen computation
- delete last_compute_cgr_;
- last_compute_cgr_ = NULL;
- delete last_compute_cg_;
- last_compute_cg_ = NULL;
-
- int dim = 2 * level - 1;
- // check for sanity of parameters
- std::vector<int> ref_lex;
- int ref_stmt_num;
- apply_xform();
- for (std::set<int>::const_iterator i = stmt_nums.begin();
- i != stmt_nums.end(); i++) {
- if (*i < 0 || *i >= stmt.size()) {
- fprintf(stderr, "statement number %d should be in [0, %d)\n", *i, stmt.size());
- throw std::invalid_argument(
- "FUSE invalid statement number " + to_string(*i));
- }
- if (level <= 0
- // || (level > (stmt[*i].xform.n_out() - 1) / 2
- // || level > stmt[*i].loop_level.size())
- ) {
- fprintf(stderr, "FUSE level %d ", level);
- fprintf(stderr, "must be greater than zero and \n");
- fprintf(stderr, "must NOT be greater than (%d - 1)/2 == %d and\n", stmt[*i].xform.n_out(), (stmt[*i].xform.n_out() - 1) / 2);
- fprintf(stderr, "must NOT be greater than %d\n", stmt[*i].loop_level.size());
- throw std::invalid_argument(
- "FUSE invalid loop level " + to_string(level));
- }
- if (ref_lex.size() == 0) {
- ref_lex = getLexicalOrder(*i);
- ref_stmt_num = *i;
- } else {
- std::vector<int> lex = getLexicalOrder(*i);
- for (int j = 0; j < dim - 1; j += 2)
- if (lex[j] != ref_lex[j])
- throw std::invalid_argument(
- "statements for fusion must be in the same level-"
- + to_string(level - 1) + " subloop");
- }
- }
-
- // collect lexicographical order values from to-be-fused statements
- std::set<int> lex_values;
- for (std::set<int>::const_iterator i = stmt_nums.begin();
- i != stmt_nums.end(); i++) {
- std::vector<int> lex = getLexicalOrder(*i);
- lex_values.insert(lex[dim - 1]);
- }
- if (lex_values.size() == 1)
- return;
- // negative dependence would prevent fusion
-
- int dep_dim = get_dep_dim_of(ref_stmt_num, level);
-
- for (std::set<int>::iterator i = lex_values.begin(); i != lex_values.end();
- i++) {
- ref_lex[dim - 1] = *i;
- std::set<int> a = getStatements(ref_lex, dim - 1);
- std::set<int>::iterator j = i;
- j++;
- for (; j != lex_values.end(); j++) {
- ref_lex[dim - 1] = *j;
- std::set<int> b = getStatements(ref_lex, dim - 1);
- for (std::set<int>::iterator ii = a.begin(); ii != a.end(); ii++)
- for (std::set<int>::iterator jj = b.begin(); jj != b.end();
- jj++) {
- std::vector<DependenceVector> dvs;
- dvs = dep.getEdge(*ii, *jj);
- for (int k = 0; k < dvs.size(); k++)
- if (dvs[k].isCarried(dep_dim)
- && dvs[k].hasNegative(dep_dim))
- throw loop_error(
- "loop error: statements " + to_string(*ii)
- + " and " + to_string(*jj)
- + " cannot be fused together due to negative dependence");
- dvs = dep.getEdge(*jj, *ii);
- for (int k = 0; k < dvs.size(); k++)
- if (dvs[k].isCarried(dep_dim)
- && dvs[k].hasNegative(dep_dim))
- throw loop_error(
- "loop error: statements " + to_string(*jj)
- + " and " + to_string(*ii)
- + " cannot be fused together due to negative dependence");
- }
- }
- }
-
- std::set<int> same_loop = getStatements(ref_lex, dim - 3);
-
- std::vector<std::set<int> > s = sort_by_same_loops(same_loop, level);
-
- std::vector<bool> s2;
-
- for (int i = 0; i < s.size(); i++) {
- s2.push_back(false);
- }
-
- for (std::set<int>::iterator kk = stmt_nums.begin(); kk != stmt_nums.end();
- kk++)
- for (int i = 0; i < s.size(); i++)
- if (s[i].find(*kk) != s[i].end()) {
-
- s2[i] = true;
- }
-
- try {
-
- //Dependence Check for Ordering Constraint
- //Graph<std::set<int>, bool> dummy = construct_induced_graph_at_level(s5,
- // dep, dep_dim);
-
- Graph<std::set<int>, bool> g = construct_induced_graph_at_level(s, dep,
- dep_dim);
- std::cout << g;
- s = typed_fusion(g, s2);
- } catch (const loop_error &e) {
-
- throw loop_error(
- "statements cannot be fused together due to negative dependence");
-
- }
-
- int order = 0;
- for (int i = 0; i < s.size(); i++) {
- for (std::set<int>::iterator it = s[i].begin(); it != s[i].end(); it++) {
- assign_const(stmt[*it].xform, 2 * level - 2, order);
- }
- order++;
- }
-
-
- //plan for selective typed fusion
-
- /*
- 1. sort the lex values of the statements
- 2. construct induced graph on sorted statements
- 3. pick a node from the graph, check if it is before/after from the candidate set for fusion
- equal-> set the max fused node of this node to be the start/target node for fusion
- before -> augment and continue
-
- 4. once target node identified and is on work queue update successors and other nodes to start node
- 5. augment and continue
- 6. if all candidate nodes dont end up in start node throw error
- 7. Get nodes and update lexical values
-
- */
-
- /* for (std::set<int>::iterator kk = stmt_nums.begin(); kk != stmt_nums.end();
- kk++)
- for (int i = 0; i < s.size(); i++)
- if (s[i].find(*kk) != s[i].end()) {
- s1.insert(s[i].begin(), s[i].end());
- s2.insert(i);
- }
-
- s3.push_back(s1);
- for (int i = 0; i < s.size(); i++)
- if (s2.find(i) == s2.end()) {
- s3.push_back(s[i]);
- s4.insert(s[i].begin(), s[i].end());
- }
- try {
- std::vector<std::set<int> > s5;
- s5.push_back(s1);
- s5.push_back(s4);
-
- //Dependence Check for Ordering Constraint
- //Graph<std::set<int>, bool> dummy = construct_induced_graph_at_level(s5,
- // dep, dep_dim);
-
- Graph<std::set<int>, bool> g = construct_induced_graph_at_level(s3, dep,
- dep_dim);
- std::cout<< g;
- s = typed_fusion(g);
- } catch (const loop_error &e) {
-
- throw loop_error(
- "statements cannot be fused together due to negative dependence");
-
- }
-
- if (s3.size() == s.size()) {
- int order = 0;
- for (int i = 0; i < s.size(); i++) {
-
- for (std::set<int>::iterator it = s[i].begin(); it != s[i].end();
- it++) {
-
- assign_const(stmt[*it].xform, 2 * level - 2, order);
-
- }
-
- order++;
- }
- } else if (s3.size() > s.size()) {
-
- int order = 0;
- for (int j = 0; j < s.size(); j++) {
- std::set<int>::iterator it3;
- for (it3 = s1.begin(); it3 != s1.end(); it3++) {
- if (s[j].find(*it3) != s[j].end())
- break;
- }
- if (it3 != s1.end()) {
- for (std::set<int>::iterator it = s1.begin(); it != s1.end();
- it++)
- assign_const(stmt[*it].xform, 2 * level - 2, order);
-
- order++;
-
- }
-
- for (int i = 0; i < s3.size(); i++) {
- std::set<int>::iterator it2;
-
- for (it2 = s3[i].begin(); it2 != s3[i].end(); it2++) {
- if (s[j].find(*it2) != s[j].end())
- break;
- }
-
- if (it2 != s3[i].end()) {
- for (std::set<int>::iterator it = s3[i].begin();
- it != s3[i].end(); it++)
- assign_const(stmt[*it].xform, 2 * level - 2, order);
-
- order++;
-
- }
- }
- }
-
- } else
- throw loop_error("Typed Fusion Error");
- */
-}
-
-
-
-void Loop::distribute(const std::set<int> &stmt_nums, int level) {
- if (stmt_nums.size() == 0 || stmt_nums.size() == 1)
- return;
- fprintf(stderr, "Loop::distribute()\n");
-
-
- // invalidate saved codegen computation
- delete last_compute_cgr_;
- last_compute_cgr_ = NULL;
- delete last_compute_cg_;
- last_compute_cg_ = NULL;
- int dim = 2 * level - 1;
- int ref_stmt_num;
- // check for sanity of parameters
- std::vector<int> ref_lex;
- for (std::set<int>::const_iterator i = stmt_nums.begin();
- i != stmt_nums.end(); i++) {
- if (*i < 0 || *i >= stmt.size())
- throw std::invalid_argument(
- "invalid statement number " + to_string(*i));
-
- if (level < 1
- || (level > (stmt[*i].xform.n_out() - 1) / 2
- || level > stmt[*i].loop_level.size()))
- throw std::invalid_argument(
- "8invalid loop level " + to_string(level));
- if (ref_lex.size() == 0) {
- ref_lex = getLexicalOrder(*i);
- ref_stmt_num = *i;
- } else {
- std::vector<int> lex = getLexicalOrder(*i);
- for (int j = 0; j <= dim - 1; j += 2)
- if (lex[j] != ref_lex[j])
- throw std::invalid_argument(
- "statements for distribution must be in the same level-"
- + to_string(level) + " subloop");
- }
- }
-
- // find SCC in the to-be-distributed loop
- int dep_dim = get_dep_dim_of(ref_stmt_num, level);
- std::set<int> same_loop = getStatements(ref_lex, dim - 1);
- Graph<int, Empty> g;
- for (std::set<int>::iterator i = same_loop.begin(); i != same_loop.end();
- i++)
- g.insert(*i);
- for (int i = 0; i < g.vertex.size(); i++)
- for (int j = i + 1; j < g.vertex.size(); j++) {
- std::vector<DependenceVector> dvs;
- dvs = dep.getEdge(g.vertex[i].first, g.vertex[j].first);
- for (int k = 0; k < dvs.size(); k++)
- if (dvs[k].isCarried(dep_dim)) {
- g.connect(i, j);
- break;
- }
- dvs = dep.getEdge(g.vertex[j].first, g.vertex[i].first);
- for (int k = 0; k < dvs.size(); k++)
- if (dvs[k].isCarried(dep_dim)) {
- g.connect(j, i);
- break;
- }
- }
- std::vector<std::set<int> > s = g.topoSort();
- // find statements that cannot be distributed due to dependence cycle
- Graph<std::set<int>, Empty> g2;
- for (int i = 0; i < s.size(); i++) {
- std::set<int> t;
- for (std::set<int>::iterator j = s[i].begin(); j != s[i].end(); j++)
- if (stmt_nums.find(g.vertex[*j].first) != stmt_nums.end())
- t.insert(g.vertex[*j].first);
- if (!t.empty())
- g2.insert(t);
- }
- for (int i = 0; i < g2.vertex.size(); i++)
- for (int j = i + 1; j < g2.vertex.size(); j++)
- for (std::set<int>::iterator ii = g2.vertex[i].first.begin();
- ii != g2.vertex[i].first.end(); ii++)
- for (std::set<int>::iterator jj = g2.vertex[j].first.begin();
- jj != g2.vertex[j].first.end(); jj++) {
- std::vector<DependenceVector> dvs;
- dvs = dep.getEdge(*ii, *jj);
- for (int k = 0; k < dvs.size(); k++)
- if (dvs[k].isCarried(dep_dim)) {
- g2.connect(i, j);
- break;
- }
- dvs = dep.getEdge(*jj, *ii);
- for (int k = 0; k < dvs.size(); k++)
- if (dvs[k].isCarried(dep_dim)) {
- g2.connect(j, i);
- break;
- }
- }
- std::vector<std::set<int> > s2 = g2.topoSort();
- // nothing to distribute
- if (s2.size() == 1)
- throw loop_error(
- "loop error: no statement can be distributed due to dependence cycle");
- std::vector<std::set<int> > s3;
- for (int i = 0; i < s2.size(); i++) {
- std::set<int> t;
- for (std::set<int>::iterator j = s2[i].begin(); j != s2[i].end(); j++)
- std::set_union(t.begin(), t.end(), g2.vertex[*j].first.begin(),
- g2.vertex[*j].first.end(), inserter(t, t.begin()));
- s3.push_back(t);
- }
- // associate other affected statements with the right distributed statements
- for (std::set<int>::iterator i = same_loop.begin(); i != same_loop.end();
- i++)
- if (stmt_nums.find(*i) == stmt_nums.end()) {
- bool is_inserted = false;
- int potential_insertion_point = 0;
- for (int j = 0; j < s3.size(); j++) {
- for (std::set<int>::iterator k = s3[j].begin();
- k != s3[j].end(); k++) {
- std::vector<DependenceVector> dvs;
- dvs = dep.getEdge(*i, *k);
- for (int kk = 0; kk < dvs.size(); kk++)
- if (dvs[kk].isCarried(dep_dim)) {
- s3[j].insert(*i);
- is_inserted = true;
- break;
- }
- dvs = dep.getEdge(*k, *i);
- for (int kk = 0; kk < dvs.size(); kk++)
- if (dvs[kk].isCarried(dep_dim))
- potential_insertion_point = j;
- }
- if (is_inserted)
- break;
- }
- if (!is_inserted)
- s3[potential_insertion_point].insert(*i);
- }
- // set lexicographical order after distribution
- int order = ref_lex[dim - 1];
- shiftLexicalOrder(ref_lex, dim - 1, s3.size() - 1);
- for (std::vector<std::set<int> >::iterator i = s3.begin(); i != s3.end();
- i++) {
- for (std::set<int>::iterator j = (*i).begin(); j != (*i).end(); j++)
- assign_const(stmt[*j].xform, dim - 1, order);
- order++;
- }
- // no need to update dependence graph
-
- return;
-}
-
-
-
-
-std::vector<IR_ArrayRef *> FindOuterArrayRefs(IR_Code *ir,
- std::vector<IR_ArrayRef *> &arr_refs) {
- std::vector<IR_ArrayRef *> to_return;
- for (int i = 0; i < arr_refs.size(); i++)
- if (!ir->parent_is_array(arr_refs[i])) {
- int j;
- for (j = 0; j < to_return.size(); j++)
- if (*to_return[j] == *arr_refs[i])
- break;
- if (j == to_return.size())
- to_return.push_back(arr_refs[i]);
- }
- return to_return;
-}
-
-
-
-
-
-std::vector<std::vector<std::string> > constructInspectorVariables(IR_Code *ir,
- std::set<IR_ArrayRef *> &arr, std::vector<std::string> &index) {
-
- fprintf(stderr, "constructInspectorVariables()\n");
-
- std::vector<std::vector<std::string> > to_return;
-
- for (std::set<IR_ArrayRef *>::iterator i = arr.begin(); i != arr.end();
- i++) {
-
- std::vector<std::string> per_index;
-
- CG_outputRepr *subscript = (*i)->index(0);
-
- if ((*i)->n_dim() > 1)
- throw ir_error(
- "multi-dimensional array support non-existent for flattening currently");
-
- while (ir->QueryExpOperation(subscript) == IR_OP_ARRAY_VARIABLE) {
-
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(subscript);
-
- IR_ArrayRef *ref = static_cast<IR_ArrayRef *>(ir->Repr2Ref(v[0]));
- //per_index.push_back(ref->name());
-
- subscript = ref->index(0);
-
- }
-
- if (ir->QueryExpOperation(subscript) == IR_OP_VARIABLE) {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(subscript);
- IR_ScalarRef *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0]));
- per_index.push_back(ref->name());
- int j;
- for (j = 0; j < index.size(); j++)
- if (index[j] == ref->name())
- break;
-
- if (j == index.size())
- throw ir_error("Non index variable in array expression");
-
- int k;
- for (k = 0; k < to_return.size(); k++)
- if (to_return[k][0] == ref->name())
- break;
- if (k == to_return.size()) {
- to_return.push_back(per_index);
- fprintf(stderr, "adding index %s\n", ref->name().c_str());
- }
-
- }
-
- }
-
- return to_return;
-
-}
-
-/*std::vector<CG_outputRepr *> constructInspectorData(IR_Code *ir, std::vector<std::vector<std::string> > &indices){
-
- std::vector<CG_outputRepr *> to_return;
-
- for(int i =0; i < indices.size(); i++)
- ir->CreateVariableDeclaration(indices[i][0]);
- return to_return;
- }
-
-
- CG_outputRepr* constructInspectorFunction(IR_Code* ir, std::vector<std::vector<std::string> > &indices){
-
- CG_outputRepr *to_return;
-
-
-
- return to_return;
- }
-
-*/
-
-CG_outputRepr * checkAndGenerateIndirectMappings(CG_outputBuilder * ocg,
- std::vector<std::vector<std::string> > &indices,
- CG_outputRepr * instance, CG_outputRepr * class_def,
- CG_outputRepr * count_var) {
-
- CG_outputRepr *to_return = NULL;
-
- for (int i = 0; i < indices.size(); i++)
- if (indices[i].size() > 1) {
- std::string index = indices[i][indices[i].size() - 1];
- CG_outputRepr *rep = ocg->CreateArrayRefExpression(
- ocg->CreateDotExpression(instance,
- ocg->lookup_member_data(class_def, index, instance)),
- count_var);
- for (int j = indices[i].size() - 2; j >= 0; j--)
- rep = ocg->CreateArrayRefExpression(indices[i][j], rep);
-
- CG_outputRepr *lhs = ocg->CreateArrayRefExpression(
- ocg->CreateDotExpression(instance,
- ocg->lookup_member_data(class_def, indices[i][0], instance)),
- count_var);
-
- to_return = ocg->StmtListAppend(to_return,
- ocg->CreateAssignment(0, lhs, rep));
-
- }
-
- return to_return;
-
-}
-
-CG_outputRepr *generatePointerAssignments(CG_outputBuilder *ocg,
- std::string prefix_name,
- std::vector<std::vector<std::string> > &indices,
- CG_outputRepr *instance,
- CG_outputRepr *class_def) {
-
- fprintf(stderr, "generatePointerAssignments()\n");
- CG_outputRepr *list = NULL;
-
- fprintf(stderr, "prefix '%s', %d indices\n", prefix_name.c_str(), indices.size());
- for (int i = 0; i < indices.size(); i++) {
-
- std::string s = prefix_name + "_" + indices[i][0];
-
- fprintf(stderr, "s %s\n", s.c_str());
-
- // create a variable definition for a pointer to int with this name
- // that seems to be the only actual result of this routine ...
- //chillAST_VarDecl *vd = new chillAST_VarDecl( "int", prefix_name.c_str(), "*", NULL);
- //vd->print(); printf("\n"); fflush(stdout);
- //vd->dump(); printf("\n"); fflush(stdout);
-
- CG_outputRepr *ptr_exp = ocg->CreatePointer(s); // but dropped on the floor. unused
- //fprintf(stderr, "ptr_exp created\n");
-
- //CG_outputRepr *rhs = ocg->CreateDotExpression(instance,
- // ocg->lookup_member_data(class_def, indices[i][0], instance));
-
- //CG_outputRepr *ptr_assignment = ocg->CreateAssignment(0, ptr_exp, rhs);
-
- //list = ocg->StmtListAppend(list, ptr_assignment);
-
- }
-
- fprintf(stderr, "generatePointerAssignments() DONE\n\n");
- return list;
-}
-
-void Loop::normalize(int stmt_num, int loop_level) {
-
- if (stmt_num < 0 || stmt_num >= stmt.size())
- throw std::invalid_argument(
-
- "invalid statement number " + to_string(stmt_num));
-
- if (loop_level <= 0)
- throw std::invalid_argument(
- "12invalid loop level " + to_string(loop_level));
- if (loop_level > stmt[stmt_num].loop_level.size())
- throw std::invalid_argument(
- "there is no loop level " + to_string(loop_level)
- + " for statement " + to_string(stmt_num));
-
- apply_xform(stmt_num);
-
- Relation r = copy(stmt[stmt_num].IS);
-
- Relation bound = get_loop_bound(r, loop_level, this->known);
- if (!bound.has_single_conjunct() || !bound.is_satisfiable()
- || bound.is_tautology())
- throw loop_error("unable to extract loop bound for normalize");
-
- // extract the loop stride
- coef_t stride;
- std::pair<EQ_Handle, Variable_ID> result = find_simplest_stride(bound,
- bound.set_var(loop_level));
- if (result.second == NULL)
- stride = 1;
- else
- stride = abs(result.first.get_coef(result.second))
- / gcd(abs(result.first.get_coef(result.second)),
- abs(result.first.get_coef(bound.set_var(loop_level))));
-
- if (stride != 1)
- throw loop_error(
- "normalize currently only handles unit stride, non unit stride present in loop bounds");
-
- GEQ_Handle lb;
-
- Conjunct *c = bound.query_DNF()->single_conjunct();
- for (GEQ_Iterator gi(c->GEQs()); gi; gi++) {
- int coef = (*gi).get_coef(bound.set_var(loop_level));
- if (coef > 0)
- lb = *gi;
- }
-
- //Loop bound already zero
- //Nothing to do.
- if (lb.is_const(bound.set_var(loop_level)) && lb.get_const() == 0)
- return;
-
- if (lb.is_const_except_for_global(bound.set_var(loop_level))) {
-
- int n = stmt[stmt_num].xform.n_out();
-
- Relation r(n, n);
- F_And *f_root = r.add_and();
- for (int j = 1; j <= n; j++)
- if (j != 2 * loop_level) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(r.input_var(j), 1);
- h.update_coef(r.output_var(j), -1);
- }
-
- stmt[stmt_num].xform = Composition(r, stmt[stmt_num].xform);
- stmt[stmt_num].xform.simplify();
-
- for (Constr_Vars_Iter ci(lb); ci; ci++) {
- if ((*ci).var->kind() == Global_Var) {
- Global_Var_ID g = (*ci).var->get_global_var();
- Variable_ID v;
- if (g->arity() == 0)
- v = stmt[stmt_num].xform.get_local(g);
- else
- v = stmt[stmt_num].xform.get_local(g,
- (*ci).var->function_of());
-
- F_And *f_super_root = stmt[stmt_num].xform.and_with_and();
- F_Exists *f_exists = f_super_root->add_exists();
- F_And *f_root = f_exists->add_and();
-
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(stmt[stmt_num].xform.output_var(2 * loop_level),
- 1);
- h.update_coef(stmt[stmt_num].xform.input_var(loop_level), -1);
- h.update_coef(v, 1);
-
- stmt[stmt_num].xform.simplify();
- }
-
- }
-
- } else
- throw loop_error("loop bounds too complex for normalize!");
-
-}
-