Beispiel #1
0
  void setupMPIInit(SgSourceFile* cur_file)
  {
    //#include "mpi.h" 
    SageInterface::insertHeader (cur_file, "mpi.h", false,true);
    SageInterface::insertHeader (cur_file, "libxomp_mpi.h", false, true);
    SgFunctionDeclaration* main_decl = findMain(cur_file);
   // TODO: handle multiple files, some of them don't have main()
    ROSE_ASSERT (main_decl != NULL);
    SgFunctionDefinition* main_def = main_decl->get_definition();
    ROSE_ASSERT (main_def != NULL);
    SgBasicBlock* func_body = main_def->get_body();
    ROSE_ASSERT (func_body != NULL);

    // Setup MPI
    SgStatement* decl_rank = buildStatementFromString("int _xomp_rank;", func_body);
    prependStatement(decl_rank, func_body);

    SgStatement* decl_nprocs= buildStatementFromString("int _xomp_nprocs;", func_body);
    prependStatement(decl_nprocs, func_body);

    // xomp_init_mpi (&argc, &argv, &_xomp_rank, &_xomp_nprocs);
    SgExprListExp * para_list = buildExprListExp (buildAddressOfOp (buildVarRefExp("argc", func_body)),
        buildAddressOfOp (buildVarRefExp("argv", func_body)),
        buildAddressOfOp (buildVarRefExp("_xomp_rank", func_body)),
        buildAddressOfOp (buildVarRefExp("_xomp_nprocs", func_body))
        );
    SgExprStatement* mpi_init_stmt = buildFunctionCallStmt ("xomp_init_mpi", buildIntType(), para_list, func_body);
    //     SgStatement* last_decl = findLastDeclarationStatement (func_body);
    insertStatementAfter (decl_rank, mpi_init_stmt);
  }
Beispiel #2
0
 // Create load/store = loads + iteration * load/store_count_per_iteration
 // lhs_exp = lhs_exp + iter_count_exp * per_iter_bytecount_exp
 SgExprStatement* buildByteCalculationStmt(SgVariableSymbol * lhs_sym, SgVariableSymbol* iter_count_sym, SgExpression* per_iter_bytecount_exp)
 {
   assert (lhs_sym != NULL);
   assert (iter_count_sym != NULL);
   assert (per_iter_bytecount_exp != NULL);
   SgExpression* lhs_exp = buildVarRefExp(lhs_sym);
   SgExpression* rhs_exp = buildAddOp( buildVarRefExp(lhs_sym),
                                       buildMultiplyOp (buildVarRefExp(iter_count_sym), per_iter_bytecount_exp) );
   return buildAssignStatement(lhs_exp, rhs_exp);
 }
Beispiel #3
0
  //! Return an expression like 8*sizeof(int)+ 3*sizeof(float) + 5*sizeof(double) for a list of variables accessed (either read or write)
  // For array variable, we should only count a single element access, not the entire array size
  // Algorithm:  
  //   Iterate on each variable in the set
  //     group them into buckets based on types, using a map<SgType*, int> to store this
  //   Iterate the list of buckets to generate count*sizeof(type) + .. expression 
  SgExpression* calculateBytes (std::set<SgInitializedName*>& name_set, SgScopeStatement* scope, bool isRead)
  {
    SgExpression* result = NULL; 
    if (name_set.size()==0) return result;

   // the input is essentially the loop body, a scope statement
   ROSE_ASSERT (scope != NULL);
    // We need to record the associated loop info.
    SgStatement* loop= NULL;
    SgForStatement* forloop = isSgForStatement(scope->get_scope());
    SgFortranDo* doloop = isSgFortranDo(scope->get_scope());

    if (forloop)
      loop = forloop;
    else if (doloop)
      loop = doloop;
    else
    {
      cerr<<"Error in CountLoadStoreBytes (): input is not loop body type:"<< scope->class_name()<<endl;
      assert(false);
    }   

    std::map<SgType* , int> type_based_counters; 

   // get all processed variables by inner loops
    std::set<SgInitializedName*> processed_var_set; 
    getVariablesProcessedByInnerLoops (scope, isRead, processed_var_set);
    
    // fill in the type-based counters
    std::set<SgInitializedName*>::iterator set_iter; 
    for (set_iter = name_set.begin(); set_iter != name_set.end(); set_iter++)
    {
      SgInitializedName* init_name = *set_iter; 
      // skip visited variable when processing inner loops
      // some global variables may be visited by another function
      // But we should count it when processing the current function!
      //
      // We group all references to a same variable into one reference for now
      // if a variable is considered when processing inner loops, the variable
      // will be skipped when processing outer loops.
      if (isRead)
      {
         // if inner loops already processed it, skip it
        if (processed_var_set.find(init_name) != processed_var_set.end())
          continue; 
        else
          LoopLoadVariables[loop].insert(init_name); 
      }
      else
      {
        if (processed_var_set.find(init_name) != processed_var_set.end())
          continue; 
        else
          LoopStoreVariables[loop].insert(init_name); 
      }
      // It is tricky here, TODO consider pointer, typedefs, reference, modifier types
      SgType* stripped_type = (*set_iter)->get_type()->stripTypedefsAndModifiers();
      SgType* base_type = NULL; 
      if (isScalarType(stripped_type))
        base_type = stripped_type;
      else if (isSgArrayType(stripped_type))
      {  // we may have multi-dimensional arrays like int a[][][];
        base_type = stripped_type; 
        do {
         base_type = isSgArrayType(base_type)->get_base_type(); 
        } while (isSgArrayType (base_type));
      }
      else 
      {
        cerr<<"Error in calculateBytes(). Unhandled stripped type:"<<stripped_type->class_name()<<endl;
        assert (false);
      }

      type_based_counters[base_type] ++; 
    } // end for

    // use the type-based counters for byte calculation
    std::map<SgType* , int>::iterator citer; 
    //It is possible now to have zero after filtering out redundant variables
    //assert (type_based_counters.size()>0);
    for (citer = type_based_counters.begin(); citer !=type_based_counters.end(); citer ++)
    {
      SgType* t = (*citer).first;
      // at this point, we should not have array types any more
      ROSE_ASSERT (isSgArrayType (t) == false); 
      int count = (*citer).second; 
      assert (t != NULL);
      assert (count>0);
      SgExpression* sizeof_exp = NULL; 
      if (is_Fortran_language())
      {
#if 0  // this does not work. cannot find func symbol for sizeof()       
      // In Fortran sizeof() is a function call, not  SgSizeOfOp.
      // type name is a variable in the AST, 
      // Too much trouble to build 
        assert (scope !=NULL);
        // This does not work
        //SgFunctionSymbol* func_sym = lookupFunctionSymbolInParentScopes(SgName("sizeof"), scope);
        SgGlobal* gscope = getGlobalScope (scope);
        assert (gscope !=NULL);
        SgFunctionSymbol* func_sym = gscope->lookup_function_symbol(SgName("sizeof"));
        assert (func_sym!=NULL);
        SgVarRefExp* type_var = buildVarRefExp( t->unparseToString(), scope );
        assert (type_var !=NULL);
        sizeof_exp = buildFunctionCallExp (func_sym, buildExprListExp(type_var));
#else
        // sizeof is not an operator in Fortran, there is no unparsing support for this
        // sizeof_exp = buildSizeOfOp(t);
        // Directly obtain an integer size value
        sizeof_exp = buildIntVal(getSizeOf(t));
#endif         
      }
      else if (is_C_language() || is_C99_language() || is_Cxx_language())
      {
        sizeof_exp = buildSizeOfOp(t);
      }
      else
      {
        cerr<<"Error in calculateBytes(). Unsupported programming language other than C/Cxx and Fortran. "<<endl;
        assert (false);
      }
      SgExpression* mop = buildMultiplyOp(buildIntVal(count), sizeof_exp);
       if (result == NULL)
         result = mop; 
       else 
         result = buildAddOp(result, mop);
    }
    return result; 
  }  
Beispiel #4
0
  //! Translate generated Pragma Attributes one by one
  void translatePragmas (std::vector <MPI_PragmaAttribute*>& Attribute_List)
  {
    std::vector<MPI_PragmaAttribute*>::iterator iter;
    for (iter = Attribute_List.begin(); iter!=Attribute_List.end(); iter ++)
    {
      MPI_PragmaAttribute* cur_attr = *iter; 
      cout<<"Translating ..." << cur_attr->toString() <<endl;
      SgScopeStatement* scope = cur_attr->pragma_node ->get_scope();
      ROSE_ASSERT (scope != NULL);
      // simply obtain the default value and remove the pragma
      if (cur_attr-> pragma_type == pragma_mpi_device_default)
      {
        mpi_device_default_choice = cur_attr->default_semantics;
        // no automatic handling of attached preprocessed info. for now
        removeStatement(cur_attr->pragma_node, false);
      }
      // find omp target device(mpi:all) begin
      else if (cur_attr-> pragma_type == pragma_mpi_device_all_begin)
      {
        iter ++; // additional increment once
        MPI_PragmaAttribute* end_attribute = *iter; 
        ROSE_ASSERT (end_attribute->pragma_type = pragma_mpi_device_all_end);
        removeStatement(cur_attr->pragma_node, false);
        removeStatement(end_attribute ->pragma_node, false);
      }  
      else if (cur_attr-> pragma_type == pragma_mpi_device_master_begin)
      { // TODO refactor into a function
        iter ++; // additional increment once
        MPI_PragmaAttribute* end_attribute = *iter; 
        ROSE_ASSERT (end_attribute->pragma_type = pragma_mpi_device_master_end);

        //insert a if (rank) .. after the end pragma
        SgIfStmt * ifstmt = buildIfStmt (buildEqualityOp(buildVarRefExp("_xomp_rank", scope), buildIntVal(0)), buildBasicBlock(), NULL);
        insertStatementAfter (end_attribute->pragma_node, ifstmt);
        SgBasicBlock * bb = isSgBasicBlock(ifstmt->get_true_body());

        SgStatement* next_stmt = getNextStatement(cur_attr->pragma_node); // the next stmt is BB, skip it by starting the search from it
        ROSE_ASSERT (next_stmt != NULL);
        // normalize all declarations
        while ( next_stmt != end_attribute ->pragma_node)
        {
          // save current stmt before getting next one 
          SgStatement* cur_stmt = next_stmt; 
          next_stmt = getNextStatement (next_stmt);
          ROSE_ASSERT (next_stmt != NULL);

          if (SgVariableDeclaration* decl = isSgVariableDeclaration (cur_stmt))
            splitVariableDeclaration (decl);
        }
        // move all non-declaration statements in between into the block
        next_stmt = getNextStatement(cur_attr->pragma_node); //reset from the beginning
        while ( next_stmt != end_attribute ->pragma_node) 
        {
          // save current stmt before getting next one 
          SgStatement* cur_stmt = next_stmt; 
          next_stmt = getNextStatement (next_stmt);
          ROSE_ASSERT (next_stmt != NULL);
           
          if (!isSgVariableDeclaration(cur_stmt))
          {
            // now remove the current stmt
            removeStatement (cur_stmt, false);
            appendStatement(cur_stmt, bb);
          }
        }
        
        // remove pragmas
        removeStatement(cur_attr->pragma_node, false);
        removeStatement(end_attribute ->pragma_node, false);
      }  

    }  // end for
  } // end translatePragmas ()
Beispiel #5
0
/*
 * Add calls to register and unregister expressions/arrays with the memory
 * management wrapper.
 */
bool RegisterPointers::addRegUnregCalls()
{
	string msg;

	if(definedInSystemHeader)
	{
		msg = "\t\t\tVariable " + NAME(varSymbol) + " is in system headers";
		WARNING(TOOL, msg);
		return false;
	}

	if(compilerGenerated)
	{
		msg = "\t\t\tVariable " + NAME(varSymbol) + " is compiler-generated";
		WARNING(TOOL, msg);
		return false;
	}

	if(addrUsedInIO)
	{
		msg = "\t\t\tVariable " + NAME(varSymbol) + " has its address taken in "
				+ "a function known to not require registering/unregistering";
		WARNING(TOOL, msg);
		return false;
	}

	//Add register/unregister calls
	SgStatement* prevStmt = NULL;
	SgExprStatement* funcCall = NULL;
	SgType* type = NULL;
	SgExpression* expr = NULL;

	if(isGlobal)
	{
		type = varName->get_type();
		SgName name = varName->get_name();
		int numVals = 1;

		if(isSgPointerType(type))
			return false;	//If its a pointer, it points to a static array, dynamic array, or scalar
							//which has its address taken (all of which have already been registered)

		SgFunctionDeclaration* main = findMain(getScope(varName));
		ROSE_ASSERT(main);
		expr = buildVarRefExp(name, varName->get_scope());
		if(isSgArrayType(type))
			numVals = getArrayElementCount(isSgArrayType(type));
		else
			expr = buildAddressOfOp(expr);

		funcCall = MMCallBuilder::buildRegisterPointerCall(expr, buildUnsignedIntVal(numVals),
				main->get_definition());
		insertStatement(getFirstStatement(main->get_definition()), funcCall);//, false, true);
		funcCall = MMCallBuilder::buildUnregisterPointerCall(expr, main->get_definition());
		instrumentEndOfFunction(main, funcCall);
	}
	else if(expression) //Address-of expressions
	{
		prevStmt = getEnclosingStatement(expression);
		funcCall = MMCallBuilder::buildRegisterPointerCall(expression, buildUnsignedIntVal(1),
				getScope(expression));
		insertStatement(prevStmt, funcCall);
		funcCall = MMCallBuilder::buildUnregisterPointerCall(expression, getScope(expression));
		instrumentEndOfFunction(getEnclosingFunctionDeclaration(prevStmt), funcCall);
	}
	else //Array types
	{
		SgVarRefExp* varRef = buildVarRefExp(varName, getScope(varName));

		int numVals = getArrayElementCount(isSgArrayType(varName->get_type()));
		funcCall = MMCallBuilder::buildRegisterPointerCall(varRef, buildUnsignedIntVal(numVals),
				varName->get_scope());
		insertStatement(varName->get_declaration(), funcCall, false, true);
		varRef = buildVarRefExp(varName, getScope(varName));
		funcCall = MMCallBuilder::buildUnregisterPointerCall(varRef, varName->get_scope());
		instrumentEndOfFunction(getEnclosingFunctionDeclaration(varName), funcCall);
	}

	return true;
}
Beispiel #6
0
// ===========================================================
//! Fixes up references in a block to point to alternative symbols.
// based on an existing symbol-to-symbol map
// Also called variable substitution. 
static void
remapVarSyms (const VarSymRemap_t& vsym_remap,  // regular shared variables
              const ASTtools::VarSymSet_t& pdSyms, // special shared variables
              const VarSymRemap_t& private_remap,  // variables using private copies
              SgBasicBlock* b)
{
  // Check if variable remapping is even needed.
  if (vsym_remap.empty() && private_remap.empty()){
    //cout << "no remapping " << endl ;
    return;
  }
  // Find all variable references
  typedef Rose_STL_Container<SgNode *> NodeList_t;
  NodeList_t refs = NodeQuery::querySubTree (b, V_SgVarRefExp);
  // For each of the references , 
  for (NodeList_t::iterator i = refs.begin (); i != refs.end (); ++i)
  {
    // Reference possibly in need of fix-up.
    SgVarRefExp* ref_orig = isSgVarRefExp (*i);
    ROSE_ASSERT (ref_orig);

    // Search for a symbol which needs to be replaced.
    // cout << "this is the symbol " <<ref_orig->get_symbol()->get_name().str() << endl ;

    VarSymRemap_t::const_iterator ref_new =  vsym_remap.find (ref_orig->get_symbol ());
    VarSymRemap_t::const_iterator ref_private =  private_remap.find (ref_orig->get_symbol ());

    // a variable could be both a variable needing passing original value and private variable 
    // such as OpenMP firstprivate, lastprivate and reduction variable
    // For variable substitution, private remap has higher priority 
    // remapping private variables
    if (ref_private != private_remap.end()) 
    {
      // get the replacement variable
      SgVariableSymbol* sym_new = ref_private->second;
      // Do the replacement
      ref_orig->set_symbol (sym_new);
    }
    else if (ref_new != vsym_remap.end ()) // Needs replacement, regular shared variables
    {
      if(Outliner::enable_debug)
	{
	  cout << "replace this " << "variable with that " << endl ;
	}
      SgVariableSymbol* sym_new = ref_new->second;
      if (Outliner::temp_variable || Outliner::useStructureWrapper)
        // uniform handling if temp variables of the same type are used
      {// two cases: variable using temp vs. variables using pointer dereferencing!

        if (pdSyms.find(ref_orig->get_symbol())==pdSyms.end()) //using temp
          ref_orig->set_symbol(sym_new);
        else
        {
          SgPointerDerefExp * deref_exp = SageBuilder::buildPointerDerefExp(buildVarRefExp(sym_new));
          deref_exp->set_need_paren(true);
          SageInterface::replaceExpression(isSgExpression(ref_orig),isSgExpression(deref_exp));

        }
      }
      else // no variable cloning is used
      {
        if (is_C_language()) 
          // old method of using pointer dereferencing indiscriminately for C input
          // TODO compare the orig and new type, use pointer dereferencing only when necessary
        {
          SgPointerDerefExp * deref_exp = SageBuilder::buildPointerDerefExp(buildVarRefExp(sym_new));
          deref_exp->set_need_paren(true);
          SageInterface::replaceExpression(isSgExpression(ref_orig),isSgExpression(deref_exp));
        }
        else
          ref_orig->set_symbol (sym_new);
      }
    } //find an entry
  } // for every refs

}