summaryrefslogtreecommitdiff
path: root/omegalib/code_gen/src/CG_suifBuilder.cc
diff options
context:
space:
mode:
authorTuowen Zhao <ztuowen@gmail.com>2016-09-17 03:22:53 +0000
committerTuowen Zhao <ztuowen@gmail.com>2016-09-17 03:22:53 +0000
commit75ff98e4d65862ff5b36b533b4f6e3ea71ede1d5 (patch)
tree498ac06b4cf78568b807fafd2619856afff69c28 /omegalib/code_gen/src/CG_suifBuilder.cc
parent29efa7b1a0d089e02a70f73f348f11878955287c (diff)
downloadchill-75ff98e4d65862ff5b36b533b4f6e3ea71ede1d5.tar.gz
chill-75ff98e4d65862ff5b36b533b4f6e3ea71ede1d5.tar.bz2
chill-75ff98e4d65862ff5b36b533b4f6e3ea71ede1d5.zip
cmake build
Diffstat (limited to 'omegalib/code_gen/src/CG_suifBuilder.cc')
-rw-r--r--omegalib/code_gen/src/CG_suifBuilder.cc678
1 files changed, 678 insertions, 0 deletions
diff --git a/omegalib/code_gen/src/CG_suifBuilder.cc b/omegalib/code_gen/src/CG_suifBuilder.cc
new file mode 100644
index 0000000..6bb91b7
--- /dev/null
+++ b/omegalib/code_gen/src/CG_suifBuilder.cc
@@ -0,0 +1,678 @@
+/*****************************************************************************
+ Copyright (C) 2008 University of Southern California
+ Copyright (C) 2009-2010 University of Utah
+ All Rights Reserved.
+
+ Purpose:
+ generate suif code for omega
+
+ Notes:
+
+ History:
+ 02/01/06 created by Chun Chen
+*****************************************************************************/
+
+#include <stack>
+#include <code_gen/CG_suifBuilder.h>
+#include <suif1/annote.h>
+#include <vector>
+
+namespace omega {
+
+//-----------------------------------------------------------------------------
+// make suif initilization happy
+//-----------------------------------------------------------------------------
+char *k_ocg_comment;
+char *k_s2c_pragma;
+char *k_cuda_dim3;
+char *k_cuda_kernel;
+char *k_cuda_modifier;
+char *k_cuda_texture_memory; //protonu--added to track texture memory type
+
+// void __attribute__ ((constructor)) my_init(void) {
+// ANNOTE(k_ocg_comment, "omega_comment", TRUE);
+// }
+
+//protonu--extern decls
+//protonu--adding stuff to make Chun's code work with Gabe's
+extern Tuple< Tuple<int> > smtNonSplitLevels;
+extern Tuple< Tuple<std::string> > loopIdxNames;//per stmt
+extern std::vector< std::pair<int, std::string> > syncs;
+extern int checkLoopLevel;
+extern int stmtForLoopCheck;
+extern int upperBoundForLevel;
+extern int lowerBoundForLevel;
+extern bool fillInBounds;
+
+
+const char *libcode_gen_ver_string = "";
+const char *libcode_gen_who_string = "";
+const char *libcode_gen_suif_string = "";
+
+
+void init_code_gen() {
+ static bool isInit = false;
+ if(!isInit)
+ {
+ isInit = true;
+ ANNOTE(k_ocg_comment, "omega_comment", TRUE);
+ ANNOTE(k_s2c_pragma, "s2c pragma", TRUE);
+ ANNOTE(k_cuda_dim3, "cuda dim3", TRUE);
+ ANNOTE(k_cuda_kernel, "cuda kernel", TRUE);
+ ANNOTE(k_cuda_modifier, "cuda modifier", TRUE);
+ }
+}
+
+
+void exit_code_gen(void) {
+}
+
+
+//-----------------------------------------------------------------------------
+// Class: CG_suifBuilder
+//-----------------------------------------------------------------------------
+
+CG_suifBuilder::CG_suifBuilder(proc_symtab *symtab)
+{
+ symtab_ = symtab;
+ init_code_gen();
+}
+
+CG_outputRepr* CG_suifBuilder::CreatePlaceHolder (int, CG_outputRepr *stmt,
+ Tuple<CG_outputRepr*> &funcList, Tuple<std::string> &loop_vars) const {
+ tree_node_list *tnl = static_cast<CG_suifRepr *>(stmt)->tnl_;
+ delete stmt;
+
+ for (int i = 1; i <= funcList.size(); i++) {
+ if (funcList[i] == NULL)
+ continue;
+
+ CG_suifRepr *repr = static_cast<CG_suifRepr*>(funcList[i]);
+ operand op = repr->op_;
+ delete repr;
+
+ var_sym *vs = static_cast<var_sym*>(symtab_->lookup_sym(loop_vars[i].c_str(), SYM_VAR));
+
+ substitute(tnl, vs, op, symtab_);
+
+ if (op.is_instr())
+ delete op.instr();
+ }
+
+ return new CG_suifRepr(tnl);
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateAssignment(int, CG_outputRepr *lhs,
+ CG_outputRepr *rhs) const {
+ if ( lhs == NULL || rhs == NULL ) {
+ fprintf(stderr, "Code generation: Missing lhs or rhs\n");
+ return NULL;
+ }
+
+ operand src = static_cast<CG_suifRepr*>(rhs)->op_;
+ if (src.is_instr() && src.instr()->opcode() == io_array) {
+ in_array *ia = static_cast<in_array *>(src.instr());
+ instruction *ins = new in_rrr(io_lod, ia->elem_type(), operand(), ia);
+ src = operand(ins);
+ }
+
+ instruction *ins;
+ operand dst = static_cast<CG_suifRepr*>(lhs)->op_;
+ if (dst.is_instr() && dst.instr()->opcode() == io_array) {
+ in_array *ia = static_cast<in_array *>(dst.instr());
+ ins = new in_rrr(io_str, type_void, operand(), operand(ia), src);
+ }
+ else
+ ins = new in_rrr(io_cpy, src.type(), dst, src);
+
+ delete lhs;
+ delete rhs;
+
+ tree_node_list *tnl = new tree_node_list;
+ tnl->append(new tree_instr(ins));
+
+ return new CG_suifRepr(tnl);
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateInvoke(const std::string &fname,
+ Tuple<CG_outputRepr*> &list) const {
+ if (fname == std::string("max") || fname == std::string("min")) {
+ if (list.size() == 0) {
+ return NULL;
+ }
+ else if (list.size() == 1) {
+ return list[1];
+ }
+ else {
+ int last = list.size();
+ operand op2 = static_cast<CG_suifRepr*>(list[last])->op_;
+ delete list[last];
+ list.delete_last();
+ CG_suifRepr *repr = static_cast<CG_suifRepr*>(CreateInvoke(fname, list));
+ operand op1 = repr->op_;
+
+ instruction *ins;
+ if (fname == std::string("max"))
+ ins = new in_rrr(io_max, op1.type(), operand(), op1, op2);
+ else
+ ins = new in_rrr(io_min, op1.type(), operand(), op1, op2);
+
+ repr->op_ = operand(ins);
+
+ return repr;
+ }
+ }
+ else {
+ fprintf(stderr, "Code generation: invoke function io_call not implemented\n");
+ return NULL;
+ }
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateAttribute(CG_outputRepr *control,
+ const std::string &commentText)const {
+ if (commentText == std::string("")) {
+ return control;
+ }
+
+ instruction *ins = new in_rrr(io_mrk);
+
+ immed_list *iml = new immed_list;
+ iml->append(immed(const_cast<char *>(commentText.c_str())));
+ ins->prepend_annote(k_ocg_comment, iml);
+
+ tree_node_list *tnl ;
+ tnl = static_cast<CG_suifRepr*>(control)->tnl_;
+ tnl->append(new tree_instr(ins));
+
+
+ return new CG_suifRepr(tnl);
+
+
+}
+
+
+
+CG_outputRepr* CG_suifBuilder::CreateComment(int, const std::string &commentText) const {
+ if ( commentText == std::string("") ) {
+ return NULL;
+ }
+
+ instruction *ins = new in_rrr(io_mrk);
+
+ immed_list *iml = new immed_list;
+ iml->append(immed(const_cast<char *>(commentText.c_str())));
+ ins->prepend_annote(k_ocg_comment, iml);
+
+ tree_node_list *tnl = new tree_node_list;
+ tnl->append(new tree_instr(ins));
+
+ return new CG_suifRepr(tnl);
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateIf(int, CG_outputRepr *guardList,
+ CG_outputRepr *true_stmtList, CG_outputRepr *false_stmtList) const {
+ static int if_counter = 1;
+ std::string s = std::string("omegaif_")+to_string(if_counter++);
+ label_sym *if_label = new label_sym(const_cast<char *>(s.c_str()));
+ symtab_->add_sym(if_label);
+
+ if ( true_stmtList == NULL && false_stmtList == NULL ) {
+ delete guardList;
+ return NULL;
+ }
+ else if ( guardList == NULL ) {
+ return StmtListAppend(true_stmtList, false_stmtList);
+ }
+
+ tree_node_list *header = new tree_node_list;
+ operand op = static_cast<CG_suifRepr*>(guardList)->op_;
+
+ std::stack<void *> S;
+ S.push(op.instr());
+ while(!S.empty()) {
+ instruction *ins = static_cast<instruction *>(S.top());
+ S.pop();
+ if (ins->opcode() == io_and) {
+ instruction *ins1 = ins->src_op(0).instr();
+ ins1->remove();
+ S.push(ins1);
+ instruction *ins2 = ins->src_op(1).instr();
+ ins2->remove();
+ S.push(ins2);
+ delete ins;
+ }
+ else {
+ ins = new in_bj(io_bfalse, if_label, operand(ins));
+ header->append(new tree_instr(ins));
+ }
+ }
+
+ tree_node_list *then_part, *else_part;
+ if (true_stmtList != NULL)
+ then_part = static_cast<CG_suifRepr*>(true_stmtList)->tnl_;
+ else
+ then_part = NULL;
+ if (false_stmtList != NULL)
+ else_part = static_cast<CG_suifRepr*>(false_stmtList)->tnl_;
+ else
+ else_part = NULL;
+ tree_if *ti = new tree_if(if_label, header, then_part, else_part);
+
+ tree_node_list *tnl = new tree_node_list;
+ tnl->append(ti);
+
+ delete guardList;
+ delete true_stmtList;
+ delete false_stmtList;
+
+ return new CG_suifRepr(tnl);
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateInductive(CG_outputRepr *index,
+ CG_outputRepr *lower,
+ CG_outputRepr *upper,
+ CG_outputRepr *step) const {
+ if ( index == NULL || lower == NULL || upper == NULL ) {
+ fprintf(stderr, "Code generation: something wrong in CreateInductive\n");
+ return NULL;
+ }
+
+ if (step == NULL)
+ step = CreateInt(1);
+
+ var_sym *index_sym = static_cast<CG_suifRepr*>(index)->op_.symbol();
+ operand lower_bound = static_cast<CG_suifRepr*>(lower)->op_;
+ operand upper_bound = static_cast<CG_suifRepr*>(upper)->op_;
+ operand step_size = static_cast<CG_suifRepr*>(step)->op_;
+
+ label_sym *contLabel = new label_sym("");
+ label_sym *brkLabel = new label_sym("");
+ symtab_->add_sym(contLabel);
+ symtab_->add_sym(brkLabel);
+ tree_for *tf = new tree_for(index_sym, FOR_SLTE, contLabel, brkLabel, NULL,
+ lower_bound, upper_bound, step_size, NULL);
+
+ tree_node_list *tnl = new tree_node_list;
+ tnl->append(tf);
+
+ delete index;
+ delete lower;
+ delete upper;
+ delete step;
+
+ return new CG_suifRepr(tnl);
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateLoop(int, CG_outputRepr *control,
+ CG_outputRepr *stmtList) const {
+ if ( stmtList == NULL ) {
+ delete control;
+ return NULL;
+ }
+ else if ( control == NULL ) {
+ fprintf(stderr, "Code generation: no inductive for this loop\n");
+ return stmtList;
+ }
+
+ tree_node_list *tnl = static_cast<CG_suifRepr*>(control)->tnl_;
+ tree_node_list_iter iter(tnl);
+ tree_for *tf = static_cast<tree_for*>(iter.step());
+
+ tree_node_list *body = static_cast<CG_suifRepr*>(stmtList)->tnl_;
+ tf->set_body(body);
+
+ delete stmtList;
+
+ return control;
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateInt(int _i) const {
+ in_ldc *ins = new in_ldc(type_s32, operand(), immed(_i));
+
+ return new CG_suifRepr(operand(ins));
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateIdent(const std::string &_s) const {
+ if ( &_s == NULL || _s == std::string("") ) {
+ return NULL;
+ }
+
+ var_sym *vs = static_cast<var_sym*>(symtab_->lookup_sym(_s.c_str(), SYM_VAR));
+
+ if (vs == NULL) {
+ vs = new var_sym(type_s32, const_cast<char*>(_s.c_str()));
+ symtab_->add_sym(vs);
+ }
+
+ return new CG_suifRepr(operand(vs));
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreatePlus(CG_outputRepr *lop,
+ CG_outputRepr *rop) const {
+ if ( rop == NULL ) {
+ return lop;
+ }
+ else if ( lop == NULL ) {
+ return rop;
+ }
+
+ operand op1 = static_cast<CG_suifRepr*>(lop)->op_;
+ operand op2 = static_cast<CG_suifRepr*>(rop)->op_;
+
+ instruction *ins = new in_rrr(io_add, op1.type(), operand(), op1, op2);
+
+ delete lop;
+ delete rop;
+
+ return new CG_suifRepr(operand(ins));
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateMinus(CG_outputRepr *lop,
+ CG_outputRepr *rop) const {
+ if ( rop == NULL ) {
+ return lop;
+ }
+ else if ( lop == NULL ) {
+ operand op = static_cast<CG_suifRepr*>(rop)->op_;
+ instruction *ins = new in_rrr(io_neg, op.type(), operand(), op);
+
+ delete rop;
+
+ return new CG_suifRepr(operand(ins));
+ }
+ else {
+ operand op1 = static_cast<CG_suifRepr*>(lop)->op_;
+ operand op2 = static_cast<CG_suifRepr*>(rop)->op_;
+
+ instruction *ins = new in_rrr(io_sub, op1.type(), operand(), op1, op2);
+
+ delete lop;
+ delete rop;
+
+ return new CG_suifRepr(operand(ins));
+ }
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateTimes(CG_outputRepr *lop,
+ CG_outputRepr *rop) const {
+ if ( rop == NULL || lop == NULL) {
+ if (rop != NULL) {
+ rop->clear();
+ delete rop;
+ }
+ if (lop != NULL) {
+ lop->clear();
+ delete lop;
+ }
+ return NULL;
+ }
+
+ operand op1 = static_cast<CG_suifRepr*>(lop)->op_;
+ operand op2 = static_cast<CG_suifRepr*>(rop)->op_;
+
+ instruction *ins = new in_rrr(io_mul, op1.type(), operand(), op1, op2);
+
+ delete lop;
+ delete rop;
+
+ return new CG_suifRepr(operand(ins));
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateIntegerDivide(CG_outputRepr *lop,
+ CG_outputRepr *rop) const {
+ if ( rop == NULL ) {
+ fprintf(stderr, "Code generation: divide by NULL\n");
+ return NULL;
+ }
+ else if ( lop == NULL ) {
+ delete rop;
+ return NULL;
+ }
+
+ // (6+5)*10 / 4
+ operand op1 = static_cast<CG_suifRepr*>(lop)->op_;
+ operand op2 = static_cast<CG_suifRepr*>(rop)->op_;
+
+ // bugs in SUIF prevent use of correct io_divfloor
+ instruction *ins = new in_rrr(io_div, op1.type(), operand(), op1, op2);
+
+ delete lop;
+ delete rop;
+
+ return new CG_suifRepr(operand(ins));
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateIntegerMod(CG_outputRepr *lop,
+ CG_outputRepr *rop) const {
+ if ( rop == NULL || lop == NULL ) {
+ return NULL;
+ }
+
+ operand op1 = static_cast<CG_suifRepr*>(lop)->op_;
+ operand op2 = static_cast<CG_suifRepr*>(rop)->op_;
+
+ // bugs in SUIF prevent use of correct io_mod
+ instruction *ins = new in_rrr(io_rem, type_s32, operand(), op1, op2);
+
+ delete lop;
+ delete rop;
+
+ return new CG_suifRepr(operand(ins));
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateAnd(CG_outputRepr *lop,
+ CG_outputRepr *rop) const {
+ if (rop == NULL)
+ return lop;
+ else if (lop == NULL)
+ return rop;
+
+ operand op1 = static_cast<CG_suifRepr*>(lop)->op_;
+ operand op2 = static_cast<CG_suifRepr*>(rop)->op_;
+
+ instruction *ins = new in_rrr(io_and, op1.type(), operand(), op1, op2);
+
+ delete lop;
+ delete rop;
+
+ return new CG_suifRepr(operand(ins));
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateGE(CG_outputRepr *lop,
+ CG_outputRepr *rop) const {
+ return CreateLE(rop, lop);
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateLE(CG_outputRepr *lop,
+ CG_outputRepr *rop) const {
+ if ( rop == NULL || lop == NULL ) {
+ return NULL;
+ }
+
+ operand op1 = static_cast<CG_suifRepr*>(lop)->op_;
+ operand op2 = static_cast<CG_suifRepr*>(rop)->op_;
+
+ instruction *ins = new in_rrr(io_sle, type_s32, operand(), op1, op2);
+
+ delete lop;
+ delete rop;
+
+ return new CG_suifRepr(operand(ins));
+}
+
+
+CG_outputRepr* CG_suifBuilder::CreateEQ(CG_outputRepr *lop,
+ CG_outputRepr *rop) const {
+ if ( rop == NULL || lop == NULL ) {
+ return NULL;
+ }
+
+ operand op1 = static_cast<CG_suifRepr*>(lop)->op_;
+ operand op2 = static_cast<CG_suifRepr*>(rop)->op_;
+
+ instruction *ins = new in_rrr(io_seq, type_s32, operand(), op1, op2);
+
+ delete lop;
+ delete rop;
+
+ return new CG_suifRepr(operand(ins));
+}
+
+
+
+CG_outputRepr* CG_suifBuilder::StmtListAppend(CG_outputRepr *list1,
+ CG_outputRepr *list2) const {
+ if ( list2 == NULL ) {
+ return list1;
+ }
+ else if ( list1 == NULL ) {
+ return list2;
+ }
+
+ tree_node_list *tnl1 = static_cast<CG_suifRepr *>(list1)->tnl_;
+ tree_node_list *tnl2 = static_cast<CG_suifRepr *>(list2)->tnl_;
+ if (tnl2 == NULL)
+ tnl1->append(new tree_instr(static_cast<CG_suifRepr *>(list2)->op_.instr()));
+ else
+ tnl1->append(tnl2);
+
+ delete list2;
+
+ return list1;
+}
+
+//protonu--Gabe's stuff added here
+//-----------------------------------------------------------------------------
+// pragma generation
+// TODO: Could allow for a immed_list* instead of a String for strongly typed prgma args
+//-----------------------------------------------------------------------------
+CG_outputRepr* CG_suifBuilder::CreatePragma(int,
+ const std::string &pragmaText) const {
+ if ( pragmaText == std::string("") ) {
+ return NULL;
+ }
+ instruction *ins = new in_rrr(io_mrk);
+ immed_list *iml = new immed_list;
+ iml->append(immed(const_cast<char*>(pragmaText.c_str())));
+ ins->append_annote(k_s2c_pragma, iml);
+ tree_node_list *tnl = new tree_node_list;
+ tnl->append(new tree_instr(ins));
+ return new CG_suifRepr(tnl);
+}
+
+CG_outputRepr* CG_suifBuilder::CreateDim3(immed varName, immed arg1, immed arg2) const {
+ instruction *ins = new in_rrr(io_mrk);
+ immed_list *iml = new immed_list;
+ iml->append(immed(varName));
+ iml->append(arg1);
+ iml->append(arg2);
+ ins->append_annote(k_cuda_dim3, iml);
+ tree_node_list *tnl = new tree_node_list;
+ tnl->append(new tree_instr(ins));
+ return new CG_suifRepr(tnl);
+}
+
+CG_outputRepr* CG_suifBuilder::CreateDim3(immed varName, immed arg1, immed arg2, immed arg3) const {
+ instruction *ins = new in_rrr(io_mrk);
+ immed_list *iml = new immed_list;
+ iml->append(immed(varName));
+ iml->append(arg1);
+ iml->append(arg2);
+ iml->append(arg3);
+ ins->append_annote(k_cuda_dim3, iml);
+ tree_node_list *tnl = new tree_node_list;
+ tnl->append(new tree_instr(ins));
+ return new CG_suifRepr(tnl);
+}
+
+CG_outputRepr* CG_suifBuilder::CreateKernel(immed_list* iml) const {
+ instruction *ins = new in_rrr(io_mrk);
+ ins->append_annote(k_cuda_kernel, iml);
+ tree_node_list *tnl = new tree_node_list;
+ tnl->append(new tree_instr(ins));
+ return new CG_suifRepr(tnl);
+}
+
+type_node* CG_suifBuilder::ModifyType(type_node* base, const char* modifier) const {
+ modifier_type* result = new modifier_type(TYPE_NULL, base);
+ immed_list *iml = new immed_list;
+ iml->append(immed((char*)modifier));
+ result->append_annote(k_cuda_modifier, iml);
+ return result;
+}
+//end-protonu
+
+
+//-----------------------------------------------------------------------------
+// suif utility
+//-----------------------------------------------------------------------------
+
+bool substitute(instruction *in, var_sym *sym, operand expr, base_symtab *st) {
+ if (in == NULL || sym == NULL)
+ return false;
+
+ bool r = false;
+ for (unsigned i = 0; i < in->num_srcs(); i++) {
+ operand op(in->src_op(i));
+
+ if (op.is_symbol() && op.symbol() == sym) {
+ in->set_src_op(i, expr.clone(st));
+ r = true;
+ }
+ else if (op.is_instr()) {
+ r = substitute(op.instr(), sym, expr, st) || r;
+ }
+ }
+
+ return r;
+}
+
+bool substitute(tree_node *tn, var_sym *sym, operand expr, base_symtab *st) {
+ if (tn == NULL)
+ return false;
+
+ bool r = false;
+ if (tn->kind() == TREE_INSTR)
+ r = substitute(static_cast<tree_instr*>(tn)->instr(), sym, expr, st) || r;
+ else {
+ for (unsigned i = 0; i < tn->num_child_lists(); i++) {
+ r = substitute(tn->child_list_num(i), sym, expr, st) || r;
+ }
+ }
+
+ return r;
+}
+
+bool substitute(tree_node_list *tnl, var_sym *sym, operand expr,
+ base_symtab *st) {
+ if (tnl == NULL)
+ return false;
+
+ bool r = false;
+ tree_node_list_iter iter(tnl);
+ while (!iter.is_empty()) {
+ tree_node *tn = iter.step();
+
+ r = substitute(tn, sym, expr, st) || r;
+ }
+
+ return r;
+}
+
+}