Beispiel #1
0
 // Build counter accumulation statement like chloads = chloads + chiterations * (2 * 8)
  // chloads is the counter name, chiterations is iteration_count_name, 2*8 is the per-iteration count expression.
  SgExprStatement* buildCounterAccumulationStmt (std::string counter_name, std::string iteration_count_name, SgExpression* count_exp_per_iteration, SgScopeStatement* scope)
  {
    assert (scope!= NULL);
    assert (count_exp_per_iteration != NULL);
    assert (counter_name.size()!=0);
    assert (iteration_count_name.size()!=0);

    SgVariableSymbol * chiterations_sym = lookupVariableSymbolInParentScopes(SgName(iteration_count_name), scope);
    assert (chiterations_sym!=NULL);

    SgVariableSymbol * counter_sym = lookupVariableSymbolInParentScopes(SgName(counter_name), scope);
    assert (counter_sym!=NULL);
    SgExprStatement* counter_acc_stmt = buildByteCalculationStmt (counter_sym, chiterations_sym, count_exp_per_iteration);

    return counter_acc_stmt; 
  }
Beispiel #2
0
void CudaOutliner::setKernelParams(int dimension, SgStatement* func_call_stmt, SgScopeStatement* scope)
{
  /*
  dim3 threads(chunksizeX, chunksizeY);

  int numBlocksX = n/ chunksizeX;
  int numBlocksY = n/ (chunksizeY*numRows);

  dim3 grid(numBlocksX, numBlocksY);
  */

  SgInitializedName* arg1 = buildInitializedName(SgName("BLOCKDIM_X"), buildIntType());
  SgInitializedName* arg2 = buildInitializedName(SgName("BLOCKDIM_Y"), buildIntType());

  SgType* dim3_t = buildOpaqueType("dim3", scope);

  SgExprListExp* exprList = buildExprListExp();
  //appendArg(exprList, arg1);
  //ppendArg(exprList, arg2);

  SgFunctionParameterList * paraList = buildFunctionParameterList();
  appendArg(paraList, arg1);
  appendArg(paraList, arg2);

  SgMemberFunctionDeclaration * funcdecl = buildNondefiningMemberFunctionDeclaration
  ("threads", dim3_t, paraList);

  SgConstructorInitializer* constr = 
    new SgConstructorInitializer(funcdecl, exprList, dim3_t, false, false,
				 false, false );

  string dimBlock = MintTools::generateBlockDimName(func_call_stmt);

  SgVariableDeclaration * dim_blocks_var_decl = buildVariableDeclaration(dimBlock, dim3_t, constr);

  /*
  string dimGrid = generateGridDimName(func_call_stmt);

  SgVariableDeclaration * dim_grid_var_decl = buildVariableDeclaration(dimGrid, dim3_t);				
  */

  cout<< dim_blocks_var_decl->unparseToString ()<< endl ;
}
/*
 *  Replace the op_par_loop with respective kernel function
 */
void OPSource::fixParLoops(SgNode *n)
{
  SgName kernel_name;
  SgFunctionCallExp *fn = isSgFunctionCallExp(n);
  if(fn != NULL)
  {
    string fn_name = fn->getAssociatedFunctionDeclaration()->get_name().getString();
    if(fn_name.compare("op_par_loop_2")==0 
    || fn_name.compare("op_par_loop_3")==0 
    || fn_name.compare("op_par_loop_4")==0
    || fn_name.compare("op_par_loop_5")==0
    || fn_name.compare("op_par_loop_6")==0
    || fn_name.compare("op_par_loop_7")==0
    || fn_name.compare("op_par_loop_8")==0
    || fn_name.compare("op_par_loop_9")==0) 
    {
      SgExprListExp* exprList = fn->get_args();
      SgExpressionPtrList &exprs = exprList->get_expressions();
      SgFunctionRefExp* varExp =  isSgFunctionRefExp(exprs[0]);
      if(varExp != NULL)
      {
        kernel_name = varExp->get_symbol()->get_name();
      }
      exprs.erase(exprs.begin());

      SgExpressionPtrList::iterator it = exprs.begin() + op_par_loop_args::num_params - 1;
      for(; it != exprs.end(); it += op_argument::num_params)
      {
        *it = buildCastExp( *it, buildPointerType(SgClassType::createType( buildStructDeclaration("op_dat<void>"))) );
      }

      // Inject Name
      exprs.insert(exprs.begin(), buildStringVal(kernel_name));
      
      // Fetch the declaration
      SgName name = SgName("op_par_loop_") + kernel_name;
      SgFunctionDeclaration *funcDecl = cudaFunctionDeclarations[kernel_name];
      if(funcDecl)
      {
        SgFunctionRefExp* ref = isSgFunctionRefExp(fn->get_function());
        SgFunctionSymbol *symbol = ref->get_symbol();
        symbol->set_declaration(funcDecl);
        ref->set_symbol(symbol);
        fn->set_function(ref);
      }
    }
  }
}
Beispiel #4
0
SgSymbol * ClangToSageTranslator::GetSymbolFromSymbolTable(clang::NamedDecl * decl) {
    if (decl == NULL) return NULL;

    SgScopeStatement * scope = SageBuilder::topScopeStack();

    SgName name(decl->getNameAsString());

#if DEBUG_SYMBOL_TABLE_LOOKUP
    std::cerr << "Lookup symbol for: " << name << std::endl;
#endif

    if (name == "") {
        return NULL;
    }

    std::list<SgScopeStatement *>::reverse_iterator it;
    SgSymbol * sym = NULL;
    switch (decl->getKind()) {
        case clang::Decl::Typedef:
        {
            it = SageBuilder::ScopeStack.rbegin();
            while (it != SageBuilder::ScopeStack.rend() && sym == NULL) {
                 sym = (*it)->lookup_typedef_symbol(name);
                 it++;
            }
            break;
        }
        case clang::Decl::Var:
        case clang::Decl::ParmVar:
        {
            it = SageBuilder::ScopeStack.rbegin();
            while (it != SageBuilder::ScopeStack.rend() && sym == NULL) {
                sym = (*it)->lookup_variable_symbol(name);
                it++;
            }
            break;
        }
        case clang::Decl::Function:
        {
            SgType * tmp_type = buildTypeFromQualifiedType(((clang::FunctionDecl *)decl)->getType());
            SgFunctionType * type = isSgFunctionType(tmp_type);
            ROSE_ASSERT(type);
            it = SageBuilder::ScopeStack.rbegin();
            while (it != SageBuilder::ScopeStack.rend() && sym == NULL) {
                sym = (*it)->lookup_function_symbol(name, type);
                it++;
            }
            break;
        }
        case clang::Decl::Field:
        {
            SgClassDeclaration * sg_class_decl = isSgClassDeclaration(Traverse(((clang::FieldDecl *)decl)->getParent()));
            ROSE_ASSERT(sg_class_decl != NULL);
            if (sg_class_decl->get_definingDeclaration() == NULL)
                std::cerr << "Runtime Error: cannot find the definition of the class/struct associate to the field: " << name << std::endl;
            else {
                scope = isSgClassDeclaration(sg_class_decl->get_definingDeclaration())->get_definition();
                // TODO: for C++, if 'scope' is in 'SageBuilder::ScopeStack': problem!!!
                //       It means that we are currently building the class
                while (scope != NULL && sym == NULL) {
                    sym = scope->lookup_variable_symbol(name);
                    scope = scope->get_scope();
                }
            }
            break;
        }
        case clang::Decl::CXXRecord:
        case clang::Decl::Record:
        {
            it = SageBuilder::ScopeStack.rbegin();
            while (it != SageBuilder::ScopeStack.rend() && sym == NULL) {
                sym = (*it)->lookup_class_symbol(name);
                it++;
            }
            break;
        }
        case clang::Decl::Label:
        {
            // Should not be reach as we use Traverse to retrieve Label (they are "terminal" statements) (it avoids the problem of forward use of label: goto before declaration)
            name = SgName(((clang::LabelDecl *)decl)->getStmt()->getName());
            it = SageBuilder::ScopeStack.rbegin();
            while (it != SageBuilder::ScopeStack.rend() && sym == NULL) {
                sym = (*it)->lookup_label_symbol(name);
                it++;
            }
            break;
        }
        case clang::Decl::EnumConstant:
        {
            name = SgName(((clang::EnumConstantDecl *)decl)->getName());
            it = SageBuilder::ScopeStack.rbegin();
            while (it != SageBuilder::ScopeStack.rend() && sym == NULL) {
                sym = (*it)->lookup_enum_field_symbol(name);
                it++;
            }
            break;
        }
        case clang::Decl::Enum:
        {
            name = SgName(((clang::EnumDecl *)decl)->getName());
            it = SageBuilder::ScopeStack.rbegin();
            while (it != SageBuilder::ScopeStack.rend() && sym == NULL) {
                sym = (*it)->lookup_enum_symbol(name);
                it++;
            }
            break;
        }
        default:
            std::cerr << "Runtime Error: Unknown type of Decl. (" << decl->getDeclKindName() << ")" << std::endl;
    }

    return sym;
}
Beispiel #5
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()
Beispiel #6
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; 
  }  
TEST(SageInterfaceTypeEquivalence, ConstVarIntLiteralArrayIsEqual){
  ::SgGlobal *global = new SgGlobal();
  // build assign-initializer, build variable declaration, build varrefexp
  ::SgBasicBlock* bb = SageBuilder::buildBasicBlock();
  bb->set_parent(global);
  ::SgAssignInitializer* init = SageBuilder::buildAssignInitializer(SageBuilder::buildIntVal(42), SageBuilder::buildIntType());
  ::SgVariableDeclaration* vDecl = isSgVariableDeclaration(SageBuilder::buildVariableDeclaration(SgName("refVar"), SageBuilder::buildConstType(SageBuilder::buildIntType()), init, bb));
//  vDecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier().setConst();
  ::SgVarRefExp* vRef = SageBuilder::buildVarRefExp(vDecl);
  ::SgArrayType* a_7 = SageBuilder::buildArrayType(SageBuilder::buildIntType(), vRef);
  ::SgArrayType* a_8 = SageBuilder::buildArrayType(SageBuilder::buildIntType(), vRef);
  bool tcRef = SageInterface::checkTypesAreEqual(a_7, a_8);
  EXPECT_EQ(tcRef, true);
  delete global;
}
Beispiel #8
0
void flattenScopes(SgFunctionDefinition * fDef)
{
	// * 3.3: find all variables in the function,give them a unique name and move them to the bgeinning of the function, this is allowed because this is for C only!!!. This would not work for classes which must be constructed

	// rename variables
	list<SgNode*> varDeclList=NodeQuery::querySubTree(fDef,V_SgInitializedName);
	for (list<SgNode*>::iterator varDecl=varDeclList.begin();varDecl!=varDeclList.end();varDecl++)
	{
		tring varName=isSgInitializedName(*varDecl)->get_name().getString();
		char numberCString[255];
		sprintf(numberCString,"%i",idNr);
		string newVarName=string("PML")+string(numberCString)+string("_")+varName;
		idNr++;

		isSgInitializedName(*varDecl)->set_name(SgName(newVarName.c_str()));		
	}					

	list<SgNode*> newDeclList;
	varDeclList.clear();
	varDeclList=NodeQuery::querySubTree(procFuncVec[procNr],V_SgVariableDeclaration);
	// the move the variable declaration to the function begin and replace the old declaration site with a definition
	for (list<SgNode*>::iterator varDecl=varDeclList.begin();varDecl!=varDeclList.end();varDecl++)
	{
		SgVariableDeclaration * varDeclStmt=isSgVariableDeclaration(*varDecl);
		SgVariableDefinition * varDef=varDeclStmt->get_definition();
		SgInitializedName *iniName=isSgInitializedName(varDef->get_vardefn());
		if (iniName->get_initializer () !=NULL)
		{
			//				cout <<"VarDecl >"<<iniName->get_name().getString()<<"< has initilizer >"<<iniName->get_initializer ()->unparseToString()<<"<"<<endl;
			// determine if it is safe to separate initializer from decl
			// for now true
			if (1)
			{
				Sg_File_Info  * fi=Sg_File_Info::generateDefaultFileInfoForTransformationNode();
				SgVarRefExp * varRef=new	SgVarRefExp (Sg_File_Info::generateDefaultFileInfoForTransformationNode(),new SgVariableSymbol(iniName));
				SgType * type=isSgAssignInitializer(iniName->get_initializer())->get_type ();
				SgAssignInitializer * sai=isSgAssignInitializer(iniName->get_initializer());
				if (sai==NULL)
				{
					cerr<<"isSgAssignInitializer(iniName->get_initializer())=NULL"<<endl;
					exit(-1);
				}
				SgExpression *lhs,*rhs;
				lhs=varRef;
				rhs=sai->get_operand ();
				if (lhs==NULL)
				{
					cerr<<"lhs=NULL"<<endl;
					exit(-1);
				}
				if (rhs==NULL)
				{
					cerr<<"rhs=NULL"<<endl;
					exit(-1);
				}
				SgAssignOp * assignment=new SgAssignOp(Sg_File_Info::generateDefaultFileInfoForTransformationNode(),lhs,rhs);
				SgExprStatement * expr=new SgExprStatement(fi,assignment);
				if (expr==NULL)
				{
					cerr<<"construction of expr failed"<<endl;
				}
				isSgAssignInitializer(iniName->get_initializer ())->set_operand(NULL);
				free(iniName->get_initializer ());
				iniName->set_initializer (NULL);
				// put the iniName in the list
				newDeclList.push_back(varDeclStmt);
				if (isSgStatement(varDeclStmt)==NULL)
				{
					cerr<<"isSgStatement(varDeclStmt)==NULL"<<endl;
				}
				LowLevelRewrite::replace(isSgStatement(varDeclStmt),isSgStatement(expr));					
			}				
		}
		else
		{
			cout <<"VarDecl >"<<iniName->get_name().getString()<<"> is uninitialized"<<endl;
			newDeclList.push_back(varDeclStmt);
			LowLevelRewrite::remove(isSgStatement(varDeclStmt));
		}
	}

	for (list<SgNode*>::iterator varDecl=newDeclList.begin();varDecl!=newDeclList.end();varDecl++)
	{
		fDef->prepend_statement(isSgStatement(*varDecl));
	}
	return ;
}
Beispiel #9
0
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);
}
Beispiel #10
0
  void instr(SgProject* project, Rose_STL_Container<SgType*> types)
  {
    SgGlobal* global = SI::getFirstGlobalScope(project);
    std::string prefix("rtc_ti_"); //struct prefix
    std::string ti_type_str("struct rtc_typeinfo*");
    SgType* ti_type = SB::buildOpaqueType(ti_type_str,global);

    //Insert declarations from the typechecking library.

    //void minalloc_check(unsigned long long addr)
    SgFunctionDeclaration* minalloc_check_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("minalloc_check"),
          SgTypeVoid::createType(),
          SB::buildFunctionParameterList(
            SB::buildInitializedName("addr",SB::buildUnsignedLongLongType())),
          global,NULL);
    SI::prependStatement(minalloc_check_decl,global);

    //void typetracker_add(unsigned long long addr, struct rtc_typeinfo* ti);
    SgFunctionDeclaration* typetracker_add_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("typetracker_add"),
          SgTypeVoid::createType(),
          SB::buildFunctionParameterList(
            SB::buildInitializedName("addr",SB::buildUnsignedLongLongType()),
            SB::buildInitializedName("ti",ti_type)),
          global,NULL);
    SI::prependStatement(typetracker_add_decl,global);

    //void setBaseType(rtc_typeinfo* ti, rtc_typeinfo* base)
    SgFunctionDeclaration* setBaseType_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("setBaseType"),
          SgTypeVoid::createType(),
          SB::buildFunctionParameterList(
            SB::buildInitializedName("ti",ti_type),
            SB::buildInitializedName("base",ti_type)),
          global,NULL);
    SI::prependStatement(setBaseType_decl,global);

    //struct rtc_typeinfo* ti_init(const char* a, size_t sz, int c)
    SgFunctionDeclaration* ti_init_decl = SB::buildNondefiningFunctionDeclaration(
                                            SgName("ti_init"),
                                            ti_type,
                                            SB::buildFunctionParameterList(
//    SB::buildInitializedName("a",SB::buildPointerType(SB::buildConstType(SB::buildCharType()))),
                                                SB::buildInitializedName("a",SB::buildPointerType(SB::buildCharType())),
//    SB::buildInitializedName("sz", SB::buildOpaqueType("size_t",global)),
                                                SB::buildInitializedName("sz", SB::buildLongLongType()),
                                                SB::buildInitializedName("c", SB::buildIntType())),
                                            global,NULL);
    SI::prependStatement(ti_init_decl,global);

    //void traverseAndPrint()
    SgFunctionDeclaration* traverseAndPrint_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("traverseAndPrint"),SgTypeVoid::createType(),SB::buildFunctionParameterList(),global,NULL);
    SI::prependStatement(traverseAndPrint_decl,global);

    //non-defining declaration of rtc_init_typeinfo
    SgName init_name("rtc_init_typeinfo");
    SgFunctionDeclaration* init_nondef = SB::buildNondefiningFunctionDeclaration(init_name,SgTypeVoid::createType(),SB::buildFunctionParameterList(),global,NULL);
    SI::prependStatement(init_nondef,global);

    //call to rtc_init_typeinfo placed in main function.
    SgFunctionDeclaration* maindecl = SI::findMain(project);
    SgExprStatement* initcall = SB::buildFunctionCallStmt(init_name,SgTypeVoid::createType(),NULL,maindecl->get_definition());
    maindecl->get_definition()->prepend_statement(initcall);

    //defining declaration of rtc_init_typeinfo
    SgFunctionDeclaration* init_definingDecl = new SgFunctionDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),init_name,init_nondef->get_type(),NULL);
    init_definingDecl->set_firstNondefiningDeclaration(init_nondef);
    SgFunctionDefinition* init_definition = new SgFunctionDefinition(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),init_definingDecl,SB::buildBasicBlock());
    init_definingDecl->set_definition(init_definition);
    SI::appendStatement(init_definingDecl,global);

    std::vector<std::string> lst;
    for(unsigned int index = 0; index < types.size(); index++)
    {
      SgType* ptr = types[index];

      ptr = ptr->stripTypedefsAndModifiers();
      if(!shouldInstrumentType(ptr))
        continue;
      std::string nameStr = prefix + Util::getNameForType(ptr).getString();
      if(!contains(lst,nameStr))
      {
        SgVariableDeclaration* decl = SB::buildVariableDeclaration(nameStr,ti_type,NULL,global);
        SI::prependStatement(decl,global);
        lst.push_back(nameStr);
      }
    }

    for(unsigned int index = 0; index < types.size(); index++)
    {
      SgType* ptr = types[index];
      ptr = ptr->stripTypedefsAndModifiers();
      if(!shouldInstrumentType(ptr))
        continue;
      std::string typeNameStr = Util::getNameForType(ptr).getString();
      std::string structNameStr = prefix + Util::getNameForType(ptr).getString();

      if(contains(lst,structNameStr))
      {
        SgExpression* lhs;
        SgExpression* rhs;

        //In case of an anonymous struct or union, we create a local, named version of the declaration so we can know its size.
        SgClassDeclaration* altDecl = NULL;
        if(isSgNamedType(ptr) && isSgClassDeclaration(isSgNamedType(ptr)->get_declaration()) && isSgClassDeclaration(isSgNamedType(ptr)->get_declaration())->get_isUnNamed())
        {
          SgClassDeclaration* originalDecl = isSgClassDeclaration(isSgNamedType(ptr)->get_declaration()->get_definingDeclaration());
          SgName altDecl_name(typeNameStr + "_def");
          altDecl = new SgClassDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),altDecl_name,originalDecl->get_class_type());

          SgClassDefinition* altDecl_definition = SB::buildClassDefinition(altDecl);

          SgDeclarationStatementPtrList originalMembers = originalDecl->get_definition()->get_members();
          for(SgDeclarationStatementPtrList::iterator it = originalMembers.begin(); it != originalMembers.end(); it++)
          {
            SgDeclarationStatement* member = *it;
            SgDeclarationStatement* membercpy = isSgDeclarationStatement(SI::copyStatement(member));
            altDecl_definition->append_member(membercpy);
          }


          SgClassDeclaration* altDecl_nondef = new SgClassDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),altDecl_name,originalDecl->get_class_type());

          altDecl_nondef->set_scope(global);
          altDecl->set_scope(global);

          altDecl->set_firstNondefiningDeclaration(altDecl_nondef);
          altDecl_nondef->set_firstNondefiningDeclaration(altDecl_nondef);
          altDecl->set_definingDeclaration(altDecl);
          altDecl_nondef->set_definingDeclaration(altDecl);


          SgClassType* altDecl_ct = SgClassType::createType(altDecl_nondef);
          altDecl->set_type(altDecl_ct);
          altDecl_nondef->set_type(altDecl_ct);

          altDecl->set_isUnNamed(false);
          altDecl_nondef->set_isUnNamed(false);

          altDecl_nondef->set_forward(true);

          SgSymbol* sym = new SgClassSymbol(altDecl_nondef);
          global->insert_symbol(altDecl_name, sym);

          altDecl->set_linkage("C");
          altDecl_nondef->set_linkage("C");

          ROSE_ASSERT(sym && sym->get_symbol_basis() == altDecl_nondef);
          ROSE_ASSERT(altDecl->get_definingDeclaration() == altDecl);
          ROSE_ASSERT(altDecl->get_firstNondefiningDeclaration() == altDecl_nondef);
          ROSE_ASSERT(altDecl->search_for_symbol_from_symbol_table() == sym);
          ROSE_ASSERT(altDecl->get_definition() == altDecl_definition);
          ROSE_ASSERT(altDecl->get_scope() == global && altDecl->get_scope() == altDecl_nondef->get_scope());
          ROSE_ASSERT(altDecl_ct->get_declaration() == altDecl_nondef);

          //For some reason, this is not working...

          //global->append_statement(altDecl);
          //global->prepend_statement(altDecl_nondef);

          //SI::setOneSourcePositionForTransformation(altDecl);
          //SI::setOneSourcePositionForTransformation(altDecl_nondef);
        }

        SgType* baseType;
        if(isSgPointerType(ptr))
          baseType = ptr->dereference();
        else
          baseType = ptr->findBaseType();

        baseType = baseType->stripTypedefsAndModifiers();
        if(baseType == NULL || baseType == ptr)
        {
          //In this case, there is no base type.
          rhs = SB::buildFunctionCallExp(SgName("ti_init"),SgTypeVoid::createType(),SB::buildExprListExp(
                                           SB::buildStringVal(ptr->unparseToString()),
                                           ((altDecl == NULL && !isSgTypeVoid(ptr)) ? (SgExpression*) SB::buildSizeOfOp(types[index]) : (SgExpression*) SB::buildIntVal(-1)),
                                           SB::buildIntVal(getClassification(ptr))
                                         ),init_definition);
        }
        else
        {
          //The type has a base type.
          std::string baseStructNameStr = prefix + Util::getNameForType(baseType).getString();
          rhs = SB::buildFunctionCallExp(SgName("ti_init"),ti_type,SB::buildExprListExp(
                                           SB::buildStringVal(ptr->unparseToString()),
                                           ((altDecl == NULL && !isSgTypeVoid(ptr)) ? (SgExpression*) SB::buildSizeOfOp(types[index]) : (SgExpression*) SB::buildIntVal(-1)),
                                           SB::buildIntVal(getClassification(ptr))
                                         ),init_definition);

          SgExprStatement* set_BT = SB::buildFunctionCallStmt(SgName("setBaseType"),ti_type,SB::buildExprListExp(
                                      SB::buildVarRefExp(structNameStr),
                                      SB::buildVarRefExp(baseStructNameStr)),
                                    init_definition);
          init_definition->append_statement(set_BT);
        }
        lhs = SB::buildVarRefExp(structNameStr);


        SgExprStatement* assignstmt = SB::buildAssignStatement(lhs,rhs);
        init_definition->prepend_statement(assignstmt);
        std::remove(lst.begin(),lst.end(),structNameStr);

      }



    }
  }