/* * 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); } } } }
/*! * \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); }