Beispiel #1
0
void assemblyOutput(char const *lineFormat, ...) {
	va_list args;
	va_start(args, lineFormat);

	char **buffer = getGlobalScope() ? &globalBuffer : &assemblyBuffer;

	char *buf1, *buf2;
	vasprintf(&buf1, lineFormat, args);
	asprintf(&buf2, "%s%s\n", *buffer, buf1);
	free(buf1);
	free(*buffer);
	*buffer = buf2;

	va_end(args);

	getGlobalScope() ? ++globalCount : ++linesCount;
}
Beispiel #2
0
dereferencedSymbol_t createString(char const *value) {
	bool const oldGlobalScope = getGlobalScope();

	setGlobalScope(true);

	int len = strlen(value) + 1;
	char *interningName;
	asprintf(&interningName, "__internedString__%s", value);

	dereferencedSymbol_t deref = getExistingSymbol(interningName, false);
	symbol_t *tab = deref.symbol;
	if(tab == &dummy) {
		tab = createArray(interningName, (varType_t){.indirectionCount = 0, .baseType = BT_CHAR, .constMask = 1}, len);
Beispiel #3
0
int main(int argc, char** argv)
{
	//Parse command-line args
	ProgramOptions po(argc, argv);

	//Initialize the AST
	SgProject* project = new SgProject(argc, argv);
	ROSE_ASSERT(project);
	AstTests::runAllTests(project); //TODO switch on/off with command-line args

	//Set the folder containing the features
	string featureFolder = "";
	bool defaultFeatures = po.getFeaturesFolder(featureFolder);
	if(!defaultFeatures)
		CallScheduler::setFeaturesFolder(featureFolder);

	//Loop through all partitioned kernels and add scheduling calls
	Rose_STL_Container<SgNode*> pragmas = querySubTree(project, V_SgPragmaDeclaration);
	Rose_STL_Container<SgNode*>::const_iterator pragmaIt = pragmas.begin();
	SgPragmaDeclaration* pragma = NULL;
	SgFunctionDeclaration* funcDecl = NULL;
	SgStatement* stmt = NULL;
	for(pragmaIt = pragmas.begin(); pragmaIt != pragmas.end(); pragmaIt++)
	{
		pragma = isSgPragmaDeclaration(*pragmaIt);
		ROSE_ASSERT(pragma);

		PragmaParser pp(pragma);
		if(pp.isPopcornPragma() && pp.getPragmaType() == PARTITIONED)
		{
			stmt = getNextStatement(pragma);
			while(!isSgFunctionDeclaration(stmt))
				stmt = getNextStatement(pragma);
			funcDecl = isSgFunctionDeclaration(stmt);
			ROSE_ASSERT(funcDecl);
			Pragmas pragmas(funcDecl);

			//Add scheduling calls
			CallScheduler cs(funcDecl, pragmas);
			cs.addSchedulerCalls();

			//Insert the header
			//TODO this won't insert the header into files
			insertHeader(po.getSchedulerHeaderLocation(), PreprocessingInfo::after, false,
					getGlobalScope(funcDecl));
		}
	}

	return backend(project);
}
Beispiel #4
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 #5
0
int main(int argc, char** argv)
{
	//Parse command-line options
	ProgramOptions po(argc, argv);

	//Initialize the AST
	SgProject* project = new SgProject(argc, argv);
	ROSE_ASSERT(project);
	AstTests::runAllTests(project); //TODO switch on/off with command-line args

	//Insert MM-wrapper header file
	string mmHeader = po.getMMWrapperHeaderLocation();
	insertHeader(mmHeader, PreprocessingInfo::after, false, getGlobalScope(findMain(project)));

	//Initialize set of system headers & compiler generated vars
	RegisterPointers::initialize();

	//Add calls to registers sizes of static variables
	RegisterVars rv(project, mmHeader);
	rv.registerStaticVars();

	//Used to accumulate all global variables
	set<SgInitializedName*> globalVars;

	//Add wrapper calls to each function/sub-function so that all pointers are registered
	Rose_STL_Container<SgNode*> pragmas = querySubTree(project, V_SgPragmaDeclaration);
	Rose_STL_Container<SgNode*>::const_iterator pragmaIt;
	Rose_STL_Container<SgNode*> funcCalls = querySubTree(project, V_SgFunctionCallExp);
	SgPragmaDeclaration* pragma;
	SgStatement* stmt;
	SgFunctionDeclaration* funcDecl;
	for(pragmaIt = pragmas.begin(); pragmaIt != pragmas.end(); pragmaIt++)
	{
		pragma = isSgPragmaDeclaration(*pragmaIt);
		ROSE_ASSERT(pragma);

		PragmaParser pp(pragma);
		if(pp.isPopcornPragma() && pp.getPragmaType() == PARTITIONED)
		{
			//Get function declaration
			stmt = getNextStatement(pragma);
			while(!isSgFunctionDeclaration(stmt))
				stmt = getNextStatement(stmt);
			funcDecl = isSgFunctionDeclaration(stmt);
			ROSE_ASSERT(funcDecl);
			Pragmas pragmas(funcDecl);

			//Save global variables
			saveGlobalVariables(pragmas.getGlobalInputs(), globalVars,
					pragmas.getFunction()->get_scope());
			saveGlobalVariables(pragmas.getGlobalOutputs(), globalVars,
					pragmas.getFunction()->get_scope());

			//Update call sites
			//TODO I don't think we need this anymore, since all sizes are
			//handled through the mm_wrapper interface
			//FunctionCallUpdater fcu(funcDecl, funcCalls);
			//fcu.updateDeclaration();
			//fcu.updateSites();
		}
	}

	//Register/unregister global variables
	RegisterVars::registerGlobalVars(globalVars);

	//Add call to initialize wrapper
	SgFunctionDeclaration* main = findMain(project);
	ROSE_ASSERT(main);
	FunctionCallUpdater::insertInitWrapperCall(main);

	return backend(project);
}