示例#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);
  }
示例#2
0
文件: CudaOutliner.C 项目: 8l/rose
// handle OpenMP private variables
// pSyms: private variable set
// scope: the scope of a private variable's local declaration
// private_remap: a map between the original variables and their private copies
static void handlePrivateVariables( const ASTtools::VarSymSet_t& pSyms,
                                    SgScopeStatement* scope, 
                                    VarSymRemap_t& private_remap)
{
  // --------------------------------------------------
  for (ASTtools::VarSymSet_t::const_reverse_iterator i = pSyms.rbegin ();
      i != pSyms.rend (); ++i)
  {
    const SgInitializedName* i_name = (*i)->get_declaration ();
    ROSE_ASSERT (i_name);
    string name_str = i_name->get_name ().str ();
    SgType * v_type = i_name->get_type();
    SgVariableDeclaration* local_var_decl = buildVariableDeclaration(name_str, v_type, NULL, scope);
    prependStatement (local_var_decl,scope);
    recordSymRemap (*i, local_var_decl, scope, private_remap);
  }
}
示例#3
0
文件: ir.cpp 项目: SchuckBeta/retdec
/**
* @brief Adds @a var as a new local variable of @a func, possibly with an
*        initializer @a init.
*
* An advatage of using this function over manually adding @a var to @a func is
* that this function also creates a VarDefStmt at the beginning of @a func, and
* places it in a proper place so that all VarDefStmts at the beginning of @a
* func are sorted alphabetically.
*
* If @a var is already a local function of @a func, this function does nothing.
*
* @par Preconditions
*  - @a func is a definition, not a declaration
*/
void addLocalVarToFunc(ShPtr<Variable> var, ShPtr<Function> func,
		ShPtr<Expression> init) {
	PRECONDITION(func->isDefinition(), "it has to be a definition");

	if (func->hasLocalVar(var)) {
		return;
	}

	func->addLocalVar(var);

	// Insert a variable-defining statement to a proper position at the
	// beginning of the function's body.
	// First, we find a proper position...
	auto stmt = func->getBody();
	while (auto varDefStmt = cast<VarDefStmt>(stmt)) {
		if (varDefStmt->getVar()->getName() > var->getName() ||
				!stmt->getSuccessor()) {
			break;
		}
		stmt = stmt->getSuccessor();
	}
	// ...then, we place a VarDefStmt of var into that position.
	stmt->prependStatement(VarDefStmt::create(var, init));
}
示例#4
0
  //A generic function to check if a loop has a tag statement prepended to it, asking for instrumentation
  //If so, the loop will be instrumented and the tag statement will be returned.
  // This function supports both C/C++ for loops and Fortran Do loops
  SgStatement* instrumentLoopForCounting(SgStatement* loop)
  {
    //get scope of the loop
    assert (loop != NULL);
    SgForStatement* forloop = isSgForStatement(loop); 
    SgFortranDo* doloop = isSgFortranDo(loop);  
    SgScopeStatement* scope = NULL; 

    if (forloop)
      scope = forloop->get_scope();
    else if (doloop)
      scope = doloop->get_scope(); 
    else
    {
      cerr<<"Error in instrumentLoopForCounting(): Unrecognized loop type:"<< loop->class_name()<<endl;
      assert(false);
    }
    ROSE_ASSERT(scope != NULL);

    // Only for a do-loop which immediately follows  chiterations =  ..
    SgVariableSymbol * chiterations_sym = lookupVariableSymbolInParentScopes(SgName("chiterations"), isSgScopeStatement(loop));
    if (chiterations_sym==NULL) return NULL;
    SgStatement* prev_stmt = getPreviousStatement(loop,false);

    // backwards search, skipping pragma declaration etc.
    while (prev_stmt!=NULL && !isAssignmentStmtOf (prev_stmt, chiterations_sym->get_declaration()))
      prev_stmt = getPreviousStatement(prev_stmt,false);
    if (prev_stmt == NULL) return NULL;

    // To support nested loops, we need to use unique chiterations variable for each loop
    // otherwise the value stored in inner loop will overwrite the iteration count for the outerloop.
    loop_id ++; // increment loop ID
    // insert size_t chiterations_id ; 
    // Find the enclosing function declaration, including its derived instances like 
    //isSgProcedureHeaderStatement, isSgProgramHeaderStatement, and isSgMemberFunctionDeclaration. 
    SgFunctionDeclaration* func_decl = getEnclosingFunctionDeclaration   (loop); 
    ROSE_ASSERT (func_decl !=NULL);
    SgFunctionDefinition* func_def = func_decl->get_definition();
    ROSE_ASSERT (func_def !=NULL);
    SgBasicBlock* func_body = func_def->get_body();
    // insert a new variable declaration
    std::string new_iter_var_name = std::string("chiterations_") + StringUtility::numberToString(loop_id);
    SgVariableDeclaration* new_iter_var_decl = buildVariableDeclaration(new_iter_var_name, chiterations_sym->get_type(), NULL, func_body); 
    SgStatement* last_decl = findLastDeclarationStatement(func_body);
    if (last_decl!=NULL)
      insertStatementAfter (last_decl, new_iter_var_decl, false);
    else
      prependStatement(new_iter_var_decl, func_body);

    // rewrite the assignment stmt's left hand variable to be the new symbol
    SgExpression* lhs = NULL; 
    bool rt = isAssignmentStatement (prev_stmt, &lhs); 
    ROSE_ASSERT (rt == true);
    ROSE_ASSERT (lhs != NULL);
    SgVarRefExp* var_ref = isSgVarRefExp (lhs);
    ROSE_ASSERT (var_ref != NULL);
    var_ref->set_symbol(getFirstVarSym (new_iter_var_decl));

    SgStatement* loop_body = NULL; 
    if (forloop)
      loop_body = forloop->get_loop_body();
    else if (doloop)
       loop_body = doloop->get_body();
    assert (loop_body != NULL);     

    // count FP operations for each loop
    CountFPOperations (loop_body);
    //chflops=chflops+chiterations*n
    FPCounters* current_result = getFPCounters (loop_body);
    if (current_result->getTotalCount() >0)
    {
      SgExprStatement* stmt = buildCounterAccumulationStmt("chflops", new_iter_var_name , buildIntVal(current_result->getTotalCount()),scope);
      insertStatementAfter (loop, stmt);
      attachComment(stmt,"      aitool generated FLOPS counting statement ...");
    }

    // Obtain per-iteration load/store bytes calculation expressions
    // excluding scalar types to match the manual version
    //CountLoadStoreBytes (SgLocatedNode* input, bool includeScalars = true, bool includeIntType = true);
    std::pair <SgExpression*, SgExpression*> load_store_count_pair = CountLoadStoreBytes (loop_body, false, true);
    // chstores=chstores+chiterations*8
    if (load_store_count_pair.second!= NULL)
    {
      SgExprStatement* store_byte_stmt = buildCounterAccumulationStmt("chstores", new_iter_var_name, load_store_count_pair.second, scope);
      insertStatementAfter (loop, store_byte_stmt);
      attachComment(store_byte_stmt,"      aitool generated Stores counting statement ...");
    }
    // handle loads stmt 2nd so it can be inserted as the first after the loop
    // build  chloads=chloads+chiterations*2*8
    if (load_store_count_pair.first != NULL)
    {
      SgExprStatement* load_byte_stmt = buildCounterAccumulationStmt("chloads", new_iter_var_name, load_store_count_pair.first, scope);
      insertStatementAfter (loop, load_byte_stmt);
      attachComment(load_byte_stmt,"      aitool generated Loads counting statement ...");
    }

    return prev_stmt; 
  } // end instrumentLoopForCounting()
示例#5
0
文件: CudaOutliner.C 项目: 8l/rose
void CudaOutliner::functionParameterHandling(ASTtools::VarSymSet_t& syms, // regular (shared) parameters
					     MintHostSymToDevInitMap_t hostToDevVars,		                      
					     const ASTtools::VarSymSet_t& pdSyms, // those must use pointer dereference
					     const ASTtools::VarSymSet_t& pSyms, 
					     // private variables, handles dead variables (neither livein nor liveout) 
					     std::set<SgInitializedName*> & readOnlyVars,
					     std::set<SgInitializedName*> & liveOutVars,
					     SgFunctionDeclaration* func) // the outlined function
{

  //ASTtools::VarSymSet_t syms;
  //std::copy(syms1.begin(), syms1.end(), std::inserter(syms,syms.begin()));

  VarSymRemap_t sym_remap;     // variable remapping for regular(shared) variables
  VarSymRemap_t private_remap; // variable remapping for private/firstprivate/reduction variables
  ROSE_ASSERT (func);
  SgFunctionParameterList* params = func->get_parameterList ();
  ROSE_ASSERT (params);
  SgFunctionDefinition* def = func->get_definition ();
  ROSE_ASSERT (def);
  SgBasicBlock* body = def->get_body ();
  ROSE_ASSERT (body);

  // Place in which to put new outlined variable symbols.
  SgScopeStatement* args_scope = isSgScopeStatement (body);
  ROSE_ASSERT (args_scope);

  // For each variable symbol, create an equivalent function parameter. 
  // Also create unpacking and repacking statements.
  int counter=0;
//  SgInitializedName* parameter1=NULL; // the wrapper parameter
  SgVariableDeclaration*  local_var_decl  =  NULL;

  // handle OpenMP private variables/ or those which are neither live-in or live-out
  handlePrivateVariables(pSyms, body, private_remap);

  // --------------------------------------------------
  // for each parameters passed to the outlined function
  // They include parameters for regular shared variables and 
  // also the shared copies for firstprivate and reduction variables

  for (ASTtools::VarSymSet_t::reverse_iterator i = syms.rbegin ();i != syms.rend (); ++i)
  {
    // Basic information about the variable to be passed into the outlined function
    // Variable symbol name
    const SgInitializedName* i_name = (*i)->get_declaration ();
    ROSE_ASSERT (i_name);
    string name_str = i_name->get_name ().str ();

    SgName p_sg_name ( name_str);
    //SgType* i_type = i_name->get_type ();
    bool readOnly = false;
    if (readOnlyVars.find(const_cast<SgInitializedName*> (i_name)) != readOnlyVars.end())
      readOnly = true;

    // step 1. Create parameters and insert it into the parameter list.
    // ----------------------------------------
    SgInitializedName* p_init_name = NULL;
    SgVariableSymbol* host_sym= const_cast<SgVariableSymbol*> (*i);
    
    if(hostToDevVars.find(host_sym) != hostToDevVars.end() ){
      //these are vector variables
      SgInitializedName* dev_name = hostToDevVars[host_sym];
      p_init_name = createInitName (dev_name->get_name(), dev_name->get_type(), func, def);

      ROSE_ASSERT (p_init_name);
      prependArg(func->get_parameterList (),p_init_name);
    }
    else{
      //scalar values
      p_init_name = createOneFunctionParameter(i_name, readOnly, func); 
    }
    // step 2. Create unpacking/unwrapping statements, also record variables to be replaced
    // ----------------------------------------
   // bool isPointerDeref = false; 

    if (Outliner::enable_classic) 
      {  // classic methods use parameters directly, no unpacking is needed
	if (!readOnly) 
	  //read only variable should not have local variable declaration, using parameter directly
	  // taking advantage of the same parameter names for readOnly variables
	  // Let postprocessing to patch up symbols for them
	  {
	    // non-readonly variables need to be mapped to their parameters with different names (p__)
	    // remapVarSyms() will use pointer dereferencing for all of them by default in C, 
	    // this is enough to mimic the classic outlining work 
	    //handleSharedVariables(*i, p_init_name, args_scope, sym_remap);
	    //handleSharedVariables(*i, body, sym_remap);

	    //Didem: I comment out this part because it uses pointer deferencing for all non-readonly variables.
	    //recordSymRemap(*i,p_init_name, args_scope, sym_remap); 
	  }
      }
    else 
      { 
	local_var_decl  = NULL; //createUnpackDecl (p_init_name, counter, isPointerDeref, i_name , NULL, body);
	ROSE_ASSERT (local_var_decl);
	prependStatement (local_var_decl,body);
	// regular and shared variables used the first local declaration
        recordSymRemap (*i, local_var_decl, args_scope, sym_remap);
	// transfer the value for firstprivate variables. 
      }


    // step 3. Create and insert companion re-pack statement in the end of the function body
    // If necessary
    // ----------------------------------------
    SgInitializedName* local_var_init = NULL;
    if (local_var_decl != NULL )
      local_var_init = local_var_decl->get_decl_item (SgName (name_str.c_str ()));

    if (!SageInterface::is_Fortran_language() && !Outliner::enable_classic)  
      ROSE_ASSERT(local_var_init!=NULL);  


    SgExprStatement* pack_stmt = createPackStmt (local_var_init);
    if (pack_stmt)
      appendStatement (pack_stmt,body);
    
    counter ++;
  } //end for

  // variable substitution
  SgBasicBlock* func_body = func->get_definition()->get_body();
  remapVarSyms (sym_remap, pdSyms, private_remap , func_body);
}