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/src | |
| 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/src')
| -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 | 
3 files changed, 1401 insertions, 0 deletions
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++; +} +}  | 
