summaryrefslogtreecommitdiff
path: root/src/transformations/loop.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/transformations/loop.cc')
-rw-r--r--src/transformations/loop.cc2791
1 files changed, 1393 insertions, 1398 deletions
diff --git a/src/transformations/loop.cc b/src/transformations/loop.cc
index 570bc90..10dc7bb 100644
--- a/src/transformations/loop.cc
+++ b/src/transformations/loop.cc
@@ -43,36 +43,36 @@
#define _DEBUG_ true
-
using namespace omega;
-const std::string Loop::tmp_loop_var_name_prefix = std::string("chill_t"); // Manu:: In fortran, first character of a variable name must be a letter, so this change
+const std::string Loop::tmp_loop_var_name_prefix = std::string(
+ "chill_t"); // Manu:: In fortran, first character of a variable name must be a letter, so this change
const std::string Loop::overflow_var_name_prefix = std::string("over");
-void echocontroltype( const IR_Control *control ) {
- switch(control->type()) {
- case IR_CONTROL_BLOCK: {
- CHILL_DEBUG_PRINT("IR_CONTROL_BLOCK\n");
- break;
- }
- case IR_CONTROL_LOOP: {
- CHILL_DEBUG_PRINT("IR_CONTROL_LOOP\n");
- break;
- }
- case IR_CONTROL_IF: {
- CHILL_DEBUG_PRINT("IR_CONTROL_IF\n");
- break;
- }
- default:
- CHILL_DEBUG_PRINT("just a bunch of statements?\n");
-
+void echocontroltype(const IR_Control *control) {
+ switch (control->type()) {
+ case IR_CONTROL_BLOCK: {
+ CHILL_DEBUG_PRINT("IR_CONTROL_BLOCK\n");
+ break;
+ }
+ case IR_CONTROL_LOOP: {
+ CHILL_DEBUG_PRINT("IR_CONTROL_LOOP\n");
+ break;
+ }
+ case IR_CONTROL_IF: {
+ CHILL_DEBUG_PRINT("IR_CONTROL_IF\n");
+ break;
+ }
+ default:
+ CHILL_DEBUG_PRINT("just a bunch of statements?\n");
+
} // switch
}
omega::Relation Loop::getNewIS(int stmt_num) const {
-
+
omega::Relation result;
-
+
if (stmt[stmt_num].xform.is_null()) {
omega::Relation known = omega::Extend_Set(omega::copy(this->known),
stmt[stmt_num].IS.n_set() - this->known.n_set());
@@ -81,32 +81,31 @@ omega::Relation Loop::getNewIS(int stmt_num) const {
omega::Relation known = omega::Extend_Set(omega::copy(this->known),
stmt[stmt_num].xform.n_out() - this->known.n_set());
result = omega::Intersection(
- omega::Range(
- omega::Restrict_Domain(
- omega::copy(stmt[stmt_num].xform),
- omega::copy(stmt[stmt_num].IS))), known);
+ omega::Range(
+ omega::Restrict_Domain(
+ omega::copy(stmt[stmt_num].xform),
+ omega::copy(stmt[stmt_num].IS))), known);
}
-
+
result.simplify(2, 4);
-
+
return result;
}
-
-void Loop::reduce(int stmt_num,
- std::vector<int> &level,
+void Loop::reduce(int stmt_num,
+ std::vector<int> &level,
int param,
- std::string func_name,
+ std::string func_name,
std::vector<int> &seq_levels,
- std::vector<int> cudaized_levels,
+ std::vector<int> cudaized_levels,
int bound_level) {
// illegal instruction?? fprintf(stderr, " Loop::reduce( stmt %d, param %d, func_name (encrypted)...)\n", stmt, param); // , func_name.c_str());
-
+
//std::cout << "Reducing stmt# " << stmt_num << " at level " << level << "\n";
//ir->printStmt(stmt[stmt_num].code);
-
+
if (stmt[stmt_num].reduction != 1) {
CHILL_DEBUG_PRINT("Cannot reduce this statement\n");
return;
@@ -132,9 +131,9 @@ void Loop::reduce(int stmt_num,
delete last_compute_cg_;
last_compute_cg_ = NULL;
fprintf(stderr, "set last_compute_cg_ = NULL;\n");
-
+
omega::CG_outputBuilder *ocg = ir->builder();
-
+
omega::CG_outputRepr *funCallRepr;
std::vector<omega::CG_outputRepr *> arg_repr_list;
apply_xform(stmt_num);
@@ -144,13 +143,13 @@ void Loop::reduce(int stmt_num,
std::vector<IR_ArrayRef *> access2;
for (int j = 0; j < access[i]->n_dim(); j++) {
std::vector<IR_ArrayRef *> access3 = ir->FindArrayRef(
- access[i]->index(j));
+ access[i]->index(j));
access2.insert(access2.end(), access3.begin(), access3.end());
}
if (access2.size() == 0) {
if (names.find(access[i]->name()) == names.end()) {
arg_repr_list.push_back(
- ocg->CreateAddressOf(access[i]->convert()));
+ ocg->CreateAddressOf(access[i]->convert()));
names.insert(access[i]->name());
if (access[i]->is_write())
reduced_write_refs.insert(access[i]->name());
@@ -165,14 +164,14 @@ void Loop::reduce(int stmt_num,
}
}
}
-
+
for (int i = 0; i < seq_levels.size(); i++)
arg_repr_list.push_back(
- ocg->CreateIdent(
- stmt[stmt_num].IS.set_var(seq_levels[i])->name()));
-
+ ocg->CreateIdent(
+ stmt[stmt_num].IS.set_var(seq_levels[i])->name()));
+
if (bound_level != -1) {
-
+
omega::Relation new_IS = copy(stmt[stmt_num].IS);
new_IS.copy_names(stmt[stmt_num].IS);
new_IS.setup_names();
@@ -181,106 +180,106 @@ void Loop::reduce(int stmt_num,
//omega::Relation r = getNewIS(stmt_num);
for (int j = dim + 1; j <= new_IS.n_set(); j++)
new_IS = omega::Project(new_IS, new_IS.set_var(j));
-
+
new_IS.simplify(2, 4);
-
+
omega::Relation bound_ = get_loop_bound(copy(new_IS), dim - 1);
omega::Variable_ID v = bound_.set_var(dim);
std::vector<omega::CG_outputRepr *> ubList;
for (omega::GEQ_Iterator e(
- const_cast<omega::Relation &>(bound_).single_conjunct()->GEQs());
+ const_cast<omega::Relation &>(bound_).single_conjunct()->GEQs());
e; e++) {
if ((*e).get_coef(v) < 0) {
// && (*e).is_const_except_for_global(v))
omega::CG_outputRepr *UPPERBOUND =
- omega::output_upper_bound_repr(ir->builder(), *e, v,
- bound_,
- std::vector<
- std::pair<omega::CG_outputRepr *, int> >(
- bound_.n_set(),
- std::make_pair(
- static_cast<omega::CG_outputRepr *>(NULL),
- 0)), uninterpreted_symbols[stmt_num]);
+ omega::output_upper_bound_repr(ir->builder(), *e, v,
+ bound_,
+ std::vector<
+ std::pair<omega::CG_outputRepr *, int> >(
+ bound_.n_set(),
+ std::make_pair(
+ static_cast<omega::CG_outputRepr *>(NULL),
+ 0)), uninterpreted_symbols[stmt_num]);
if (UPPERBOUND != NULL)
ubList.push_back(UPPERBOUND);
-
+
}
-
+
}
-
- omega::CG_outputRepr * ubRepr;
+
+ omega::CG_outputRepr *ubRepr;
if (ubList.size() > 1) {
-
+
ubRepr = ir->builder()->CreateInvoke("min", ubList);
arg_repr_list.push_back(ubRepr);
} else if (ubList.size() == 1)
arg_repr_list.push_back(ubList[0]);
}
-
+
funCallRepr = ocg->CreateInvoke(func_name, arg_repr_list);
stmt[stmt_num].code = funCallRepr;
for (int i = 0; i < level.size(); i++) {
//stmt[*i].code = outputStatement(ocg, stmt[*i].code, 0, mapping, known, std::vector<CG_outputRepr *>(mapping.n_out(), NULL));
std::vector<std::string> loop_vars;
loop_vars.push_back(stmt[stmt_num].IS.set_var(level[i])->name());
-
+
std::vector<omega::CG_outputRepr *> subs;
subs.push_back(ocg->CreateInt(0));
-
+
stmt[stmt_num].code = ocg->CreateSubstitutedStmt(0, stmt[stmt_num].code,
loop_vars, subs);
-
+
}
-
+
omega::Relation new_IS = copy(stmt[stmt_num].IS);
new_IS.copy_names(stmt[stmt_num].IS);
new_IS.setup_names();
new_IS.simplify();
int old_size = new_IS.n_set();
-
+
omega::Relation R = omega::copy(stmt[stmt_num].IS);
R.copy_names(stmt[stmt_num].IS);
R.setup_names();
-
+
for (int i = level.size() - 1; i >= 0; i--) {
int j;
-
+
for (j = 0; j < cudaized_levels.size(); j++) {
if (cudaized_levels[j] == level[i])
break;
-
+
}
-
+
if (j == cudaized_levels.size()) {
R = omega::Project(R, level[i], omega::Input_Var);
R.simplify();
-
+
}
//
-
+
}
-
+
omega::F_And *f_Root = R.and_with_and();
for (int i = level.size() - 1; i >= 0; i--) {
int j;
-
+
for (j = 0; j < cudaized_levels.size(); j++) {
if (cudaized_levels[j] == level[i])
break;
-
+
}
-
+
if (j == cudaized_levels.size()) {
-
+
omega::EQ_Handle h = f_Root->add_EQ();
-
+
h.update_coef(R.set_var(level[i]), 1);
h.update_const(-1);
}
//
-
+
}
-
+
R.simplify();
stmt[stmt_num].IS = R;
}
@@ -303,22 +302,22 @@ bool Loop::isInitialized() const {
bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
std::vector<ir_tree_node *> &ir_stmt) {
-
+
CHILL_DEBUG_PRINT("extract_ir_stmts()\n");
CHILL_DEBUG_PRINT("ir_tree has %d statements\n", ir_tree.size());
ir_stmt = extract_ir_stmts(ir_tree);
-
- CHILL_DEBUG_PRINT("nesting level stmt size = %d\n", (int)ir_stmt.size());
+
+ CHILL_DEBUG_PRINT("nesting level stmt size = %d\n", (int) ir_stmt.size());
stmt_nesting_level_.resize(ir_stmt.size());
-
+
std::vector<int> stmt_nesting_level(ir_stmt.size());
-
- CHILL_DEBUG_PRINT("%d statements?\n", (int)ir_stmt.size());
-
+
+ CHILL_DEBUG_PRINT("%d statements?\n", (int) ir_stmt.size());
+
// find out how deeply nested each statement is. (how can these be different?)
for (int i = 0; i < ir_stmt.size(); i++) {
- fprintf(stderr, "i %d\n", i);
+ fprintf(stderr, "i %d\n", i);
ir_stmt[i]->payload = i;
int t = 0;
ir_tree_node *itn = ir_stmt[i];
@@ -331,23 +330,24 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
stmt_nesting_level[i] = t;
CHILL_DEBUG_PRINT("stmt_nesting_level[%d] = %d\n", i, t);
}
-
+
if (actual_code.size() == 0)
- actual_code = std::vector<CG_outputRepr*>(ir_stmt.size());
-
+ actual_code = std::vector<CG_outputRepr *>(ir_stmt.size());
+
stmt = std::vector<Statement>(ir_stmt.size());
- CHILL_DEBUG_PRINT("in init_loop, made %d stmts\n", (int)ir_stmt.size());
-
- uninterpreted_symbols = std::vector<std::map<std::string, std::vector<omega::CG_outputRepr * > > >(ir_stmt.size());
- uninterpreted_symbols_stringrepr = std::vector<std::map<std::string, std::vector<omega::CG_outputRepr * > > >(ir_stmt.size());
-
+ CHILL_DEBUG_PRINT("in init_loop, made %d stmts\n", (int) ir_stmt.size());
+
+ uninterpreted_symbols = std::vector<std::map<std::string, std::vector<omega::CG_outputRepr *> > >(ir_stmt.size());
+ uninterpreted_symbols_stringrepr = std::vector<std::map<std::string, std::vector<omega::CG_outputRepr *> > >(
+ ir_stmt.size());
+
int n_dim = -1;
int max_loc;
//std::vector<std::string> index;
for (int i = 0; i < ir_stmt.size(); i++) {
int max_nesting_level = -1;
int loc;
-
+
// find the max nesting level and remember the statement that was at that level
for (int j = 0; j < ir_stmt.size(); j++) {
if (stmt_nesting_level[j] > max_nesting_level) {
@@ -355,23 +355,23 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
loc = j;
}
}
-
+
CHILL_DEBUG_PRINT("max nesting level %d at location %d\n", max_nesting_level, loc);
-
+
// most deeply nested statement acting as a reference point
if (n_dim == -1) {
CHILL_DEBUG_PRINT("n_dim now max_nesting_level %d\n", max_nesting_level);
n_dim = max_nesting_level;
max_loc = loc;
-
+
index = std::vector<std::string>(n_dim);
-
+
ir_tree_node *itn = ir_stmt[loc];
CHILL_DEBUG_PRINT("itn = stmt[%d]\n", loc);
int cur_dim = n_dim - 1;
while (itn->parent != NULL) {
CHILL_DEBUG_PRINT("parent\n");
-
+
itn = itn->parent;
if (itn->content->type() == IR_CONTROL_LOOP) {
CHILL_DEBUG_PRINT("IR_CONTROL_LOOP cur_dim %d\n", cur_dim);
@@ -382,258 +382,264 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
}
}
}
-
+
CHILL_DEBUG_PRINT("align loops by names,\n");
// align loops by names, temporary solution
ir_tree_node *itn = ir_stmt[loc]; // defined outside loops??
int depth = stmt_nesting_level_[loc] - 1;
-
+
for (int t = depth; t >= 0; t--) {
int y = t;
itn = ir_stmt[loc];
-
+
while ((itn->parent != NULL) && (y >= 0)) {
itn = itn->parent;
if (itn->content->type() == IR_CONTROL_LOOP)
y--;
}
-
+
if (itn->content->type() == IR_CONTROL_LOOP && itn->payload == -1) {
CG_outputBuilder *ocg = ir->builder();
-
+
itn->payload = depth - t;
-
+
CG_outputRepr *code =
- static_cast<IR_Block *>(ir_stmt[loc]->content)->extract();
-
+ static_cast<IR_Block *>(ir_stmt[loc]->content)->extract();
+
std::vector<CG_outputRepr *> index_expr;
std::vector<std::string> old_index;
CG_outputRepr *repl = ocg->CreateIdent(index[itn->payload]);
index_expr.push_back(repl);
old_index.push_back(
- static_cast<IR_Loop *>(itn->content)->index()->name());
+ static_cast<IR_Loop *>(itn->content)->index()->name());
code = ocg->CreateSubstitutedStmt(0, code, old_index,
index_expr);
-
- replace.insert(std::pair<int, CG_outputRepr*>(loc, code));
+
+ replace.insert(std::pair<int, CG_outputRepr *>(loc, code));
//stmt[loc].code = code;
-
+
}
}
-
+
CHILL_DEBUG_PRINT("set relation variable names ****\n");
// set relation variable names
-
+
// this finds the loop variables for loops enclosing this statement and puts
// them in an Omega Relation (just their names, which could fail)
-
+
CHILL_DEBUG_PRINT("Relation r(%d)\n", n_dim);
Relation r(n_dim);
F_And *f_root = r.add_and();
itn = ir_stmt[loc];
int temp_depth = depth;
while (itn->parent != NULL) {
-
+
itn = itn->parent;
if (itn->content->type() == IR_CONTROL_LOOP) {
- fprintf(stderr, "it's a loop. temp_depth %d\n", temp_depth);
+ fprintf(stderr, "it's a loop. temp_depth %d\n", temp_depth);
fprintf(stderr, "r.name_set_var( %d, %s )\n", itn->payload + 1, index[temp_depth].c_str());
r.name_set_var(itn->payload + 1, index[temp_depth]);
-
+
temp_depth--;
}
//static_cast<IR_Loop *>(itn->content)->index()->name());
}
- fprintf(stderr, "Relation r "); r.print(); fflush(stdout);
+ fprintf(stderr, "Relation r ");
+ r.print();
+ fflush(stdout);
//fprintf(stderr, "f_root "); f_root->print(stderr); fprintf(stderr, "\n");
-
+
/*while (itn->parent != NULL) {
itn = itn->parent;
if (itn->content->type() == IR_CONTROL_LOOP)
r.name_set_var(itn->payload+1, static_cast<IR_Loop *>(itn->content)->index()->name());
}*/
-
-
-
-
- fprintf(stderr, "extract information from loop/if structures\n");
+
+
+
+
+ fprintf(stderr, "extract information from loop/if structures\n");
// extract information from loop/if structures
std::vector<bool> processed(n_dim, false);
std::vector<std::string> vars_to_be_reversed;
-
+
std::vector<std::string> insp_lb;
std::vector<std::string> insp_ub;
-
+
itn = ir_stmt[loc];
while (itn->parent != NULL) { // keep heading upward
itn = itn->parent;
-
+
switch (itn->content->type()) {
- case IR_CONTROL_LOOP: {
- fprintf(stderr, "loop.cc l 462 IR_CONTROL_LOOP\n");
- IR_Loop *lp = static_cast<IR_Loop *>(itn->content);
- Variable_ID v = r.set_var(itn->payload + 1);
- int c;
-
- try {
- c = lp->step_size();
- //fprintf(stderr, "step size %d\n", c);
- if (c > 0) {
+ case IR_CONTROL_LOOP: {
+ fprintf(stderr, "loop.cc l 462 IR_CONTROL_LOOP\n");
+ IR_Loop *lp = static_cast<IR_Loop *>(itn->content);
+ Variable_ID v = r.set_var(itn->payload + 1);
+ int c;
+
+ try {
+ c = lp->step_size();
+ //fprintf(stderr, "step size %d\n", c);
+ if (c > 0) {
+ CG_outputRepr *lb = lp->lower_bound();
+ fprintf(stderr, "loop.cc, got the lower bound. it is:\n");
+ lb->dump();
+ printf("\n");
+ fflush(stdout);
+
+ exp2formula(ir, r, f_root, freevar, lb, v, 's',
+ IR_COND_GE, true, uninterpreted_symbols[i], uninterpreted_symbols_stringrepr[i]);
+
+ CG_outputRepr *ub = lp->upper_bound();
+ //fprintf(stderr, "loop.cc, got the upper bound. it is:\n");
+ //ub->dump(); printf("\n"); fflush(stdout);
+
+
+
+ IR_CONDITION_TYPE cond = lp->stop_cond();
+ if (cond == IR_COND_LT || cond == IR_COND_LE)
+ exp2formula(ir, r, f_root, freevar, ub, v, 's',
+ cond, true, uninterpreted_symbols[i], uninterpreted_symbols_stringrepr[i]);
+ else
+ throw ir_error("loop condition not supported");
+
+
+ if ((ir->QueryExpOperation(lp->lower_bound())
+ == IR_OP_ARRAY_VARIABLE)
+ && (ir->QueryExpOperation(lp->lower_bound())
+ == ir->QueryExpOperation(
+ lp->upper_bound()))) {
+
+ fprintf(stderr, "loop.cc lower and upper are both IR_OP_ARRAY_VARIABLE?\n");
+
+ std::vector<CG_outputRepr *> v =
+ ir->QueryExpOperand(lp->lower_bound());
+ IR_ArrayRef *ref =
+ static_cast<IR_ArrayRef *>(ir->Repr2Ref(
+ v[0]));
+ std::string s0 = ref->name();
+ std::vector<CG_outputRepr *> v2 =
+ ir->QueryExpOperand(lp->upper_bound());
+ IR_ArrayRef *ref2 =
+ static_cast<IR_ArrayRef *>(ir->Repr2Ref(
+ v2[0]));
+ std::string s1 = ref2->name();
+
+ if (s0 == s1) {
+ insp_lb.push_back(s0);
+ insp_ub.push_back(s1);
+
+ }
+
+ }
+
+
+ } else if (c < 0) {
+ CG_outputBuilder *ocg = ir->builder();
+ CG_outputRepr *lb = lp->lower_bound();
+ lb = ocg->CreateMinus(NULL, lb);
+ exp2formula(ir, r, f_root, freevar, lb, v, 's',
+ IR_COND_GE, true, uninterpreted_symbols[i], uninterpreted_symbols_stringrepr[i]);
+ CG_outputRepr *ub = lp->upper_bound();
+ ub = ocg->CreateMinus(NULL, ub);
+ IR_CONDITION_TYPE cond = lp->stop_cond();
+ if (cond == IR_COND_GE)
+ exp2formula(ir, r, f_root, freevar, ub, v, 's',
+ IR_COND_LE, true, uninterpreted_symbols[i], uninterpreted_symbols_stringrepr[i]);
+ else if (cond == IR_COND_GT)
+ exp2formula(ir, r, f_root, freevar, ub, v, 's',
+ IR_COND_LT, true, uninterpreted_symbols[i], uninterpreted_symbols_stringrepr[i]);
+ else
+ throw ir_error("loop condition not supported");
+
+ vars_to_be_reversed.push_back(lp->index()->name());
+ } else
+ throw ir_error("loop step size zero");
+ } catch (const ir_error &e) {
+ actual_code[loc] =
+ static_cast<IR_Block *>(ir_stmt[loc]->content)->extract();
+ for (int i = 0; i < itn->children.size(); i++)
+ delete itn->children[i];
+ itn->children = std::vector<ir_tree_node *>();
+ itn->content = itn->content->convert();
+ return false;
+ }
+
+ // check for loop increment or decrement that is not 1
+ //fprintf(stderr, "abs(c)\n");
+ if (abs(c) != 1) {
+ F_Exists *f_exists = f_root->add_exists();
+ Variable_ID e = f_exists->declare();
+ F_And *f_and = f_exists->add_and();
+ Stride_Handle h = f_and->add_stride(abs(c));
+ if (c > 0)
+ h.update_coef(e, 1);
+ else
+ h.update_coef(e, -1);
+ h.update_coef(v, -1);
CG_outputRepr *lb = lp->lower_bound();
- fprintf(stderr, "loop.cc, got the lower bound. it is:\n");
- lb->dump(); printf("\n"); fflush(stdout);
-
- exp2formula(ir, r, f_root, freevar, lb, v, 's',
- IR_COND_GE, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
-
- CG_outputRepr *ub = lp->upper_bound();
- //fprintf(stderr, "loop.cc, got the upper bound. it is:\n");
- //ub->dump(); printf("\n"); fflush(stdout);
-
-
-
- IR_CONDITION_TYPE cond = lp->stop_cond();
- if (cond == IR_COND_LT || cond == IR_COND_LE)
- exp2formula(ir, r, f_root, freevar, ub, v, 's',
- cond, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
+ exp2formula(ir, r, f_and, freevar, lb, e, 's', IR_COND_EQ,
+ true, uninterpreted_symbols[i], uninterpreted_symbols_stringrepr[i]);
+ }
+
+ processed[itn->payload] = true;
+ break;
+ }
+
+
+ case IR_CONTROL_IF: {
+ fprintf(stderr, "IR_CONTROL_IF\n");
+ IR_If *theif = static_cast<IR_If *>(itn->content);
+
+ CG_outputRepr *cond =
+ static_cast<IR_If *>(itn->content)->condition();
+
+ try {
+ if (itn->payload % 2 == 1)
+ exp2constraint(ir, r, f_root, freevar, cond, true, uninterpreted_symbols[i],
+ uninterpreted_symbols_stringrepr[i]);
+ else {
+ F_Not *f_not = f_root->add_not();
+ F_And *f_and = f_not->add_and();
+ exp2constraint(ir, r, f_and, freevar, cond, true, uninterpreted_symbols[i],
+ uninterpreted_symbols_stringrepr[i]);
+ }
+ } catch (const ir_error &e) {
+ std::vector<ir_tree_node *> *t;
+ if (itn->parent == NULL)
+ t = &ir_tree;
else
- throw ir_error("loop condition not supported");
-
-
- if ((ir->QueryExpOperation(lp->lower_bound())
- == IR_OP_ARRAY_VARIABLE)
- && (ir->QueryExpOperation(lp->lower_bound())
- == ir->QueryExpOperation(
- lp->upper_bound()))) {
-
- fprintf(stderr, "loop.cc lower and upper are both IR_OP_ARRAY_VARIABLE?\n");
-
- std::vector<CG_outputRepr *> v =
- ir->QueryExpOperand(lp->lower_bound());
- IR_ArrayRef *ref =
- static_cast<IR_ArrayRef *>(ir->Repr2Ref(
- v[0]));
- std::string s0 = ref->name();
- std::vector<CG_outputRepr *> v2 =
- ir->QueryExpOperand(lp->upper_bound());
- IR_ArrayRef *ref2 =
- static_cast<IR_ArrayRef *>(ir->Repr2Ref(
- v2[0]));
- std::string s1 = ref2->name();
-
- if (s0 == s1) {
- insp_lb.push_back(s0);
- insp_ub.push_back(s1);
-
+ t = &(itn->parent->children);
+ int id = itn->payload;
+ int i = t->size() - 1;
+ while (i >= 0) {
+ if ((*t)[i] == itn) {
+ for (int j = 0; j < itn->children.size(); j++)
+ delete itn->children[j];
+ itn->children = std::vector<ir_tree_node *>();
+ itn->content = itn->content->convert();
+ } else if ((*t)[i]->payload >> 1 == id >> 1) {
+ delete (*t)[i];
+ t->erase(t->begin() + i);
}
-
+ i--;
}
-
-
- } else if (c < 0) {
- CG_outputBuilder *ocg = ir->builder();
- CG_outputRepr *lb = lp->lower_bound();
- lb = ocg->CreateMinus(NULL, lb);
- exp2formula(ir, r, f_root, freevar, lb, v, 's',
- IR_COND_GE, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
- CG_outputRepr *ub = lp->upper_bound();
- ub = ocg->CreateMinus(NULL, ub);
- IR_CONDITION_TYPE cond = lp->stop_cond();
- if (cond == IR_COND_GE)
- exp2formula(ir, r, f_root, freevar, ub, v, 's',
- IR_COND_LE, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
- else if (cond == IR_COND_GT)
- exp2formula(ir, r, f_root, freevar, ub, v, 's',
- IR_COND_LT, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
- else
- throw ir_error("loop condition not supported");
-
- vars_to_be_reversed.push_back(lp->index()->name());
- } else
- throw ir_error("loop step size zero");
- } catch (const ir_error &e) {
- actual_code[loc] =
- static_cast<IR_Block *>(ir_stmt[loc]->content)->extract();
+ return false;
+ }
+
+ break;
+ }
+ default:
+ //fprintf(stderr, "default?\n");
for (int i = 0; i < itn->children.size(); i++)
delete itn->children[i];
itn->children = std::vector<ir_tree_node *>();
itn->content = itn->content->convert();
return false;
- }
-
- // check for loop increment or decrement that is not 1
- //fprintf(stderr, "abs(c)\n");
- if (abs(c) != 1) {
- F_Exists *f_exists = f_root->add_exists();
- Variable_ID e = f_exists->declare();
- F_And *f_and = f_exists->add_and();
- Stride_Handle h = f_and->add_stride(abs(c));
- if (c > 0)
- h.update_coef(e, 1);
- else
- h.update_coef(e, -1);
- h.update_coef(v, -1);
- CG_outputRepr *lb = lp->lower_bound();
- exp2formula(ir, r, f_and, freevar, lb, e, 's', IR_COND_EQ,
- true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
- }
-
- processed[itn->payload] = true;
- break;
- }
-
-
- case IR_CONTROL_IF: {
- fprintf(stderr, "IR_CONTROL_IF\n");
- IR_If *theif = static_cast<IR_If *>(itn->content);
-
- CG_outputRepr *cond =
- static_cast<IR_If *>(itn->content)->condition();
-
- try {
- if (itn->payload % 2 == 1)
- exp2constraint(ir, r, f_root, freevar, cond, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
- else {
- F_Not *f_not = f_root->add_not();
- F_And *f_and = f_not->add_and();
- exp2constraint(ir, r, f_and, freevar, cond, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
- }
- } catch (const ir_error &e) {
- std::vector<ir_tree_node *> *t;
- if (itn->parent == NULL)
- t = &ir_tree;
- else
- t = &(itn->parent->children);
- int id = itn->payload;
- int i = t->size() - 1;
- while (i >= 0) {
- if ((*t)[i] == itn) {
- for (int j = 0; j < itn->children.size(); j++)
- delete itn->children[j];
- itn->children = std::vector<ir_tree_node *>();
- itn->content = itn->content->convert();
- } else if ((*t)[i]->payload >> 1 == id >> 1) {
- delete (*t)[i];
- t->erase(t->begin() + i);
- }
- i--;
- }
- return false;
- }
-
- break;
- }
- default:
- //fprintf(stderr, "default?\n");
- for (int i = 0; i < itn->children.size(); i++)
- delete itn->children[i];
- itn->children = std::vector<ir_tree_node *>();
- itn->content = itn->content->convert();
- return false;
}
}
-
-
+
+
//fprintf(stderr, "add information for missing loops n_dim(%d)\n", n_dim);
// add information for missing loops
for (int j = 0; j < n_dim; j++)
@@ -645,18 +651,18 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
&& itn->payload == j)
break;
}
-
+
Variable_ID v = r.set_var(j + 1);
if (loc < max_loc) {
-
+
CG_outputBuilder *ocg = ir->builder();
-
+
CG_outputRepr *lb =
- static_cast<IR_Loop *>(itn->content)->lower_bound();
-
+ static_cast<IR_Loop *>(itn->content)->lower_bound();
+
exp2formula(ir, r, f_root, freevar, lb, v, 's', IR_COND_EQ,
- false,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
-
+ false, uninterpreted_symbols[i], uninterpreted_symbols_stringrepr[i]);
+
/* if (ir->QueryExpOperation(
static_cast<IR_Loop *>(itn->content)->lower_bound())
== IR_OP_VARIABLE) {
@@ -684,15 +690,15 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
}
*/
-
+
} else { // loc > max_loc
-
+
CG_outputBuilder *ocg = ir->builder();
CG_outputRepr *ub =
- static_cast<IR_Loop *>(itn->content)->upper_bound();
-
+ static_cast<IR_Loop *>(itn->content)->upper_bound();
+
exp2formula(ir, r, f_root, freevar, ub, v, 's', IR_COND_EQ,
- false,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
+ false, uninterpreted_symbols[i], uninterpreted_symbols_stringrepr[i]);
/*if (ir->QueryExpOperation(
static_cast<IR_Loop *>(itn->content)->upper_bound())
== IR_OP_VARIABLE) {
@@ -724,29 +730,29 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
*/
}
}
-
+
r.setup_names();
r.simplify();
-
+
// THIS IS MISSING IN PROTONU's
for (int j = 0; j < insp_lb.size(); j++) {
-
+
std::string lb = insp_lb[j] + "_";
std::string ub = lb + "_";
-
+
Global_Var_ID u, l;
bool found_ub = false;
bool found_lb = false;
for (DNF_Iterator di(copy(r).query_DNF()); di; di++)
for (Constraint_Iterator ci = (*di)->constraints(); ci; ci++)
-
+
for (Constr_Vars_Iter cvi(*ci); cvi; cvi++) {
Variable_ID v = cvi.curr_var();
if (v->kind() == Global_Var)
if (v->get_global_var()->arity() > 0) {
-
+
std::string name =
- v->get_global_var()->base_name();
+ v->get_global_var()->base_name();
if (name == lb) {
l = v->get_global_var();
found_lb = true;
@@ -755,9 +761,9 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
found_ub = true;
}
}
-
+
}
-
+
if (found_lb && found_ub) {
Relation known_(copy(r).n_set());
known_.copy_names(copy(r));
@@ -770,12 +776,12 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
g.update_coef(index_lb, -1);
g.update_const(-1);
addKnown(known_);
-
+
}
-
+
}
-
-
+
+
fprintf(stderr, "loop.cc L441 insert the statement\n");
// insert the statement
CG_outputBuilder *ocg = ir->builder();
@@ -785,36 +791,38 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
repl = ocg->CreateMinus(NULL, repl);
reverse_expr.push_back(repl);
}
- fprintf(stderr, "loop.cc before extract\n");
+ fprintf(stderr, "loop.cc before extract\n");
CG_outputRepr *code =
- static_cast<IR_Block *>(ir_stmt[loc]->content)->extract();
+ static_cast<IR_Block *>(ir_stmt[loc]->content)->extract();
fprintf(stderr, "code = ocg->CreateSubstitutedStmt(...)\n");
- ((CG_chillRepr *)code)->Dump(); fflush(stdout);
-
+ ((CG_chillRepr *) code)->Dump();
+ fflush(stdout);
+
code = ocg->CreateSubstitutedStmt(0, code, vars_to_be_reversed,
reverse_expr);
fprintf(stderr, "stmt\n");
- ((CG_chillRepr *)code)->Dump(); fflush(stdout);
+ ((CG_chillRepr *) code)->Dump();
+ fflush(stdout);
stmt[loc].code = code;
stmt[loc].IS = r;
-
+
//Anand: Add Information on uninterpreted function constraints to
//Known relation
-
- fprintf(stderr, "loop.cc stmt[%d].loop_level has size n_dim %d\n", loc, n_dim);
+
+ fprintf(stderr, "loop.cc stmt[%d].loop_level has size n_dim %d\n", loc, n_dim);
stmt[loc].loop_level = std::vector<LoopLevel>(n_dim);
stmt[loc].ir_stmt_node = ir_stmt[loc];
stmt[loc].has_inspector = false;
- fprintf(stderr, "for int i < n_dim(%d)\n", n_dim);
+ fprintf(stderr, "for int i < n_dim(%d)\n", n_dim);
for (int ii = 0; ii < n_dim; ii++) {
stmt[loc].loop_level[ii].type = LoopLevelOriginal;
stmt[loc].loop_level[ii].payload = ii;
stmt[loc].loop_level[ii].parallel_level = 0;
}
- fprintf(stderr, "whew\n");
-
+ fprintf(stderr, "whew\n");
+
stmt_nesting_level[loc] = -1;
}
dump();
@@ -824,36 +832,35 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
}
-
Loop::Loop(const IR_Control *control) {
-
- CHILL_DEBUG_PRINT("control type is %d ", control->type());
+
+ CHILL_DEBUG_PRINT("control type is %d \n", control->type());
echocontroltype(control);
- CHILL_DEBUG_PRINT("2set last_compute_cg_ = NULL; \n");
+ CHILL_DEBUG_PRINT("set last_compute_cg_ = NULL; \n");
last_compute_cgr_ = NULL;
last_compute_cg_ = NULL;
ir = const_cast<IR_Code *>(control->ir_); // point to the CHILL IR that this loop came from
- if (ir == 0) {
- CHILL_DEBUG_PRINT("ir gotten from control = 0x%x\n", (long)ir);
- CHILL_DEBUG_PRINT("loop.cc GONNA DIE SOON *******************************\n\n");
+ if (ir == 0) {
+ CHILL_DEBUG_PRINT("ir gotten from control = 0x%x\n", (long) ir);
+ CHILL_DEBUG_PRINT("GONNA DIE SOON *******************************\n\n");
}
-
+
init_code = NULL;
cleanup_code = NULL;
tmp_loop_var_name_counter = 1;
overflow_var_name_counter = 1;
known = Relation::True(0);
-
+
CHILL_DEBUG_PRINT("calling build_ir_tree()\n");
CHILL_DEBUG_PRINT("about to clone control\n");
ir_tree = build_ir_tree(control->clone(), NULL);
//fprintf(stderr,"in Loop::Loop. ir_tree has %ld parts\n", ir_tree.size());
-
+
// std::vector<ir_tree_node *> ir_stmt;
//fprintf(stderr, "loop.cc after build_ir_tree() %ld statements\n", stmt.size());
-
+
int count = 0;
//fprintf(stderr, "before init_loops, %d freevar\n", freevar.size());
//fprintf(stderr, "count %d\n", count++);
@@ -861,19 +868,19 @@ Loop::Loop(const IR_Control *control) {
while (!init_loop(ir_tree, ir_stmt)) {
//fprintf(stderr, "count %d\n", count++);
}
- fprintf(stderr, "after init_loop, %d freevar\n", (int)freevar.size());
-
-
- fprintf(stderr, "loop.cc after init_loop, %d statements\n", (int)stmt.size());
+ fprintf(stderr, "after init_loop, %d freevar\n", (int) freevar.size());
+
+
+ fprintf(stderr, "loop.cc after init_loop, %d statements\n", (int) stmt.size());
for (int i = 0; i < stmt.size(); i++) {
- std::map<int, CG_outputRepr*>::iterator it = replace.find(i);
-
+ std::map<int, CG_outputRepr *>::iterator it = replace.find(i);
+
if (it != replace.end())
stmt[i].code = it->second;
else
stmt[i].code = stmt[i].code;
}
-
+
if (stmt.size() != 0)
dep = DependenceGraph(stmt[0].IS.n_set());
else
@@ -881,42 +888,42 @@ Loop::Loop(const IR_Control *control) {
// init the dependence graph
for (int i = 0; i < stmt.size(); i++)
dep.insert();
-
- fprintf(stderr, "this really REALLY needs some comments\n");
+
+ fprintf(stderr, "this really REALLY needs some comments\n");
// this really REALLY needs some comments
for (int i = 0; i < stmt.size(); i++) {
- fprintf(stderr, "i %d\n", i);
+ fprintf(stderr, "i %d\n", i);
stmt[i].reduction = 0; // Manu -- initialization
for (int j = i; j < stmt.size(); j++) {
- fprintf(stderr, "j %d\n", j);
+ fprintf(stderr, "j %d\n", j);
std::pair<std::vector<DependenceVector>,
- std::vector<DependenceVector> > dv = test_data_dependences(
- ir,
- stmt[i].code,
- stmt[i].IS,
- stmt[j].code,
- stmt[j].IS,
- freevar,
- index,
- stmt_nesting_level_[i],
- stmt_nesting_level_[j],
- uninterpreted_symbols[ i ],
- uninterpreted_symbols_stringrepr[ i ]);
-
- fprintf(stderr, "dv.first.size() %d\n", (int)dv.first.size());
+ std::vector<DependenceVector> > dv = test_data_dependences(
+ ir,
+ stmt[i].code,
+ stmt[i].IS,
+ stmt[j].code,
+ stmt[j].IS,
+ freevar,
+ index,
+ stmt_nesting_level_[i],
+ stmt_nesting_level_[j],
+ uninterpreted_symbols[i],
+ uninterpreted_symbols_stringrepr[i]);
+
+ fprintf(stderr, "dv.first.size() %d\n", (int) dv.first.size());
for (int k = 0; k < dv.first.size(); k++) {
- fprintf(stderr, "k1 %d\n", k);
+ fprintf(stderr, "k1 %d\n", k);
if (is_dependence_valid(ir_stmt[i], ir_stmt[j], dv.first[k],
true))
dep.connect(i, j, dv.first[k]);
else {
dep.connect(j, i, dv.first[k].reverse());
}
-
+
}
-
- for (int k = 0; k < dv.second.size(); k++) {
- fprintf(stderr, "k2 %d\n", k);
+
+ for (int k = 0; k < dv.second.size(); k++) {
+ fprintf(stderr, "k2 %d\n", k);
if (is_dependence_valid(ir_stmt[j], ir_stmt[i], dv.second[k],
false))
dep.connect(j, i, dv.second[k]);
@@ -926,64 +933,64 @@ Loop::Loop(const IR_Control *control) {
}
}
}
-
- fprintf(stderr, "\n\n*** LOTS OF REDUCTIONS ***\n\n");
-
+
+ fprintf(stderr, "\n\n*** LOTS OF REDUCTIONS ***\n\n");
+
// TODO: Reduction check
// Manu:: Initial implementation / algorithm
std::set<int> reducCand = std::set<int>();
std::vector<int> canReduce = std::vector<int>();
- fprintf(stderr, "\ni range %d\n", stmt.size());
+ fprintf(stderr, "\ni range %d\n", stmt.size());
for (int i = 0; i < stmt.size(); i++) {
- fprintf(stderr, "i %d\n", i);
+ fprintf(stderr, "i %d\n", i);
if (!dep.hasEdge(i, i)) {
continue;
}
- fprintf(stderr, "dep.hasEdge(%d, %d)\n", i, i);
+ fprintf(stderr, "dep.hasEdge(%d, %d)\n", i, i);
// for each statement check if it has all the three dependences (RAW, WAR, WAW)
// If there is such a statement, it is a reduction candidate. Mark all reduction candidates.
std::vector<DependenceVector> tdv = dep.getEdge(i, i);
- fprintf(stderr, "tdv size %d\n", tdv.size());
+ fprintf(stderr, "tdv size %d\n", tdv.size());
for (int j = 0; j < tdv.size(); j++) {
- fprintf(stderr, "ij %d %d\n", i, j);
- if (tdv[j].is_reduction_cand) {
- fprintf(stderr, "reducCand.insert( %d )\n", i);
+ fprintf(stderr, "ij %d %d\n", i, j);
+ if (tdv[j].is_reduction_cand) {
+ fprintf(stderr, "reducCand.insert( %d )\n", i);
reducCand.insert(i);
}
}
}
-
- fprintf(stderr, "loop.cc reducCand.size() %d\n", reducCand.size());
+
+ fprintf(stderr, "loop.cc reducCand.size() %d\n", reducCand.size());
bool reduc;
std::set<int>::iterator it;
- int counter = 0;
+ int counter = 0;
for (it = reducCand.begin(); it != reducCand.end(); it++) {
- fprintf(stderr, "counter %d\n", counter);
+ fprintf(stderr, "counter %d\n", counter);
reduc = true;
for (int j = 0; j < stmt.size(); j++) {
- fprintf(stderr, "j %d\n", j);
+ fprintf(stderr, "j %d\n", j);
if ((*it != j)
&& (stmt_nesting_level_[*it] < stmt_nesting_level_[j])) {
if (dep.hasEdge(*it, j) || dep.hasEdge(j, *it)) {
- fprintf(stderr, "counter %d j %d reduc = false\n", counter, j);
+ fprintf(stderr, "counter %d j %d reduc = false\n", counter, j);
reduc = false;
break;
}
}
counter += 1;
}
-
+
if (reduc) {
- fprintf(stderr, "canReduce.push_back()\n");
+ fprintf(stderr, "canReduce.push_back()\n");
canReduce.push_back(*it);
stmt[*it].reduction = 2; // First, assume that reduction is possible with some processing
}
}
-
-
+
+
// If reduction is possible without processing, update the value of the reduction variable to 1
- fprintf(stderr, "loop.cc canReduce.size() %d\n", canReduce.size());
+ fprintf(stderr, "loop.cc canReduce.size() %d\n", canReduce.size());
for (int i = 0; i < canReduce.size(); i++) {
// Here, assuming that stmtType returns 1 when there is a single statement within stmt[i]
if (stmtType(ir, stmt[canReduce[i]].code) == 1) {
@@ -993,9 +1000,9 @@ Loop::Loop(const IR_Control *control) {
stmt[canReduce[i]].reductionOp = opType;
}
}
-
+
// printing out stuff for debugging
-
+
if (DEP_DEBUG) {
std::cout << "STATEMENTS THAT CAN BE REDUCED: \n";
for (int i = 0; i < canReduce.size(); i++) {
@@ -1015,21 +1022,21 @@ Loop::Loop(const IR_Control *control) {
}
}
// cleanup the IR tree
-
- fprintf(stderr, "init dumb transformation relations\n");
+
+ fprintf(stderr, "init dumb transformation relations\n");
// init dumb transformation relations e.g. [i, j] -> [ 0, i, 0, j, 0]
for (int i = 0; i < stmt.size(); i++) {
int n = stmt[i].IS.n_set();
stmt[i].xform = Relation(n, 2 * n + 1);
F_And *f_root = stmt[i].xform.add_and();
-
+
for (int j = 1; j <= n; j++) {
EQ_Handle h = f_root->add_EQ();
h.update_coef(stmt[i].xform.output_var(2 * j), 1);
h.update_coef(stmt[i].xform.input_var(j), -1);
}
-
+
for (int j = 1; j <= 2 * n + 1; j += 2) {
EQ_Handle h = f_root->add_EQ();
h.update_coef(stmt[i].xform.output_var(j), 1);
@@ -1037,7 +1044,7 @@ Loop::Loop(const IR_Control *control) {
stmt[i].xform.simplify();
}
//fprintf(stderr, "done with dumb\n");
-
+
if (stmt.size() != 0)
num_dep_dim = stmt[0].IS.n_set();
else
@@ -1056,19 +1063,19 @@ Loop::Loop(const IR_Control *control) {
}
Loop::~Loop() {
-
+
delete last_compute_cgr_;
delete last_compute_cg_;
-
+
for (int i = 0; i < stmt.size(); i++)
if (stmt[i].code != NULL) {
stmt[i].code->clear();
delete stmt[i].code;
}
-
+
for (int i = 0; i < ir_tree.size(); i++)
delete ir_tree[i];
-
+
if (init_code != NULL) {
init_code->clear();
delete init_code;
@@ -1080,54 +1087,52 @@ Loop::~Loop() {
}
-
-
int Loop::get_dep_dim_of(int stmt_num, int level) const {
if (stmt_num < 0 || stmt_num >= stmt.size())
throw std::invalid_argument("invaid statement " + to_string(stmt_num));
-
+
if (level < 1 || level > stmt[stmt_num].loop_level.size())
return -1;
-
+
int trip_count = 0;
while (true) {
switch (stmt[stmt_num].loop_level[level - 1].type) {
- case LoopLevelOriginal:
- return stmt[stmt_num].loop_level[level - 1].payload;
- case LoopLevelTile:
- level = stmt[stmt_num].loop_level[level - 1].payload;
- if (level < 1)
- return -1;
- if (level > stmt[stmt_num].loop_level.size())
- throw loop_error("incorrect loop level information for statement "
- + to_string(stmt_num));
- break;
- default:
- throw loop_error(
- "unknown loop level information for statement "
- + to_string(stmt_num));
+ case LoopLevelOriginal:
+ return stmt[stmt_num].loop_level[level - 1].payload;
+ case LoopLevelTile:
+ level = stmt[stmt_num].loop_level[level - 1].payload;
+ if (level < 1)
+ return -1;
+ if (level > stmt[stmt_num].loop_level.size())
+ throw loop_error("incorrect loop level information for statement "
+ + to_string(stmt_num));
+ break;
+ default:
+ throw loop_error(
+ "unknown loop level information for statement "
+ + to_string(stmt_num));
}
trip_count++;
if (trip_count >= stmt[stmt_num].loop_level.size())
throw loop_error(
- "incorrect loop level information for statement "
- + to_string(stmt_num));
+ "incorrect loop level information for statement "
+ + to_string(stmt_num));
}
}
int Loop::get_last_dep_dim_before(int stmt_num, int level) const {
if (stmt_num < 0 || stmt_num >= stmt.size())
throw std::invalid_argument("invaid statement " + to_string(stmt_num));
-
+
if (level < 1)
return -1;
if (level > stmt[stmt_num].loop_level.size())
level = stmt[stmt_num].loop_level.size() + 1;
-
+
for (int i = level - 1; i >= 1; i--)
if (stmt[stmt_num].loop_level[i - 1].type == LoopLevelOriginal)
return stmt[stmt_num].loop_level[i - 1].payload;
-
+
return -1;
}
@@ -1139,14 +1144,14 @@ void Loop::print_internal_loop_structure() const {
if (2 * j < lex.size())
std::cout << lex[2 * j];
switch (stmt[i].loop_level[j].type) {
- case LoopLevelOriginal:
- std::cout << "(dim:" << stmt[i].loop_level[j].payload << ")";
- break;
- case LoopLevelTile:
- std::cout << "(tile:" << stmt[i].loop_level[j].payload << ")";
- break;
- default:
- std::cout << "(unknown)";
+ case LoopLevelOriginal:
+ std::cout << "(dim:" << stmt[i].loop_level[j].payload << ")";
+ break;
+ case LoopLevelTile:
+ std::cout << "(tile:" << stmt[i].loop_level[j].payload << ")";
+ break;
+ default:
+ std::cout << "(unknown)";
}
std::cout << ' ';
}
@@ -1159,96 +1164,102 @@ void Loop::print_internal_loop_structure() const {
}
}
-void Loop::debugRelations() const {
- const int m = stmt.size();
+void Loop::debugRelations() const {
+ const int m = stmt.size();
{
std::vector<Relation> IS(m);
std::vector<Relation> xforms(m);
-
+
for (int i = 0; i < m; i++) {
IS[i] = stmt[i].IS;
xforms[i] = stmt[i].xform; // const stucks
}
-
- printf("\nxforms:\n");
- for (int i = 0; i < m; i++) { xforms[i].print(); printf("\n"); }
- printf("\nIS:\n");
- for (int i = 0; i < m; i++) { IS[i].print(); printf("\n"); }
- fflush(stdout);
+
+ printf("\nxforms:\n");
+ for (int i = 0; i < m; i++) {
+ xforms[i].print();
+ printf("\n");
+ }
+ printf("\nIS:\n");
+ for (int i = 0; i < m; i++) {
+ IS[i].print();
+ printf("\n");
+ }
+ fflush(stdout);
}
}
CG_outputRepr *Loop::getCode(int effort) const {
- fprintf(stderr,"\nloop.cc Loop::getCode( effort %d )\n", effort );
-
+ fprintf(stderr, "\nloop.cc Loop::getCode( effort %d )\n", effort);
+
const int m = stmt.size();
if (m == 0)
return NULL;
const int n = stmt[0].xform.n_out();
-
+
if (last_compute_cg_ == NULL) {
- fprintf(stderr, "Loop::getCode() last_compute_cg_ == NULL\n");
-
+ fprintf(stderr, "Loop::getCode() last_compute_cg_ == NULL\n");
+
std::vector<Relation> IS(m);
std::vector<Relation> xforms(m);
for (int i = 0; i < m; i++) {
IS[i] = stmt[i].IS;
xforms[i] = stmt[i].xform;
}
-
- debugRelations();
-
-
+
+ debugRelations();
+
+
Relation known = Extend_Set(copy(this->known), n - this->known.n_set());
- printf("\nknown:\n"); known.print(); printf("\n\n"); fflush(stdout);
-
+ printf("\nknown:\n");
+ known.print();
+ printf("\n\n");
+ fflush(stdout);
+
last_compute_cg_ = new CodeGen(xforms, IS, known);
delete last_compute_cgr_;
last_compute_cgr_ = NULL;
- }
- else {
- fprintf(stderr, "Loop::getCode() last_compute_cg_ NOT NULL\n");
+ } else {
+ fprintf(stderr, "Loop::getCode() last_compute_cg_ NOT NULL\n");
}
-
+
if (last_compute_cgr_ == NULL || last_compute_effort_ != effort) {
delete last_compute_cgr_;
last_compute_cgr_ = last_compute_cg_->buildAST(effort);
last_compute_effort_ = effort;
}
-
+
std::vector<CG_outputRepr *> stmts(m);
- fprintf(stderr, "%d stmts\n", m);
+ fprintf(stderr, "%d stmts\n", m);
for (int i = 0; i < m; i++)
stmts[i] = stmt[i].code;
CG_outputBuilder *ocg = ir->builder();
- fprintf(stderr, "calling last_compute_cgr_->printRepr()\n");
- CG_outputRepr *repr = last_compute_cgr_->printRepr(ocg, stmts,
+ fprintf(stderr, "calling last_compute_cgr_->printRepr()\n");
+ CG_outputRepr *repr = last_compute_cgr_->printRepr(ocg, stmts,
uninterpreted_symbols);
-
+
if (init_code != NULL)
repr = ocg->StmtListAppend(init_code->clone(), repr);
if (cleanup_code != NULL)
repr = ocg->StmtListAppend(repr, cleanup_code->clone());
-
- fprintf(stderr,"\nloop.cc Loop::getCode( effort %d ) DONE\n", effort );
+
+ fprintf(stderr, "\nloop.cc Loop::getCode( effort %d ) DONE\n", effort);
return repr;
}
-
-
void Loop::printCode(int effort) const {
- fprintf(stderr,"\nloop.cc Loop::printCode( effort %d )\n", effort );
+ fprintf(stderr, "\nloop.cc Loop::printCode( effort %d )\n", effort);
const int m = stmt.size();
if (m == 0)
return;
const int n = stmt[0].xform.n_out();
-
+
if (last_compute_cg_ == NULL) {
- fprintf(stderr, "Loop::printCode(), last_compute_cg_ == NULL\n");
+ fprintf(stderr, "Loop::printCode(), last_compute_cg_ == NULL\n");
std::vector<Relation> IS(m);
std::vector<Relation> xforms(m);
for (int i = 0; i < m; i++) {
@@ -1256,22 +1267,21 @@ void Loop::printCode(int effort) const {
xforms[i] = stmt[i].xform;
}
Relation known = Extend_Set(copy(this->known), n - this->known.n_set());
-
+
last_compute_cg_ = new CodeGen(xforms, IS, known);
delete last_compute_cgr_;
last_compute_cgr_ = NULL;
- }
- else fprintf(stderr, "Loop::printCode(), last_compute_cg_ NOT NULL\n");
-
+ } else fprintf(stderr, "Loop::printCode(), last_compute_cg_ NOT NULL\n");
+
if (last_compute_cgr_ == NULL || last_compute_effort_ != effort) {
delete last_compute_cgr_;
last_compute_cgr_ = last_compute_cg_->buildAST(effort);
last_compute_effort_ = effort;
}
-
+
std::string repr = last_compute_cgr_->printString(
- uninterpreted_symbols_stringrepr);
- fprintf(stderr, "leaving Loop::printCode()\n");
+ uninterpreted_symbols_stringrepr);
+ fprintf(stderr, "leaving Loop::printCode()\n");
std::cout << repr << std::endl;
}
@@ -1297,20 +1307,20 @@ void Loop::printDependenceGraph() const {
std::vector<Relation> Loop::getNewIS() const {
const int m = stmt.size();
-
+
std::vector<Relation> new_IS(m);
for (int i = 0; i < m; i++)
new_IS[i] = getNewIS(i);
-
+
return new_IS;
}
// pragmas are tied to loops only ???
void Loop::pragma(int stmt_num, int level, const std::string &pragmaText) {
// check sanity of parameters
- if(stmt_num < 0)
+ if (stmt_num < 0)
throw std::invalid_argument("invalid statement " + to_string(stmt_num));
-
+
CG_outputBuilder *ocg = ir->builder();
CG_outputRepr *code = stmt[stmt_num].code;
ocg->CreatePragmaAttribute(code, level, pragmaText);
@@ -1331,9 +1341,9 @@ void Loop::pragma(int stmt_num, int level, const std::string &pragmaText) {
void Loop::prefetch(int stmt_num, int level, const std::string &arrName, int hint) {
// check sanity of parameters
- if(stmt_num < 0)
+ if (stmt_num < 0)
throw std::invalid_argument("invalid statement " + to_string(stmt_num));
-
+
CG_outputBuilder *ocg = ir->builder();
CG_outputRepr *code = stmt[stmt_num].code;
ocg->CreatePrefetchAttribute(code, level, arrName, hint);
@@ -1341,13 +1351,13 @@ void Loop::prefetch(int stmt_num, int level, const std::string &arrName, int hin
std::vector<int> Loop::getLexicalOrder(int stmt_num) const {
assert(stmt_num < stmt.size());
-
+
const int n = stmt[stmt_num].xform.n_out();
std::vector<int> lex(n, 0);
-
+
for (int i = 0; i < n; i += 2)
lex[i] = get_const(stmt[stmt_num].xform, i, Output_Var);
-
+
return lex;
}
@@ -1356,13 +1366,13 @@ std::vector<int> Loop::getLexicalOrder(int stmt_num) const {
std::set<int> Loop::getSubLoopNest(int stmt_num, int level) const {
assert(stmt_num >= 0 && stmt_num < stmt.size());
assert(level > 0 && level <= stmt[stmt_num].loop_level.size());
-
+
std::set<int> working;
for (int i = 0; i < stmt.size(); i++)
if (const_cast<Loop *>(this)->stmt[i].IS.is_upper_bound_satisfiable()
&& stmt[i].loop_level.size() >= level)
working.insert(i);
-
+
for (int i = 1; i <= level; i++) {
int a = getLexicalOrder(stmt_num, i);
for (std::set<int>::iterator j = working.begin(); j != working.end();) {
@@ -1373,14 +1383,14 @@ std::set<int> Loop::getSubLoopNest(int stmt_num, int level) const {
++j;
}
}
-
+
return working;
}
int Loop::getLexicalOrder(int stmt_num, int level) const {
assert(stmt_num >= 0 && stmt_num < stmt.size());
- assert(level > 0 && level <= stmt[stmt_num].loop_level.size()+1);
-
+ assert(level > 0 && level <= stmt[stmt_num].loop_level.size() + 1);
+
Relation &r = const_cast<Loop *>(this)->stmt[stmt_num].xform;
for (EQ_Iterator e(r.single_conjunct()->EQs()); e; e++)
if (abs((*e).get_coef(r.output_var(2 * level - 1))) == 1) {
@@ -1395,15 +1405,15 @@ int Loop::getLexicalOrder(int stmt_num, int level) const {
return (*e).get_coef(r.output_var(2 * level - 1)) > 0 ? -t : t;
}
}
-
+
throw loop_error(
- "can't find lexical order for statement " + to_string(stmt_num)
- + "'s loop level " + to_string(level));
+ "can't find lexical order for statement " + to_string(stmt_num)
+ + "'s loop level " + to_string(level));
}
std::set<int> Loop::getStatements(const std::vector<int> &lex, int dim) const {
const int m = stmt.size();
-
+
std::set<int> same_loops;
for (int i = 0; i < m; i++) {
if (dim < 0)
@@ -1417,32 +1427,32 @@ std::set<int> Loop::getStatements(const std::vector<int> &lex, int dim) const {
if (j > dim)
same_loops.insert(i);
}
-
+
}
-
+
return same_loops;
}
void Loop::shiftLexicalOrder(const std::vector<int> &lex, int dim, int amount) {
const int m = stmt.size();
-
+
if (amount == 0)
return;
-
+
for (int i = 0; i < m; i++) {
std::vector<int> lex2 = getLexicalOrder(i);
-
+
bool need_shift = true;
-
+
for (int j = 0; j < dim; j++)
if (lex2[j] != lex[j]) {
need_shift = false;
break;
}
-
+
if (!need_shift)
continue;
-
+
if (amount > 0) {
if (lex2[dim] < lex[dim])
continue;
@@ -1450,94 +1460,94 @@ void Loop::shiftLexicalOrder(const std::vector<int> &lex, int dim, int amount) {
if (lex2[dim] > lex[dim])
continue;
}
-
+
assign_const(stmt[i].xform, dim, lex2[dim] + amount);
}
}
std::vector<std::set<int> > Loop::sort_by_same_loops(std::set<int> active,
int level) {
-
+
std::set<int> not_nested_at_this_level;
- std::map<ir_tree_node*, std::set<int> > sorted_by_loop;
+ std::map<ir_tree_node *, std::set<int> > sorted_by_loop;
std::map<int, std::set<int> > sorted_by_lex_order;
std::vector<std::set<int> > to_return;
bool lex_order_already_set = false;
for (std::set<int>::iterator it = active.begin(); it != active.end();
it++) {
-
+
if (stmt[*it].ir_stmt_node == NULL)
lex_order_already_set = true;
}
-
+
if (lex_order_already_set) {
-
+
for (std::set<int>::iterator it = active.begin(); it != active.end();
it++) {
std::map<int, std::set<int> >::iterator it2 =
- sorted_by_lex_order.find(
- get_const(stmt[*it].xform, 2 * (level - 1),
- Output_Var));
-
+ sorted_by_lex_order.find(
+ get_const(stmt[*it].xform, 2 * (level - 1),
+ Output_Var));
+
if (it2 != sorted_by_lex_order.end())
it2->second.insert(*it);
else {
-
+
std::set<int> to_insert;
-
+
to_insert.insert(*it);
-
+
sorted_by_lex_order.insert(
- std::pair<int, std::set<int> >(
- get_const(stmt[*it].xform, 2 * (level - 1),
- Output_Var), to_insert));
-
+ std::pair<int, std::set<int> >(
+ get_const(stmt[*it].xform, 2 * (level - 1),
+ Output_Var), to_insert));
+
}
-
+
}
-
+
for (std::map<int, std::set<int> >::iterator it2 =
- sorted_by_lex_order.begin(); it2 != sorted_by_lex_order.end();
+ sorted_by_lex_order.begin(); it2 != sorted_by_lex_order.end();
it2++)
to_return.push_back(it2->second);
-
+
} else {
-
+
for (std::set<int>::iterator it = active.begin(); it != active.end();
it++) {
-
- ir_tree_node* itn = stmt[*it].ir_stmt_node;
+
+ ir_tree_node *itn = stmt[*it].ir_stmt_node;
itn = itn->parent;
//while (itn->content->type() != IR_CONTROL_LOOP && itn != NULL)
// itn = itn->parent;
-
+
while ((itn != NULL) && (itn->payload != level - 1)) {
itn = itn->parent;
- while (itn != NULL && itn->content->type() != IR_CONTROL_LOOP )
+ while (itn != NULL && itn->content->type() != IR_CONTROL_LOOP)
itn = itn->parent;
}
-
+
if (itn == NULL)
not_nested_at_this_level.insert(*it);
else {
- std::map<ir_tree_node*, std::set<int> >::iterator it2 =
- sorted_by_loop.find(itn);
-
+ std::map<ir_tree_node *, std::set<int> >::iterator it2 =
+ sorted_by_loop.find(itn);
+
if (it2 != sorted_by_loop.end())
it2->second.insert(*it);
else {
std::set<int> to_insert;
-
+
to_insert.insert(*it);
-
+
sorted_by_loop.insert(
- std::pair<ir_tree_node*, std::set<int> >(itn,
- to_insert));
-
+ std::pair<ir_tree_node *, std::set<int> >(itn,
+ to_insert));
+
}
-
+
}
-
+
}
if (not_nested_at_this_level.size() > 0) {
for (std::set<int>::iterator it = not_nested_at_this_level.begin();
@@ -1545,34 +1555,34 @@ std::vector<std::set<int> > Loop::sort_by_same_loops(std::set<int> active,
std::set<int> temp;
temp.insert(*it);
to_return.push_back(temp);
-
+
}
}
- for (std::map<ir_tree_node*, std::set<int> >::iterator it2 =
- sorted_by_loop.begin(); it2 != sorted_by_loop.end(); it2++)
+ for (std::map<ir_tree_node *, std::set<int> >::iterator it2 =
+ sorted_by_loop.begin(); it2 != sorted_by_loop.end(); it2++)
to_return.push_back(it2->second);
}
return to_return;
}
-void update_successors(int n,
- int node_num[],
+void update_successors(int n,
+ int node_num[],
int cant_fuse_with[],
- Graph<std::set<int>, bool> &g,
+ Graph<std::set<int>, bool> &g,
std::list<int> &work_list,
- std::list<bool> &type_list,
+ std::list<bool> &type_list,
std::vector<bool> types) {
-
+
std::set<int> disconnect;
for (Graph<std::set<int>, bool>::EdgeList::iterator i =
- g.vertex[n].second.begin(); i != g.vertex[n].second.end(); i++) {
+ g.vertex[n].second.begin(); i != g.vertex[n].second.end(); i++) {
int m = i->first;
-
+
if (node_num[m] != -1)
throw loop_error("Graph input for fusion has cycles not a DAG!!");
-
+
std::vector<bool> check_ = g.getEdge(n, m);
-
+
bool has_bad_edge_path = false;
for (int i = 0; i < check_.size(); i++)
if (!check_[i]) {
@@ -1589,12 +1599,12 @@ void update_successors(int n,
}
disconnect.insert(m);
}
-
-
+
+
for (std::set<int>::iterator i = disconnect.begin(); i != disconnect.end();
i++) {
g.disconnect(n, *i);
-
+
bool no_incoming_edges = true;
for (int j = 0; j < g.vertex.size(); j++)
if (j != *i)
@@ -1602,7 +1612,7 @@ void update_successors(int n,
no_incoming_edges = false;
break;
}
-
+
if (no_incoming_edges) {
work_list.push_back(*i);
type_list.push_back(types[*i]);
@@ -1611,35 +1621,32 @@ void update_successors(int n,
}
-
int Loop::getMinLexValue(std::set<int> stmts, int level) {
-
+
int min;
-
+
std::set<int>::iterator it = stmts.begin();
min = getLexicalOrder(*it, level);
-
+
for (; it != stmts.end(); it++) {
int curr = getLexicalOrder(*it, level);
if (curr < min)
min = curr;
}
-
+
return min;
}
-
-
Graph<std::set<int>, bool> Loop::construct_induced_graph_at_level(
- std::vector<std::set<int> > s, DependenceGraph dep, int dep_dim) {
+ std::vector<std::set<int> > s, DependenceGraph dep, int dep_dim) {
Graph<std::set<int>, bool> g;
-
+
for (int i = 0; i < s.size(); i++)
g.insert(s[i]);
-
+
for (int i = 0; i < s.size(); i++) {
-
+
for (int j = i + 1; j < s.size(); j++) {
bool has_true_edge_i_to_j = false;
bool has_true_edge_j_to_i = false;
@@ -1647,32 +1654,32 @@ Graph<std::set<int>, bool> Loop::construct_induced_graph_at_level(
bool is_connected_j_to_i = false;
for (std::set<int>::iterator ii = s[i].begin(); ii != s[i].end();
ii++) {
-
+
for (std::set<int>::iterator jj = s[j].begin();
jj != s[j].end(); jj++) {
-
+
std::vector<DependenceVector> dvs = dep.getEdge(*ii, *jj);
for (int k = 0; k < dvs.size(); k++)
if (dvs[k].is_control_dependence()
|| (dvs[k].is_data_dependence()
&& dvs[k].has_been_carried_at(dep_dim))) {
-
+
if (dvs[k].is_data_dependence()
&& dvs[k].has_negative_been_carried_at(
- dep_dim)) {
+ dep_dim)) {
//g.connect(i, j, false);
is_connected_i_to_j = true;
break;
} else {
//g.connect(i, j, true);
-
+
has_true_edge_i_to_j = true;
//break
}
}
-
+
//if (is_connected)
-
+
// break;
// if (has_true_edge_i_to_j && !is_connected_i_to_j)
// g.connect(i, j, true);
@@ -1681,72 +1688,71 @@ Graph<std::set<int>, bool> Loop::construct_induced_graph_at_level(
if (dvs[k].is_control_dependence()
|| (dvs[k].is_data_dependence()
&& dvs[k].has_been_carried_at(dep_dim))) {
-
+
if (is_connected_i_to_j || has_true_edge_i_to_j)
throw loop_error(
- "Graph input for fusion has cycles not a DAG!!");
-
+ "Graph input for fusion has cycles not a DAG!!");
+
if (dvs[k].is_data_dependence()
&& dvs[k].has_negative_been_carried_at(
- dep_dim)) {
+ dep_dim)) {
//g.connect(i, j, false);
is_connected_j_to_i = true;
break;
} else {
//g.connect(i, j, true);
-
+
has_true_edge_j_to_i = true;
//break;
}
}
-
+
// if (is_connected)
//break;
// if (is_connected)
//break;
}
-
+
//if (is_connected)
// break;
}
-
-
+
+
if (is_connected_i_to_j)
g.connect(i, j, false);
else if (has_true_edge_i_to_j)
g.connect(i, j, true);
-
+
if (is_connected_j_to_i)
g.connect(j, i, false);
else if (has_true_edge_j_to_i)
g.connect(j, i, true);
-
+
}
}
return g;
}
-
std::vector<std::set<int> > Loop::typed_fusion(Graph<std::set<int>, bool> g,
std::vector<bool> &types) {
-
+
bool roots[g.vertex.size()];
-
+
for (int i = 0; i < g.vertex.size(); i++)
roots[i] = true;
-
+
for (int i = 0; i < g.vertex.size(); i++)
for (int j = i + 1; j < g.vertex.size(); j++) {
-
+
if (g.hasEdge(i, j))
roots[j] = false;
-
+
if (g.hasEdge(j, i))
roots[i] = false;
-
+
}
-
+
std::list<int> work_list;
std::list<bool> type_list;
int cant_fuse_with[g.vertex.size()];
@@ -1755,11 +1761,11 @@ std::vector<std::set<int> > Loop::typed_fusion(Graph<std::set<int>, bool> g,
int lastnum = 0;
std::vector<std::set<int> > s;
//Each Fused set's representative node
-
+
int node_to_fused_nodes[g.vertex.size()];
int node_num[g.vertex.size()];
int next[g.vertex.size()];
-
+
for (int i = 0; i < g.vertex.size(); i++) {
if (roots[i] == true) {
work_list.push_back(i);
@@ -1770,17 +1776,17 @@ std::vector<std::set<int> > Loop::typed_fusion(Graph<std::set<int>, bool> g,
node_num[i] = -1;
next[i] = 0;
}
-
-
+
+
// topological sort according to chun's permute algorithm
// std::vector<std::set<int> > s = g.topoSort();
std::vector<std::set<int> > s2 = g.topoSort();
if (work_list.empty() || (s2.size() != g.vertex.size())) {
-
+
std::cout << s2.size() << "\t" << g.vertex.size() << std::endl;
throw loop_error("Input for fusion not a DAG!!");
-
-
+
+
}
int fused_nodes_counter = 0;
while (!work_list.empty()) {
@@ -1802,19 +1808,19 @@ std::vector<std::set<int> > Loop::typed_fusion(Graph<std::set<int>, bool> g,
p = fused;
else
p = next[cant_fuse_with[n]];
-
+
if (p != 0) {
int rep_node = node_to_fused_nodes[p];
node_num[n] = node_num[rep_node];
-
+
try {
update_successors(n, node_num, cant_fuse_with, g, work_list,
type_list, types);
} catch (const loop_error &e) {
-
+
throw loop_error(
- "statements cannot be fused together due to negative dependence");
-
+ "statements cannot be fused together due to negative dependence");
+
}
for (std::set<int>::iterator it = g.vertex[n].first.begin();
it != g.vertex[n].first.end(); it++)
@@ -1826,81 +1832,80 @@ std::vector<std::set<int> > Loop::typed_fusion(Graph<std::set<int>, bool> g,
lastnum = lastnum + 1;
node_num[n] = lastnum;
node_to_fused_nodes[node_num[n]] = n;
-
+
if (lastfused == 0) {
fused = lastnum;
lastfused = fused;
} else {
next[lastfused] = lastnum;
lastfused = lastnum;
-
+
}
-
+
try {
update_successors(n, node_num, cant_fuse_with, g, work_list,
type_list, types);
} catch (const loop_error &e) {
-
+
throw loop_error(
- "statements cannot be fused together due to negative dependence");
-
+ "statements cannot be fused together due to negative dependence");
+
}
fused_nodes_counter++;
}
-
+
} else {
s.push_back(g.vertex[n].first);
lastnum = lastnum + 1;
node_num[n] = lastnum;
node_to_fused_nodes[node_num[n]] = n;
-
+
try {
update_successors(n, node_num, cant_fuse_with, g, work_list,
type_list, types);
} catch (const loop_error &e) {
-
+
throw loop_error(
- "statements cannot be fused together due to negative dependence");
-
+ "statements cannot be fused together due to negative dependence");
+
}
//fused_nodes_counter++;
-
+
}
-
+
}
-
+
return s;
}
-
-
void Loop::setLexicalOrder(int dim, const std::set<int> &active,
int starting_order, std::vector<std::vector<std::string> > idxNames) {
- fprintf(stderr, "Loop::setLexicalOrder() %d idxNames active size %d starting_order %d\n", idxNames.size(), active.size(), starting_order);
+ fprintf(stderr, "Loop::setLexicalOrder() %d idxNames active size %d starting_order %d\n", idxNames.size(),
+ active.size(), starting_order);
if (active.size() == 0)
return;
- for (int i=0; i< idxNames.size(); i++) {
+ for (int i = 0; i < idxNames.size(); i++) {
std::vector<std::string> what = idxNames[i];
- for (int j=0; j<what.size(); j++) {
- fprintf(stderr, "%2d %2d %s\n", i,j, what[j].c_str());
+ for (int j = 0; j < what.size(); j++) {
+ fprintf(stderr, "%2d %2d %s\n", i, j, what[j].c_str());
}
}
// check for sanity of parameters
if (dim < 0 || dim % 2 != 0)
throw std::invalid_argument(
- "invalid constant loop level to set lexicographical order");
+ "invalid constant loop level to set lexicographical order");
std::vector<int> lex;
int ref_stmt_num;
for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
if ((*i) < 0 || (*i) >= stmt.size())
throw std::invalid_argument(
- "invalid statement number " + to_string(*i));
+ "invalid statement number " + to_string(*i));
if (dim >= stmt[*i].xform.n_out())
throw std::invalid_argument(
- "invalid constant loop level to set lexicographical order");
+ "invalid constant loop level to set lexicographical order");
if (i == active.begin()) {
lex = getLexicalOrder(*i);
ref_stmt_num = *i;
@@ -1909,10 +1914,10 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
for (int j = 0; j < dim; j += 2)
if (lex[j] != lex2[j])
throw std::invalid_argument(
- "statements are not in the same sub loop nest");
+ "statements are not in the same sub loop nest");
}
}
-
+
// separate statements by current loop level types
int level = (dim + 2) / 2;
std::map<std::pair<LoopLevelType, int>, std::set<int> > active_by_level_type;
@@ -1922,21 +1927,21 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
active_by_no_level.insert(*i);
else
active_by_level_type[std::make_pair(
- stmt[*i].loop_level[level - 1].type,
- stmt[*i].loop_level[level - 1].payload)].insert(*i);
+ stmt[*i].loop_level[level - 1].type,
+ stmt[*i].loop_level[level - 1].payload)].insert(*i);
}
-
+
// further separate statements due to control dependences
std::vector<std::set<int> > active_by_level_type_splitted;
for (std::map<std::pair<LoopLevelType, int>, std::set<int> >::iterator i =
- active_by_level_type.begin(); i != active_by_level_type.end(); i++)
+ active_by_level_type.begin(); i != active_by_level_type.end(); i++)
active_by_level_type_splitted.push_back(i->second);
for (std::set<int>::iterator i = active_by_no_level.begin();
i != active_by_no_level.end(); i++)
for (int j = active_by_level_type_splitted.size() - 1; j >= 0; j--) {
std::set<int> controlled, not_controlled;
for (std::set<int>::iterator k =
- active_by_level_type_splitted[j].begin();
+ active_by_level_type_splitted[j].begin();
k != active_by_level_type_splitted[j].end(); k++) {
std::vector<DependenceVector> dvs = dep.getEdge(*i, *k);
bool is_controlled = false;
@@ -1952,19 +1957,19 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
}
if (controlled.size() != 0 && not_controlled.size() != 0) {
active_by_level_type_splitted.erase(
- active_by_level_type_splitted.begin() + j);
+ active_by_level_type_splitted.begin() + j);
active_by_level_type_splitted.push_back(controlled);
active_by_level_type_splitted.push_back(not_controlled);
}
}
-
+
// set lexical order separating loops with different loop types first
if (active_by_level_type_splitted.size() + active_by_no_level.size() > 1) {
int dep_dim = get_last_dep_dim_before(ref_stmt_num, level) + 1;
-
+
Graph<std::set<int>, Empty> g;
for (std::vector<std::set<int> >::iterator i =
- active_by_level_type_splitted.begin();
+ active_by_level_type_splitted.begin();
i != active_by_level_type_splitted.end(); i++)
g.insert(*i);
for (std::set<int>::iterator i = active_by_no_level.begin();
@@ -1986,7 +1991,7 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
if (dvs[k].is_control_dependence()
|| (dvs[k].is_data_dependence()
&& !dvs[k].has_been_carried_before(
- dep_dim))) {
+ dep_dim))) {
g.connect(i, j);
connected = true;
break;
@@ -2010,7 +2015,7 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
if (dvs[k].is_control_dependence()
|| (dvs[k].is_data_dependence()
&& !dvs[k].has_been_carried_before(
- dep_dim))) {
+ dep_dim))) {
g.connect(j, i);
connected = true;
break;
@@ -2022,13 +2027,13 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
break;
}
}
-
+
std::vector<std::set<int> > s = g.topoSort();
if (s.size() != g.vertex.size())
throw loop_error(
- "cannot separate statements with different loop types at loop level "
- + to_string(level));
-
+ "cannot separate statements with different loop types at loop level "
+ + to_string(level));
+
// assign lexical order
int order = starting_order;
for (int i = 0; i < s.size(); i++) {
@@ -2041,19 +2046,18 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
assign_const(stmt[cur_stmt].xform, j, 0);
order++;
} else { // recurse !
- fprintf(stderr, "Loop:setLexicalOrder() recursing\n");
+ fprintf(stderr, "Loop:setLexicalOrder() recursing\n");
setLexicalOrder(dim, cur_scc, order, idxNames);
order += sz;
}
}
- }
- else { // set lexical order separating single iteration statements and loops
+ } else { // set lexical order separating single iteration statements and loops
std::set<int> true_singles;
std::set<int> nonsingles;
std::map<coef_t, std::set<int> > fake_singles;
std::set<int> fake_singles_;
-
+
// sort out statements that do not require loops
for (std::set<int>::iterator i = active.begin(); i != active.end();
i++) {
@@ -2071,7 +2075,7 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
fake_singles_.insert(*i);
try {
fake_singles[get_const(cur_IS, dim + 1, Set_Var)].insert(
- *i);
+ *i);
} catch (const std::exception &e) {
fake_singles[posInfinity].insert(*i);
}
@@ -2079,60 +2083,60 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
} else
nonsingles.insert(*i);
}
-
-
+
+
// split nonsingles forcibly according to negative dependences present (loop unfusible)
int dep_dim = get_dep_dim_of(ref_stmt_num, level);
-
+
if (dim < stmt[ref_stmt_num].xform.n_out() - 1) {
-
+
bool dummy_level_found = false;
-
+
std::vector<std::set<int> > s;
-
+
s = sort_by_same_loops(active, level);
bool further_levels_exist = false;
-
+
if (!idxNames.empty())
if (level <= idxNames[ref_stmt_num].size())
if (idxNames[ref_stmt_num][level - 1].length() == 0) {
// && s.size() == 1) {
int order1 = 0;
dummy_level_found = true;
-
+
for (int i = level; i < idxNames[ref_stmt_num].size();
i++)
if (idxNames[ref_stmt_num][i].length() > 0)
further_levels_exist = true;
-
+
}
-
+
//if (!dummy_level_found) {
-
+
if (s.size() > 1) {
-
+
std::vector<bool> types;
for (int i = 0; i < s.size(); i++)
types.push_back(true);
-
+
Graph<std::set<int>, bool> g = construct_induced_graph_at_level(
- s, dep, dep_dim);
+ s, dep, dep_dim);
s = typed_fusion(g, types);
}
int order = starting_order;
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, dim, order);
stmt[*it].xform.simplify();
}
-
+
if ((dim + 2) <= (stmt[ref_stmt_num].xform.n_out() - 1)) { // recurse !
- fprintf(stderr, "Loop:setLexicalOrder() recursing\n");
+ fprintf(stderr, "Loop:setLexicalOrder() recursing\n");
setLexicalOrder(dim + 2, s[i], order, idxNames);
}
-
+
order++;
}
//}
@@ -2231,8 +2235,8 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
break;
}
*/
-
-
+
+
// assign lexical order
/*int order = starting_order;
for (int i = 0; i < s.size(); i++) {
@@ -2261,17 +2265,16 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
*/
}
- fprintf(stderr, "LEAVING Loop::setLexicalOrder() %d idxNames\n", idxNames.size());
- for (int i=0; i< idxNames.size(); i++) {
+ fprintf(stderr, "LEAVING Loop::setLexicalOrder() %d idxNames\n", idxNames.size());
+ for (int i = 0; i < idxNames.size(); i++) {
std::vector<std::string> what = idxNames[i];
- for (int j=0; j<what.size(); j++) {
- fprintf(stderr, "%2d %2d %s\n", i,j, what[j].c_str());
+ for (int j = 0; j < what.size(); j++) {
+ fprintf(stderr, "%2d %2d %s\n", i, j, what[j].c_str());
}
}
}
-
void Loop::apply_xform() {
std::set<int> active;
for (int i = 0; i < stmt.size(); i++)
@@ -2280,26 +2283,26 @@ void Loop::apply_xform() {
}
void Loop::apply_xform(int stmt_num) {
- fprintf(stderr, "apply_xform( %d )\n", stmt_num);
+ fprintf(stderr, "apply_xform( %d )\n", stmt_num);
std::set<int> active;
active.insert(stmt_num);
apply_xform(active);
}
void Loop::apply_xform(std::set<int> &active) {
- fflush(stdout);
+ fflush(stdout);
fprintf(stderr, "loop.cc apply_xform( set )\n");
-
+
int max_n = 0;
-
+
omega::CG_outputBuilder *ocg = ir->builder();
for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
int n = stmt[*i].loop_level.size();
if (n > max_n)
max_n = n;
-
+
std::vector<int> lex = getLexicalOrder(*i);
-
+
omega::Relation mapping(2 * n + 1, n);
omega::F_And *f_root = mapping.add_and();
for (int j = 1; j <= n; j++) {
@@ -2309,7 +2312,7 @@ void Loop::apply_xform(std::set<int> &active) {
}
mapping = omega::Composition(mapping, stmt[*i].xform);
mapping.simplify();
-
+
// match omega input/output variables to variable names in the code
for (int j = 1; j <= stmt[*i].IS.n_set(); j++)
mapping.name_input_var(j, stmt[*i].IS.set_var(j)->name());
@@ -2317,28 +2320,28 @@ void Loop::apply_xform(std::set<int> &active) {
mapping.name_output_var(j,
tmp_loop_var_name_prefix
+ omega::to_string(
- tmp_loop_var_name_counter + j - 1));
+ tmp_loop_var_name_counter + j - 1));
mapping.setup_names();
mapping.print(); // "{[I] -> [_t1] : I = _t1 }
- fflush(stdout);
-
+ fflush(stdout);
+
omega::Relation known = Extend_Set(copy(this->known),
mapping.n_out() - this->known.n_set());
//stmt[*i].code = outputStatement(ocg, stmt[*i].code, 0, mapping, known, std::vector<CG_outputRepr *>(mapping.n_out(), NULL));
-
- omega::CG_outputBuilder *ocgr = ir->builder();
-
-
+
+ omega::CG_outputBuilder *ocgr = ir->builder();
+
+
//this is probably CG_chillBuilder;
-
+
omega::CG_stringBuilder *ocgs = new omega::CG_stringBuilder;
if (uninterpreted_symbols[*i].size() == 0) {
-
-
+
+
std::set<std::string> globals;
-
+
for (omega::DNF_Iterator di(stmt[*i].IS.query_DNF()); di; di++) {
-
+
for (omega::Constraint_Iterator e(*di); e; e++) {
for (omega::Constr_Vars_Iter cvi(*e); cvi; cvi++) {
omega::Variable_ID v = cvi.curr_var();
@@ -2349,105 +2352,106 @@ void Loop::apply_xform(std::set<int> &active) {
globals.insert(v->name());
std::vector<omega::CG_outputRepr *> reprs;
std::vector<omega::CG_outputRepr *> reprs2;
-
+
for (int l = 1; l <= g->arity(); l++) {
omega::CG_outputRepr *temp = ocgr->CreateIdent(
- stmt[*i].IS.set_var(l)->name());
+ stmt[*i].IS.set_var(l)->name());
omega::CG_outputRepr *temp2 = ocgs->CreateIdent(
- stmt[*i].IS.set_var(l)->name());
-
+ stmt[*i].IS.set_var(l)->name());
+
reprs.push_back(temp);
reprs2.push_back(temp2);
}
uninterpreted_symbols[*i].insert(
- std::pair<std::string,
- std::vector<omega::CG_outputRepr *> >(
- v->get_global_var()->base_name(),
- reprs));
+ std::pair<std::string,
+ std::vector<omega::CG_outputRepr *> >(
+ v->get_global_var()->base_name(),
+ reprs));
uninterpreted_symbols_stringrepr[*i].insert(
- std::pair<std::string,
- std::vector<omega::CG_outputRepr *> >(
- v->get_global_var()->base_name(),
- reprs2));
+ std::pair<std::string,
+ std::vector<omega::CG_outputRepr *> >(
+ v->get_global_var()->base_name(),
+ reprs2));
}
}
}
}
}
-
+
std::vector<std::string> loop_vars;
for (int j = 1; j <= stmt[*i].IS.n_set(); j++) {
loop_vars.push_back(stmt[*i].IS.set_var(j)->name());
}
- for (int j = 0; j<loop_vars.size(); j++) {
- fprintf(stderr, "loop vars %d %s\n", j, loop_vars[j].c_str());
+ for (int j = 0; j < loop_vars.size(); j++) {
+ fprintf(stderr, "loop vars %d %s\n", j, loop_vars[j].c_str());
}
std::vector<CG_outputRepr *> subs = output_substitutions(ocg,
Inverse(copy(mapping)),
std::vector<std::pair<CG_outputRepr *, int> >(
- mapping.n_out(),
- std::make_pair(
- static_cast<CG_outputRepr *>(NULL), 0)),
+ mapping.n_out(),
+ std::make_pair(
+ static_cast<CG_outputRepr *>(NULL), 0)),
uninterpreted_symbols[*i]);
-
+
std::vector<CG_outputRepr *> subs2;
for (int l = 0; l < subs.size(); l++)
subs2.push_back(subs[l]->clone());
-
- fprintf(stderr, "%d uninterpreted symbols\n", (int)uninterpreted_symbols.size());
- for (int j = 0; j<loop_vars.size(); j++) {
- fprintf(stderr, "loop vars %d %s\n", j, loop_vars[j].c_str());
- }
-
-
- int count = 0;
+
+ fprintf(stderr, "%d uninterpreted symbols\n", (int) uninterpreted_symbols.size());
+ for (int j = 0; j < loop_vars.size(); j++) {
+ fprintf(stderr, "loop vars %d %s\n", j, loop_vars[j].c_str());
+ }
+
+
+ int count = 0;
for (std::map<std::string, std::vector<CG_outputRepr *> >::iterator it =
- uninterpreted_symbols[*i].begin();
+ uninterpreted_symbols[*i].begin();
it != uninterpreted_symbols[*i].end(); it++) {
- fprintf(stderr, "\ncount %d\n", count);
-
+ fprintf(stderr, "\ncount %d\n", count);
+
std::vector<CG_outputRepr *> reprs_ = it->second;
- fprintf(stderr, "%d reprs_\n", (int)reprs_.size());
-
+ fprintf(stderr, "%d reprs_\n", (int) reprs_.size());
+
std::vector<CG_outputRepr *> reprs_2;
for (int k = 0; k < reprs_.size(); k++) {
- fprintf(stderr, "k %d\n", k);
+ fprintf(stderr, "k %d\n", k);
std::vector<CG_outputRepr *> subs;
for (int l = 0; l < subs2.size(); l++) {
- fprintf(stderr, "l %d\n", l);
+ fprintf(stderr, "l %d\n", l);
subs.push_back(subs2[l]->clone());
}
-
+
fprintf(stderr, "clone\n");
- CG_outputRepr *c = reprs_[k]->clone();
- c->dump(); fflush(stdout);
-
- fprintf(stderr, "createsub\n");
+ CG_outputRepr *c = reprs_[k]->clone();
+ c->dump();
+ fflush(stdout);
+
+ fprintf(stderr, "createsub\n");
CG_outputRepr *s = ocgr->CreateSubstitutedStmt(0, c,
loop_vars, subs, true);
-
- fprintf(stderr, "push back\n");
- reprs_2.push_back( s );
-
+
+ fprintf(stderr, "push back\n");
+ reprs_2.push_back(s);
+
}
-
+
it->second = reprs_2;
count++;
- fprintf(stderr, "bottom\n");
+ fprintf(stderr, "bottom\n");
}
-
+
std::vector<CG_outputRepr *> subs3 = output_substitutions(
- ocgs, Inverse(copy(mapping)),
- std::vector<std::pair<CG_outputRepr *, int> >(
- mapping.n_out(),
- std::make_pair(
- static_cast<CG_outputRepr *>(NULL), 0)),
- uninterpreted_symbols_stringrepr[*i]);
-
+ ocgs, Inverse(copy(mapping)),
+ std::vector<std::pair<CG_outputRepr *, int> >(
+ mapping.n_out(),
+ std::make_pair(
+ static_cast<CG_outputRepr *>(NULL), 0)),
+ uninterpreted_symbols_stringrepr[*i]);
+
for (std::map<std::string, std::vector<CG_outputRepr *> >::iterator it =
- uninterpreted_symbols_stringrepr[*i].begin();
+ uninterpreted_symbols_stringrepr[*i].begin();
it != uninterpreted_symbols_stringrepr[*i].end(); it++) {
-
+
std::vector<CG_outputRepr *> reprs_ = it->second;
std::vector<CG_outputRepr *> reprs_2;
for (int k = 0; k < reprs_.size(); k++) {
@@ -2460,13 +2464,13 @@ void Loop::apply_xform(std::set<int> &active) {
*/
reprs_2.push_back(subs3[k]->clone());
}
-
+
it->second = reprs_2;
-
+
}
-
-
- fprintf(stderr, "loop.cc stmt[*i].code =\n");
+
+
+ fprintf(stderr, "loop.cc stmt[*i].code =\n");
//stmt[*i].code->dump();
//fprintf(stderr, "\n");
stmt[*i].code = ocg->CreateSubstitutedStmt(0, stmt[*i].code, loop_vars,
@@ -2474,10 +2478,10 @@ void Loop::apply_xform(std::set<int> &active) {
//fprintf(stderr, "loop.cc substituted code =\n");
//stmt[*i].code->dump();
//fprintf(stderr, "\n");
-
+
stmt[*i].IS = omega::Range(Restrict_Domain(mapping, stmt[*i].IS));
stmt[*i].IS.simplify();
-
+
// replace original transformation relation with straight 1-1 mapping
//fprintf(stderr, "replace original transformation relation with straight 1-1 mapping\n");
mapping = Relation(n, 2 * n + 1);
@@ -2493,46 +2497,44 @@ void Loop::apply_xform(std::set<int> &active) {
h.update_const(-lex[j - 1]);
}
stmt[*i].xform = mapping;
-
+
//fprintf(stderr, "\ncode is: \n");
//stmt[*i].code->dump();
//fprintf(stderr, "\n\n");
-
+
}
-
+
tmp_loop_var_name_counter += max_n;
- fflush(stdout);
- fprintf(stderr, "loop.cc LEAVING apply_xform( set )\n\n");
+ fflush(stdout);
+ fprintf(stderr, "loop.cc LEAVING apply_xform( set )\n\n");
//for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
// fprintf(stderr, "\nloop.cc stmt[i].code =\n");
// stmt[*i].code->dump();
// fprintf(stderr, "\n\n");
//}
-
-}
-
+}
void Loop::addKnown(const Relation &cond) {
-
+
// invalidate saved codegen computation
delete last_compute_cgr_;
last_compute_cgr_ = NULL;
delete last_compute_cg_;
last_compute_cg_ = NULL;
fprintf(stderr, "Loop::addKnown(), SETTING last_compute_cg_ = NULL\n");
-
+
int n1 = this->known.n_set();
-
+
Relation r = copy(cond);
int n2 = r.n_set();
-
+
if (n1 < n2)
this->known = Extend_Set(this->known, n2 - n1);
else if (n1 > n2)
r = Extend_Set(r, n1 - n2);
-
+
this->known = Intersection(this->known, r);
}
@@ -2540,11 +2542,11 @@ void Loop::removeDependence(int stmt_num_from, int stmt_num_to) {
// check for sanity of parameters
if (stmt_num_from >= stmt.size())
throw std::invalid_argument(
- "invalid statement number " + to_string(stmt_num_from));
+ "invalid statement number " + to_string(stmt_num_from));
if (stmt_num_to >= stmt.size())
throw std::invalid_argument(
- "invalid statement number " + to_string(stmt_num_to));
-
+ "invalid statement number " + to_string(stmt_num_to));
+
dep.disconnect(stmt_num_from, stmt_num_to);
}
@@ -2556,14 +2558,14 @@ void Loop::dump() const {
if (2 * j < lex.size())
std::cout << lex[2 * j];
switch (stmt[i].loop_level[j].type) {
- case LoopLevelOriginal:
- std::cout << "(dim:" << stmt[i].loop_level[j].payload << ")";
- break;
- case LoopLevelTile:
- std::cout << "(tile:" << stmt[i].loop_level[j].payload << ")";
- break;
- default:
- std::cout << "(unknown)";
+ case LoopLevelOriginal:
+ std::cout << "(dim:" << stmt[i].loop_level[j].payload << ")";
+ break;
+ case LoopLevelTile:
+ std::cout << "(tile:" << stmt[i].loop_level[j].payload << ")";
+ break;
+ default:
+ std::cout << "(unknown)";
}
std::cout << ' ';
}
@@ -2579,16 +2581,16 @@ void Loop::dump() const {
bool Loop::nonsingular(const std::vector<std::vector<int> > &T) {
if (stmt.size() == 0)
return true;
-
+
// check for sanity of parameters
for (int i = 0; i < stmt.size(); i++) {
if (stmt[i].loop_level.size() != num_dep_dim)
throw std::invalid_argument(
- "nonsingular loop transformations must be applied to original perfect loop nest");
+ "nonsingular loop transformations must be applied to original perfect loop nest");
for (int j = 0; j < stmt[i].loop_level.size(); j++)
if (stmt[i].loop_level[j].type != LoopLevelOriginal)
throw std::invalid_argument(
- "nonsingular loop transformations must be applied to original perfect loop nest");
+ "nonsingular loop transformations must be applied to original perfect loop nest");
}
if (T.size() != num_dep_dim)
throw std::invalid_argument("invalid transformation matrix");
@@ -2619,81 +2621,80 @@ bool Loop::nonsingular(const std::vector<std::vector<int> > &T) {
h.update_coef(mapping.output_var(i), -1);
h.update_coef(mapping.input_var(i), 1);
}
-
+
// update transformation relations
for (int i = 0; i < stmt.size(); i++)
stmt[i].xform = Composition(copy(mapping), stmt[i].xform);
-
+
// update dependence graph
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();
+ dep.vertex[i].second.begin(); j != dep.vertex[i].second.end();
j++) {
std::vector<DependenceVector> dvs = j->second;
for (int k = 0; k < dvs.size(); k++) {
DependenceVector &dv = dvs[k];
switch (dv.type) {
- case DEP_W2R:
- case DEP_R2W:
- case DEP_W2W:
- case DEP_R2R: {
- std::vector<coef_t> lbounds(num_dep_dim), ubounds(
- num_dep_dim);
- for (int p = 0; p < num_dep_dim; p++) {
- coef_t lb = 0;
- coef_t ub = 0;
- for (int q = 0; q < num_dep_dim; q++) {
- if (T[p][q] > 0) {
- if (lb == -posInfinity
- || dv.lbounds[q] == -posInfinity)
- lb = -posInfinity;
- else
- lb += T[p][q] * dv.lbounds[q];
- if (ub == posInfinity
- || dv.ubounds[q] == posInfinity)
- ub = posInfinity;
- else
- ub += T[p][q] * dv.ubounds[q];
- } else if (T[p][q] < 0) {
- if (lb == -posInfinity
- || dv.ubounds[q] == posInfinity)
- lb = -posInfinity;
- else
- lb += T[p][q] * dv.ubounds[q];
- if (ub == posInfinity
- || dv.lbounds[q] == -posInfinity)
- ub = posInfinity;
- else
- ub += T[p][q] * dv.lbounds[q];
+ case DEP_W2R:
+ case DEP_R2W:
+ case DEP_W2W:
+ case DEP_R2R: {
+ std::vector<coef_t> lbounds(num_dep_dim), ubounds(
+ num_dep_dim);
+ for (int p = 0; p < num_dep_dim; p++) {
+ coef_t lb = 0;
+ coef_t ub = 0;
+ for (int q = 0; q < num_dep_dim; q++) {
+ if (T[p][q] > 0) {
+ if (lb == -posInfinity
+ || dv.lbounds[q] == -posInfinity)
+ lb = -posInfinity;
+ else
+ lb += T[p][q] * dv.lbounds[q];
+ if (ub == posInfinity
+ || dv.ubounds[q] == posInfinity)
+ ub = posInfinity;
+ else
+ ub += T[p][q] * dv.ubounds[q];
+ } else if (T[p][q] < 0) {
+ if (lb == -posInfinity
+ || dv.ubounds[q] == posInfinity)
+ lb = -posInfinity;
+ else
+ lb += T[p][q] * dv.ubounds[q];
+ if (ub == posInfinity
+ || dv.lbounds[q] == -posInfinity)
+ ub = posInfinity;
+ else
+ ub += T[p][q] * dv.lbounds[q];
+ }
}
+ if (T[p].size() == num_dep_dim + 1) {
+ if (lb != -posInfinity)
+ lb += T[p][num_dep_dim];
+ if (ub != posInfinity)
+ ub += T[p][num_dep_dim];
+ }
+ lbounds[p] = lb;
+ ubounds[p] = ub;
}
- if (T[p].size() == num_dep_dim + 1) {
- if (lb != -posInfinity)
- lb += T[p][num_dep_dim];
- if (ub != posInfinity)
- ub += T[p][num_dep_dim];
- }
- lbounds[p] = lb;
- ubounds[p] = ub;
+ dv.lbounds = lbounds;
+ dv.ubounds = ubounds;
+
+ break;
}
- dv.lbounds = lbounds;
- dv.ubounds = ubounds;
-
- break;
- }
- default:
- ;
+ default:;
}
}
j->second = dvs;
}
-
+
// set constant loop values
std::set<int> active;
for (int i = 0; i < stmt.size(); i++)
active.insert(i);
setLexicalOrder(0, active);
-
+
return true;
}
@@ -2706,12 +2707,11 @@ bool Loop::is_dependence_valid_based_on_lex_order(int i, int j,
if (!dv.is_scalar_dependence) {
for (last_dim = 0;
last_dim < lex_i.size() && (lex_i[last_dim] == lex_j[last_dim]);
- last_dim++)
- ;
+ last_dim++);
last_dim = last_dim / 2;
if (last_dim == 0)
return true;
-
+
for (int i = 0; i < last_dim; i++) {
if (dv.lbounds[i] > 0)
return true;
@@ -2721,9 +2721,9 @@ bool Loop::is_dependence_valid_based_on_lex_order(int i, int j,
}
if (before)
return true;
-
+
return false;
-
+
}
// Manu:: reduction operation
@@ -2731,7 +2731,7 @@ bool Loop::is_dependence_valid_based_on_lex_order(int i, int j,
void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
std::string arrName, int memory_type, int padding_alignment,
int assign_then_accumulate, int padding_stride) {
-
+
//std::cout << "In scalar_expand function: " << stmt_num << ", " << arrName << "\n";
//std::cout.flush();
@@ -2744,10 +2744,10 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
// check for sanity of parameters
bool found_non_constant_size_dimension = false;
-
+
if (stmt_num < 0 || stmt_num >= stmt.size())
throw std::invalid_argument(
- "invalid statement number " + to_string(stmt_num));
+ "invalid statement number " + to_string(stmt_num));
//Anand: adding check for privatized levels
//if (arrName != "RHS")
// throw std::invalid_argument(
@@ -2755,34 +2755,33 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
for (int i = 0; i < levels.size(); i++) {
if (levels[i] <= 0 || levels[i] > stmt[stmt_num].loop_level.size())
throw std::invalid_argument(
- "1invalid loop level " + to_string(levels[i]));
-
+ "1invalid loop level " + to_string(levels[i]));
+
if (i > 0) {
if (levels[i] < levels[i - 1])
throw std::invalid_argument(
- "loop levels must be in ascending order");
+ "loop levels must be in ascending order");
}
}
//end --adding check for privatized levels
-
+
delete last_compute_cgr_;
last_compute_cgr_ = NULL;
delete last_compute_cg_;
last_compute_cg_ = NULL;
fprintf(stderr, "Loop::scalar_expand(), SETTING last_compute_cg_ = NULL\n");
- fprintf(stderr, "\nloop.cc finding array accesses in stmt %d of the code\n",stmt_num );
+ fprintf(stderr, "\nloop.cc finding array accesses in stmt %d of the code\n", stmt_num);
std::vector<IR_ArrayRef *> access = ir->FindArrayRef(stmt[stmt_num].code);
- fprintf(stderr, "loop.cc L2726 %d access\n", access.size());
+ fprintf(stderr, "loop.cc L2726 %d access\n", access.size());
IR_ArraySymbol *sym = NULL;
- fprintf(stderr, "arrName %s\n", arrName.c_str());
- if (arrName == "RHS") {
- fprintf(stderr, "sym RHS\n");
+ fprintf(stderr, "arrName %s\n", arrName.c_str());
+ if (arrName == "RHS") {
+ fprintf(stderr, "sym RHS\n");
sym = access[0]->symbol();
- }
- else {
- fprintf(stderr, "looking for array %s in access\n", arrName.c_str());
+ } else {
+ fprintf(stderr, "looking for array %s in access\n", arrName.c_str());
for (int k = 0; k < access.size(); k++) { // BUH
//fprintf(stderr, "access[%d] = %s ", k, access[k]->getTypeString()); access[k]->print(0,stderr); fprintf(stderr, "\n");
@@ -2791,34 +2790,34 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//fprintf(stderr, "comparing %s to %s\n", name.c_str(), arrName.c_str());
if (access[k]->symbol()->name() == arrName) {
- fprintf(stderr, "found it sym access[ k=%d ]\n", k);
+ fprintf(stderr, "found it sym access[ k=%d ]\n", k);
sym = access[k]->symbol();
- }
+ }
}
}
- if (!sym) fprintf(stderr, "DIDN'T FIND IT\n");
- fprintf(stderr, "sym %p\n", sym);
+ if (!sym) fprintf(stderr, "DIDN'T FIND IT\n");
+ fprintf(stderr, "sym %p\n", sym);
// collect array references by name
std::vector<int> lex = getLexicalOrder(stmt_num);
int dim = 2 * levels[levels.size() - 1] - 1;
std::set<int> same_loop = getStatements(lex, dim - 1);
-
+
//Anand: shifting this down
// assign_const(stmt[newStmt_num].xform, 2*level+1, 1);
-
+
// std::cout << " before temp array name \n ";
// create a temporary variable
IR_Symbol *tmp_sym;
-
+
// get the loop upperbound, that would be the size of the temp array.
omega::coef_t lb[levels.size()], ub[levels.size()], size[levels.size()];
-
+
//Anand Adding apply xform so that tiled loop bounds are reflected
fprintf(stderr, "Adding apply xform so that tiled loop bounds are reflected\n");
apply_xform(same_loop);
- fprintf(stderr, "loop.cc, back from apply_xform()\n");
-
+ fprintf(stderr, "loop.cc, back from apply_xform()\n");
+
//Anand commenting out the folowing 4 lines
/* copy(stmt[stmt_num].IS).query_variable_bounds(
copy(stmt[stmt_num].IS).set_var(level), lb, ub);
@@ -2890,32 +2889,32 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
std::vector<int> size_int;
Relation xform = copy(stmt[stmt_num].xform);
for (int i = 0; i < n_dim; i++) {
-
+
dim = 2 * levels[i] - 1;
//Anand: Commenting out the lines below: not required
// if (i != 0)
// reduced_copy_is = Project(reduced_copy_is, level - 1 + i, Set_Var);
Relation bound = get_loop_bound(copy(reduced_copy_is), levels[i] - 1);
-
+
// extract stride
std::pair<EQ_Handle, Variable_ID> result = find_simplest_stride(bound,
bound.set_var(levels[i]));
if (result.second != NULL)
index_stride[i] = abs(result.first.get_coef(result.second))
- / gcd(abs(result.first.get_coef(result.second)),
- abs(
- result.first.get_coef(
- bound.set_var(levels[i]))));
+ / gcd(abs(result.first.get_coef(result.second)),
+ abs(
+ result.first.get_coef(
+ bound.set_var(levels[i]))));
else
index_stride[i] = 1;
// std::cout << "simplest_stride 11:: " << index_stride[i] << "\n";
-
+
// check if this array index requires loop
Conjunct *c = bound.query_DNF()->single_conjunct();
for (EQ_Iterator ei(c->EQs()); ei; ei++) {
if ((*ei).has_wildcards())
continue;
-
+
int coef = (*ei).get_coef(bound.set_var(levels[i]));
if (coef != 0) {
int sign = 1;
@@ -2923,59 +2922,58 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
coef = -coef;
sign = -1;
}
-
+
CG_outputRepr *op = NULL;
for (Constr_Vars_Iter ci(*ei); ci; ci++) {
switch ((*ci).var->kind()) {
- case Input_Var: {
- if ((*ci).var != bound.set_var(levels[i]))
+ case Input_Var: {
+ if ((*ci).var != bound.set_var(levels[i]))
+ if ((*ci).coef * sign == 1)
+ op = ocg1->CreateMinus(op,
+ ocg1->CreateIdent((*ci).var->name()));
+ else if ((*ci).coef * sign == -1)
+ op = ocg1->CreatePlus(op,
+ ocg1->CreateIdent((*ci).var->name()));
+ else if ((*ci).coef * sign > 1) {
+ op = ocg1->CreateMinus(op,
+ ocg1->CreateTimes(
+ ocg1->CreateInt(
+ abs((*ci).coef)),
+ ocg1->CreateIdent(
+ (*ci).var->name())));
+ } else
+ // (*ci).coef*sign < -1
+ op = ocg1->CreatePlus(op,
+ ocg1->CreateTimes(
+ ocg1->CreateInt(
+ abs((*ci).coef)),
+ ocg1->CreateIdent(
+ (*ci).var->name())));
+ break;
+ }
+ case Global_Var: {
+ Global_Var_ID g = (*ci).var->get_global_var();
if ((*ci).coef * sign == 1)
op = ocg1->CreateMinus(op,
- ocg1->CreateIdent((*ci).var->name()));
+ ocg1->CreateIdent(g->base_name()));
else if ((*ci).coef * sign == -1)
op = ocg1->CreatePlus(op,
- ocg1->CreateIdent((*ci).var->name()));
- else if ((*ci).coef * sign > 1) {
+ ocg1->CreateIdent(g->base_name()));
+ else if ((*ci).coef * sign > 1)
op = ocg1->CreateMinus(op,
ocg1->CreateTimes(
- ocg1->CreateInt(
- abs((*ci).coef)),
- ocg1->CreateIdent(
- (*ci).var->name())));
- }
+ ocg1->CreateInt(abs((*ci).coef)),
+ ocg1->CreateIdent(g->base_name())));
else
// (*ci).coef*sign < -1
op = ocg1->CreatePlus(op,
ocg1->CreateTimes(
- ocg1->CreateInt(
- abs((*ci).coef)),
- ocg1->CreateIdent(
- (*ci).var->name())));
- break;
- }
- case Global_Var: {
- Global_Var_ID g = (*ci).var->get_global_var();
- if ((*ci).coef * sign == 1)
- op = ocg1->CreateMinus(op,
- ocg1->CreateIdent(g->base_name()));
- else if ((*ci).coef * sign == -1)
- op = ocg1->CreatePlus(op,
- ocg1->CreateIdent(g->base_name()));
- else if ((*ci).coef * sign > 1)
- op = ocg1->CreateMinus(op,
- ocg1->CreateTimes(
- ocg1->CreateInt(abs((*ci).coef)),
- ocg1->CreateIdent(g->base_name())));
- else
- // (*ci).coef*sign < -1
- op = ocg1->CreatePlus(op,
- ocg1->CreateTimes(
- ocg1->CreateInt(abs((*ci).coef)),
- ocg1->CreateIdent(g->base_name())));
- break;
- }
- default:
- throw loop_error("unsupported array index expression");
+ ocg1->CreateInt(abs((*ci).coef)),
+ ocg1->CreateIdent(g->base_name())));
+ break;
+ }
+ default:
+ throw loop_error("unsupported array index expression");
}
}
if ((*ei).get_const() != 0)
@@ -2983,7 +2981,7 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
ocg1->CreateInt(-sign * ((*ei).get_const())));
if (coef != 1)
op = ocg1->CreateIntegerFloor(op, ocg1->CreateInt(coef));
-
+
index_lb[i] = op;
is_index_eq[i] = true;
break;
@@ -2991,7 +2989,7 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
}
if (is_index_eq[i])
continue;
-
+
// separate lower and upper bounds
std::vector<GEQ_Handle> lb_list, ub_list;
std::set<Variable_ID> excluded_floor_vars;
@@ -3006,23 +3004,22 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
excluded_floor_vars).first) {
clean_bound = false;
break;
- }
- else
- h= find_floor_definition(bound, (*cvi).var,
- excluded_floor_vars).second;
-
+ } else
+ h = find_floor_definition(bound, (*cvi).var,
+ excluded_floor_vars).second;
+
if (!clean_bound)
continue;
- else{
+ else {
if (coef > 0)
lb_list.push_back(h);
else if (coef < 0)
ub_list.push_back(h);
- continue;
- }
-
+ continue;
+ }
+
}
-
+
if (coef > 0)
lb_list.push_back(*gi);
else if (coef < 0)
@@ -3030,7 +3027,7 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
}
if (lb_list.size() == 0 || ub_list.size() == 0)
throw loop_error("failed to calcuate array footprint size");
-
+
// build lower bound representation
std::vector<CG_outputRepr *> lb_repr_list;
/* for (int j = 0; j < lb_list.size(); j++){
@@ -3045,7 +3042,7 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
index_lb[i] = ocg1->CreateInvoke("max", lb_repr_list);
else if (lb_repr_list.size() == 1)
index_lb[i] = lb_repr_list[0];
-
+
// build temporary array size representation
{
Relation cal(copy_is.n_set(), 1);
@@ -3053,65 +3050,65 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
for (int j = 0; j < ub_list.size(); j++)
for (int k = 0; k < lb_list.size(); k++) {
GEQ_Handle h = f_root->add_GEQ();
-
+
for (Constr_Vars_Iter ci(ub_list[j]); ci; ci++) {
switch ((*ci).var->kind()) {
- case Input_Var: {
- int pos = (*ci).var->get_position();
- h.update_coef(cal.input_var(pos), (*ci).coef);
- break;
- }
- case Global_Var: {
- Global_Var_ID g = (*ci).var->get_global_var();
- Variable_ID v;
- if (g->arity() == 0)
- v = cal.get_local(g);
- else
- v = cal.get_local(g, (*ci).var->function_of());
- h.update_coef(v, (*ci).coef);
- break;
- }
- default:
- throw loop_error(
- "cannot calculate temporay array size statically");
+ case Input_Var: {
+ int pos = (*ci).var->get_position();
+ h.update_coef(cal.input_var(pos), (*ci).coef);
+ break;
+ }
+ case Global_Var: {
+ Global_Var_ID g = (*ci).var->get_global_var();
+ Variable_ID v;
+ if (g->arity() == 0)
+ v = cal.get_local(g);
+ else
+ v = cal.get_local(g, (*ci).var->function_of());
+ h.update_coef(v, (*ci).coef);
+ break;
+ }
+ default:
+ throw loop_error(
+ "cannot calculate temporay array size statically");
}
}
h.update_const(ub_list[j].get_const());
-
+
for (Constr_Vars_Iter ci(lb_list[k]); ci; ci++) {
switch ((*ci).var->kind()) {
- case Input_Var: {
- int pos = (*ci).var->get_position();
- h.update_coef(cal.input_var(pos), (*ci).coef);
- break;
- }
- case Global_Var: {
- Global_Var_ID g = (*ci).var->get_global_var();
- Variable_ID v;
- if (g->arity() == 0)
- v = cal.get_local(g);
- else
- v = cal.get_local(g, (*ci).var->function_of());
- h.update_coef(v, (*ci).coef);
- break;
- }
- default:
- throw loop_error(
- "cannot calculate temporay array size statically");
+ case Input_Var: {
+ int pos = (*ci).var->get_position();
+ h.update_coef(cal.input_var(pos), (*ci).coef);
+ break;
+ }
+ case Global_Var: {
+ Global_Var_ID g = (*ci).var->get_global_var();
+ Variable_ID v;
+ if (g->arity() == 0)
+ v = cal.get_local(g);
+ else
+ v = cal.get_local(g, (*ci).var->function_of());
+ h.update_coef(v, (*ci).coef);
+ break;
+ }
+ default:
+ throw loop_error(
+ "cannot calculate temporay array size statically");
}
}
h.update_const(lb_list[k].get_const());
-
+
h.update_const(1);
h.update_coef(cal.output_var(1), -1);
}
-
+
cal = Restrict_Domain(cal, copy(copy_is));
for (int j = 1; j <= cal.n_inp(); j++) {
cal = Project(cal, j, Input_Var);
}
cal.simplify();
-
+
// pad temporary array size
// TODO: for variable array size, create padding formula
//int padding_stride = 0;
@@ -3125,50 +3122,50 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
gi++)
if ((*gi).is_const(cal.output_var(1))) {
coef_t size = (*gi).get_const()
- / (-(*gi).get_coef(cal.output_var(1)));
-
+ / (-(*gi).get_coef(cal.output_var(1)));
+
if (padding_alignment > 1 && i == n_dim - 1) { // align to boundary for data packing
int residue = size % padding_alignment;
if (residue)
size = size + padding_alignment - residue;
}
-
+
index_sz.push_back(
- std::make_pair(i, ocg1->CreateInt(size)));
+ std::make_pair(i, ocg1->CreateInt(size)));
is_index_bound_const = true;
size_int.push_back(size);
size_repr.push_back(ocg1->CreateInt(size));
-
+
// std::cout << "============================== size :: "
// << size << "\n";
-
+
}
-
+
if (!is_index_bound_const) {
-
+
found_non_constant_size_dimension = true;
Conjunct *c = bound.query_DNF()->single_conjunct();
for (GEQ_Iterator gi(c->GEQs());
gi && !is_index_bound_const; gi++) {
int coef = (*gi).get_coef(bound.set_var(levels[i]));
if (coef < 0) {
-
+
size_repr.push_back(
- ocg1->CreatePlus(
- output_upper_bound_repr(ocg1, *gi,
- bound.set_var(levels[i]),
- bound,
- std::vector<
- std::pair<
- CG_outputRepr *,
- int> >(
- bound.n_set(),
- std::make_pair(
- static_cast<CG_outputRepr *>(NULL),
- 0)),
- uninterpreted_symbols[stmt_num]),
- ocg1->CreateInt(1)));
-
+ ocg1->CreatePlus(
+ output_upper_bound_repr(ocg1, *gi,
+ bound.set_var(levels[i]),
+ bound,
+ std::vector<
+ std::pair<
+ CG_outputRepr *,
+ int> >(
+ bound.n_set(),
+ std::make_pair(
+ static_cast<CG_outputRepr *>(NULL),
+ 0)),
+ uninterpreted_symbols[stmt_num]),
+ ocg1->CreateInt(1)));
+
/*CG_outputRepr *op = NULL;
for (Constr_Vars_Iter ci(*gi); ci; ci++) {
if ((*ci).var != cal.output_var(1)) {
@@ -3238,13 +3235,13 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
}
}
//size[i] = ub[i];
-
+
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
-
+
//Anand: Creating IS of new statement
-
+
//for(int l = dim; l < stmt[stmt_num].xform.n_out(); l+=2)
//std::cout << "In scalar_expand function 3: " << stmt_num << ", " << arrName << "\n";
//std::cout.flush();
@@ -3256,16 +3253,16 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//}
//fprintf(stderr, "\n");
-
+
shiftLexicalOrder(lex, dim + 1, 1);
Statement s = stmt[stmt_num];
s.ir_stmt_node = NULL;
int newStmt_num = stmt.size();
- fprintf(stderr, "loop.cc L3249 adding stmt %d\n", stmt.size());
+ fprintf(stderr, "loop.cc L3249 adding stmt %d\n", stmt.size());
stmt.push_back(s);
-
- fprintf(stderr, "uninterpreted_symbols.push_back() newStmt_num %d\n", newStmt_num);
+
+ fprintf(stderr, "uninterpreted_symbols.push_back() newStmt_num %d\n", newStmt_num);
uninterpreted_symbols.push_back(uninterpreted_symbols[stmt_num]);
uninterpreted_symbols_stringrepr.push_back(uninterpreted_symbols_stringrepr[stmt_num]);
stmt[newStmt_num].code = stmt[stmt_num].code->clone();
@@ -3286,16 +3283,16 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//assign_const(stmt[newStmt_num].xform, stmt[stmt_num].xform.n_out(), 1);//Anand: change from 2*level + 1 to stmt[stmt_num].xform.size()
//Anand-End creating IS of new statement
-
- CG_outputRepr * tmpArrSz;
+
+ CG_outputRepr *tmpArrSz;
CG_outputBuilder *ocg = ir->builder();
-
+
//for(int k =0; k < levels.size(); k++ )
// size_repr.push_back(ocg->CreateInt(size[k]));//Anand: copying apply_xform functionality to prevent IS modification
//due to side effects with uninterpreted function symbols and failures in omega
-
+
//int n = stmt[stmt_num].loop_level.size();
-
+
/*Relation mapping(2 * n + 1, n);
F_And *f_root = mapping.add_and();
for (int j = 1; j <= n; j++) {
@@ -3318,64 +3315,68 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
Relation size_ = omega::Range(Restrict_Domain(mapping, copy(stmt[stmt_num].IS)));
size_.simplify();
*/
-
+
//Anand -commenting out tmp sym creation as symbol may have more than one dimension
//tmp_sym = ir->CreateArraySymbol(tmpArrSz, sym);
std::vector<CG_outputRepr *> lhs_index;
CG_outputRepr *arr_ref_repr;
arr_ref_repr = ocg->CreateIdent(
- stmt[stmt_num].IS.set_var(levels[levels.size() - 1])->name());
-
+ stmt[stmt_num].IS.set_var(levels[levels.size() - 1])->name());
+
CG_outputRepr *total_size = size_repr[0];
- fprintf(stderr, "total_size = "); total_size->dump(); fflush(stdout);
+ fprintf(stderr, "total_size = ");
+ total_size->dump();
+ fflush(stdout);
for (int i = 1; i < size_repr.size(); i++) {
- fprintf(stderr, "total_size now "); total_size->dump(); fflush(stdout); fprintf(stderr, " times something\n\n");
+ fprintf(stderr, "total_size now ");
+ total_size->dump();
+ fflush(stdout);
+ fprintf(stderr, " times something\n\n");
total_size = ocg->CreateTimes(total_size->clone(),
size_repr[i]->clone());
-
+
}
-
+
// COMMENT NEEDED
//fprintf(stderr, "\nloop.cc COMMENT NEEDED\n");
for (int k = levels.size() - 2; k >= 0; k--) {
- CG_outputRepr *temp_repr =ocg->CreateIdent(stmt[stmt_num].IS.set_var(levels[k])->name());
- for (int l = k + 1; l < levels.size(); l++) {
+ CG_outputRepr *temp_repr = ocg->CreateIdent(stmt[stmt_num].IS.set_var(levels[k])->name());
+ for (int l = k + 1; l < levels.size(); l++) {
//fprintf(stderr, "\nloop.cc CREATETIMES\n");
temp_repr = ocg->CreateTimes(temp_repr->clone(),
size_repr[l]->clone());
}
-
+
//fprintf(stderr, "\nloop.cc CREATEPLUS\n");
arr_ref_repr = ocg->CreatePlus(arr_ref_repr->clone(),
temp_repr->clone());
}
-
+
//fprintf(stderr, "loop.cc, about to die\n");
std::vector<CG_outputRepr *> to_push;
to_push.push_back(total_size);
- if (!found_non_constant_size_dimension) {
- fprintf(stderr, "constant size dimension\n");
+ if (!found_non_constant_size_dimension) {
+ fprintf(stderr, "constant size dimension\n");
tmp_sym = ir->CreateArraySymbol(sym, to_push, memory_type);
- }
- else {
- fprintf(stderr, "NON constant size dimension?\n");
+ } else {
+ fprintf(stderr, "NON constant size dimension?\n");
//tmp_sym = ir->CreatePointerSymbol(sym, to_push);
tmp_sym = ir->CreatePointerSymbol(sym, to_push);
static_cast<IR_PointerSymbol *>(tmp_sym)->set_size(0, total_size); // ??
ptr_variables.push_back(static_cast<IR_PointerSymbol *>(tmp_sym));
- fprintf(stderr, "ptr_variables now has %d entries\n", ptr_variables.size());
+ fprintf(stderr, "ptr_variables now has %d entries\n", ptr_variables.size());
}
-
+
// add tmp_sym to Loop symtables ??
-
+
// std::cout << " temp array name == " << tmp_sym->name().c_str() << "\n";
-
+
// get loop index variable at the given "level"
// Relation R = omega::Range(Restrict_Domain(copy(stmt[stmt_num].xform), copy(stmt[stmt_num].IS)));
// stmt[stmt_num].IS.print();
@@ -3383,9 +3384,9 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
// std::cout << stmt[stmt_num].IS.n_set() << std::endl;
// std::string v = stmt[stmt_num].IS.set_var(level)->name();
// std::cout << "loop index variable is '" << v.c_str() << "'\n";
-
+
// create a reference for the temporary array
- fprintf(stderr, "create a reference for the temporary array\n");
+ fprintf(stderr, "create a reference for the temporary array\n");
//std::cout << "In scalar_expand function 4: " << stmt_num << ", " << arrName << "\n";
//std::cout.flush();
@@ -3396,7 +3397,7 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//}
//fprintf(stderr, "\n");
-
+
std::vector<CG_outputRepr *> to_push2;
to_push2.push_back(arr_ref_repr); // can have only one entry
@@ -3405,21 +3406,20 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
IR_ArrayRef *tmp_array_ref;
- IR_PointerArrayRef * tmp_ptr_array_ref; // was IR_PointerArrayref
+ IR_PointerArrayRef *tmp_ptr_array_ref; // was IR_PointerArrayref
if (!found_non_constant_size_dimension) {
fprintf(stderr, "constant size\n");
tmp_array_ref = ir->CreateArrayRef(
- static_cast<IR_ArraySymbol *>(tmp_sym), to_push2);
- }
- else {
- fprintf(stderr, "NON constant size\n");
+ static_cast<IR_ArraySymbol *>(tmp_sym), to_push2);
+ } else {
+ fprintf(stderr, "NON constant size\n");
tmp_ptr_array_ref = ir->CreatePointerArrayRef(
- static_cast<IR_PointerSymbol *>(tmp_sym), to_push2);
+ static_cast<IR_PointerSymbol *>(tmp_sym), to_push2);
// TODO static_cast<IR_PointerSymbol *>(tmp_sym), to_push2);
}
- fflush(stdout);
+ fflush(stdout);
//fprintf(stderr, "\n%d statements\n", stmt.size());
//for (int i=0; i<stmt.size(); i++) {
@@ -3432,22 +3432,22 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//std::string stemp;
//stemp = tmp_array_ref->name();
//std::cout << "Created array reference --> " << stemp.c_str() << "\n";
-
+
// get the RHS expression
- fprintf(stderr, "get the RHS expression arrName %s\n", arrName.c_str());
+ fprintf(stderr, "get the RHS expression arrName %s\n", arrName.c_str());
CG_outputRepr *rhs;
if (arrName == "RHS") {
rhs = ir->GetRHSExpression(stmt[stmt_num].code);
-
+
std::vector<IR_ArrayRef *> symbols = ir->FindArrayRef(rhs);
}
std::set<std::string> sym_names;
-
+
//for (int i = 0; i < symbols.size(); i++)
// sym_names.insert(symbols[i]->symbol()->name());
-
- fflush(stdout);
+
+ fflush(stdout);
//fprintf(stderr, "\nbefore if (arrName == RHS)\n%d statements\n", stmt.size()); // problem is after here
//for (int i=0; i<stmt.size(); i++) {
@@ -3457,15 +3457,14 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//fprintf(stderr, "\n");
if (arrName == "RHS") {
-
+
std::vector<IR_ArrayRef *> symbols = ir->FindArrayRef(rhs);
-
+
for (int i = 0; i < symbols.size(); i++)
sym_names.insert(symbols[i]->symbol()->name());
- }
- else {
+ } else {
- fprintf(stderr, "finding array refs in stmt_num %d\n", stmt_num);
+ fprintf(stderr, "finding array refs in stmt_num %d\n", stmt_num);
//fprintf(stderr, "\n%d statements\n", stmt.size());
//for (int i=0; i<stmt.size(); i++) {
// fprintf(stderr, "%2d ", i);
@@ -3474,15 +3473,15 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//fprintf(stderr, "\n");
std::vector<IR_ArrayRef *> refs = ir->FindArrayRef(stmt[stmt_num].code);
- fprintf(stderr, "\n%d refs\n", refs.size());
+ fprintf(stderr, "\n%d refs\n", refs.size());
+
-
bool found = false;
for (int j = 0; j < refs.size(); j++) {
- CG_outputRepr* to_replace;
+ CG_outputRepr *to_replace;
- fprintf(stderr, "j %d build new assignment statement with temporary array\n",j);
+ fprintf(stderr, "j %d build new assignment statement with temporary array\n", j);
// build new assignment statement with temporary array
if (!found_non_constant_size_dimension) {
to_replace = tmp_array_ref->convert();
@@ -3494,7 +3493,7 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//CR->Dump();
if (refs[j]->name() == arrName) {
- fflush(stdout);
+ fflush(stdout);
fprintf(stderr, "loop.cc L353\n"); // problem is after here
//fprintf(stderr, "\n%d statements\n", stmt.size());
//for (int i=0; i<stmt.size(); i++) {
@@ -3502,15 +3501,15 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
// ((CG_chillRepr *)stmt[i].code)->Dump();
//}
//fprintf(stderr, "\n");
-
+
sym_names.insert(refs[j]->symbol()->name());
-
+
if (!found) {
- if (!found_non_constant_size_dimension) {
- fprintf(stderr, "constant size2\n");
- omega::CG_outputRepr * t = tmp_array_ref->convert();
- omega::CG_outputRepr * r = refs[j]->convert()->clone();
+ if (!found_non_constant_size_dimension) {
+ fprintf(stderr, "constant size2\n");
+ omega::CG_outputRepr *t = tmp_array_ref->convert();
+ omega::CG_outputRepr *r = refs[j]->convert()->clone();
//CR = (CG_chillRepr *) t;
//CR->Dump();
//CR = (CG_chillRepr *) r;
@@ -3518,14 +3517,13 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//fprintf(stderr, "lhs t %p lhs r %p\n", t, r);
stmt[newStmt_num].code =
- ir->builder()->CreateAssignment(0,
- t, // tmp_array_ref->convert(),
- r); // refs[j]->convert()->clone()
- }
- else {
- fprintf(stderr, "NON constant size2\n");
- omega::CG_outputRepr * t = tmp_ptr_array_ref->convert(); // this fails
- omega::CG_outputRepr * r = refs[j]->convert()->clone();
+ ir->builder()->CreateAssignment(0,
+ t, // tmp_array_ref->convert(),
+ r); // refs[j]->convert()->clone()
+ } else {
+ fprintf(stderr, "NON constant size2\n");
+ omega::CG_outputRepr *t = tmp_ptr_array_ref->convert(); // this fails
+ omega::CG_outputRepr *r = refs[j]->convert()->clone();
//omega::CG_chillRepr *CR = (omega::CG_chillRepr *) t;
//CR->Dump();
@@ -3534,21 +3532,21 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//fprintf(stderr, "lhs t %p lhs r %p\n", t, r);
stmt[newStmt_num].code =
- ir->builder()->CreateAssignment(0,
- t, // tmp_ptr_array_ref->convert(),
- r ); // refs[j]->convert()->clone());
+ ir->builder()->CreateAssignment(0,
+ t, // tmp_ptr_array_ref->convert(),
+ r); // refs[j]->convert()->clone());
}
found = true;
-
+
}
-
+
// refs[j] has no parent?
- fprintf(stderr, "replacing refs[%d]\n", j );
+ fprintf(stderr, "replacing refs[%d]\n", j);
ir->ReplaceExpression(refs[j], to_replace);
}
-
+
}
-
+
}
//ToDo need to update the dependence graph
//Anand adding dependence graph update
@@ -3561,10 +3559,10 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
//fprintf(stderr, "\n");
dep.insert();
-
+
//Anand:Copying Dependence checks from datacopy code, might need to be a separate function/module
// in the future
-
+
/*for (int i = 0; i < newStmt_num; i++) {
std::vector<std::vector<DependenceVector> > D;
@@ -3615,41 +3613,41 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
*/
//Anand--end dependence check
if (arrName == "RHS") {
-
+
// build new assignment statement with temporary array
if (!found_non_constant_size_dimension) {
if (assign_then_accumulate) {
stmt[newStmt_num].code = ir->builder()->CreateAssignment(0,
tmp_array_ref->convert(), rhs);
- fprintf(stderr, "ir->ReplaceRHSExpression( stmt_ num %d )\n", stmt_num);
+ fprintf(stderr, "ir->ReplaceRHSExpression( stmt_ num %d )\n", stmt_num);
ir->ReplaceRHSExpression(stmt[stmt_num].code, tmp_array_ref);
} else {
CG_outputRepr *temp = tmp_array_ref->convert()->clone();
if (ir->QueryExpOperation(stmt[stmt_num].code)
!= IR_OP_PLUS_ASSIGNMENT)
throw ir_error(
- "Statement is not a += accumulation statement");
+ "Statement is not a += accumulation statement");
- fprintf(stderr, "replacing in a +=\n");
+ fprintf(stderr, "replacing in a +=\n");
stmt[newStmt_num].code = ir->builder()->CreatePlusAssignment(0,
temp->clone(), rhs);
-
- CG_outputRepr * lhs = ir->GetLHSExpression(stmt[stmt_num].code);
-
+
+ CG_outputRepr *lhs = ir->GetLHSExpression(stmt[stmt_num].code);
+
CG_outputRepr *assignment = ir->builder()->CreateAssignment(0,
lhs, temp->clone());
Statement init_ = stmt[newStmt_num]; // copy ??
init_.ir_stmt_node = NULL;
-
+
init_.code = stmt[newStmt_num].code->clone();
init_.IS = copy(stmt[newStmt_num].IS);
init_.xform = copy(stmt[newStmt_num].xform);
init_.has_inspector = false; // ??
Relation mapping(init_.IS.n_set(), init_.IS.n_set());
-
+
F_And *f_root = mapping.add_and();
-
+
for (int i = 1; i <= mapping.n_inp(); i++) {
EQ_Handle h = f_root->add_EQ();
//if (i < levels[0]) {
@@ -3660,7 +3658,7 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
h.update_const(-1);
h.update_coef(mapping.output_var(i), 1);
}
-
+
/*else {
int j;
for (j = 0; j < levels.size(); j++)
@@ -3683,18 +3681,18 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
*/
//}
}
-
+
mapping.simplify();
// match omega input/output variables to variable names in the code
for (int j = 1; j <= init_.IS.n_set(); j++)
mapping.name_output_var(j, init_.IS.set_var(j)->name());
for (int j = 1; j <= init_.IS.n_set(); j++)
mapping.name_input_var(j, init_.IS.set_var(j)->name());
-
+
mapping.setup_names();
-
+
init_.IS = omega::Range(
- omega::Restrict_Domain(mapping, init_.IS));
+ omega::Restrict_Domain(mapping, init_.IS));
std::vector<int> lex = getLexicalOrder(newStmt_num);
int dim = 2 * levels[0] - 1;
//init_.IS.print();
@@ -3704,11 +3702,11 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
shiftLexicalOrder(lex, dim + 1, 1);
init_.reduction = stmt[newStmt_num].reduction;
init_.reductionOp = stmt[newStmt_num].reductionOp;
-
+
init_.code = ir->builder()->CreateAssignment(0, temp->clone(),
ir->builder()->CreateInt(0));
- fprintf(stderr, "loop.cc L3693 adding stmt %d\n", stmt.size());
+ fprintf(stderr, "loop.cc L3693 adding stmt %d\n", stmt.size());
stmt.push_back(init_);
uninterpreted_symbols.push_back(uninterpreted_symbols[newStmt_num]);
@@ -3726,47 +3724,45 @@ void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
if (ir->QueryExpOperation(stmt[stmt_num].code)
!= IR_OP_PLUS_ASSIGNMENT)
throw ir_error(
- "Statement is not a += accumulation statement");
+ "Statement is not a += accumulation statement");
stmt[newStmt_num].code = ir->builder()->CreatePlusAssignment(0,
temp->clone(), rhs);
-
- CG_outputRepr * lhs = ir->GetLHSExpression(stmt[stmt_num].code);
-
+
+ CG_outputRepr *lhs = ir->GetLHSExpression(stmt[stmt_num].code);
+
CG_outputRepr *assignment = ir->builder()->CreateAssignment(0,
lhs, temp->clone());
-
+
stmt[stmt_num].code = assignment;
}
// call function to replace rhs with temporary array
}
}
-
+
//std::cout << "End of scalar_expand function!! \n";
-
+
// if(arrName == "RHS"){
DependenceVector dv;
std::vector<DependenceVector> E;
dv.lbounds = std::vector<omega::coef_t>(4);
dv.ubounds = std::vector<omega::coef_t>(4);
dv.type = DEP_W2R;
-
+
for (int k = 0; k < 4; k++) {
dv.lbounds[k] = 0;
dv.ubounds[k] = 0;
-
+
}
-
+
//std::vector<IR_ArrayRef*> array_refs = ir->FindArrayRef(stmt[newStmt_num].code);
dv.sym = tmp_sym->clone();
-
+
E.push_back(dv);
-
+
dep.connect(newStmt_num, stmt_num, E);
// }
-
-}
-
+}
std::pair<Relation, Relation> createCSRstyleISandXFORM(CG_outputBuilder *ocg,
@@ -3775,98 +3771,98 @@ std::pair<Relation, Relation> createCSRstyleISandXFORM(CG_outputBuilder *ocg,
std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols,
std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols_string,
Loop *this_loop) {
-
+
Relation IS(outer_loop_bounds.size() + 1 + zero_loop_bounds.size());
Relation XFORM(outer_loop_bounds.size() + 1 + zero_loop_bounds.size(),
2 * (outer_loop_bounds.size() + 1 + zero_loop_bounds.size()) + 1);
-
- F_And * f_r_ = IS.add_and();
- F_And * f_root = XFORM.add_and();
-
+
+ F_And *f_r_ = IS.add_and();
+ F_And *f_root = XFORM.add_and();
+
if (outer_loop_bounds.size() > 0) {
for (int it = 0; it < IS.n_set(); it++) {
IS.name_set_var(it + 1,
const_cast<Relation &>(outer_loop_bounds[0]).set_var(it + 1)->name());
XFORM.name_input_var(it + 1,
const_cast<Relation &>(outer_loop_bounds[0]).set_var(it + 1)->name());
-
+
}
} else if (zero_loop_bounds.size() > 0) {
for (int it = 0; it < IS.n_set(); it++) {
IS.name_set_var(it + 1,
const_cast<Relation &>(zero_loop_bounds.begin()->second).set_var(
- it + 1)->name());
+ it + 1)->name());
XFORM.name_input_var(it + 1,
const_cast<Relation &>(zero_loop_bounds.begin()->second).set_var(
- it + 1)->name());
-
+ it + 1)->name());
+
}
-
+
}
-
+
for (int i = 0; i < outer_loop_bounds.size(); i++)
IS = replace_set_var_as_another_set_var(IS, outer_loop_bounds[i], i + 1,
i + 1);
-
+
int count = 1;
for (std::map<int, Relation>::iterator i = zero_loop_bounds.begin();
i != zero_loop_bounds.end(); i++, count++)
IS = replace_set_var_as_another_set_var(IS, i->second,
outer_loop_bounds.size() + 1 + count, i->first);
-
+
if (outer_loop_bounds.size() > 0) {
Free_Var_Decl *lb = new Free_Var_Decl(index_name + "_", 1); // index_
Variable_ID csr_lb = IS.get_local(lb, Input_Tuple);
-
+
Free_Var_Decl *ub = new Free_Var_Decl(index_name + "__", 1); // index__
Variable_ID csr_ub = IS.get_local(ub, Input_Tuple);
-
+
//lower bound
-
- F_And * f_r = IS.and_with_and();
+
+ F_And *f_r = IS.and_with_and();
GEQ_Handle lower_bound = f_r->add_GEQ();
lower_bound.update_coef(csr_lb, -1);
lower_bound.update_coef(IS.set_var(outer_loop_bounds.size() + 1), 1);
-
+
//upper bound
-
+
GEQ_Handle upper_bound = f_r->add_GEQ();
upper_bound.update_coef(csr_ub, 1);
upper_bound.update_coef(IS.set_var(outer_loop_bounds.size() + 1), -1);
upper_bound.update_const(-1);
-
+
omega::CG_stringBuilder *ocgs = new CG_stringBuilder;
-
+
std::vector<omega::CG_outputRepr *> reprs;
std::vector<omega::CG_outputRepr *> reprs2;
-
+
std::vector<omega::CG_outputRepr *> reprs3;
std::vector<omega::CG_outputRepr *> reprs4;
-
+
reprs.push_back(
- ocg->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
+ ocg->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
reprs2.push_back(
- ocgs->CreateIdent(
- IS.set_var(outer_loop_bounds.size())->name()));
+ ocgs->CreateIdent(
+ IS.set_var(outer_loop_bounds.size())->name()));
uninterpreted_symbols.insert(
- std::pair<std::string, std::vector<CG_outputRepr *> >(
- index_name + "_", reprs));
+ std::pair<std::string, std::vector<CG_outputRepr *> >(
+ index_name + "_", reprs));
uninterpreted_symbols_string.insert(
- std::pair<std::string, std::vector<CG_outputRepr *> >(
- index_name + "_", reprs2));
-
+ std::pair<std::string, std::vector<CG_outputRepr *> >(
+ index_name + "_", reprs2));
+
std::string arg = "(" + IS.set_var(outer_loop_bounds.size())->name()
- + ")";
- std::vector< std::string > argvec;
- argvec.push_back( arg );
-
+ + ")";
+ std::vector<std::string> argvec;
+ argvec.push_back(arg);
+
CG_outputRepr *repr = ocg->CreateArrayRefExpression(index_name,
ocg->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
-
+
//fprintf(stderr, "( VECTOR _)\n");
//fprintf(stderr, "loop.cc calling CreateDefineMacro( %s, argvec, repr)\n", (index_name + "_").c_str());
this_loop->ir->CreateDefineMacro(index_name + "_", argvec, repr);
-
+
Relation known_(copy(IS).n_set());
known_.copy_names(copy(IS));
known_.setup_names();
@@ -3878,80 +3874,81 @@ std::pair<Relation, Relation> createCSRstyleISandXFORM(CG_outputBuilder *ocg,
g.update_coef(index_lb, -1);
g.update_const(-1);
this_loop->addKnown(known_);
-
+
reprs3.push_back(
-
- ocg->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
+
+ ocg->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
reprs4.push_back(
-
- ocgs->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
-
+
+ ocgs->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
+
CG_outputRepr *repr2 = ocg->CreateArrayRefExpression(index_name,
ocg->CreatePlus(
- ocg->CreateIdent(
- IS.set_var(outer_loop_bounds.size())->name()),
- ocg->CreateInt(1)));
-
+ ocg->CreateIdent(
+ IS.set_var(outer_loop_bounds.size())->name()),
+ ocg->CreateInt(1)));
+
//fprintf(stderr, "( VECTOR __)\n");
//fprintf(stderr, "loop.cc calling CreateDefineMacro( %s, argvec, repr)\n", (index_name + "__").c_str());
-
+
this_loop->ir->CreateDefineMacro(index_name + "__", argvec, repr2);
-
+
uninterpreted_symbols.insert(
- std::pair<std::string, std::vector<CG_outputRepr *> >(
- index_name + "__", reprs3));
+ std::pair<std::string, std::vector<CG_outputRepr *> >(
+ index_name + "__", reprs3));
uninterpreted_symbols_string.insert(
- std::pair<std::string, std::vector<CG_outputRepr *> >(
- index_name + "__", reprs4));
+ std::pair<std::string, std::vector<CG_outputRepr *> >(
+ index_name + "__", reprs4));
} else {
Free_Var_Decl *ub = new Free_Var_Decl(index_name);
Variable_ID csr_ub = IS.get_local(ub);
- F_And * f_r = IS.and_with_and();
+ F_And *f_r = IS.and_with_and();
GEQ_Handle upper_bound = f_r->add_GEQ();
upper_bound.update_coef(csr_ub, 1);
upper_bound.update_coef(IS.set_var(outer_loop_bounds.size() + 1), -1);
upper_bound.update_const(-1);
-
+
GEQ_Handle lower_bound = f_r->add_GEQ();
lower_bound.update_coef(IS.set_var(outer_loop_bounds.size() + 1), 1);
-
+
}
-
+
for (int j = 1; j <= XFORM.n_inp(); j++) {
omega::EQ_Handle h = f_root->add_EQ();
h.update_coef(XFORM.output_var(2 * j), 1);
h.update_coef(XFORM.input_var(j), -1);
}
-
+
for (int j = 1; j <= XFORM.n_out(); j += 2) {
omega::EQ_Handle h = f_root->add_EQ();
h.update_coef(XFORM.output_var(j), 1);
}
-
+
if (_DEBUG_) {
IS.print();
XFORM.print();
-
+
}
-
+
return std::pair<Relation, Relation>(IS, XFORM);
-
+
}
std::pair<Relation, Relation> construct_reduced_IS_And_XFORM(IR_Code *ir,
- const Relation &is, const Relation &xform, const std::vector<int> loops,
+ const Relation &is, const Relation &xform,
+ const std::vector<int> loops,
std::vector<int> &lex_order, Relation &known,
std::map<std::string, std::vector<CG_outputRepr *> > &uninterpreted_symbols) {
-
+
Relation IS(loops.size());
Relation XFORM(loops.size(), 2 * loops.size() + 1);
int count_ = 1;
std::map<int, int> pos_mapping;
-
+
int n = is.n_set();
Relation is_and_known = Intersection(copy(is),
Extend_Set(copy(known), n - known.n_set()));
-
+
for (int it = 0; it < loops.size(); it++, count_++) {
IS.name_set_var(count_,
const_cast<Relation &>(is).set_var(loops[it])->name());
@@ -3963,11 +3960,11 @@ std::pair<Relation, Relation> construct_reduced_IS_And_XFORM(IR_Code *ir,
const_cast<Relation &>(xform).output_var((loops[it]) * 2 - 1)->name());
pos_mapping.insert(std::pair<int, int>(count_, loops[it]));
}
-
+
XFORM.name_output_var(2 * loops.size() + 1,
const_cast<Relation &>(xform).output_var(is.n_set() * 2 + 1)->name());
-
- F_And * f_r = IS.add_and();
+
+ F_And *f_r = IS.add_and();
for (std::map<int, int>::iterator it = pos_mapping.begin();
it != pos_mapping.end(); it++)
IS = replace_set_var_as_another_set_var(IS, is_and_known, it->first,
@@ -4012,9 +4009,9 @@ std::pair<Relation, Relation> construct_reduced_IS_And_XFORM(IR_Code *ir,
CHILL_DEBUG_END
F_And *f_root = XFORM.add_and();
-
+
count_ = 1;
-
+
for (int j = 1; j <= loops.size(); j++) {
omega::EQ_Handle h = f_root->add_EQ();
h.update_coef(XFORM.output_var(2 * j), 1);
@@ -4025,7 +4022,7 @@ std::pair<Relation, Relation> construct_reduced_IS_And_XFORM(IR_Code *ir,
h.update_coef(XFORM.output_var(count_ * 2 - 1), 1);
h.update_const(-lex_order[count_ * 2 - 2]);
}
-
+
omega::EQ_Handle h = f_root->add_EQ();
h.update_coef(XFORM.output_var((loops.size()) * 2 + 1), 1);
h.update_const(-lex_order[xform.n_out() - 1]);
@@ -4035,34 +4032,34 @@ std::pair<Relation, Relation> construct_reduced_IS_And_XFORM(IR_Code *ir,
IS.print();
XFORM.print();
CHILL_DEBUG_END
-
+
return std::pair<Relation, Relation>(IS, XFORM);
-
+
}
std::set<std::string> inspect_repr_for_scalars(IR_Code *ir,
- CG_outputRepr * repr, std::set<std::string> ignore) {
-
+ CG_outputRepr *repr, std::set<std::string> ignore) {
+
std::vector<IR_ScalarRef *> refs = ir->FindScalarRef(repr);
std::set<std::string> loop_vars;
-
+
for (int i = 0; i < refs.size(); i++)
if (ignore.find(refs[i]->name()) == ignore.end())
loop_vars.insert(refs[i]->name());
-
+
return loop_vars;
-
+
}
std::set<std::string> inspect_loop_bounds(IR_Code *ir, const Relation &R,
int pos,
std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols) {
-
+
if (!R.is_set())
throw loop_error("Input R has to be a set not a relation!");
-
+
std::set<std::string> vars;
-
+
std::vector<CG_outputRepr *> refs;
Variable_ID v = const_cast<Relation &>(R).set_var(pos);
for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
@@ -4071,48 +4068,48 @@ std::set<std::string> inspect_loop_bounds(IR_Code *ir, const Relation &R,
for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
Variable_ID v = cvi.curr_var();
switch (v->kind()) {
-
- case Global_Var: {
- Global_Var_ID g = v->get_global_var();
- Variable_ID v2;
- if (g->arity() > 0) {
-
- std::string s = g->base_name();
- std::copy(
- uninterpreted_symbols.find(s)->second.begin(),
- uninterpreted_symbols.find(s)->second.end(),
- back_inserter(refs));
-
+
+ case Global_Var: {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() > 0) {
+
+ std::string s = g->base_name();
+ std::copy(
+ uninterpreted_symbols.find(s)->second.begin(),
+ uninterpreted_symbols.find(s)->second.end(),
+ back_inserter(refs));
+
+ }
+
+ break;
}
-
- break;
- }
- default:
- break;
+ default:
+ break;
}
}
-
+
}
}
}
-
+
for (int i = 0; i < refs.size(); i++) {
std::vector<IR_ScalarRef *> refs_ = ir->FindScalarRef(refs[i]);
-
+
for (int j = 0; j < refs_.size(); j++)
vars.insert(refs_[j]->name());
-
+
}
return vars;
}
-CG_outputRepr * create_counting_loop_body(IR_Code *ir, const Relation &R,
- int pos, CG_outputRepr * count,
- std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols) {
-
+CG_outputRepr *create_counting_loop_body(IR_Code *ir, const Relation &R,
+ int pos, CG_outputRepr *count,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols) {
+
if (!R.is_set())
throw loop_error("Input R has to be a set not a relation!");
-
+
CG_outputRepr *ub, *lb;
ub = NULL;
lb = NULL;
@@ -4126,42 +4123,42 @@ CG_outputRepr * create_counting_loop_body(IR_Code *ir, const Relation &R,
for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
Variable_ID v = cvi.curr_var();
switch (v->kind()) {
-
- case Global_Var: {
- Global_Var_ID g = v->get_global_var();
- Variable_ID v2;
- if (g->arity() > 0) {
-
- std::string s = g->base_name();
-
- if ((*gi).get_coef(v) > 0) {
- if (ub != NULL)
- throw ir_error(
- "bound expression too complex!");
-
- ub = ir->builder()->CreateInvoke(s,
- uninterpreted_symbols.find(s)->second);
- //ub = ir->builder()->CreateMinus(ub->clone(), ir->builder()->CreateInt(-(*gi).get_const()));
- same_ge_1 = true;
-
- } else {
- if (lb != NULL)
- throw ir_error(
- "bound expression too complex!");
- lb = ir->builder()->CreateInvoke(s,
- uninterpreted_symbols.find(s)->second);
- same_ge_2 = true;
-
+
+ case Global_Var: {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() > 0) {
+
+ std::string s = g->base_name();
+
+ if ((*gi).get_coef(v) > 0) {
+ if (ub != NULL)
+ throw ir_error(
+ "bound expression too complex!");
+
+ ub = ir->builder()->CreateInvoke(s,
+ uninterpreted_symbols.find(s)->second);
+ //ub = ir->builder()->CreateMinus(ub->clone(), ir->builder()->CreateInt(-(*gi).get_const()));
+ same_ge_1 = true;
+
+ } else {
+ if (lb != NULL)
+ throw ir_error(
+ "bound expression too complex!");
+ lb = ir->builder()->CreateInvoke(s,
+ uninterpreted_symbols.find(s)->second);
+ same_ge_2 = true;
+
+ }
}
+
+ break;
}
-
- break;
- }
- default:
- break;
+ default:
+ break;
}
}
-
+
if (same_ge_1 && same_ge_2)
lb = ir->builder()->CreatePlus(lb->clone(),
ir->builder()->CreateInt(-(*gi).get_const()));
@@ -4173,181 +4170,179 @@ CG_outputRepr * create_counting_loop_body(IR_Code *ir, const Relation &R,
ir->builder()->CreateInt(-(*gi).get_const()));
}
}
-
+
}
-
+
return ir->builder()->CreatePlusAssignment(0, count,
ir->builder()->CreatePlus(
- ir->builder()->CreateMinus(ub->clone(), lb->clone()),
- ir->builder()->CreateInt(1)));
+ ir->builder()->CreateMinus(ub->clone(), lb->clone()),
+ ir->builder()->CreateInt(1)));
}
-
std::map<std::string, std::vector<std::string> > recurse_on_exp_for_arrays(
- IR_Code * ir, CG_outputRepr * exp) {
-
+ IR_Code *ir, CG_outputRepr *exp) {
+
std::map<std::string, std::vector<std::string> > arr_index_to_ref;
switch (ir->QueryExpOperation(exp)) {
-
- case IR_OP_ARRAY_VARIABLE: {
- IR_ArrayRef *ref = dynamic_cast<IR_ArrayRef *>(ir->Repr2Ref(exp));
- IR_PointerArrayRef *ref_ =
- dynamic_cast<IR_PointerArrayRef *>(ir->Repr2Ref(exp));
- if (ref == NULL && ref_ == NULL)
- throw loop_error("Array symbol unidentifiable!");
-
- if (ref != NULL) {
- std::vector<std::string> s0;
-
- for (int i = 0; i < ref->n_dim(); i++) {
- CG_outputRepr * index = ref->index(i);
- std::map<std::string, std::vector<std::string> > a0 =
- recurse_on_exp_for_arrays(ir, index);
- std::vector<std::string> s;
- for (std::map<std::string, std::vector<std::string> >::iterator j =
- a0.begin(); j != a0.end(); j++) {
- if (j->second.size() != 1 && (j->second)[0] != "")
- throw loop_error(
- "indirect array references not allowed in guard!");
- s.push_back(j->first);
+
+ case IR_OP_ARRAY_VARIABLE: {
+ IR_ArrayRef *ref = dynamic_cast<IR_ArrayRef *>(ir->Repr2Ref(exp));
+ IR_PointerArrayRef *ref_ =
+ dynamic_cast<IR_PointerArrayRef *>(ir->Repr2Ref(exp));
+ if (ref == NULL && ref_ == NULL)
+ throw loop_error("Array symbol unidentifiable!");
+
+ if (ref != NULL) {
+ std::vector<std::string> s0;
+
+ for (int i = 0; i < ref->n_dim(); i++) {
+ CG_outputRepr *index = ref->index(i);
+ std::map<std::string, std::vector<std::string> > a0 =
+ recurse_on_exp_for_arrays(ir, index);
+ std::vector<std::string> s;
+ for (std::map<std::string, std::vector<std::string> >::iterator j =
+ a0.begin(); j != a0.end(); j++) {
+ if (j->second.size() != 1 && (j->second)[0] != "")
+ throw loop_error(
+ "indirect array references not allowed in guard!");
+ s.push_back(j->first);
+ }
+ std::copy(s.begin(), s.end(), back_inserter(s0));
}
- std::copy(s.begin(), s.end(), back_inserter(s0));
- }
- arr_index_to_ref.insert(
- std::pair<std::string, std::vector<std::string> >(
- ref->name(), s0));
- } else {
- std::vector<std::string> s0;
- for (int i = 0; i < ref_->n_dim(); i++) {
- CG_outputRepr * index = ref_->index(i);
- std::map<std::string, std::vector<std::string> > a0 =
- recurse_on_exp_for_arrays(ir, index);
- std::vector<std::string> s;
- for (std::map<std::string, std::vector<std::string> >::iterator j =
- a0.begin(); j != a0.end(); j++) {
- if (j->second.size() != 1 && (j->second)[0] != "")
- throw loop_error(
- "indirect array references not allowed in guard!");
- s.push_back(j->first);
+ arr_index_to_ref.insert(
+ std::pair<std::string, std::vector<std::string> >(
+ ref->name(), s0));
+ } else {
+ std::vector<std::string> s0;
+ for (int i = 0; i < ref_->n_dim(); i++) {
+ CG_outputRepr *index = ref_->index(i);
+ std::map<std::string, std::vector<std::string> > a0 =
+ recurse_on_exp_for_arrays(ir, index);
+ std::vector<std::string> s;
+ for (std::map<std::string, std::vector<std::string> >::iterator j =
+ a0.begin(); j != a0.end(); j++) {
+ if (j->second.size() != 1 && (j->second)[0] != "")
+ throw loop_error(
+ "indirect array references not allowed in guard!");
+ s.push_back(j->first);
+ }
+ std::copy(s.begin(), s.end(), back_inserter(s0));
}
- std::copy(s.begin(), s.end(), back_inserter(s0));
+ arr_index_to_ref.insert(
+ std::pair<std::string, std::vector<std::string> >(
+ ref_->name(), s0));
}
- arr_index_to_ref.insert(
- std::pair<std::string, std::vector<std::string> >(
- ref_->name(), s0));
+ break;
}
- break;
- }
- case IR_OP_PLUS:
- case IR_OP_MINUS:
- case IR_OP_MULTIPLY:
- case IR_OP_DIVIDE: {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
- std::map<std::string, std::vector<std::string> > a0 =
- recurse_on_exp_for_arrays(ir, v[0]);
- std::map<std::string, std::vector<std::string> > a1 =
- recurse_on_exp_for_arrays(ir, v[1]);
- arr_index_to_ref.insert(a0.begin(), a0.end());
- arr_index_to_ref.insert(a1.begin(), a1.end());
- break;
-
- }
- case IR_OP_POSITIVE:
- case IR_OP_NEGATIVE: {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
- std::map<std::string, std::vector<std::string> > a0 =
- recurse_on_exp_for_arrays(ir, v[0]);
-
- arr_index_to_ref.insert(a0.begin(), a0.end());
- break;
-
- }
- case IR_OP_VARIABLE: {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
- IR_ScalarRef *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0]));
-
- std::string s = ref->name();
- std::vector<std::string> to_insert;
- to_insert.push_back("");
- arr_index_to_ref.insert(
- std::pair<std::string, std::vector<std::string> >(s,
- to_insert));
- break;
- }
- case IR_OP_CONSTANT:
- break;
-
- default: {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
-
- for (int i = 0; i < v.size(); i++) {
+ case IR_OP_PLUS:
+ case IR_OP_MINUS:
+ case IR_OP_MULTIPLY:
+ case IR_OP_DIVIDE: {
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
std::map<std::string, std::vector<std::string> > a0 =
- recurse_on_exp_for_arrays(ir, v[i]);
-
+ recurse_on_exp_for_arrays(ir, v[0]);
+ std::map<std::string, std::vector<std::string> > a1 =
+ recurse_on_exp_for_arrays(ir, v[1]);
arr_index_to_ref.insert(a0.begin(), a0.end());
+ arr_index_to_ref.insert(a1.begin(), a1.end());
+ break;
+
+ }
+ case IR_OP_POSITIVE:
+ case IR_OP_NEGATIVE: {
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
+ std::map<std::string, std::vector<std::string> > a0 =
+ recurse_on_exp_for_arrays(ir, v[0]);
+
+ arr_index_to_ref.insert(a0.begin(), a0.end());
+ break;
+
+ }
+ case IR_OP_VARIABLE: {
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
+ IR_ScalarRef *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0]));
+
+ std::string s = ref->name();
+ std::vector<std::string> to_insert;
+ to_insert.push_back("");
+ arr_index_to_ref.insert(
+ std::pair<std::string, std::vector<std::string> >(s,
+ to_insert));
+ break;
+ }
+ case IR_OP_CONSTANT:
+ break;
+
+ default: {
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
+
+ for (int i = 0; i < v.size(); i++) {
+ std::map<std::string, std::vector<std::string> > a0 =
+ recurse_on_exp_for_arrays(ir, v[i]);
+
+ arr_index_to_ref.insert(a0.begin(), a0.end());
+ }
+
+ break;
}
-
- break;
- }
}
return arr_index_to_ref;
}
-
std::vector<CG_outputRepr *> find_guards(IR_Code *ir, IR_Control *code) {
CHILL_DEBUG_PRINT("find_guards()\n");
std::vector<CG_outputRepr *> guards;
switch (code->type()) {
- case IR_CONTROL_IF: {
- CHILL_DEBUG_PRINT("find_guards() it's an if\n");
- CG_outputRepr *cond = dynamic_cast<IR_If*>(code)->condition();
-
- std::vector<CG_outputRepr *> then_body;
- std::vector<CG_outputRepr *> else_body;
- IR_Block *ORTB = dynamic_cast<IR_If*>(code)->then_body();
- if (ORTB != NULL) {
- CHILL_DEBUG_PRINT("recursing on then\n");
- then_body = find_guards(ir, ORTB);
- //dynamic_cast<IR_If*>(code)->then_body());
- }
- if (dynamic_cast<IR_If*>(code)->else_body() != NULL) {
- CHILL_DEBUG_PRINT("recursing on then\n");
- else_body = find_guards(ir,
- dynamic_cast<IR_If*>(code)->else_body());
+ case IR_CONTROL_IF: {
+ CHILL_DEBUG_PRINT("find_guards() it's an if\n");
+ CG_outputRepr *cond = dynamic_cast<IR_If *>(code)->condition();
+
+ std::vector<CG_outputRepr *> then_body;
+ std::vector<CG_outputRepr *> else_body;
+ IR_Block *ORTB = dynamic_cast<IR_If *>(code)->then_body();
+ if (ORTB != NULL) {
+ CHILL_DEBUG_PRINT("recursing on then\n");
+ then_body = find_guards(ir, ORTB);
+ //dynamic_cast<IR_If*>(code)->then_body());
+ }
+ if (dynamic_cast<IR_If *>(code)->else_body() != NULL) {
+ CHILL_DEBUG_PRINT("recursing on then\n");
+ else_body = find_guards(ir,
+ dynamic_cast<IR_If *>(code)->else_body());
+ }
+
+ guards.push_back(cond);
+ if (then_body.size() > 0)
+ std::copy(then_body.begin(), then_body.end(),
+ back_inserter(guards));
+ if (else_body.size() > 0)
+ std::copy(else_body.begin(), else_body.end(),
+ back_inserter(guards));
+ break;
}
-
- guards.push_back(cond);
- if (then_body.size() > 0)
- std::copy(then_body.begin(), then_body.end(),
- back_inserter(guards));
- if (else_body.size() > 0)
- std::copy(else_body.begin(), else_body.end(),
- back_inserter(guards));
- break;
- }
- case IR_CONTROL_BLOCK: {
- CHILL_DEBUG_PRINT("it's a control block\n");
- IR_Block* IRCB = dynamic_cast<IR_Block*>(code);
- CHILL_DEBUG_PRINT("calling ir->FindOneLevelControlStructure(IRCB);\n");
- std::vector<IR_Control *> stmts = ir->FindOneLevelControlStructure(IRCB);
-
- for (int i = 0; i < stmts.size(); i++) {
- std::vector<CG_outputRepr *> stmt_repr = find_guards(ir, stmts[i]);
- std::copy(stmt_repr.begin(), stmt_repr.end(),
- back_inserter(guards));
+ case IR_CONTROL_BLOCK: {
+ CHILL_DEBUG_PRINT("it's a control block\n");
+ IR_Block *IRCB = dynamic_cast<IR_Block *>(code);
+ CHILL_DEBUG_PRINT("calling ir->FindOneLevelControlStructure(IRCB);\n");
+ std::vector<IR_Control *> stmts = ir->FindOneLevelControlStructure(IRCB);
+
+ for (int i = 0; i < stmts.size(); i++) {
+ std::vector<CG_outputRepr *> stmt_repr = find_guards(ir, stmts[i]);
+ std::copy(stmt_repr.begin(), stmt_repr.end(),
+ back_inserter(guards));
+ }
+ break;
}
- break;
- }
- case IR_CONTROL_LOOP: {
- CHILL_DEBUG_PRINT("it's a control loop\n");
- std::vector<CG_outputRepr *> body = find_guards(ir,
- dynamic_cast<IR_Loop*>(code)->body());
- if (body.size() > 0)
- std::copy(body.begin(), body.end(), back_inserter(guards));
- break;
- } // loop
+ case IR_CONTROL_LOOP: {
+ CHILL_DEBUG_PRINT("it's a control loop\n");
+ std::vector<CG_outputRepr *> body = find_guards(ir,
+ dynamic_cast<IR_Loop *>(code)->body());
+ if (body.size() > 0)
+ std::copy(body.begin(), body.end(), back_inserter(guards));
+ break;
+ } // loop
} // switch
return guards;
}
@@ -4359,43 +4354,43 @@ bool sort_helper(std::pair<std::string, std::vector<std::string> > i,
for (int k = 0; k < i.second.size(); k++)
if (i.second[k] != "")
c1++;
-
+
for (int k = 0; k < j.second.size(); k++)
if (j.second[k] != "")
c2++;
return (c1 < c2);
-
+
}
bool sort_helper_2(std::pair<int, int> i, std::pair<int, int> j) {
-
+
return (i.second < j.second);
-
+
}
std::vector<std::string> construct_iteration_order(
- std::map<std::string, std::vector<std::string> > & input) {
+ std::map<std::string, std::vector<std::string> > &input) {
std::vector<std::string> arrays;
std::vector<std::string> scalars;
std::vector<std::pair<std::string, std::vector<std::string> > > input_aid;
-
+
for (std::map<std::string, std::vector<std::string> >::iterator j =
- input.begin(); j != input.end(); j++)
+ input.begin(); j != input.end(); j++)
input_aid.push_back(
- std::pair<std::string, std::vector<std::string> >(j->first,
- j->second));
-
+ std::pair<std::string, std::vector<std::string> >(j->first,
+ j->second));
+
std::sort(input_aid.begin(), input_aid.end(), sort_helper);
-
+
for (int j = 0; j < input_aid[input_aid.size() - 1].second.size(); j++)
if (input_aid[input_aid.size() - 1].second[j] != "") {
arrays.push_back(input_aid[input_aid.size() - 1].second[j]);
-
+
}
-
+
if (arrays.size() > 0) {
for (int i = input_aid.size() - 2; i >= 0; i--) {
-
+
int max_count = 0;
for (int j = 0; j < input_aid[i].second.size(); j++)
if (input_aid[i].second[j] != "") {
@@ -4421,7 +4416,7 @@ std::vector<std::string> construct_iteration_order(
}
}
} else {
-
+
for (int i = input_aid.size() - 1; i >= 0; i--) {
arrays.push_back(input_aid[i].first);
}