summaryrefslogtreecommitdiff
path: root/ir_suif_utils.cc
diff options
context:
space:
mode:
authordhuth <derickhuth@gmail.com>2014-08-27 09:52:06 -0600
committerdhuth <derickhuth@gmail.com>2014-08-27 09:52:06 -0600
commitbff810cc371a38f493d688c54f71013f5a7d53bf (patch)
treefbe86954bb3c01deb21da9e41ebff5baa2889a45 /ir_suif_utils.cc
downloadchill-bff810cc371a38f493d688c54f71013f5a7d53bf.tar.gz
chill-bff810cc371a38f493d688c54f71013f5a7d53bf.tar.bz2
chill-bff810cc371a38f493d688c54f71013f5a7d53bf.zip
Initial commit
Diffstat (limited to 'ir_suif_utils.cc')
-rw-r--r--ir_suif_utils.cc477
1 files changed, 477 insertions, 0 deletions
diff --git a/ir_suif_utils.cc b/ir_suif_utils.cc
new file mode 100644
index 0000000..f4e4edf
--- /dev/null
+++ b/ir_suif_utils.cc
@@ -0,0 +1,477 @@
+/*****************************************************************************
+ Copyright (C) 2008 University of Southern California
+ Copyright (C) 2009 University of Utah
+ All Rights Reserved.
+
+ Purpose:
+ SUIF interface utilities.
+
+ Notes:
+
+ Update history:
+ 01/2006 created by Chun Chen
+*****************************************************************************/
+
+#include <suif1.h>
+#include <useful.h>
+#include <vector>
+#include <algorithm>
+#include <code_gen/CG_suifRepr.h>
+#include "ir_suif_utils.hh"
+
+// ----------------------------------------------------------------------------
+// Mandatory SUIF stuff
+// ----------------------------------------------------------------------------
+char *prog_ver_string = "1.3.0.5-gccfix";
+char *prog_who_string = "automatically generated from chill";
+char *prog_suif_string = "suif";
+
+// static file_set_entry *fse = NULL;
+// static proc_sym *psym = NULL;
+
+// class SUIF_IR;
+
+// SUIF_IR *ir = NULL;
+
+// SUIF_IR::SUIF_IR(char *filename, int proc_num) {
+// // LIBRARY(ipmath, init_ipmath, exit_ipmath);
+// LIBRARY(useful, init_useful, exit_useful);
+// LIBRARY(annotes, init_annotes, exit_annotes);
+
+// int argc = 3;
+// char *argv[3];
+// argv[0] = "loop_xform";
+// argv[1] = strdup(filename);
+// argv[2] = strdup(filename);
+// char *pos = strrchr(argv[2], '.');
+// if (pos == NULL)
+// strcat(argv[2], ".lxf");
+// else {
+// *pos = '\0';
+// strcat(argv[2], ".lxf");
+// }
+// init_suif(argc, argv);
+
+// fileset->add_file(argv[1], argv[2]);
+// fileset->reset_iter();
+// _fse = fileset->next_file();
+// _fse->reset_proc_iter();
+// int cur_proc = 0;
+// while ((_psym = _fse->next_proc()) && cur_proc < proc_num)
+// ++cur_proc;
+// if (cur_proc != proc_num) {
+// fprintf(stderr, "procedure number %d couldn't be found\n", proc_num);
+// exit(1);
+// }
+// if (!_psym->is_in_memory())
+// _psym->read_proc(TRUE, _psym->src_lang() == src_fortran);
+
+// push_clue(_psym->block());
+// }
+
+
+// SUIF_IR::~SUIF_IR() {
+// pop_clue(_psym->block());
+// if (!_psym->is_written())
+// _psym->write_proc(_fse);
+// _psym->flush_proc();
+
+// exit_suif1();
+// }
+
+
+// tree_for *SUIF_IR::get_loop(int loop_num) {
+// std::vector<tree_for *> loops = find_loops(_psym->block()->body());
+// if (loop_num >= loops.size()) {
+// fprintf(stderr, "loop number %d couldn't be found\n", loop_num);
+// exit(1);
+// }
+// return loops[loop_num];
+// }
+
+
+// void SUIF_IR::commit(Loop *lp, int loop_num) {
+// if (lp == NULL)
+// return;
+
+// if (lp->init_code != NULL) {
+// tree_node_list *init_tnl = static_cast<CG_suifRepr *>(lp->init_code->clone())->GetCode();
+// tree_node_list_iter iter(lp->symtab->block()->body());
+// iter.step();
+// lp->symtab->block()->body()->insert_before(init_tnl, iter.cur_elem());
+// }
+
+// tree_node_list *code = lp->getCode();
+// std::vector<tree_for *> loops = find_loops(_psym->block()->body());
+// tree_node_list *tnl = loops[loop_num]->parent();
+// tnl->insert_before(code, loops[loop_num]->list_e());
+// tnl->remove(loops[loop_num]->list_e());
+// }
+
+
+// extern void start_suif(int &argc, char *argv[]) {
+// // LIBRARY(ipmath, init_ipmath, exit_ipmath);
+// LIBRARY(useful, init_useful, exit_useful);
+// LIBRARY(annotes, init_annotes, exit_annotes);
+
+// init_suif(argc, argv);
+// }
+
+// tree_for *init_loop(char *filename, int proc_num, int loop_num) {
+// // LIBRARY(ipmath, init_ipmath, exit_ipmath);
+// LIBRARY(useful, init_useful, exit_useful);
+// LIBRARY(annotes, init_annotes, exit_annotes);
+
+// int argc = 3;
+// char *argv[3];
+// argv[0] = "loop_xform";
+// argv[1] = filename;
+// argv[2] = strdup(filename);
+// char *pos = strrchr(argv[2], '.');
+// if (pos == NULL)
+// strcat(argv[2], ".lxf");
+// else {
+// *pos = '\0';
+// strcat(argv[2], ".lxf");
+// }
+// printf("%s %s %s\n", argv[0], argv[1], argv[2]);
+// init_suif(argc, argv);
+
+// fileset->add_file(argv[1], argv[2]);
+// fileset->reset_iter();
+// fse = fileset->next_file();
+// fse->reset_proc_iter();
+// int cur_proc = 0;
+// while ((psym = fse->next_proc()) && cur_proc < proc_num)
+// ++cur_proc;
+// if (cur_proc != proc_num) {
+// fprintf(stderr, "procedure number %d couldn't be found\n", proc_num);
+// exit(1);
+// }
+
+// if (!psym->is_in_memory())
+// psym->read_proc(TRUE, psym->src_lang() == src_fortran);
+
+// push_clue(psym->block());
+// std::vector<tree_for *> loops = find_loops(psym->block()->body());
+// if (loop_num >= loops.size())
+// return NULL;
+// return loops[loop_num];
+// }
+
+
+// void finalize_loop() {
+
+// printf("finalize %d\n", fse);
+// pop_clue(psym->block());
+// if (!psym->is_written())
+// psym->write_proc(fse);
+// psym->flush_proc();
+// }
+
+
+
+// // ----------------------------------------------------------------------------
+// // Class: CG_suifArray
+// // ----------------------------------------------------------------------------
+// CG_suifArray::CG_suifArray(in_array *ia_): ia(ia_) {
+// var_sym *vs = get_sym_of_array(ia);
+// name = String(vs->name());
+
+// for (int i = 0; i < ia->dims(); i++)
+// index.push_back(new CG_suifRepr(ia->index(i)));
+// }
+
+// bool CG_suifArray::is_write() {
+// return is_lhs(ia);
+// }
+
+
+// ----------------------------------------------------------------------------
+// Find array index in various situations.
+// ----------------------------------------------------------------------------
+operand find_array_index(in_array *ia, int n, int dim, bool is_fortran) {
+ if (!is_fortran)
+ dim = n - dim - 1;
+ int level = n - dim -1;
+
+ in_array *current = ia;
+
+ while (true) {
+ int n = current->dims();
+ if (level < n) {
+ return current->index(level);
+ }
+ else {
+ level = level - n;
+ operand op = current->base_op();
+ assert(op.is_instr());
+ instruction *ins = op.instr();
+ if (ins->opcode() != io_cvt)
+ return operand();
+ operand op2 = static_cast<in_rrr *>(ins)->src_op();
+ assert(op2.is_instr());
+ instruction *ins2 = op2.instr();
+ assert(ins2->opcode() == io_lod);
+ operand op3 = static_cast<in_rrr *>(ins2)->src_op();
+ assert(op3.is_instr());
+ instruction *ins3 = op3.instr();
+ assert(ins3->opcode() == io_array);
+ current = static_cast<in_array *>(ins3);
+ }
+ }
+}
+
+
+
+
+// ----------------------------------------------------------------------------
+// Check if a tree_node is doing nothing
+// ----------------------------------------------------------------------------
+bool is_null_statement(tree_node *tn) {
+ if (tn->kind() != TREE_INSTR)
+ return false;
+
+ instruction *ins = static_cast<tree_instr*>(tn)->instr();
+
+ if (ins->opcode() == io_mrk || ins->opcode() == io_nop)
+ return true;
+ else
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+// Miscellaneous loop functions
+// ----------------------------------------------------------------------------
+std::vector<tree_for *> find_deepest_loops(tree_node *tn) {
+ if (tn->kind() == TREE_FOR) {
+ std::vector<tree_for *> loops;
+
+ tree_for *tnf = static_cast<tree_for *>(tn);
+ loops.insert(loops.end(), tnf);
+ std::vector<tree_for *> t = find_deepest_loops(tnf->body());
+ std::copy(t.begin(), t.end(), std::back_inserter(loops));
+
+ return loops;
+ }
+ else if (tn->kind() == TREE_BLOCK) {
+ tree_block *tnb = static_cast<tree_block *>(tn);
+ return find_deepest_loops(tnb->body());
+ }
+ else
+ return std::vector<tree_for *>();
+}
+
+std::vector<tree_for *> find_deepest_loops(tree_node_list *tnl) {
+ std::vector<tree_for *> loops;
+
+ tree_node_list_iter iter(tnl);
+ while (!iter.is_empty()) {
+ tree_node *tn = iter.step();
+
+ std::vector<tree_for *> t = find_deepest_loops(tn);
+
+ if (t.size() > loops.size())
+ loops = t;
+ }
+
+ return loops;
+}
+
+std::vector<tree_for *> find_loops(tree_node_list *tnl) {
+ std::vector<tree_for *> result;
+
+ tree_node_list_iter iter(tnl);
+ while (!iter.is_empty()) {
+ tree_node *tn = iter.step();
+ if (tn->kind() == TREE_FOR)
+ result.push_back(static_cast<tree_for *>(tn));
+ }
+
+ return result;
+}
+
+
+std::vector<tree_for *> find_outer_loops(tree_node *tn) {
+ std::vector<tree_for *> loops;
+
+ while(tn) {
+ if(tn->kind() == TREE_FOR)
+ loops.insert(loops.begin(),static_cast<tree_for*>(tn));
+ tn = (tn->parent())?tn->parent()->parent():NULL;
+ }
+
+ return loops;
+}
+
+std::vector<tree_for *> find_common_loops(tree_node *tn1, tree_node *tn2) {
+ std::vector<tree_for *> loops1 = find_outer_loops(tn1);
+ std::vector<tree_for *> loops2 = find_outer_loops(tn2);
+
+ std::vector<tree_for *> loops;
+
+ for (unsigned i = 0; i < std::min(loops1.size(), loops2.size()); i++) {
+ if (loops1[i] == loops2[i])
+ loops.insert(loops.end(), loops1[i]);
+ else
+ break;
+ }
+
+ return loops;
+}
+
+
+//-----------------------------------------------------------------------------
+// Determine the lexical order between two instructions.
+//-----------------------------------------------------------------------------
+LexicalOrderType lexical_order(tree_node *tn1, tree_node *tn2) {
+ if (tn1 == tn2)
+ return LEX_MATCH;
+
+ std::vector<tree_node *> tnv1;
+ std::vector<tree_node_list *> tnlv1;
+ while (tn1 != NULL && tn1->parent() != NULL) {
+ tnv1.insert(tnv1.begin(), tn1);
+ tnlv1.insert(tnlv1.begin(), tn1->parent());
+ tn1 = tn1->parent()->parent();
+ }
+
+ std::vector<tree_node *> tnv2;
+ std::vector<tree_node_list *> tnlv2;
+ while (tn2 != NULL && tn2->parent() != NULL) {
+ tnv2.insert(tnv2.begin(), tn2);
+ tnlv2.insert(tnlv2.begin(), tn2->parent());
+ tn2 = tn2->parent()->parent();
+ }
+
+ for (int i = 0; i < std::min(tnlv1.size(), tnlv2.size()); i++) {
+ if (tnlv1[i] == tnlv2[i] && tnv1[i] != tnv2[i]) {
+ tree_node_list_iter iter(tnlv1[i]);
+
+ while (!iter.is_empty()) {
+ tree_node *tn = iter.step();
+
+ if (tn == tnv1[i])
+ return LEX_BEFORE;
+ else if (tn == tnv2[i])
+ return LEX_AFTER;
+ }
+
+ break;
+ }
+ }
+
+ return LEX_UNKNOWN;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Get the list of array instructions
+//-----------------------------------------------------------------------------
+std::vector<in_array *> find_arrays(instruction *ins) {
+ std::vector<in_array *> arrays;
+ if (ins->opcode() == io_array) {
+ arrays.insert(arrays.end(), static_cast<in_array *>(ins));
+ }
+ else {
+ for (int i = 0; i < ins->num_srcs(); i++) {
+ operand op(ins->src_op(i));
+ if (op.is_instr()) {
+ std::vector<in_array *> t = find_arrays(op.instr());
+ std::copy(t.begin(), t.end(), back_inserter(arrays));
+ }
+ }
+ }
+ return arrays;
+}
+
+std::vector<in_array *> find_arrays(tree_node_list *tnl) {
+ std::vector<in_array *> arrays, t;
+ tree_node_list_iter iter(tnl);
+
+ while (!iter.is_empty()) {
+ tree_node *tn = iter.step();
+
+ if (tn->kind() == TREE_FOR) {
+ tree_for *tnf = static_cast<tree_for *>(tn);
+
+ t = find_arrays(tnf->body());
+ std::copy(t.begin(), t.end(), back_inserter(arrays));
+ }
+ else if (tn->kind() == TREE_IF) {
+ tree_if *tni = static_cast<tree_if *>(tn);
+
+ t = find_arrays(tni->header());
+ std::copy(t.begin(), t.end(), back_inserter(arrays));
+ t = find_arrays(tni->then_part());
+ std::copy(t.begin(), t.end(), back_inserter(arrays));
+ t = find_arrays(tni->else_part());
+ std::copy(t.begin(), t.end(), back_inserter(arrays));
+ }
+ else if (tn->kind() == TREE_BLOCK) {
+ t = find_arrays(static_cast<tree_block *>(tn)->body());
+ std::copy(t.begin(), t.end(), back_inserter(arrays));
+ }
+ else if (tn->kind() == TREE_INSTR) {
+ t = find_arrays(static_cast<tree_instr *>(tn)->instr());
+ std::copy(t.begin(), t.end(), back_inserter(arrays));
+ }
+ }
+
+ return arrays;
+}
+
+// std::vector<CG_suifArray *> find_array_access(instruction *ins) {
+// std::vector<CG_suifArray *> arrays;
+
+// if (ins->opcode() == io_array) {
+// arrays.push_back(new CG_suifArray(static_cast<in_array *>(ins)));
+// }
+// else {
+// for (int i = 0; i < ins->num_srcs(); i++) {
+// operand op(ins->src_op(i));
+// if (op.is_instr()) {
+// std::vector<CG_suifArray *> t = find_array_access(op.instr());
+// std::copy(t.begin(), t.end(), back_inserter(arrays));
+// }
+// }
+// }
+// return arrays;
+// }
+
+// std::vector<CG_suifArray *> find_array_access(tree_node_list *tnl) {
+// std::vector<CG_suifArray *> arrays, t;
+// tree_node_list_iter iter(tnl);
+
+// while (!iter.is_empty()) {
+// tree_node *tn = iter.step();
+
+// if (tn->kind() == TREE_FOR) {
+// tree_for *tnf = static_cast<tree_for *>(tn);
+
+// t = find_array_access(tnf->body());
+// std::copy(t.begin(), t.end(), back_inserter(arrays));
+// }
+// else if (tn->kind() == TREE_IF) {
+// tree_if *tni = static_cast<tree_if *>(tn);
+
+// t = find_array_access(tni->header());
+// std::copy(t.begin(), t.end(), back_inserter(arrays));
+// t = find_array_access(tni->then_part());
+// std::copy(t.begin(), t.end(), back_inserter(arrays));
+// t = find_array_access(tni->else_part());
+// std::copy(t.begin(), t.end(), back_inserter(arrays));
+// }
+// else if (tn->kind() == TREE_BLOCK) {
+// t = find_array_access(static_cast<tree_block *>(tn)->body());
+// std::copy(t.begin(), t.end(), back_inserter(arrays));
+// }
+// else if (tn->kind() == TREE_INSTR) {
+// t = find_array_access(static_cast<tree_instr *>(tn)->instr());
+// std::copy(t.begin(), t.end(), back_inserter(arrays));
+// }
+// }
+
+// return arrays;
+// }