/*
 *  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);
      }
    }
  }
}
Esempio n. 2
0
/*!
 *  \brief Creates a new outlined-function parameter for a given
 *  variable. The requirement is to preserve data read/write semantics.
 *
 *  For C/C++: we use pointer dereferencing to implement pass-by-reference
 *    In a recent implementation, side effect analysis is used to find out
 *    variables which are not modified so pointer types are not used.
 *

 *
 *  Given a variable (i.e., its type and name) whose references are to
 *  be outlined, create a suitable outlined-function parameter. 
 *  For C/C++, the  parameter is created as a pointer, to support parameter passing of
 *  aggregate types in C programs. 
 *  Moreover, the type is made 'void' if the base type is not a primitive type.
 *   
 *  An original type may need adjustments before we can make a pointer type from it.
 *  For example: 
 *    a)Array types from a function parameter: its first dimension is auto converted to a pointer type 
 *
 *    b) Pointer to a C++ reference type is illegal, we create a pointer to its
 *    base type in this case. It also match the semantics for addressof(refType) 
 *
 * 
 *  The implementation follows two steps:
 *     step 1: adjust a variable's base type
 *     step 2: decide on its function parameter type
 *  Liao, 8/14/2009
 */
static OutlinedFuncParam_t createParam (const SgInitializedName* i_name, bool readOnly=false)
{

  ROSE_ASSERT (i_name);
  SgType* init_type = i_name->get_type();
  ROSE_ASSERT (init_type);

  // Stores the real parameter type to be used in new_param_type
  string init_name = i_name->get_name ().str (); 

  SgType* param_base_type;
  //has to be not scalar                                                                                                                                              
  if(isSgArrayType (init_type) ){

    SgType* base_type = init_type->findBaseType();
    param_base_type = buildPointerType(base_type);
  }
  else if (isSgPointerType (init_type))
    {
      //Didem, this used to be 2 but I changed into 0. Didn't make any sense
      init_name = init_name.substr(0);
      //Didem: I have changed the types into 1D pointer type 
      SgType* base_type = init_type->findBaseType();
      param_base_type = buildPointerType(base_type);

      //param_base_type = init_type;
    }
  else{
    param_base_type = init_type;
  }

   // The parameter name reflects the type: the same name means the same type, 
   // p__ means a pointer type
  string new_param_name = init_name;
  SgType* new_param_type = NULL;

  // For classic behavior, read only variables are passed by values for C/C++
  // They share the same name and type
  if (Outliner::enable_classic) 
  { 
    // read only parameter: pass-by-value, the same type and name
    // shared parameters  : already pointer type 
    //if (readOnly)
    {

      new_param_type = param_base_type;
    }
    /*
    else
    {
      new_param_name= "d__" + new_param_name;
      new_param_type = SgPointerType::createType (param_base_type);

      }*/
  }
  else // very conservative one, assume the worst side effects (all are written) 
  {
    new_param_name= new_param_name;
  }

  // So use base type directly
  // C/C++ parameters will use their new param type to implement pass-by-reference

  return OutlinedFuncParam_t (new_param_name, new_param_type);
}