diff options
author | Tuowen Zhao <ztuowen@gmail.com> | 2016-09-19 21:14:58 +0000 |
---|---|---|
committer | Tuowen Zhao <ztuowen@gmail.com> | 2016-09-19 21:14:58 +0000 |
commit | 210f77d2c32f14d2e99577fd3c9842bb19d47e50 (patch) | |
tree | 5edb327c919b8309e301c3440fb6668a0075c8ef /lib/rosecg | |
parent | a66ce5cd670c4d3c0dc449720f5bc45dd4c281b8 (diff) | |
download | chill-210f77d2c32f14d2e99577fd3c9842bb19d47e50.tar.gz chill-210f77d2c32f14d2e99577fd3c9842bb19d47e50.tar.bz2 chill-210f77d2c32f14d2e99577fd3c9842bb19d47e50.zip |
Moved most modules into lib
Diffstat (limited to 'lib/rosecg')
-rw-r--r-- | lib/rosecg/CMakeLists.txt | 18 | ||||
-rw-r--r-- | lib/rosecg/include/CG_roseBuilder.h | 108 | ||||
-rw-r--r-- | lib/rosecg/include/CG_roseRepr.h | 46 | ||||
-rw-r--r-- | lib/rosecg/include/rose_attributes.h | 91 | ||||
-rw-r--r-- | lib/rosecg/src/CG_roseBuilder.cc | 1093 | ||||
-rw-r--r-- | lib/rosecg/src/CG_roseRepr.cc | 125 | ||||
-rw-r--r-- | lib/rosecg/src/rose_attributes.cc | 183 |
7 files changed, 1664 insertions, 0 deletions
diff --git a/lib/rosecg/CMakeLists.txt b/lib/rosecg/CMakeLists.txt new file mode 100644 index 0000000..610bc50 --- /dev/null +++ b/lib/rosecg/CMakeLists.txt @@ -0,0 +1,18 @@ +set(CODEGEN_ROSE_SRC + src/CG_roseBuilder.cc + src/CG_roseRepr.cc + src/rose_attributes.cc + ) + +include_directories( + include + ${OMEGA_INC} + ${ROSEHOME}/include + ${ROSEHOME}/include/rose + ${BOOSTHOME}/include + ) + +add_library(rosecg ${CODEGEN_ROSE_SRC}) + +install(TARGETS rosecg + DESTINATION lib) diff --git a/lib/rosecg/include/CG_roseBuilder.h b/lib/rosecg/include/CG_roseBuilder.h new file mode 100644 index 0000000..bb622c7 --- /dev/null +++ b/lib/rosecg/include/CG_roseBuilder.h @@ -0,0 +1,108 @@ +#ifndef CG_roseBuilder_h +#define CG_roseBuilder_h + +#include <basic/Tuple.h> +#include "rose_attributes.h" +#include <code_gen/CG_outputBuilder.h> +#include "CG_roseRepr.h" +#include <string> + +namespace omega { + +class CG_roseBuilder : public CG_outputBuilder { +public: + CG_roseBuilder(int isFortran, SgGlobal* global, SgGlobal* global_scope, SgSymbolTable* symtab1, SgSymbolTable* symtab2, SgNode* root); + ~CG_roseBuilder(); + + //! substitute variables in stmt + CG_outputRepr *CreateSubstitutedStmt(int indent, CG_outputRepr *stmt, + const std::vector<std::string> &vars, + std::vector<CG_outputRepr *> &subs) const; + + + + //! assignment generation + CG_outputRepr* CreateAssignment(int indent, CG_outputRepr* lhs, + CG_outputRepr* rhs) const; + + //! function invocation generation + CG_outputRepr* CreateInvoke(const std::string &funcName, + std::vector<CG_outputRepr *> &argList) const; + + //! comment generation + CG_outputRepr* CreateComment(int indent, const std::string &commentText) const; + //! Attribute generation + CG_outputRepr* CreateAttribute(CG_outputRepr *control, + const std::string &commentText) const; + //! Pragma Attribute + CG_outputRepr* CreatePragmaAttribute(CG_outputRepr *scopeStmt, int looplevel, + const std::string &pragmaText) const; + + //! Prefetch Attribute + CG_outputRepr* CreatePrefetchAttribute(CG_outputRepr *scopeStmt, int looplevel, + const std::string &arrName, int hint) const; + + //! if stmt gen operations + CG_outputRepr* CreateIf(int indent, CG_outputRepr* guardCondition, + CG_outputRepr* true_stmtList, CG_outputRepr* false_stmtList) const; + + //! inductive variable generation, to be used in CreateLoop as control + CG_outputRepr* CreateInductive(CG_outputRepr* index, + CG_outputRepr* lower, + CG_outputRepr* upper, + CG_outputRepr* step) const; + + //! loop stmt generation + CG_outputRepr* CreateLoop(int indent, CG_outputRepr* control, + CG_outputRepr* stmtList) const; + + CG_outputRepr* CreateInt(int num ) const; + bool isInteger(CG_outputRepr *op) const; + CG_outputRepr* CreateIdent(const std::string &varName) const; + + //! binary arithmetic operations + CG_outputRepr* CreatePlus(CG_outputRepr* lop, CG_outputRepr* rop) const; + CG_outputRepr* CreateMinus(CG_outputRepr* lop, CG_outputRepr* rop) const; + CG_outputRepr* CreateTimes(CG_outputRepr* lop, CG_outputRepr* rop) const; + CG_outputRepr* CreateIntegerFloor(CG_outputRepr* lop, CG_outputRepr* rop) const; + CG_outputRepr* CreateIntegerMod(CG_outputRepr* lop, CG_outputRepr* rop) const; + + //! binary logical operations + CG_outputRepr* CreateAnd(CG_outputRepr* lop, CG_outputRepr* rop) const; + + //--------------------------------------------------------------------------- + // binary relational operations + //--------------------------------------------------------------------------- + // CG_outputRepr* CreateGE(CG_outputRepr*, CG_outputRepr*) const; + CG_outputRepr* CreateLE(CG_outputRepr* lop, CG_outputRepr* rop) const; + CG_outputRepr* CreateEQ(CG_outputRepr* lop, CG_outputRepr* rop) const; + + //--------------------------------------------------------------------------- + // stmt list gen operations + //--------------------------------------------------------------------------- + CG_outputRepr* + StmtListAppend(CG_outputRepr* list1, CG_outputRepr* list2) const; + + CG_outputRepr* CreateDim3(const char* varName, CG_outputRepr* arg1, CG_outputRepr* arg2, CG_outputRepr* arg3 = NULL) const; + + // Manu:: added for fortran support + bool isInputFortran() const; + +private: + SgSymbolTable *symtab_; + SgSymbolTable *symtab2_; + SgNode* root_; + SgGlobal* global_; + SgGlobal* global_scope; + int isFortran; // Manu:: added for fortran support +}; + +extern char *k_ocg_comment; +std::vector<SgVarRefExp *>substitute(SgNode *tnl, const SgVariableSymbol *sym, SgExpression *expr,SgNode* root) ; + + + + +} // namespace + +#endif diff --git a/lib/rosecg/include/CG_roseRepr.h b/lib/rosecg/include/CG_roseRepr.h new file mode 100644 index 0000000..28553e7 --- /dev/null +++ b/lib/rosecg/include/CG_roseRepr.h @@ -0,0 +1,46 @@ +#ifndef CG_roseRepr_h +#define CG_roseRepr_h + +#include <code_gen/CG_outputRepr.h> +#include "rose.h" + +namespace omega { + +class CG_roseRepr : public CG_outputRepr { + friend class CG_roseBuilder; +public: + CG_roseRepr(); + CG_roseRepr(SgNode *tnl); + CG_roseRepr(SgExpression *exp); + CG_roseRepr(SgStatementPtrList* stmtlist); + + ~CG_roseRepr(); + CG_outputRepr *clone() const; + void clear(); + + SgNode* GetCode() const; + SgStatementPtrList* GetList() const; + SgExpression *GetExpression() const; + + + + + //--------------------------------------------------------------------------- + // Dump operations + //--------------------------------------------------------------------------- + void Dump() const; +private: + // only one of _tnl and _op would be active at any time, depending on + // whether it is building a statement list or an expression tree + SgNode *tnl_; + SgExpression *op_; + SgStatementPtrList *list_; + void DumpFileHelper(SgNode* node, FILE* fp) const; + //operand op_; +}; + + + +} // namespace + +#endif diff --git a/lib/rosecg/include/rose_attributes.h b/lib/rosecg/include/rose_attributes.h new file mode 100644 index 0000000..9766f52 --- /dev/null +++ b/lib/rosecg/include/rose_attributes.h @@ -0,0 +1,91 @@ +#ifndef ROSE_ATTRIBUTES_HH +#define ROSE_ATTRIBUTES_HH + +#include "rose.h" +#include <algorithm> +#include <string> +#include <vector> + +namespace omega { + +class CodeInsertion; + +typedef std::vector<CodeInsertion*> CodeInsertionPtrList; +typedef std::vector<CodeInsertion*>::iterator CodeInsertionPtrListItr; + +class CodeInsertion { +public: + int loop_level; + bool marked; + CodeInsertion(int looplevel) { this->loop_level = looplevel; marked = false; } + ~CodeInsertion() {} + virtual SgStatement* getStatement(SgScopeStatement* scopeStmt = NULL) = 0; +}; + +class PragmaInsertion : public CodeInsertion { +private: + std::string name; +public: + PragmaInsertion(int loop_level, const std::string &pragma) : CodeInsertion(loop_level) { this->name = std::string(pragma); } + ~PragmaInsertion() { } + virtual SgStatement* getStatement(SgScopeStatement* scopeStmt = NULL); +}; + +class MMPrefetchInsertion : public CodeInsertion { +private: + std::string arrName; + std::vector<std::string*> indecies; + std::vector<int> offsets; + int indexCount; + int cacheHint; + void initialize(const std::string& arrName, int hint); + void addDim(int offset); + void addDim(int offset, const std::string& indexer); + SgExpression* buildArrArg(SgScopeStatement* scopeStmt); + SgExpression* makeIndexExp(int dim, SgScopeStatement* scopeStmt); +public: + MMPrefetchInsertion(int loop_level, const std::string &arr, int hint) : CodeInsertion(loop_level) + { this->initialize(arr, hint); } + ~MMPrefetchInsertion() { } + virtual SgStatement* getStatement(SgScopeStatement* scopeStmt = NULL); +}; + +class CodeInsertionAttribute : public AstAttribute { +private: + std::vector<CodeInsertion*> code_insertions; +public: + CodeInsertionAttribute() { code_insertions = std::vector<CodeInsertion*>(); } + ~CodeInsertionAttribute() {} + + void add(CodeInsertion* ci) { code_insertions.push_back(ci); } + CodeInsertionPtrListItr begin() { return code_insertions.begin(); } + CodeInsertionPtrListItr end() { return code_insertions.end(); } + void remove(CodeInsertion* ci) { std::remove(code_insertions.begin(), code_insertions.end(), ci); } + int countCodeInsertions() { return code_insertions.size(); } +}; + +struct CodeInsertionMark { +public: + SgStatement* stmt; + CodeInsertion* ci; +}; + +class CodeInsertionVisitor : public AstPrePostProcessing { +private: + int loop_level; + std::vector<CodeInsertionMark*> ci_marks; + void markStmt(SgStatement* stmt, CodeInsertion* ci); +public: + void initialize(); + virtual void preOrderVisit(SgNode* n); + virtual void postOrderVisit(SgNode* n); + void insertCode(); +}; + +void postProcessRoseCodeInsertion(SgProject* proj); +void copyAttributes(SgNode* s, SgNode* d); +CodeInsertionAttribute* getOrCreateCodeInsertionAttribute(SgNode* node); + +} + +#endif diff --git a/lib/rosecg/src/CG_roseBuilder.cc b/lib/rosecg/src/CG_roseBuilder.cc new file mode 100644 index 0000000..09370a4 --- /dev/null +++ b/lib/rosecg/src/CG_roseBuilder.cc @@ -0,0 +1,1093 @@ +/***************************************************************************** + 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 "CG_roseBuilder.h" +#include <string> + +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; + +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<std::string> &vars, std::vector<CG_outputRepr*> &subs) const { + + SgStatementPtrList* list = static_cast<CG_roseRepr *>(stmt)->list_; + SgNode *tnl; + SgStatement* statement; + if (list != NULL) { + delete stmt; + for (int i = 0; i < subs.size(); i++) { + if (subs[i] == NULL) + continue; + + CG_roseRepr *repr = static_cast<CG_roseRepr*>(subs[i]); + SgExpression* op = repr->op_; + + for (SgStatementPtrList::iterator it = (*list).begin(); + it != (*list).end(); it++) { + statement = (*it); + tnl = isSgNode(statement); + + 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::vector<SgVarRefExp *> array = substitute(tnl, + (const SgVariableSymbol*) vs, op, root_); + for (std::vector<SgVarRefExp *>::iterator it = + array.begin(); it != array.end(); it++) { + + 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()); + + } + } 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"); + } + + } + } + + } + + delete repr; + subs[i] = NULL; + + if (subs[i] != NULL) + throw ir_error("not freed properly"); + + } + + return new CG_roseRepr(list); + + } else { + tnl = static_cast<CG_roseRepr *>(stmt)->tnl_; + + 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<CG_roseRepr*>(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::vector<SgVarRefExp *> 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())) { + } + } + + for (std::vector<SgVarRefExp *>::iterator j = array.begin(); + j != array.end(); j++) { + + 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()); + + } + } 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"); + + } + + } + } + } + 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<CG_roseRepr*>(rhs)->op_; + SgExpression* dst = static_cast<CG_roseRepr*>(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<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[0]; + } else { + int last = list.size() - 1; + SgExpression* op2 = static_cast<CG_roseRepr*>(list[last])->op_; + delete list[last]; + list.erase(list.end()-1); + CG_roseRepr *repr = static_cast<CG_roseRepr*>(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<CG_roseRepr *>(CreateLE(new CG_roseRepr(op2), new CG_roseRepr(op1)))->op_; + appendExpression(arg_list, cond); + ins = isSgExpression(buildFunctionCallExp(fName, retType, arg_list, global_)); + } + + } 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<CG_roseRepr *>(CreateLE(new CG_roseRepr(op1), new CG_roseRepr(op2)))->op_; + appendExpression(arg_list, cond); + ins = isSgExpression(buildFunctionCallExp(fName, retType, arg_list, global_)); + } + + } + + 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 { + + 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<CG_roseRepr*>(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<CG_roseRepr*>(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<CG_roseRepr*>(true_stmtList)->tnl_)); + then_part = isSgStatement(then_part2); + } else + then_part = isSgStatement(static_cast<CG_roseRepr*>(true_stmtList)->tnl_); + } + } else { + then_part = NULL; + } + if (false_stmtList != NULL) { + else_part1 = static_cast<CG_roseRepr*>(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<CG_roseRepr*>(false_stmtList)->tnl_)); + else_part = isSgStatement(else_part2); + } else + else_part = isSgStatement(static_cast<CG_roseRepr*>(false_stmtList)->tnl_); + } + } else { + else_part = NULL; + } + + SgIfStmt* ti = buildIfStmt(header, isSgStatement(then_part), + isSgStatement(else_part)); + + 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<CG_roseRepr*>(index)->op_); + SgExpression* lower_bound = static_cast<CG_roseRepr*>(lower)->op_; + SgExpression* upper_bound = static_cast<CG_roseRepr*>(upper)->op_; + SgExpression* step_size = static_cast<CG_roseRepr*>(step)->op_; + + 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()) { + 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 { + + 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<CG_roseRepr*>(control)->tnl_; + + tnl->setAttribute("omega_comment", new AstTextAttribute(commentText)); + + return static_cast<CG_roseRepr*>(control); + +} + +//----------------------------------------------------------------------------- +// Pragma Attribute +//----------------------------------------------------------------------------- +CG_outputRepr* CG_roseBuilder::CreatePragmaAttribute(CG_outputRepr *stmt, int looplevel, const std::string &pragmaText) const { + SgNode *tnl = static_cast<CG_roseRepr*>(stmt)->tnl_; + CodeInsertionAttribute* attr = NULL; + if (!tnl->attributeExists("code_insertion")) { + attr = new CodeInsertionAttribute(); + tnl->setAttribute("code_insertion", attr); + } + else { + attr = static_cast<CodeInsertionAttribute*>(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<CG_roseRepr*>(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<CG_roseRepr*>(control)->tnl_; + SgForStatement *tf = isSgForStatement(tnl); + + // Manu :: fortran support + SgFortranDo *tfd = NULL; + if (isInputFortran()) { + tfd = isSgFortranDo(tnl); + } + SgStatementPtrList * body = static_cast<CG_roseRepr*>(stmtList)->list_; + + if (body != NULL) { + if (!((*body).empty())) { + if ((*body).size() == 1) { + 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 { + // 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<CG_roseRepr*>(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<CG_roseRepr *>(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<CG_roseRepr*>(lop)->op_; + SgExpression* op2 = static_cast<CG_roseRepr*>(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<CG_roseRepr*>(rop)->op_; + SgMinusOp *ins = buildMinusOp(op); + + delete rop; + + return new CG_roseRepr(isSgExpression(ins)); + } else { + SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; + SgExpression* op2 = static_cast<CG_roseRepr*>(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<CG_roseRepr*>(lop)->op_; + SgExpression* op2 = static_cast<CG_roseRepr*>(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<CG_roseRepr*>(lop)->op_; + SgExpression* op2 = static_cast<CG_roseRepr*>(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<CG_roseRepr*>(lop)->op_; + SgExpression* op2 = static_cast<CG_roseRepr*>(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) + return lop; + else if (lop == NULL) + return rop; + + SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; + SgExpression* op2 = static_cast<CG_roseRepr*>(rop)->op_; + + SgAndOp *ins = buildAndOp(op1, op2); + + delete lop; + delete rop; + + return new CG_roseRepr(isSgExpression(ins)); + +} + +//----------------------------------------------------------------------------- +// binary relational operations +//----------------------------------------------------------------------------- +CG_outputRepr* CG_roseBuilder::CreateLE(CG_outputRepr *lop, + CG_outputRepr *rop) const { + if (rop == NULL || lop == NULL) { + return NULL; + } + + SgExpression* op1 = static_cast<CG_roseRepr*>(lop)->op_; + SgExpression* op2 = static_cast<CG_roseRepr*>(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<CG_roseRepr*>(lop)->op_; + SgExpression* op2 = static_cast<CG_roseRepr*>(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::StmtListAppend(CG_outputRepr *list1, + CG_outputRepr *list2) const { + + if (list2 == NULL) { + return list1; + } else if (list1 == NULL) { + return list2; + } + + SgStatementPtrList* new_list; + + SgStatementPtrList* tnl1 = static_cast<CG_roseRepr *>(list1)->list_; + SgStatementPtrList* tnl2 = static_cast<CG_roseRepr *>(list2)->list_; + SgNode* one = static_cast<CG_roseRepr *>(list1)->tnl_; + SgNode* two = static_cast<CG_roseRepr *>(list2)->tnl_; + + SgExpression* exp1 = static_cast<CG_roseRepr *>(list1)->op_; + SgExpression* exp2 = static_cast<CG_roseRepr *>(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!!"); + 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<CG_outputRepr *>(new_rep); + + } else if ((one != NULL) && (two == NULL)) { + + return static_cast<CG_outputRepr *>(new CG_roseRepr(one)); + + } else if ((two != NULL) && (one == NULL)) { + return static_cast<CG_outputRepr *>(new CG_roseRepr(two)); + + } + + } else { + if ((tnl2 != NULL) && (tnl1 == NULL)) { + 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); + + } + return static_cast<CG_outputRepr *>(new CG_roseRepr(new_list)); + } + } else if ((tnl1 != NULL) && (tnl2 == NULL)) { + if (two == NULL) + return list1; + else { + + (*tnl1).push_back(isSgStatement(two)); + return static_cast<CG_outputRepr *>(new CG_roseRepr(tnl1)); + + } + + } else if ((tnl1 != NULL) && (tnl2 != NULL)) { + + for (SgStatementPtrList::iterator it = (*tnl2).begin(); + it != (*tnl2).end(); it++) { + (*tnl1).push_back(*it); + + } + + return static_cast<CG_outputRepr *>(new CG_roseRepr(tnl1)); + } + + } + +} + + +CG_outputRepr* CG_roseBuilder::CreateDim3(const char* varName, CG_outputRepr* arg1, + CG_outputRepr* arg2, CG_outputRepr* arg3) const { + + SgFunctionSymbol * ctor_symbol = global_scope->lookup_function_symbol( + SgName("dim3")); + + SgExprListExp * ctor_args; + if(arg3 != NULL) + ctor_args = buildExprListExp(static_cast<CG_roseRepr*>(arg1)->op_, + static_cast<CG_roseRepr*>(arg2)->op_, static_cast<CG_roseRepr*>(arg3)->op_); + else + ctor_args = buildExprListExp(static_cast<CG_roseRepr*>(arg1)->op_, + static_cast<CG_roseRepr*>(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(decl); + return new CG_roseRepr(tnl2); + +} + +std::vector<SgVarRefExp *> substitute(SgNode *in, const SgVariableSymbol *sym, + SgExpression* expr, SgNode* root) { + + SgStatement* stmt; + SgExpression* op; + std::vector<SgVarRefExp *> 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<SgVarRefExp *> 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<SgVarRefExp *> a = substitute( + isSgNode(tnf->get_for_init_stmt()), sym, expr, root); + std::copy(a.begin(), a.end(), back_inserter(arrays)); + std::vector<SgVarRefExp *> a1 = substitute( + isSgNode(tnf->get_test()), sym, expr, root); + std::copy(a1.begin(), a1.end(), back_inserter(arrays)); + std::vector<SgVarRefExp *> a2 = substitute( + isSgNode(tnf->get_increment()), sym, expr, root); + std::copy(a2.begin(), a2.end(), back_inserter(arrays)); + std::vector<SgVarRefExp *> 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<SgVarRefExp *> a = substitute( + isSgNode(tnf->get_initialization()), sym, expr, root); + std::copy(a.begin(), a.end(), back_inserter(arrays)); + std::vector<SgVarRefExp *> a1 = substitute( + isSgNode(tnf->get_bound()), sym, expr, root); + std::copy(a1.begin(), a1.end(), back_inserter(arrays)); + std::vector<SgVarRefExp *> a2 = substitute( + isSgNode(tnf->get_increment()), sym, expr, root); + std::copy(a2.begin(), a2.end(), back_inserter(arrays)); + std::vector<SgVarRefExp *> 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<SgVarRefExp *> a = substitute(isSgNode(*it), + sym, expr, root); + + 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<SgVarRefExp *> 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); + std::vector<SgVarRefExp *> a = substitute( + isSgNode(tni->get_conditional()), sym, expr, root); + std::copy(a.begin(), a.end(), back_inserter(arrays)); + std::vector<SgVarRefExp *> a1 = substitute( + isSgNode(tni->get_true_body()), sym, expr, root); + std::copy(a1.begin(), a1.end(), back_inserter(arrays)); + std::vector<SgVarRefExp *> 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<SgVarRefExp *> a = substitute( + isSgNode(isSgExprStatement(stmt)->get_expression()), + sym, expr, root); + std::copy(a.begin(), a.end(), back_inserter(arrays)); + } + } + else { + op = isSgExpression(in); + std::string y = sym->get_name().getString(); + + if (isSgBinaryOp(op)) { + + isSgBinaryOp(op)->get_lhs_operand()->set_parent(op); + isSgBinaryOp(op)->get_rhs_operand()->set_parent(op); + + std::vector<SgVarRefExp *> a = substitute( + isSgBinaryOp(op)->get_lhs_operand(), sym, expr, root); + std::copy(a.begin(), a.end(), back_inserter(arrays)); + std::vector<SgVarRefExp *> a1 = substitute( + isSgBinaryOp(op)->get_rhs_operand(), sym, expr, root); + std::copy(a1.begin(), a1.end(), back_inserter(arrays)); + } else if (isSgUnaryOp(op)) { + std::vector<SgVarRefExp *> 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())) { + arrays.push_back(isSgVarRefExp(op)); + } + } + 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<SgVarRefExp *> 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<SgVarRefExp *> a = substitute(isSgNode(*it), + sym, expr, root); + std::copy(a.begin(), a.end(), back_inserter(arrays)); + } + + } + + } + } + + return arrays; +} + +} // namespace diff --git a/lib/rosecg/src/CG_roseRepr.cc b/lib/rosecg/src/CG_roseRepr.cc new file mode 100644 index 0000000..0b0c073 --- /dev/null +++ b/lib/rosecg/src/CG_roseRepr.cc @@ -0,0 +1,125 @@ +/***************************************************************************** + Copyright (C) 2008 University of Southern California. + All Rights Reserved. + + Purpose: + omega holder for suif implementaion + + Notes: + + History: + 02/01/06 - Chun Chen - created +*****************************************************************************/ + +#include "CG_roseRepr.h" +#include "rose_attributes.h" +#include <stdio.h> +#include <string.h> +#include <cstring> +namespace omega { + + + + +CG_roseRepr::CG_roseRepr(): tnl_(NULL), op_(NULL), list_(NULL){ + +} + +CG_roseRepr::CG_roseRepr(SgNode *tnl): tnl_(tnl), op_(NULL),list_(NULL) { +} + +CG_roseRepr::CG_roseRepr(SgExpression* op): tnl_(NULL), op_(op),list_(NULL){ +} +CG_roseRepr::CG_roseRepr(SgStatementPtrList* stmtlist):tnl_(NULL), op_(NULL), list_(stmtlist){ +} + +CG_roseRepr::~CG_roseRepr() { + // delete nothing here. operand or tree_node_list should already be + // grafted to other expression tree or statement list +} + +CG_outputRepr* CG_roseRepr::clone() const { + + if( tnl_ != NULL) { + SgTreeCopy tc; + SgNode *tnl = tnl_->copy(tc); + copyAttributes(tnl_, tnl); + + tnl->set_parent(tnl_->get_parent()); + return new CG_roseRepr(tnl); + } + else if(op_ != NULL) + { + SgTreeCopy tc1; + SgNode* op = isSgNode(op_)->copy(tc1); + copyAttributes(op_, op); + + op->set_parent(isSgNode(op_)->get_parent()); + return new CG_roseRepr(isSgExpression(op)); + } + else if(list_ != NULL) + { + SgStatementPtrList* list2 = new SgStatementPtrList; + + for(SgStatementPtrList::iterator it = (*list_).begin(); it != (*list_).end(); it++){ + SgTreeCopy tc3; + SgNode *tnl2 = isSgNode(*it)->copy(tc3); + copyAttributes(*it, tnl2); + + tnl2->set_parent(isSgNode(*it)->get_parent()); + + (*list2).push_back(isSgStatement(tnl2)); + } + return new CG_roseRepr(list2); + } + + return NULL; +} + +void CG_roseRepr::clear() { + if(tnl_ != NULL) { + delete tnl_; + tnl_ = NULL; + } +} + +SgNode* CG_roseRepr::GetCode() const { + return tnl_; +} + +SgStatementPtrList* CG_roseRepr::GetList() const { + return list_; +} + +SgExpression* CG_roseRepr::GetExpression() const { + return op_; +} +void CG_roseRepr::Dump() const { +SgNode* tnl = tnl_; +SgExpression* op = op_ ; + if(tnl != NULL) + DumpFileHelper(tnl, stdout); + else if(op != NULL) + DumpFileHelper(isSgNode(op), stdout); + +} + +void CG_roseRepr::DumpFileHelper(SgNode* node, FILE *fp) const{ + std::string x; + size_t numberOfSuccessors = node->get_numberOfTraversalSuccessors(); + if(numberOfSuccessors == 0){ + x = node->unparseToString (); + fprintf(fp, "%s", x.c_str()); + } + else{ + for (size_t idx = 0; idx < numberOfSuccessors; idx++) + { + SgNode *child = NULL; + child = node->get_traversalSuccessorByIndex(idx); + DumpFileHelper(child, fp); + } + +} +} + +} // namespace diff --git a/lib/rosecg/src/rose_attributes.cc b/lib/rosecg/src/rose_attributes.cc new file mode 100644 index 0000000..3debb2d --- /dev/null +++ b/lib/rosecg/src/rose_attributes.cc @@ -0,0 +1,183 @@ +#include "rose_attributes.h" + +namespace omega { + +CodeInsertionAttribute* getOrCreateCodeInsertionAttribute(SgNode* node) { + CodeInsertionAttribute* attr; + if(node->attributeExists("code_insertion")) + return static_cast<CodeInsertionAttribute*>(node->getAttribute("code_insertion")); + attr = new CodeInsertionAttribute(); + node->setAttribute("code_insertion", attr); + return attr; +} + +void postProcessRoseCodeInsertion(SgProject* proj) { + //generatePDF(*proj); + CodeInsertionVisitor visitor = CodeInsertionVisitor(); + visitor.initialize(); + visitor.traverseInputFiles(proj); + visitor.insertCode(); +} + +// Swap a code insertion from one node (sn) to another (dn) +// -- note that this function does not currently remove the insertion from the sn node +void moveCodeInsertion(SgNode* sn, CodeInsertion* ci, SgNode* dn) { + CodeInsertionAttribute* new_attr; + // TODO in the near future: replace the above statement with 'new_attr = getOrCreateCodeInsertionAttribute(...)' + CodeInsertionAttribute* old_attr = static_cast<CodeInsertionAttribute*>(sn->getAttribute("code_insertion")); + if(dn->attributeExists("code_insertion")) { + new_attr = static_cast<CodeInsertionAttribute*>(dn->getAttribute("code_insertion")); + } + else { + new_attr = new CodeInsertionAttribute(); + dn->setAttribute("code_insertion", new_attr); + } + new_attr->add(ci); +} + +// A function that copies a specific attribute from one node to another +// this function exists to get around a ROSE limitation that does not +// copy attributes +void copyAttribute(std::string attr_name, SgNode* s, SgNode* d) { + if(s->attributeExists(attr_name)) { + d->setAttribute(attr_name,s->getAttribute(attr_name)); + } +} + +// TODO: find all existng attributes and iterate over them instead of doing them +// individually +void copyAttributes(SgNode* s, SgNode* d) { + copyAttribute("code_insertion", s, d); + //...any other attributes... +} + +void CodeInsertionVisitor::initialize() { + this->loop_level = 0; + this->ci_marks = std::vector<CodeInsertionMark*>(); +} + +void CodeInsertionVisitor::markStmt(SgStatement* stmt, CodeInsertion* ci) { + // this check prevents multiple copies of stmts + // -- may be changed in the future + if(!ci->marked) { + CodeInsertionMark* pos = new CodeInsertionMark(); + pos->stmt = stmt; + pos->ci = ci; + this->ci_marks.push_back(pos); + ci->marked = true; + } +} + +// increase loop_level as the visitor descends +void CodeInsertionVisitor::preOrderVisit(SgNode* n) { + if (isSgForStatement(n)) { + this->loop_level++; + } +} + +void CodeInsertionVisitor::postOrderVisit(SgNode* n) { + if(isSgForStatement(n)) { + this->loop_level--; + } + if(isSgStatement(n)) { + if(n->attributeExists("code_insertion")) { + CodeInsertionAttribute *attr = static_cast<CodeInsertionAttribute*>(n->getAttribute("code_insertion")); + for(CodeInsertionPtrListItr itr = attr->begin(); itr != attr->end(); ++itr) { + CodeInsertion *insertion = *itr; + // check loop level -- if it is equivelent, mark statement for insertion + // -- else, move attribute up to parent + if(insertion->loop_level != this->loop_level) { + moveCodeInsertion(n, insertion, n->get_parent()); + } + else { + this->markStmt(isSgStatement(n), insertion); + } + } + } + } +} + +// final stage of algorithm that inserts marked statements +void CodeInsertionVisitor::insertCode() { + for(std::vector<CodeInsertionMark*>::iterator itr = this->ci_marks.begin(); itr != this->ci_marks.end(); ++itr) { + CodeInsertionMark* mark = *itr; + SgScopeStatement* scope = static_cast<SgScopeStatement*>(mark->stmt->get_parent()); + SageInterface::insertStatementBefore(mark->stmt, mark->ci->getStatement(scope)); + } +} + +SgStatement* PragmaInsertion::getStatement(SgScopeStatement* scopeStmt) { + SgStatement* stmt = SageBuilder::buildPragmaDeclaration(this->name); + return stmt; +} + +//SgStatement* MMPrefetchInsertion::getStatement(SgScopeStatement* scopeStmt) { +// const SgName& name = SgName("_mm_prefetch"); +// SgType* rtype = SageBuilder::buildVoidType(); +// SgExpression* arr_arg = SageBuilder::buildVarRefExp(this->arrName); +// SgExpression* hint_arg = SageBuilder::buildShortVal(this->cacheHint); +// SgExprListExp* args = SageBuilder::buildExprListExp(arr_arg,hint_arg); +// SgStatement* stmt = SageBuilder::buildFunctionCallStmt(name, rtype, args, scopeStmt); +// return stmt; +//} + +SgStatement* MMPrefetchInsertion::getStatement(SgScopeStatement* scopeStmt) { + const SgName fname = SgName("_mm_prefetch"); + SgType* rtype = SageBuilder::buildVoidType(); + SgExpression* arr_arg = this->buildArrArg(scopeStmt); + SgExpression* hint_arg = SageBuilder::buildShortVal(this->cacheHint); + SgExprListExp* args = SageBuilder::buildExprListExp(arr_arg, hint_arg); + return SageBuilder::buildFunctionCallStmt(fname, rtype, args, scopeStmt); +} + +SgExpression* MMPrefetchInsertion::buildArrArg(SgScopeStatement* scopeStmt) { + // if there are no index arguments given, just return a variable reference + if(this->indexCount == 0) { + const SgName aname = SgName(this->arrName); + return SageBuilder::buildVarRefExp(aname, scopeStmt); + } + std::vector<SgExpression*> argList = std::vector<SgExpression*>(); + // foreach dimension + for(int i = 0; i < this->indexCount; i++) { + argList.push_back(this->makeIndexExp(i, scopeStmt)); + } + return SageBuilder::buildExprListExp(argList); +} + +SgExpression* MMPrefetchInsertion::makeIndexExp(int dim, SgScopeStatement* scopeStmt) { + //(i + offset) or (offset) or (i) + std::string* indexer = this->indecies.at(dim); + int offset = this->offsets.at(dim); + if(indexer == NULL) { + return SageBuilder::buildIntVal(offset); + } + else { + const SgName name = SgName(*indexer); + SgVarRefExp* iref = SageBuilder::buildVarRefExp(name, scopeStmt); + if(offset == 0) { + return iref; + } + else { + return SageBuilder::buildAddOp(iref, SageBuilder::buildIntVal(offset)); + } + } +} + +void MMPrefetchInsertion::initialize(const std::string& arrName, int hint) { + this->arrName = std::string(arrName); + this->cacheHint = hint; + this->indecies = std::vector<std::string*>(); + this->offsets = std::vector<int>(); + this->indexCount = 0; +} +void MMPrefetchInsertion::addDim(int offset) { + this->offsets.push_back(offset); + this->indecies.push_back(NULL); + this->indexCount++; +} +void MMPrefetchInsertion::addDim(int offset, const std::string& indexer) { + this->offsets.push_back(offset); + this->indecies.push_back(new std::string(indexer)); + this->indexCount++; +} +} |