void InstrumentationFunction::buildDeclaration(SgProject* project) {
   // *****************************************************
   // Create the functionDeclaration
   // *****************************************************

   Sg_File_Info * file_info = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
   SgType *function_return_type = new SgTypeVoid();

   type = new SgFunctionType(function_return_type, false);

   SgFunctionDeclaration *functionDeclaration = new SgFunctionDeclaration(file_info, name, type);

   // ********************************************************************
   // Create the InitializedName for a parameter within the parameter list
   // ********************************************************************
   /*
   SgName var1_name = "textString";

   SgTypeChar * var1_type            = new SgTypeChar();
   SgPointerType *pointer_type       = new SgPointerType(var1_type);
   SgInitializer * var1_initializer  = NULL;
   SgInitializedName *var1_init_name = new SgInitializedName(var1_name, pointer_type, var1_initializer, NULL);

   // Insert argument in function parameter list
   ROSE_ASSERT(functionDeclaration != NULL);
   ROSE_ASSERT(functionDeclaration->get_parameterList() != NULL);

   ROSE_ASSERT(functionDeclaration->get_parameterList() != NULL);
   functionDeclaration->get_parameterList()->append_arg(var1_init_name);
   */
   SgSourceFile* sourceFile = isSgSourceFile(project->get_fileList()[0]);
   ROSE_ASSERT(sourceFile != NULL);
   SgGlobal* globalScope = sourceFile->get_globalScope();
   ROSE_ASSERT(globalScope != NULL);

   // Set the parent node in the AST (this could be done by the AstPostProcessing
   functionDeclaration->set_parent(globalScope);

   // Set the scope explicitly (since it could be different from the parent?)
   // This can't be done by the AstPostProcessing (unless we relax some constraints)
   functionDeclaration->set_scope(globalScope);

   // If it is not a forward declaration then the unparser will skip the ";" at the end (need to fix this better)
   functionDeclaration->setForward();
   ROSE_ASSERT(functionDeclaration->isForward() == true);

   // Mark function as extern "C"
   functionDeclaration->get_declarationModifier().get_storageModifier().setExtern();
   functionDeclaration->set_linkage("C");  // This mechanism could be improved!

   // Add function declaration to global scope
   globalScope->prepend_declaration(functionDeclaration);

   symbol = new SgFunctionSymbol(functionDeclaration);
   // All any modifications to be fixed up (parents etc)
   // AstPostProcessing(project); // This is not allowed and should be fixed!
   AstPostProcessing(globalScope);
}
Beispiel #2
0
SgFunctionDeclaration * CudaOutliner::generateFunction ( SgBasicBlock* s,
                                                         const string& func_name_str,
                                                         ASTtools::VarSymSet_t& syms,
							 MintHostSymToDevInitMap_t hostToDevVars,
							 const ASTtools::VarSymSet_t& pdSyms,
                                                         const ASTtools::VarSymSet_t& psyms,
                                                         SgScopeStatement* scope)
{
  //Create a function named 'func_name_str', with a parameter list from 'syms'                                                             
  //pdSyms specifies symbols which must use pointer dereferencing if replaced during outlining,  
  //only used when -rose:outline:temp_variable is used                                                                                     
  //psyms are the symbols for OpenMP private variables, or dead variables (not live-in, not live-out)    

  ROSE_ASSERT ( s && scope);
  ROSE_ASSERT(isSgGlobal(scope));

  // step 1: perform necessary liveness and side effect analysis, if requested.     
  // ---------------------------------------------------------                                                                           
  std::set< SgInitializedName *> liveIns, liveOuts;
  // Collect read-only variables of the outlining target                                                                                
  std::set<SgInitializedName*> readOnlyVars;
  if (Outliner::temp_variable||Outliner::enable_classic)
    {
      SgStatement* firstStmt = (s->get_statements())[0];
      if (isSgForStatement(firstStmt)&& Outliner::enable_liveness)
        {
          LivenessAnalysis * liv = SageInterface::call_liveness_analysis (SageInterface::getProject());
	  SageInterface::getLiveVariables(liv, isSgForStatement(firstStmt), liveIns, liveOuts);
        }
      SageInterface::collectReadOnlyVariables(s,readOnlyVars);
      if (0)//Outliner::enable_debug)
        {
          cout<<"  INFO:Mint: CudaOutliner::generateFunction()---Found "<<readOnlyVars.size()<<" read only variables..:";
          for (std::set<SgInitializedName*>::const_iterator iter = readOnlyVars.begin();
               iter!=readOnlyVars.end(); iter++)
            cout<<" "<<(*iter)->get_name().getString()<<" ";
          cout<<endl;
          cout<<"CudaOutliner::generateFunction() -----Found "<<liveOuts.size()<<" live out variables..:";
          for (std::set<SgInitializedName*>::const_iterator iter = liveOuts.begin();
               iter!=liveOuts.end(); iter++)
            cout<<" "<<(*iter)->get_name().getString()<<" ";
          cout<<endl;
        }
    }
    //step 2. Create function skeleton, 'func'.             
    // -----------------------------------------                
  SgName func_name (func_name_str);
  SgFunctionParameterList *parameterList = buildFunctionParameterList();
  
  SgType* func_Type = SgTypeVoid::createType ();
  SgFunctionDeclaration* func = createFuncSkeleton (func_name, func_Type ,parameterList, scope);

  //adds __global__ keyword 
  func->get_functionModifier().setCudaKernel();
 
  ROSE_ASSERT (func);

  // Liao, 4/15/2009 , enforce C-bindings  for C++ outlined code 
  // enable C code to call this outlined function                                                                                
  // Only apply to C++ , pure C has trouble in recognizing extern "C"                                                    
  // Another way is to attach the function with preprocessing info:                                                     
  // #if __cplusplus                                                                                                           
  // extern "C"                                                                                                              
  // #endif                                                                                                                                
  // We don't choose it since the language linkage information is not explicit in AST                                                           
  if ( SageInterface::is_Cxx_language() || is_mixed_C_and_Cxx_language() \
       || is_mixed_Fortran_and_Cxx_language() || is_mixed_Fortran_and_C_and_Cxx_language() )
    {
      // Make function 'extern "C"'                                                                                                                                         
      func->get_declarationModifier().get_storageModifier().setExtern();
      func->set_linkage ("C");
    }

  //step 3. Create the function body                                                                                       
  // -----------------------------------------                                                                                              
  // Generate the function body by deep-copying 's'.                                                                                       
              
  SgBasicBlock* func_body = func->get_definition()->get_body();
  ROSE_ASSERT (func_body != NULL);

  // This does a copy of the statements in "s" to the function body of the outlined function.                                             
  ROSE_ASSERT(func_body->get_statements().empty() == true);

  // This calls AST copy on each statement in the SgBasicBlock, but not on the block, so the                                          
  // symbol table is setup by AST copy mechanism and it is  setup properly
  SageInterface::moveStatementsBetweenBlocks (s, func_body);

  if (Outliner::useNewFile)
    ASTtools::setSourcePositionAtRootAndAllChildrenAsTransformation(func_body);

  //step 4: variable handling, including:                                                                                                  
  // -----------------------------------------                                                                                             
  //   create parameters of the outlined functions                                                                                        
  //   add statements to unwrap the parameters if wrapping is requested
  //   add repacking statements if necessary                                                                                               
  //   replace variables to access to parameters, directly or indirectly                                                                  
  //   do not wrap parameters 
  Outliner::enable_classic = true;

  functionParameterHandling(syms, hostToDevVars, pdSyms, psyms, readOnlyVars, liveOuts, func);
  ROSE_ASSERT (func != NULL);
  
  // Retest this...  // Copied the similar fix from the rose outliner                        
  //     Liao 2/6/2013. It is essential to rebuild function type after the parameter list is finalized.
  //     The original function type was build using empty parameter list.
  SgType* stale_func_type = func->get_type();
  func->set_type(buildFunctionType(func->get_type()->get_return_type(), buildFunctionParameterTypeList(func->get_parameterList())));
  SgFunctionDeclaration* non_def_func = isSgFunctionDeclaration(func->get_firstNondefiningDeclaration ()) ;
  ROSE_ASSERT (non_def_func != NULL);
  ROSE_ASSERT (stale_func_type == non_def_func->get_type());
  non_def_func->set_type(func->get_type());

  ROSE_ASSERT(func->get_definition()->get_body()->get_parent() == func->get_definition());

  ROSE_ASSERT(scope->lookup_function_symbol(func->get_name()));

  return func;
}  
SgFunctionSymbol*
SimpleInstrumentation::buildNewFunctionDeclaration ( SgStatement* statementLocation, SgFunctionType* previousFunctionType )
   {
  // *****************************************************
  // Create the functionDeclaration
  // *****************************************************

  // Must mark the newly built node to be a part of a transformation so that it will be unparsed!
     Sg_File_Info * file_info = new Sg_File_Info();
     ROSE_ASSERT(file_info != NULL);
     file_info->set_isPartOfTransformation(true);

     SgName function_name = "contest_call";
     ROSE_ASSERT(previousFunctionType != NULL);
     SgFunctionDeclaration* functionDeclaration = new SgFunctionDeclaration(file_info, function_name, previousFunctionType);
     ROSE_ASSERT(functionDeclaration != NULL);
     ROSE_ASSERT(functionDeclaration->get_parameterList() != NULL);

  // ********************************************************************
  // Create the InitializedName for a parameter within the parameter list
  // ********************************************************************
     SgTypePtrList & argList = previousFunctionType->get_arguments();
     SgTypePtrList::iterator i = argList.begin();
     while ( i != argList.end() )
        {
          SgName var_name = "";
          SgInitializer* var_initializer = NULL;
          SgInitializedName *var_init_name = new SgInitializedName(var_name, *i, var_initializer, NULL);
          functionDeclaration->get_parameterList()->append_arg(var_init_name);
          i++;
        }

  // Add any additional function arguments here! Make sure that the function type is consistant.

  // Get the scope
     SgScopeStatement* scope = statementLocation->get_scope();

  // Set the parent node in the AST (this could be done by the AstPostProcessing
     functionDeclaration->set_parent(scope);

  // Set the scope explicitly (since it could be different from the parent?)
     functionDeclaration->set_scope(scope);

  // If it is not a forward declaration then the unparser will skip the ";" at the end (need to fix this better)
     functionDeclaration->setForward();
     ROSE_ASSERT(functionDeclaration->isForward() == true);

  // Mark function as extern "C"
     functionDeclaration->get_declarationModifier().get_storageModifier().setExtern();
     functionDeclaration->set_linkage("C");  // This mechanism could be improved!

     bool inFront = true;
     SgGlobal* globalScope = TransformationSupport::getGlobalScope(statementLocation);
     SgFunctionDeclaration* functionDeclarationInGlobalScope = 
          TransformationSupport::getFunctionDeclaration(statementLocation);
     ROSE_ASSERT(globalScope != NULL);
     ROSE_ASSERT(functionDeclarationInGlobalScope != NULL);
     globalScope->insert_statement(functionDeclarationInGlobalScope,functionDeclaration,inFront);

     SgFunctionSymbol* functionSymbol = new SgFunctionSymbol(functionDeclaration);
     ROSE_ASSERT(functionSymbol != NULL);
     ROSE_ASSERT(functionSymbol->get_type() != NULL);

     return functionSymbol;
   }