/***************************************************************************** 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 #include #include struct ir_error: public std::runtime_error { ir_error(const std::string &msg) : std::runtime_error(msg) { } }; using namespace SageBuilder; using namespace SageInterface; using namespace OmpSupport; namespace omega { //----------------------------------------------------------------------------- // make suif initilization happy //----------------------------------------------------------------------------- char *k_ocg_comment; // void __attribute__ ((constructor)) my_init(void) { // ANNOTE(k_ocg_comment, "omega_comment", TRUE); // } /* const char *libcode_gen_ver_string = ""; const char *libcode_gen_who_string = ""; const char *libcode_gen_suif_string = ""; void init_code_gen(int&, char* []) { ANNOTE(k_ocg_comment, "omega_comment", TRUE); } void exit_code_gen(void) { } */ CG_roseBuilder::CG_roseBuilder(int is_fortran, SgGlobal* global, SgGlobal* firstScope, SgSymbolTable* symtab, SgSymbolTable* symtab2, SgNode* root) : isFortran(is_fortran), global_(global), global_scope(firstScope), symtab_(symtab), symtab2_( symtab2), root_(root) { } CG_roseBuilder::~CG_roseBuilder() { } // Manu:: returns true if input is in fortran, else returns false bool CG_roseBuilder::isInputFortran() const{ if (isFortran) return true; else return false; } //----------------------------------------------------------------------------- // place holder generation //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::CreateSubstitutedStmt(int, CG_outputRepr *stmt, const std::vector &vars, std::vector &subs) const { SgStatementPtrList* list = static_cast(stmt)->list_; SgNode *tnl; SgStatement* statement; if (list != NULL) { //statement = *((*list).begin()); //tnl = isSgNode(statement); delete stmt; for (int i = 0; i < subs.size(); i++) { if (subs[i] == NULL) continue; CG_roseRepr *repr = static_cast(subs[i]); SgExpression* op = repr->op_; for (SgStatementPtrList::iterator it = (*list).begin(); it != (*list).end(); it++) { statement = (*it); tnl = isSgNode(statement); // std::string master = tnl->unparseToString(); int j; int not_in_symtab_; not_in_symtab_ = 0; SgVariableSymbol *vs = symtab_->find_variable( SgName(vars[i].c_str())); if (vs == NULL) { not_in_symtab_ = 1; vs = symtab2_->find_variable(SgName(vars[i].c_str())); } if (vs != NULL) { //std::string x = vars[i].c_str() ; //std::string y = isSgNode(op)->unparseToString(); std::vector array = substitute(tnl, (const SgVariableSymbol*) vs, op, root_); for (std::vector::iterator it = array.begin(); it != array.end(); it++) { // std::string z = isSgNode(array[j])->unparseToString(); if (isSgVarRefExp(op)) { if (strcmp( isSgVarRefExp(op)->get_symbol()->get_name().getString().c_str(), vs->get_name().getString().c_str())) { (*it)->set_symbol( isSgVarRefExp(op)->get_symbol()); // std::string z = isSgNode(array[j])->unparseToString(); // isSgBinaryOp(array[j]->get_parent())->replace_expression(array[j], op); } } else if (isSgExpression(op)) { if (isSgBinaryOp((*it)->get_parent())) isSgBinaryOp((*it)->get_parent())->replace_expression( *it, op); else if (isSgUnaryOp((*it)->get_parent())) isSgUnaryOp((*it)->get_parent())->replace_expression( *it, op); else if (isSgExprListExp((*it)->get_parent())) isSgExprListExp((*it)->get_parent())->replace_expression( *it, op); else throw ir_error("unrecognized expression type"); } } /* std::vector array2 = substitute (tnl,(const SgVariableSymbol*) vs, op, root_); if(array2.size() != 0) throw ir_error("variable replacement unsuccessful"); */ } } delete repr; subs[i] = NULL; if (subs[i] != NULL) throw ir_error("not freed properly"); } return new CG_roseRepr(list); } else { tnl = static_cast(stmt)->tnl_; //std::string master = tnl->unparseToString(); if (tnl == NULL) throw ir_error("both list and tnl are null!!"); delete stmt; int j; int not_in_symtab_; for (int i = 0; i < subs.size(); i++) { if (subs[i] == NULL) continue; not_in_symtab_ = 0; CG_roseRepr *repr = static_cast(subs[i]); SgExpression* op = repr->op_; delete repr; subs[i] = NULL; SgVariableSymbol *vs = symtab_->find_variable( SgName(vars[i].c_str())); if (vs == NULL) { not_in_symtab_ = 1; vs = symtab2_->find_variable(SgName(vars[i].c_str())); } if (vs != NULL) { //std::string x = vars[i].c_str() ; //std::string y = isSgNode(op)->unparseToString(); std::vector array = substitute(tnl, vs, op, root_); if (not_in_symtab_ && isSgVarRefExp(op)) { if (strcmp( isSgVarRefExp(op)->get_symbol()->get_name().getString().c_str(), vs->get_name().getString().c_str())) { // symtab2_->remove(vs); } } /* else if(not_in_symtab_ && isSgVarRefExp(isSgAddOp(op)->get_lhs_operand())){ if(strcmp(isSgVarRefExp(isSgAddOp(op)->get_lhs_operand())->get_symbol()->get_name().getString().c_str(),\ vs->get_name().getString().c_str())){ symtab2_->remove(vs); } }*/ //symtab2_->remove(vs); for (std::vector::iterator j = array.begin(); j != array.end(); j++) { // std::string z = isSgNode(array[j])->unparseToString(); if (isSgVarRefExp(op)) { if (strcmp( isSgVarRefExp(op)->get_symbol()->get_name().getString().c_str(), vs->get_name().getString().c_str())) { (*j)->set_symbol(isSgVarRefExp(op)->get_symbol()); //isSgBinaryOp(array[j]->get_parent())->replace_expression(array[j], op); // std::string z = isSgNode(array[j])->unparseToString(); } } else if (isSgExpression(op)) { if (isSgBinaryOp((*j)->get_parent())) isSgBinaryOp((*j)->get_parent())->replace_expression( *j, op); else if (isSgUnaryOp((*j)->get_parent())) isSgUnaryOp((*j)->get_parent())->replace_expression( *j, op); else if (isSgExprListExp((*j)->get_parent())) { // Manu:: fortran indices are stored this way isSgExprListExp((*j)->get_parent())->replace_expression(*j, op); } else throw ir_error("unrecognized expression type"); /* if(strcmp(isSgVarRefExp(isSgAddOp(op)->get_lhs_operand())->get_symbol()->get_name().getString().c_str(),\ vs->get_name().getString().c_str() )){ array[j]->set_symbol(isSgVarRefExp(isSgAddOp(op)->get_lhs_operand())->get_symbol()); */ } } /* std::vector array2 = substitute (tnl,(const SgVariableSymbol*) vs, op, root_); if(array2.size() != 0) throw ir_error("variable replacement unsuccessful"); */ } /* SgExpression* exp = NULL; if(stmt1 = isSgStatement(tnl)){ if (SgExprStatement* expr_stmt = isSgExprStatement(stmt1)) exp = expr_stmt->get_expression(); else if( block = isSgBasicBlock(tnl)){ SgStatementPtrList& stmts = block->get_statements(); SgExpression* exp2; for(int i =0; i < stmts.size(); i++){ if(isSgExprStatement(stmts[i])){ exp2 = isSgExprStatement(stmts[i])->get_expression(); if(exp2 != NULL){ if(isSgBinaryOp(exp2)) { substitute(isSgBinaryOp(exp2)->get_lhs_operand(), vs, op, root_, exp2); substitute(isSgBinaryOp(exp2)->get_rhs_operand(), vs, op, root_, exp2); } else if (isSgUnaryOp(exp2)) substitute(isSgUnaryOp(exp2)->get_operand(), vs, op, root_, exp2); }//end if }//end if }//end for }//end else else if(SgForStatement* for_stmt = isSgForStatement(tnl)){ SgForStatement* temp = for_stmt; while(isSgForStatement(temp)){ } } }//end if else exp = isSgExpression(tnl); if(exp != NULL){ if(isSgBinaryOp(exp)) { substitute(isSgBinaryOp(exp)->get_lhs_operand(), vs, op, root_, exp); substitute(isSgBinaryOp(exp)->get_rhs_operand(), vs, op, root_, exp); } else if (isSgUnaryOp(exp)) substitute(isSgUnaryOp(exp)->get_operand(), vs, op, root_, exp); } // if (op.is_instr()) // delete op.instr(); } */ } return new CG_roseRepr(tnl); } } //----------------------------------------------------------------------------- // assignment generation //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::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; } SgExpression* src = static_cast(rhs)->op_; SgExpression* dst = static_cast(lhs)->op_; SgExprStatement* ins = buildAssignStatement(dst, src); src->set_parent(ins); dst->set_parent(ins); SgStatementPtrList* new_list = new SgStatementPtrList; (*new_list).push_back(isSgStatement(ins)); delete lhs; delete rhs; return new CG_roseRepr(new_list); } //----------------------------------------------------------------------------- // function invocation generation //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::CreateInvoke(const std::string &fname, std::vector &list) const { // Manu:: debug // std::cout << "--------- CreateInvoke --------- \n"; if (fname == std::string("max") || fname == std::string("min")) { if (list.size() == 0) { return NULL; } else if (list.size() == 1) { return list[0]; } else { int last = list.size() - 1; SgExpression* op2 = static_cast(list[last])->op_; delete list[last]; list.erase(list.end()-1); CG_roseRepr *repr = static_cast(CreateInvoke(fname, list)); SgExpression* op1 = repr->op_; SgExpression *ins; SgExprListExp* arg_list = buildExprListExp(); appendExpression(arg_list, op1); appendExpression(arg_list, op2); SgVarRefExp* opaque_var; if (fname == std::string("max")) { opaque_var = buildOpaqueVarRefExp("__rose_gt", global_); ins = isSgExpression(buildFunctionCallExp(opaque_var, arg_list)); // Manu:: fortran support if (isInputFortran()) { SgName fName("merge"); SgTypeInt *retType = buildIntType(); SgExpression *cond = static_cast(CreateLE(new CG_roseRepr(op2), new CG_roseRepr(op1)))->op_; appendExpression(arg_list, cond); ins = isSgExpression(buildFunctionCallExp(fName, retType, arg_list, global_)); // std::cout << "--------- CreateInvoke:: " << isSgNode(ins)->unparseToString().c_str() << "\n"; } } else { opaque_var = buildOpaqueVarRefExp("__rose_lt", global_); ins = isSgExpression(buildFunctionCallExp(opaque_var, arg_list)); // Manu:: fortran support if (isInputFortran()) { SgName fName("merge"); SgTypeInt *retType = buildIntType(); SgExpression *cond = static_cast(CreateLE(new CG_roseRepr(op1), new CG_roseRepr(op2)))->op_; appendExpression(arg_list, cond); ins = isSgExpression(buildFunctionCallExp(fName, retType, arg_list, global_)); // std::cout << "--------- CreateInvoke:: " << isSgNode(ins)->unparseToString().c_str() << "\n"; } } repr->op_ = ins; return repr; } } else { fprintf(stderr, "Code generation: invoke function io_call not implemented\n"); return NULL; } } //----------------------------------------------------------------------------- // comment generation //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::CreateComment(int, const std::string &commentText) const { if (commentText == std::string("")) { return NULL; } SgLocatedNode *tnl = new SgLocatedNode(); buildComment(tnl, "//omega_comment: " + commentText); return new CG_roseRepr(isSgNode(tnl)); } //----------------------------------------------------------------------------- // if stmt gen operations //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::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++); // SgLabelStatement* label =buildLabelStatement(SgName(const_cast(s.c_str()))); if (true_stmtList == NULL && false_stmtList == NULL) { delete guardList; return NULL; } else if (guardList == NULL) { return StmtListAppend(true_stmtList, false_stmtList); } SgExpression* header = static_cast(guardList)->op_; SgStatementPtrList *then_part1, *else_part1; SgStatement* then_part; SgStatement* else_part; SgBasicBlock* then_part2; SgBasicBlock* else_part2; if (true_stmtList != NULL) { then_part1 = static_cast(true_stmtList)->list_; if (then_part1 != NULL) { then_part = *((*then_part1).begin()); if ((*then_part1).size() > 1) { then_part2 = buildBasicBlock(); for (SgStatementPtrList::iterator it = (*then_part1).begin(); it != (*then_part1).end(); it++) { then_part2->append_statement(*it); } then_part = isSgStatement(then_part2); } } else { // Manu:: fortran support (if part) if (isInputFortran()) { then_part2 = buildBasicBlock(); then_part2->append_statement(isSgStatement(static_cast(true_stmtList)->tnl_)); then_part = isSgStatement(then_part2); } else then_part = isSgStatement(static_cast(true_stmtList)->tnl_); } } else { then_part = NULL; } if (false_stmtList != NULL) { else_part1 = static_cast(false_stmtList)->list_; if (else_part1 != NULL) { else_part = *((*else_part1).begin()); if ((*else_part1).size() > 1) { else_part2 = buildBasicBlock(); for (SgStatementPtrList::iterator it2 = (*else_part1).begin(); it2 != (*else_part1).end(); it2++) { else_part2->append_statement(*it2); } else_part = isSgStatement(else_part2); } } else { // Manu:: fortran support (if part) if (isInputFortran()) { else_part2 = buildBasicBlock(); else_part2->append_statement(isSgStatement(static_cast(false_stmtList)->tnl_)); else_part = isSgStatement(else_part2); } else else_part = isSgStatement(static_cast(false_stmtList)->tnl_); } } else { else_part = NULL; } SgIfStmt* ti = buildIfStmt(header, isSgStatement(then_part), isSgStatement(else_part)); // label->set_scope(ti);//may have to be shifted to after symbol table insertion // SgLabelSymbol* if_label = isSgLabelSymbol(label->get_symbol_from_symbol_table()); // symtab_->insert( SgName(const_cast(s.c_str())) , isSgSymbol(if_label)); delete guardList; delete true_stmtList; delete false_stmtList; return new CG_roseRepr(isSgNode(ti)); } //----------------------------------------------------------------------------- // inductive variable generation, to be used in CreateLoop as control //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::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 = new CG_roseRepr(isSgExpression(buildIntVal(1))); SgVarRefExp *index_sym = isSgVarRefExp( static_cast(index)->op_); SgExpression* lower_bound = static_cast(lower)->op_; SgExpression* upper_bound = static_cast(upper)->op_; SgExpression* step_size = static_cast(step)->op_; /* label_sym *contLabel = new label_sym(""); label_sym *brkLabel = new label_sym(""); may not be required on rose?! */ SgStatement* for_init_stmt = buildAssignStatement(index_sym, lower_bound); SgLessOrEqualOp* cond = buildLessOrEqualOp(index_sym, upper_bound); SgExprStatement* test = buildExprStatement(cond); SgPlusAssignOp* increment = buildPlusAssignOp(index_sym, step_size); SgForStatement *for_stmt = buildForStatement(for_init_stmt, isSgStatement(test), increment, NULL); delete index; delete lower; delete upper; delete step; // Manu if (isInputFortran()) { // std::cout << "CG_roseBuilder:: need to construct a fortran do statement\n"; SgFortranDo * forStmt=new SgFortranDo(Sg_File_Info::generateDefaultFileInfoForTransformationNode()); forStmt->set_has_end_statement(true); forStmt->set_bound(upper_bound); forStmt->set_increment(step_size); forStmt->set_initialization(isSgExprStatement(for_init_stmt)->get_expression()); return new CG_roseRepr(isSgNode(forStmt)); } else { // std::cout << "CG_roseBuilder:: for statement is fine\n"; return new CG_roseRepr(isSgNode(for_stmt)); } } //----------------------------------------------------------------------------- // Attribute Creation //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::CreateAttribute(CG_outputRepr *control, const std::string &commentText) const { SgNode *tnl = static_cast(control)->tnl_; tnl->setAttribute("omega_comment", new AstTextAttribute(commentText)); return static_cast(control); } //----------------------------------------------------------------------------- // Pragma Attribute //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::CreatePragmaAttribute(CG_outputRepr *stmt, int looplevel, const std::string &pragmaText) const { SgNode *tnl = static_cast(stmt)->tnl_; CodeInsertionAttribute* attr = NULL; if (!tnl->attributeExists("code_insertion")) { attr = new CodeInsertionAttribute(); tnl->setAttribute("code_insertion", attr); } else { attr = static_cast(tnl->getAttribute("code_insertion")); } attr->add(new PragmaInsertion(looplevel, pragmaText)); return stmt; } //----------------------------------------------------------------------------- // Prefetch Attribute //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::CreatePrefetchAttribute(CG_outputRepr* stmt, int looplevel, const std::string &arrName, int hint) const { SgNode *tnl = static_cast(stmt)->tnl_; CodeInsertionAttribute *attr = getOrCreateCodeInsertionAttribute(tnl); attr->add(new MMPrefetchInsertion(looplevel, arrName, hint)); } //----------------------------------------------------------------------------- // loop stmt generation //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::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; } SgNode *tnl = static_cast(control)->tnl_; SgForStatement *tf = isSgForStatement(tnl); // Manu :: fortran support SgFortranDo *tfd = NULL; if (isInputFortran()) { tfd = isSgFortranDo(tnl); } // Manu:: debug /* if (!tf) { std::cout << "CreateLoop:: Not a for loop\n"; if (isSgFortranDo(tnl)) std::cout << "CreateLoop:: It is a fortran do loop\n"; } */ SgStatementPtrList * body = static_cast(stmtList)->list_; if (body != NULL) { if (!((*body).empty())) { if ((*body).size() == 1) { // if(isSgBasicBlock(*((*body).begin()))){ if (!isInputFortran()) { // Manu:: added if-else for fortran support tf->set_loop_body(*((*body).begin())); (*((*body).begin()))->set_parent(tf); } else { SgBasicBlock* bb1 = buildBasicBlock(); bb1->set_parent(tfd); bb1->append_statement(*((*body).begin())); tfd->set_body(bb1); } // } /* else{ SgBasicBlock* bb1 = buildBasicBlock(); bb1->set_parent(tf); bb1->append_statement(*((*body).begin())); tf->set_loop_body(bb1); }*/ } else { // Manu:: support for fortran label (do - continue) SgName *sname = NULL; SgBasicBlock* bb = buildBasicBlock(); if (!isInputFortran()) bb->set_parent(tf); else bb->set_parent(tfd); for (SgStatementPtrList::iterator it = (*body).begin(); it != (*body).end(); it++) { bb->append_statement(*it); (*it)->set_parent(bb); } if (!isInputFortran()) tf->set_loop_body(bb); else { tfd->set_body(bb); } } } } else { SgNode* tnl2 = static_cast(stmtList)->tnl_; if (tnl2 != NULL) { if (!isInputFortran()) { tf->set_loop_body(isSgStatement(tnl2)); tnl2->set_parent(tf); } else { SgBasicBlock* bb1 = buildBasicBlock(); bb1->set_parent(tfd); bb1->append_statement(isSgStatement(tnl2)); tfd->set_body(bb1); tnl2->set_parent(bb1); } } } delete stmtList; return control; } //----------------------------------------------------------------------------- // basic int, identifier gen operations //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::CreateInt(int _i) const { return new CG_roseRepr(isSgExpression(buildIntVal(_i))); } bool CG_roseBuilder::isInteger(CG_outputRepr *op) const{ SgExpression *op1 = static_cast(op)->op_; if(op1) if(isSgIntVal(op1)) return true; return false; } CG_outputRepr* CG_roseBuilder::CreateIdent(const std::string &_s) const { SgVariableSymbol *vs = symtab_->find_variable(SgName(_s.c_str())); SgVariableSymbol *vs2 = symtab2_->find_variable(SgName(_s.c_str())); if (vs == NULL && vs2 == NULL) { SgVariableDeclaration* defn = buildVariableDeclaration( SgName(_s.c_str()), buildIntType()); SgInitializedNamePtrList& variables = defn->get_variables(); SgInitializedNamePtrList::const_iterator i = variables.begin(); SgInitializedName* initializedName = *i; vs = new SgVariableSymbol(initializedName); prependStatement(defn, isSgScopeStatement(root_)); vs->set_parent(symtab2_); symtab2_->insert(SgName(_s.c_str()), vs); return new CG_roseRepr(isSgExpression(buildVarRefExp(vs))); } /* May have problem */ if (!isSgExpression(buildVarRefExp(SgName(_s.c_str())))) throw ir_error("error in Create ident!!"); if (vs2 != NULL) return new CG_roseRepr(isSgExpression(buildVarRefExp(vs2))); return new CG_roseRepr(isSgExpression(buildVarRefExp(vs))); } //----------------------------------------------------------------------------- // binary arithmetic operations //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::CreatePlus(CG_outputRepr *lop, CG_outputRepr *rop) const { if (rop == NULL) { return lop; } else if (lop == NULL) { return rop; } SgExpression* op1 = static_cast(lop)->op_; SgExpression* op2 = static_cast(rop)->op_; SgAddOp *ins = buildAddOp(op1, op2); op1->set_parent(ins); op2->set_parent(ins); delete lop; delete rop; return new CG_roseRepr(isSgExpression(ins)); } CG_outputRepr* CG_roseBuilder::CreateMinus(CG_outputRepr *lop, CG_outputRepr *rop) const { if (rop == NULL) { return lop; /* May Cause Problem */ } else if (lop == NULL) { SgExpression *op = static_cast(rop)->op_; SgMinusOp *ins = buildMinusOp(op); delete rop; return new CG_roseRepr(isSgExpression(ins)); } else { SgExpression* op1 = static_cast(lop)->op_; SgExpression* op2 = static_cast(rop)->op_; SgSubtractOp *ins = buildSubtractOp(op1, op2); op1->set_parent(ins); op2->set_parent(ins); delete lop; delete rop; return new CG_roseRepr(isSgExpression(ins)); } } CG_outputRepr* CG_roseBuilder::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; } SgExpression* op1 = static_cast(lop)->op_; SgExpression* op2 = static_cast(rop)->op_; SgMultiplyOp *ins = buildMultiplyOp(op1, op2); op1->set_parent(ins); op2->set_parent(ins); delete lop; delete rop; return new CG_roseRepr(isSgExpression(ins)); } CG_outputRepr* CG_roseBuilder::CreateIntegerFloor(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 SgExpression* op1 = static_cast(lop)->op_; SgExpression* op2 = static_cast(rop)->op_; // bugs in SUIF prevent use of correct io_divfloor SgDivideOp *ins = buildDivideOp(op1, op2); delete lop; delete rop; return new CG_roseRepr(isSgExpression(ins)); } CG_outputRepr* CG_roseBuilder::CreateIntegerMod(CG_outputRepr *lop, CG_outputRepr *rop) const { if (rop == NULL || lop == NULL) { return NULL; } SgExpression* op1 = static_cast(lop)->op_; SgExpression* op2 = static_cast(rop)->op_; // bugs in SUIF prevent use of correct io_mod SgModOp *ins; if (!isInputFortran()) { ins = buildModOp(op1, op2); delete lop; delete rop; return new CG_roseRepr(isSgExpression(ins)); } else { // Manu:: fortran mod is a function call and not an operator (f77 and f90) SgExpression *fins; SgName fName("MOD"); SgExprListExp* arg_list = buildExprListExp(); appendExpression(arg_list, op1); appendExpression(arg_list, op2); SgTypeInt *retType = buildIntType(); fins = isSgExpression(buildFunctionCallExp(fName, retType, arg_list, global_)); return new CG_roseRepr(isSgExpression(fins)); } } //----------------------------------------------------------------------------- // binary logical operations //----------------------------------------------------------------------------- CG_outputRepr* CG_roseBuilder::CreateAnd(CG_outputRepr *lop, CG_outputRepr *rop) const { /*if (rop == NULL || lop == NULL) { return NULL; }*/ if (rop == NULL) return lop; else if (lop == NULL) return rop; SgExpression* op1 = static_cast(lop)->op_; SgExpression* op2 = static_cast(rop)->op_; SgAndOp *ins = buildAndOp(op1, op2); delete lop; delete rop; return new CG_roseRepr(isSgExpression(ins)); } //----------------------------------------------------------------------------- // binary relational operations //----------------------------------------------------------------------------- /*CG_outputRepr* CG_roseBuilder::CreateGE(CG_outputRepr *lop, CG_outputRepr *rop) const { return CreateLE(rop, lop); }*/ CG_outputRepr* CG_roseBuilder::CreateLE(CG_outputRepr *lop, CG_outputRepr *rop) const { if (rop == NULL || lop == NULL) { return NULL; } SgExpression* op1 = static_cast(lop)->op_; SgExpression* op2 = static_cast(rop)->op_; SgLessOrEqualOp *ins = buildLessOrEqualOp(op1, op2); delete lop; delete rop; return new CG_roseRepr(isSgExpression(ins)); } CG_outputRepr* CG_roseBuilder::CreateEQ(CG_outputRepr *lop, CG_outputRepr *rop) const { if (rop == NULL || lop == NULL) { return NULL; } SgExpression* op1 = static_cast(lop)->op_; SgExpression* op2 = static_cast(rop)->op_; SgEqualityOp *ins = buildEqualityOp(op1, op2); delete lop; delete rop; return new CG_roseRepr(isSgExpression(ins)); } //----------------------------------------------------------------------------- // stmt list gen operations //----------------------------------------------------------------------------- /*CG_outputRepr* CG_roseBuilder::CreateStmtList(CG_outputRepr *singleton) const { if (singleton == NULL) { return new CG_roseRepr(new SgStatementPtrList); } SgStatementPtrList *tnl = static_cast(singleton)->list_; SgNode* sgn = static_cast(singleton)->tnl_; if (tnl == NULL) tnl = new SgStatementPtrList; if (sgn == NULL) { SgExpression* op = static_cast(singleton)->op_; if (op != NULL) (*tnl).push_back( buildExprStatement( static_cast(singleton)->op_)); } else (*tnl).push_back(isSgStatement(sgn)); delete singleton; return new CG_roseRepr(tnl); // tnl = isSgNode(buildBasicBlock(buildExprStatement(static_cast(singleton)->op_))); // delete singleton; // return new CG_roseRepr(tnl); } CG_outputRepr* CG_roseBuilder::StmtListInsertLast(CG_outputRepr *list, CG_outputRepr *node) const { return StmtListAppend(list, node); } */ CG_outputRepr* CG_roseBuilder::StmtListAppend(CG_outputRepr *list1, CG_outputRepr *list2) const { if (list2 == NULL) { return list1; } else if (list1 == NULL) { return list2; } // SgStatement* parent; // SgStatement* stmt1; // SgStatement* stmt2; SgStatementPtrList* new_list; SgStatementPtrList* tnl1 = static_cast(list1)->list_; SgStatementPtrList* tnl2 = static_cast(list2)->list_; SgNode* one = static_cast(list1)->tnl_; SgNode* two = static_cast(list2)->tnl_; SgExpression* exp1 = static_cast(list1)->op_; SgExpression* exp2 = static_cast(list2)->op_; if (exp1 || exp2) throw ir_error("error in stmtlistappend!!"); if (tnl1 && one) throw ir_error("error in stmtlistappend!!"); if (tnl2 && two) throw ir_error("error in stmtlistappend!!"); // SgNode* sg1 = static_cast(list1)->tnl_; //if((*tnl1).empty()){ // if(SgStatement* stmt = isSgStatement(sg1)) // (*tnl1).push_back(stmt); //else if(isSgScopeStatement(sg1)){ // SgStatementPtrList scopeStmtPtrLst = isSgScopeStatement(sg1)->generateStatementList(); // for(SgStatementPtrList::iterator it1 = scopeStmtPtrLst.begin();it1 != scopeStmtPtrLst.end(); it1++) // (*tnl1).push_back(*it1); //} //} if ((tnl1 == NULL) && (tnl2 == NULL)) { if ((one != NULL) && (two != NULL)) { new_list = new SgStatementPtrList; (*new_list).push_back(isSgStatement(one)); (*new_list).push_back(isSgStatement(two)); CG_roseRepr* new_rep = new CG_roseRepr(new_list); return static_cast(new_rep); } else if ((one != NULL) && (two == NULL)) { return static_cast(new CG_roseRepr(one)); } else if ((two != NULL) && (one == NULL)) { return static_cast(new CG_roseRepr(two)); } } else { if ((tnl2 != NULL) && (tnl1 == NULL)) { /* for(SgStatementPtrList::iterator it = (*tnl2).begin(); it != (*tnl2).end(); it++) { (*tnl1).push_back(*it); } */ if (one == NULL) return list2; else { new_list = new SgStatementPtrList; (*new_list).push_back(isSgStatement(one)); for (SgStatementPtrList::iterator it = (*tnl2).begin(); it != (*tnl2).end(); it++) { (*new_list).push_back(*it); } //delete list2; return static_cast(new CG_roseRepr(new_list)); } } else if ((tnl1 != NULL) && (tnl2 == NULL)) { if (two == NULL) return list1; else { (*tnl1).push_back(isSgStatement(two)); // delete list1; return static_cast(new CG_roseRepr(tnl1)); } } else if ((tnl1 != NULL) && (tnl2 != NULL)) { for (SgStatementPtrList::iterator it = (*tnl2).begin(); it != (*tnl2).end(); it++) { (*tnl1).push_back(*it); } // delete list2; // delete list1; return static_cast(new CG_roseRepr(tnl1)); } //else{ // SgNode* tnll2 = static_cast(list2)->tnl_; // if(tnll2 != NULL){ // if(isSgStatement(tnll2)) // (*tnl1).push_back(isSgStatement(tnll2)); // else if(isSgScopeStatement(tnll2)){ // SgStatementPtrList scopeStmtPtrLst1 = isSgScopeStatement(tnll2)->generateStatementList(); // for(SgStatementPtrList::iterator it2 = scopeStmtPtrLst1.begin();it2 != scopeStmtPtrLst1.end(); it2++) // (*tnl1).push_back(*it2); // } //} // else{ // SgStatement* stmt2 = isSgStatement(buildExprStatement(static_cast(list2)->op_)); // (*tnl1).push_back(stmt2); // } //} // stmt2 = isSgStatement(tnl2); // std::string c = tnl1->unparseToString(); // std::string d = isSgNode(stmt2)->unparseToString(); // if(isSgForStatement(tnl1) || isSgBasicBlock(tnl1)) // isSgScopeStatement(tnl1)->append_statement(stmt2); // else // { // stmt1 = isSgStatement(tnl1); // parent = isSgStatement(tnl1->get_parent()); // if(isSgForStatement(tnl1->get_parent()) || isSgBasicBlock(tnl1->get_parent())) // isSgScopeStatement(tnl1->get_parent())->append_statement(stmt2); // else if (isSgStatement(tnl1->get_parent())) // isSgStatement(tnl1->get_parent())->insert_statement(stmt1, stmt2, false); // } } // delete list2; // return list1; } CG_outputRepr* CG_roseBuilder::CreateDim3(const char* varName, CG_outputRepr* arg1, CG_outputRepr* arg2, CG_outputRepr* arg3) const { //SgName type_name("dim3"); //SgClassSymbol * type_symbol = global_scope->lookup_class_symbol(type_name); // SgClassDeclaration * type_decl = isSgClassDeclaration( // type_symbol->get_declaration()); //SgVariableDeclaration * var_decl = buildVariableDeclaration(varName, type_symbol->get_type()); SgFunctionSymbol * ctor_symbol = global_scope->lookup_function_symbol( SgName("dim3")); SgExprListExp * ctor_args; if(arg3 != NULL) ctor_args = buildExprListExp(static_cast(arg1)->op_, static_cast(arg2)->op_, static_cast(arg3)->op_); else ctor_args = buildExprListExp(static_cast(arg1)->op_, static_cast(arg2)->op_); SgFunctionCallExp * dim3_func_call = buildFunctionCallExp( buildFunctionRefExp(ctor_symbol->get_declaration()), ctor_args); char joined_str[20]; strcpy(joined_str, "dim3 "); strcat(joined_str, varName); SgExprStatement* decl = buildAssignStatement( buildOpaqueVarRefExp(joined_str, isSgScopeStatement(root_)), dim3_func_call); SgStatementPtrList *tnl2 = new SgStatementPtrList; // (*tnl2).push_back(var_decl); (*tnl2).push_back(decl); return new CG_roseRepr(tnl2); } /*CG_outputRepr* CG_roseBuilder::CreateDim3(const char* varName, int arg1, int arg2) const { SgName type_name("dim3"); SgClassSymbol * type_symbol = global_scope->lookup_class_symbol(type_name); SgClassDeclaration * type_decl = isSgClassDeclaration( type_symbol->get_declaration()); //SgVariableDeclaration * var_decl = buildVariableDeclaration(varName, type_symbol->get_type()); SgFunctionSymbol * ctor_symbol = global_scope->lookup_function_symbol( SgName("dim3")); SgExprListExp * ctor_args = buildExprListExp(buildIntVal(arg1), buildIntVal(arg2)); SgFunctionCallExp * dim3_func_call = buildFunctionCallExp( buildFunctionRefExp(ctor_symbol->get_declaration()), ctor_args); char joined_str[20]; strcpy(joined_str, "dim3 "); strcat(joined_str, varName); SgExprStatement* decl = buildAssignStatement( buildOpaqueVarRefExp(joined_str, isSgScopeStatement(root_)), dim3_func_call); SgStatementPtrList *tnl2 = new SgStatementPtrList; // (*tnl2).push_back(var_decl); (*tnl2).push_back(decl); return new CG_roseRepr(tnl2); } CG_outputRepr* CG_roseBuilder::CreateDim3(const char* varName, int arg1, int arg2, int arg3) const { SgName type_name("dim3"); SgClassSymbol * type_symbol = global_scope->lookup_class_symbol(type_name); SgClassDeclaration * type_decl = isSgClassDeclaration( type_symbol->get_declaration()); //SgVariableDeclaration * var_decl = buildVariableDeclaration(varName, type_symbol->get_type()); SgFunctionSymbol * ctor_symbol = global_scope->lookup_function_symbol( SgName("dim3")); SgExprListExp * ctor_args = buildExprListExp(buildIntVal(arg1), buildIntVal(arg2), buildIntVal(arg3)); SgFunctionCallExp * dim3_func_call = buildFunctionCallExp( buildFunctionRefExp(ctor_symbol->get_declaration()), ctor_args); char joined_str[20]; strcpy(joined_str, "dim3 "); strcat(joined_str, varName); SgExprStatement* decl = buildAssignStatement( buildOpaqueVarRefExp(joined_str, isSgScopeStatement(root_)), dim3_func_call); SgStatementPtrList *tnl2 = new SgStatementPtrList; // (*tnl2).push_back(var_decl); (*tnl2).push_back(decl); return new CG_roseRepr(tnl2); } */ /*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; } */ std::vector substitute(SgNode *in, const SgVariableSymbol *sym, SgExpression* expr, SgNode* root) { SgStatement* stmt; SgExpression* op; std::vector arrays; if (in != NULL) { if (stmt = isSgStatement(in)) { if (isSgBasicBlock(stmt)) { SgStatementPtrList& stmts = isSgBasicBlock(stmt)->get_statements(); for (int i = 0; i < stmts.size(); i++) { stmts[i]->set_parent(stmt); std::vector a = substitute( isSgNode(stmts[i]), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); } } else if (isSgForStatement(stmt)) { SgForStatement *tnf = isSgForStatement(stmt); tnf->get_for_init_stmt()->set_parent(tnf); tnf->get_test()->set_parent(tnf); tnf->get_increment()->set_parent(tnf); tnf->get_loop_body()->set_parent(tnf); std::vector a = substitute( isSgNode(tnf->get_for_init_stmt()), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); std::vector a1 = substitute( isSgNode(tnf->get_test()), sym, expr, root); std::copy(a1.begin(), a1.end(), back_inserter(arrays)); std::vector a2 = substitute( isSgNode(tnf->get_increment()), sym, expr, root); std::copy(a2.begin(), a2.end(), back_inserter(arrays)); std::vector a3 = substitute( isSgNode(tnf->get_loop_body()), sym, expr, root); std::copy(a3.begin(), a3.end(), back_inserter(arrays)); } else if (isSgFortranDo(stmt)) { // Manu:: fortran support SgFortranDo *tnf = isSgFortranDo(stmt); tnf->get_initialization()->set_parent(tnf); tnf->get_bound()->set_parent(tnf); tnf->get_increment()->set_parent(tnf); tnf->get_body()->set_parent(tnf); std::vector a = substitute( isSgNode(tnf->get_initialization()), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); std::vector a1 = substitute( isSgNode(tnf->get_bound()), sym, expr, root); std::copy(a1.begin(), a1.end(), back_inserter(arrays)); std::vector a2 = substitute( isSgNode(tnf->get_increment()), sym, expr, root); std::copy(a2.begin(), a2.end(), back_inserter(arrays)); std::vector a3 = substitute( isSgNode(tnf->get_body()), sym, expr, root); std::copy(a3.begin(), a3.end(), back_inserter(arrays)); } else if (isSgForInitStatement(stmt)) { SgStatementPtrList& stmts = isSgForInitStatement(stmt)->get_init_stmt(); for (SgStatementPtrList::iterator it = stmts.begin(); it != stmts.end(); it++) { std::vector a = substitute(isSgNode(*it), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); } } /*else if(isSgFortranDo(stmt)){ SgFortranDo *tfortran = isSgFortranDo(stmt); omega::CG_roseRepr *r = new omega::CG_roseRepr(isSgStatement(tfortran->get_body())); std::vector a = FindArrayRef(r); delete r; std::copy(a.begin(), a.end(), back_inserter(arrays)); }*/ else if (isSgVariableDeclaration(stmt)) { if (SgExpression *init = isSgVariableDeclaration(stmt)->get_variables().front()->get_initializer()) { if (isSgAssignInitializer(init)) { std::vector a = substitute( isSgAssignInitializer(init)->get_operand(), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); } } } else if (isSgIfStmt(stmt)) { SgIfStmt* tni = isSgIfStmt(stmt); //tni->get_conditional()->set_parent(tni); //tni->get_true_body()->set_parent(tni); //tni->get_false_body()->set_parent(tni); std::vector a = substitute( isSgNode(tni->get_conditional()), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); std::vector a1 = substitute( isSgNode(tni->get_true_body()), sym, expr, root); std::copy(a1.begin(), a1.end(), back_inserter(arrays)); std::vector a2 = substitute( isSgNode(tni->get_false_body()), sym, expr, root); std::copy(a2.begin(), a2.end(), back_inserter(arrays)); } else if (isSgExprStatement(stmt)) { (isSgExprStatement(stmt)->get_expression())->set_parent( isSgExprStatement(stmt)); std::vector a = substitute( isSgNode(isSgExprStatement(stmt)->get_expression()), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); } //end else if } //end if else { op = isSgExpression(in); // std::string x = isSgNode(op)->unparseToString(); std::string y = sym->get_name().getString(); // std::cout << "------substitute else:: " << in->unparseToString().c_str() << ", " << y.c_str() << "\n"; if (isSgBinaryOp(op)) { isSgBinaryOp(op)->get_lhs_operand()->set_parent(op); isSgBinaryOp(op)->get_rhs_operand()->set_parent(op); std::vector a = substitute( isSgBinaryOp(op)->get_lhs_operand(), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); std::vector a1 = substitute( isSgBinaryOp(op)->get_rhs_operand(), sym, expr, root); std::copy(a1.begin(), a1.end(), back_inserter(arrays)); } else if (isSgUnaryOp(op)) { //isSgUnaryOp(op)->get_operand()->set_parent(op); //std::string x = isSgNode(op)->unparseToString(); //std::cout< a = substitute( isSgUnaryOp(op)->get_operand(), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); } else if (isSgVarRefExp(op)) { std::string z = isSgVarRefExp(op)->get_symbol()->get_name().getString(); if (!strcmp(z.c_str(), y.c_str())) { //isSgVarRefExp(op)->set_symbol(isSgVarRefExp(expr)->get_symbol()); arrays.push_back(isSgVarRefExp(op)); //replaceVariableReferences(root, isSgVarRefExp(in)->get_symbol(), temp); //r = true; } //end if } //end else if else if (isSgCallExpression(op)) { SgExprListExp* exprs = isSgCallExpression(op)->get_args(); SgExpressionPtrList &expr_list = exprs->get_expressions(); for (SgExpressionPtrList::iterator it = expr_list.begin(); it != expr_list.end(); it++) { std::vector a = substitute(isSgNode(*it), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); } } else if (isSgExprListExp(op)) { // Manu:: fortran indices are stored this way SgExpressionPtrList &expr_list = isSgExprListExp(op)->get_expressions(); for (SgExpressionPtrList::iterator it = expr_list.begin(); it != expr_list.end(); it++) { std::vector a = substitute(isSgNode(*it), sym, expr, root); std::copy(a.begin(), a.end(), back_inserter(arrays)); } } //end else if //else if(!isSgValueExp(op)) // throw ir_error("unrecognized expression type"); } //end else } //end if /* bool r = false; if (isSgVarRefExp(in) && (isSgVarRefExp(in)->get_symbol() == sym)) { omega::CG_roseRepr *result = new omega::CG_roseRepr(expr); SgExpression* expr1 = result->GetExpression(); delete result; SgVariableSymbol* temp = isSgVarRefExp(expr1)->get_symbol(); parent->replace_expression(in, expr1); replaceVariableReferences(root, isSgVarRefExp(in)->get_symbol(), temp); r = true; } else if(isSgBinaryOp(in)){ substitute(isSgBinaryOp(in)->get_lhs_operand(), sym, expr, root, in); substitute(isSgBinaryOp(in)->get_rhs_operand(), sym, expr, root, in); } else if(isSgUnaryOp(in)) substitute(isSgUnaryOp(in)->get_operand(), sym, expr, root, in); */ return arrays; } /*bool substitute(SgStatement *tn, SgVariableSymbol *sym, SgExpression* expr, SgNode* root, SgSymbolTable* symtab) { if (tn == NULL) return false; bool r = false; if( tn != NULL){ if(isSgExpression(tn)){ r = substitute(isSgExpression(tn), sym, expr, root, isSgExpression(tn)) || r; } else { omega::CG_roseRepr *result = new omega::CG_roseRepr(expr); SgExpression* expr1 = result->GetExpression(); tn->replace_expression(buildVarRefExp(sym), expr1); for (unsigned i = 0; i < tn->get_numberOfTraversalSuccessors(); i++) r = substitute(isSgStatement(tn->get_traversalSuccessorByIndex(i)), sym, expr, root, symtab) || r; } } return r; } bool substitute(SgNode *tnl, SgVariableSymbol *sym, SgExpression* expr, SgNode* root, SgSymbolTable* symtab) { if (tnl == NULL) return false; bool r = false; for(int i=0; i < tnl->get_numberOfTraversalSuccessors(); i++){ SgNode* tn = tnl->get_traversalSuccessorByIndex(i); r = substitute(isSgStatement(tn), sym, expr, root, symtab) || r; } return r; } */ } // namespace