SynthesizedAttribute
visitorTraversal::evaluateSynthesizedAttribute ( SgNode* n, SynthesizedAttributesList childAttributes )
   {
  // Fold up the list of child attributes using logical or, i.e. the local
  // result will be true iff one of the child attributes is true.
     SynthesizedAttribute localResult =
         std::accumulate(childAttributes.begin(), childAttributes.end(),
                         false, std::logical_or<bool>());

     if (isSgForStatement(n) != NULL)
        {
          printf ("Found a for loop ... \n");
          localResult = true;
        }

     return localResult;
   }
Esempio n. 2
0
		virtual void visit(SgNode * n) {
			switch (n->variantT()) {
				case V_SgFunctionDeclaration:
				{
					SgFunctionDeclaration * func_decl = isSgFunctionDeclaration(n);
					ROSE_ASSERT(func_decl != NULL);
					std::string func_name = func_decl->get_name().getString();
//					std::cout << "Found SgFunctionDeclaration: " << func_name << std::endl;
					if (func_name == "caller")
						p_caller = func_decl;
					if (func_name == "kernel")
						p_kernel = func_decl;
					break;
				}
				case V_SgForStatement:
				{
					SgForStatement * for_stmt = isSgForStatement(n);
					ROSE_ASSERT(for_stmt != NULL);
//					std::cout << "Found SgForStatement." << std::endl;
					p_for_stmts.push_back(for_stmt);
					break;
				}
				case V_SgFunctionCallExp:
				{
					SgFunctionCallExp * func_call = isSgFunctionCallExp(n);
					ROSE_ASSERT(func_call != NULL);
					SgFunctionRefExp * func_ref = isSgFunctionRefExp(func_call->get_function());
					ROSE_ASSERT(func_ref != NULL);
//					std::cout << "Found SgFunctionCallExp: " << func_ref->getAssociatedFunctionDeclaration ()->get_name().getString() << std::endl;
					if (func_ref->getAssociatedFunctionDeclaration()->get_name().getString() == "kernel")
						p_kernel_call_site = func_call;
					break;
				}
                                case V_SgSourceFile: // fix the file suffix, Liao 12/29/2010
                                {
                                     SgSourceFile * sfile = isSgSourceFile (n);
                                     ROSE_ASSERT (sfile != NULL);
                                     sfile->set_Cuda_only(true);
                                }
				default:{}
			}
		}
Esempio n. 3
0
/* recommenderTraversal::visit */
void recommenderTraversal::visit(SgNode *node) {
    Sg_File_Info *info = NULL;
    SgFunctionDefinition *function = NULL;
    SgForStatement *c_loop = NULL;
    SgNode *grandparent = NULL;
    SgNode *parent = NULL;
    int node_found = 0;

    info = node->get_file_info();

    /* Find code fragment for bottlenecks type 'loop' in C */
    if ((isSgForStatement(node)) && (info->get_line() == fragment->line)
        && (PERFEXPERT_HOTSPOT_LOOP == fragment->type)) {

        /* Found a C loop on the exact line number */
        OUTPUT_VERBOSE((8, "         [loop] %s (line %d)",
            _GREEN((char *)"found"), info->get_line()));

        /* Extract the loop fragment */
        if (PERFEXPERT_SUCCESS != output_fragment(node, info, fragment)) {
            OUTPUT(("%s", _ERROR((char *)"extracting fragment")));
            rc = PERFEXPERT_ERROR;
            return;
        }

        /* Save the fragment path and filename */
        PERFEXPERT_ALLOC(char, fragment->fragment_file, (strlen(globals.workdir)
            + strlen(FRAGMENTS_DIR) + strlen(fragment->file) + 15));
        sprintf(fragment->fragment_file, "%s/%s/%s_%d", globals.workdir,
            FRAGMENTS_DIR, fragment->file, fragment->line);

        /* What is the loop detph and who is parent node */
        if (2 <= fragment->depth) {
            parent = node->get_parent();

            /* It is a basic block. Who is this basic block's parent? */
            if (NULL != isSgBasicBlock(parent)) {
                parent = parent->get_parent();
            }

            /* Is it a for/do/while? */
            if (isSgForStatement(parent)) {
                info = parent->get_file_info();
                fragment->outer_loop_line = info->get_line();

                /* The parent is a loop */
                OUTPUT_VERBOSE((8, "         [parent loop] %s (line %d)",
                    _GREEN((char *)"found"), fragment->outer_loop_line));

                /* Extract the parent loop fragment */
                if (PERFEXPERT_SUCCESS != output_fragment(parent, info,
                    fragment)) {
                    OUTPUT(("%s", _ERROR((char *)"extracting fragment")));
                    rc = PERFEXPERT_ERROR;
                    return;
                }

                /* Save the fragment path and filename */
                PERFEXPERT_ALLOC(char, fragment->outer_loop_fragment_file,
                    (strlen(globals.workdir) + strlen(FRAGMENTS_DIR)
                    + strlen(fragment->file) + 15));
                sprintf(fragment->outer_loop_fragment_file, "%s/%s/%s_%d",
                    globals.workdir, FRAGMENTS_DIR, fragment->file,
                    fragment->outer_loop_line);

                /* What is the loop detph and who is the grandparent node */
                if (3 <= fragment->depth) {
                    grandparent = parent->get_parent();

                    /* It is a basic block. Who is this basic block's parent? */
                    if (NULL != isSgBasicBlock(grandparent)) {
                        grandparent = grandparent->get_parent();
                    }

                    /* Is it a for/do/while? */
                    if (isSgForStatement(grandparent)) {
                        info = grandparent->get_file_info();
                        fragment->outer_outer_loop_line = info->get_line();

                        /* The grandparent is a loop */
                        OUTPUT_VERBOSE((8, "   [grandparent loop] %s (line %d)",
                            _GREEN((char *)"found"),
                            fragment->outer_outer_loop_line));

                        /* Extract the parent loop fragment */
                        if (PERFEXPERT_SUCCESS != output_fragment(grandparent,
                            info, fragment)) {
                            OUTPUT(("%s",
                                _ERROR((char *)"extracting fragment")));
                            rc = PERFEXPERT_ERROR;
                            return;
                        }

                        /* Save the fragment path and filename */
                        PERFEXPERT_ALLOC(char,
                            fragment->outer_outer_loop_fragment_file,
                            (strlen(globals.workdir) + strlen(FRAGMENTS_DIR) +
                            strlen(fragment->file) + 15));
                        sprintf(fragment->outer_outer_loop_fragment_file,
                            "%s/%s/%s_%d", globals.workdir, FRAGMENTS_DIR,
                            fragment->file, fragment->outer_outer_loop_line);
                    }
                }
            }
Esempio n. 4
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()
Esempio n. 5
0
  // Count the load and store bytes for the 
  // I think we can only return expressions to calculate the value, not the actual values,
  // since sizeof(type) is machine dependent
  //   Consider both scalar and  array accesses by default. Consider both floating point and integer types by default.
  // return a pair of expressions:  
  //       load_byte_exp, and 
  //       store_byte_exp
  // Algorithm: 
  //    1.  Call side effect analysis to find read/write variables, some reference may trigger both read and write accesses
  //        Accesses to the same array/scalar variable are grouped into one read (or write) access
  //         e.g. array[i][j],  array[i][j+1],  array[i][j-1], etc are counted a single access
  //    2.  Group accesses based on the types (same type?  increment the same counter to shorten expression length)
  //    4.  Iterate on the results to generate expression like  2*sizeof(float) + 5* sizeof(double)
  // As an approximate, we use simple analysis here assuming no function calls.
  std::pair <SgExpression*, SgExpression*> CountLoadStoreBytes (SgLocatedNode* input, bool includeScalars /* = true */, bool includeIntType /* = true */)
  {
    std::pair <SgExpression*, SgExpression*> result; 
    assert (input != NULL);
   // the input is essentially the loop body, a scope statement
    SgScopeStatement* scope = isSgScopeStatement(input);

    // 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:"<< input->class_name()<<endl;
      assert(false);
    }

    //Plan A: use and extend Qing's side effect analysis
    std::set<SgInitializedName*> readVars;
    std::set<SgInitializedName*> writeVars;

    bool success = SageInterface::collectReadWriteVariables (isSgStatement(input), readVars, writeVars);
    if (success!= true)
    {
       cout<<"Warning: CountLoadStoreBytes(): failed to collect load/store, mostly due to existence of function calls inside of loop body @ "<<input->get_file_info()->get_line()<<endl;
    }

    std::set<SgInitializedName*>::iterator it;
    if (debug)
      cout<<"debug: found read variables (SgInitializedName) count = "<<readVars.size()<<endl;
    for (it=readVars.begin(); it!=readVars.end(); it++)
    {
      SgInitializedName* iname = (*it);
      if (debug)
        cout<<scalar_or_array (iname->get_type()) <<" "<<iname->get_name()<<"@"<<iname->get_file_info()->get_line()<<endl;
    }

    if (!includeScalars )
      readVars =  filterVariables (readVars);
    if (debug)
      cout<<"debug: found write variables (SgInitializedName) count = "<<writeVars.size()<<endl;
    for (it=writeVars.begin(); it!=writeVars.end(); it++)
    {
      SgInitializedName* iname = (*it);
      if (debug)
        cout<<scalar_or_array(iname->get_type()) <<" "<<iname->get_name()<<"@"<<iname->get_file_info()->get_line()<<endl;
    }
    if (!includeScalars )
      writeVars =  filterVariables (writeVars);
    result.first =  calculateBytes (readVars, scope, true);
    result.second =  calculateBytes (writeVars, scope, false);
    return result;
  }
Esempio n. 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; 
  }  
    EdgeConditionKind CFGEdge::condition() const {
#if 0
        SgAsmNode* srcNode = src.getNode();
        unsigned int srcIndex = src.getIndex();
        SgAsmNode* tgtNode = tgt.getNode();
        unsigned int tgtIndex = tgt.getIndex();
        if (isSgAsmMov(srcNode) ) {
            SgAsmMov* ifs = isSgAsmMov(srcNode);
#if 0
            if (ifs->get_true_body() == tgtNode) {
                return eckTrue;
            } else if (ifs->get_false_body() == tgtNode) {
                return eckFalse;
            } else ROSE_ASSERT (!"Bad successor in if statement");
#endif
        }
#if 0
        else if (isSgWhileStmt(srcNode) && srcIndex == 1) {
            if (srcNode == tgtNode) {
                // False case for while test
                return eckFalse;
            } else {
                return eckTrue;
            }
        } else if (isSgDoWhileStmt(srcNode) && srcIndex == 2) {
            // tgtIndex values are 0 for true branch and 3 for false branch
            if (tgtIndex == 0) {
                return eckTrue;
            } else {
                return eckFalse;
            }
        } else if (isSgForStatement(srcNode) && srcIndex == 2) {
            if (srcNode == tgtNode) {
                // False case for test
                return eckFalse;
            } else {
                return eckTrue;
            }
        } else if (isSgSwitchStatement(srcNode) && isSgCaseOptionStmt(tgtNode)) {
            return eckCaseLabel;
        } else if (isSgSwitchStatement(srcNode) && isSgDefaultOptionStmt(tgtNode)){
            return eckDefault;
        } else if (isSgConditionalExp(srcNode) && srcIndex == 1) {
            SgConditionalExp* ce = isSgConditionalExp(srcNode);
            if (ce->get_true_exp() == tgtNode) {
                return eckTrue;
            } else if (ce->get_false_exp() == tgtNode) {
                return eckFalse;
            } else ROSE_ASSERT (!"Bad successor in conditional expression");
        } else if (isSgAndOp(srcNode) && srcIndex == 1) {
            if (srcNode == tgtNode) {
                // Short-circuited false case
                return eckFalse;
            } else {
                return eckTrue;
            }
        } else if (isSgOrOp(srcNode) && srcIndex == 1) {
            if (srcNode == tgtNode) {
                // Short-circuited true case
                return eckTrue;
            } else {
                return eckFalse;
            }
        } 
#endif
        else {
            // No key
            return eckUnconditional;
        }
#else
    // DQ (11/28/2009): This function was already commented out, but must return a value for use in MSVC.
       return eckFalse;
#endif
    }
Esempio n. 8
0
POETCode* POETAstInterface::Ast2POET(const Ast& n)
{
  static SgTemplateInstantiationFunctionDecl* tmp=0;
  SgNode* input = (SgNode*) n;
  if (input == 0) return EMPTY;
  POETCode* res = POETAstInterface::find_Ast2POET(input);
  if (res != 0) return res;

  {
  SgProject* sageProject=isSgProject(input); 
  if (sageProject != 0) {
    int filenum = sageProject->numberOfFiles(); 
    for (int i = 0; i < filenum; ++i) { 
      SgSourceFile* sageFile = isSgSourceFile(sageProject->get_fileList()[i]); 
      SgGlobal *root = sageFile->get_globalScope(); 
      SgDeclarationStatementPtrList declList = root->get_declarations ();
      POETCode* curfile = ROSE_2_POET_list(declList, 0, tmp);
      curfile = new POETCode_ext(sageFile, curfile);
      POETAstInterface::set_Ast2POET(sageFile, curfile);
      res=LIST(curfile, res);
    }
    POETAstInterface::set_Ast2POET(sageProject,res); 
    return res;
  } }
  { 
  SgBasicBlock* block = isSgBasicBlock(input);
  if (block != 0) {
    res=ROSE_2_POET_list(block->get_statements(), res, tmp);
    POETAstInterface::set_Ast2POET(block, res); 
    return res;
  } }
  { 
  SgExprListExp* block = isSgExprListExp(input);
  if (block != 0) {
    res=ROSE_2_POET_list(block->get_expressions(), 0, tmp);
    POETAstInterface::set_Ast2POET(block, res); 
    return res;
  } }
 {
  SgForStatement *f = isSgForStatement(input);
  if (f != 0) {
      POETCode* init = ROSE_2_POET_list(f->get_for_init_stmt()->get_init_stmt(),0, tmp);
      POETCode* ctrl = new POETCode_ext(f, TUPLE3(init,Ast2POET(f->get_test_expr()), Ast2POET(f->get_increment())));
      res = CODE_ACC("Nest", PAIR(ctrl,Ast2POET(f->get_loop_body())));  
      POETAstInterface::set_Ast2POET(input, res); 
      return res;
  }
  }
  {
    SgVarRefExp * v = isSgVarRefExp(input);
    if (v != 0) {
       res = STRING(v->get_symbol()->get_name().str());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
    SgMemberFunctionRefExp * v = isSgMemberFunctionRefExp(input);
    if (v != 0) {
       res = STRING(v->get_symbol()->get_name().str());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
    SgIntVal * v = isSgIntVal(input);
    if (v != 0) {
       res = ICONST(v->get_value());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
   SgInitializedName* var = isSgInitializedName(input);
   if (var != 0) {
     POETCode* name = STRING(var->get_name().str()); 
     POETCode* init = Ast2POET(var->get_initializer());
     res = new POETCode_ext(var, PAIR(name,init));
     POETAstInterface::set_Ast2POET(input, res); 
     return res;
   }
  }

/*
  {
  std::string fname;
  AstInterface::AstList params;
  AstNodeType returnType;
  AstNodePtr body;
  if (AstInterface :: IsFunctionDefinition( input, &fname, &params, (AstInterface::AstList*)0, &body, (AstInterface::AstTypeList*)0, &returnType)) {
if (body != AST_NULL)
 std::cerr << "body not empty:" << fname << "\n";
      POETCode* c = TUPLE4(STRING(fname), ROSE_2_POET_list(0,params,0), 
                 STRING(AstInterface::GetTypeName(returnType)), 
                 Ast2POET(body.get_ptr()));
      res = new POETCode_ext(input, c);
      POETAstInterface::set_Ast2POET(input,res);
      return res;
  } }   
*/

  AstInterface::AstList c = AstInterface::GetChildrenList(input);
  switch (input->variantT()) {
    case V_SgCastExp:
    case V_SgAssignInitializer:
      res = Ast2POET(c[0]); 
      POETAstInterface::set_Ast2POET(input, res); return res; 
    case V_SgDotExp:
     {
      POETCode* v1 = Ast2POET(c[1]);
      if (dynamic_cast<POETString*>(v1)->get_content() == "operator()") 
           return Ast2POET(c[0]);
      res = CODE_ACC("Bop",TUPLE3(STRING("."), Ast2POET(c[0]), v1)); return res;
     }
    case V_SgLessThanOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("<"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgSubtractOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("-"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgAddOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("+"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgMultiplyOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("*"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgDivideOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("/"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgAssignOp:
      res = CODE_ACC("Assign",PAIR(Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgFunctionCallExp:
      res = CODE_ACC("FunctionCall",PAIR(Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
  } 
  POETCode * c2 = 0; 
  if (tmp == 0) tmp=isSgTemplateInstantiationFunctionDecl(input);
   switch (c.size()) {
   case 0: break;
   case 1: c2 = Ast2POET(c[0]); break;
   case 2: c2 = PAIR(Ast2POET(c[0]),Ast2POET(c[1])); break;
   case 3: c2 = TUPLE3(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2])); break;
   case 4: c2 = TUPLE4(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2]),Ast2POET(c[3])); break;
   default: 
     //std::cerr << "too many children: " << c.size() << ":" << input->unparseToString() << "\n";
     c2 = EMPTY;
   }
  if (tmp == input) tmp = 0;
  res = new POETCode_ext(input, c2); 
  POETAstInterface::set_Ast2POET(input,res);
  return res;
}
/** Visits AST nodes in post-order. This is function-evaluation order. */
bool FunctionEvaluationOrderTraversal::evaluateSynthesizedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute, SynthesizedAttributesList)
{
    SgFunctionCallExp* functionCall = isSgFunctionCallExp(astNode);
    if (functionCall == NULL)
        return false; //dummy return value
    
    FunctionCallInfo functionCallInfo(functionCall);

    // Can't lift function call arguments from the following:
    // 1. For loop test and increment
    // 2. While loop test
    // 3. Do-While loop test
    // 4. Either arms of ternary op
    // 5. RHS of any short circuit expression
    // An alternative is to use comma operators and use assignemnt op as done by the original author. 
    // for(;foo(bar());) ==> T i; for(;i=bar();foo(i);)
    // But using assignement op is not always safe and it requires us to always have a default constructor
    // There is also an issue when the return type is a reference and we'll have to use & op to get a pointer
    // but if & op is overloaded we may not get the pointer.
    // Taking all these in view, I am simpling not lifting such expressions.
    
    if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_TEST ||
        parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT ||
        parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION ||
        parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION) {

        // ***** FOR UNSAFE TRANSFORMATION *******
        //Temporary variables should be declared before the stmt
        ROSE_ASSERT(isSgStatement(parentAttribute.currentScope));
        functionCallInfo.tempVarDeclarationLocation = isSgStatement(parentAttribute.currentScope);
        functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE;

        nonNormalizableFunctionCalls.push_back(functionCallInfo);
        return false;
    }

    // In future, if the function call is assured to be side effect free, then we can lift it from short circuit and conditional expressions
    if(parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM ||
       parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM ||
       parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS){
        
        if(!IsFunctionCallSideEffectFree(functionCall)) {
            
            // ***** FOR UNSAFE TRANSFORMATION *******
            //Temporary variables should be declared before the stmt
            ROSE_ASSERT(parentAttribute.lastStatement);
            functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement;
            functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE;

            nonNormalizableFunctionCalls.push_back(functionCallInfo);
            return false;
        }
    }
    
    //Handle for loops (being inside the body of a for loop doesn't need special handling)
    if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INIT)
    {
        SgForStatement* forLoop = isSgForStatement(parentAttribute.currentScope);
        ROSE_ASSERT(forLoop != NULL);
        //Temporary variables should be declared before the loop
        functionCallInfo.tempVarDeclarationLocation = forLoop;
        functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE;
    }
    else if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE)
    {
        //Assume we're in a basic block. Then just insert right before the current statement
        ROSE_ASSERT(parentAttribute.scopeStatus = FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement;
        functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE;
    }
    else
    {
        //Unhandled condition?!
        ROSE_ASSERT(false);
    }

    normalizableFunctionCalls.push_back(functionCallInfo);
    return false; //dummy return value
}
/** Visits AST nodes in pre-order */
FunctionCallInheritedAttribute FunctionEvaluationOrderTraversal::evaluateInheritedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute)
{
    FunctionCallInheritedAttribute result = parentAttribute;
    SgForStatement* parentForLoop = isSgForStatement(parentAttribute.currentScope);
    SgWhileStmt* parentWhileLoop = isSgWhileStmt(parentAttribute.currentScope);
    SgDoWhileStmt* parentDoWhileLoop = isSgDoWhileStmt(parentAttribute.currentScope);
    
    SgConditionalExp* parentSgConditionalExp = astNode->get_parent() ? isSgConditionalExp(astNode->get_parent()) : NULL;
    SgAndOp* parentAndOp =  astNode->get_parent() ?isSgAndOp(astNode->get_parent()) : NULL;
    SgOrOp* parentOrOp =  astNode->get_parent() ? isSgOrOp(astNode->get_parent()) : NULL;

    if (isSgForStatement(astNode))
        result.currentScope = isSgForStatement(astNode);
    else if (isSgWhileStmt(astNode))
        result.currentScope = isSgWhileStmt(astNode);
    else if (isSgDoWhileStmt(astNode))
        result.currentScope = isSgDoWhileStmt(astNode);
    //else if (isSgConditionalExp(astNode))
    //    result.currentScope = isSgConditionalExp(astNode);
    //else if (isSgAndOp(astNode))
    //    result.currentScope = isSgAndOp(astNode);
    //else if (isSgOrOp(astNode))
    //    result.currentScope = isSgOrOp(astNode);
    else if (isSgForInitStatement(astNode)) {
        ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INIT;
        ROSE_ASSERT(isSgForStatement(result.currentScope));
    } else if (parentForLoop != NULL && parentForLoop->get_test() == astNode) {
        ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_TEST;
    } else if (parentForLoop != NULL && parentForLoop->get_increment() == astNode) {
        ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT;
    } else if (parentWhileLoop != NULL && parentWhileLoop->get_condition() == astNode) {
        ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION;
    } else if (parentDoWhileLoop != NULL && parentDoWhileLoop->get_condition() == astNode) {
        ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION;
    } else if( parentSgConditionalExp != NULL && parentSgConditionalExp->get_true_exp() == astNode) {
        // if the scope status was safe, turn it into unsafe
        if (IsStatusSafe(result.scopeStatus))
            result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM;
    } else if(parentSgConditionalExp != NULL && parentSgConditionalExp->get_false_exp() == astNode) {
        // if the scope status was safe, turn it into unsafe
        if (IsStatusSafe(result.scopeStatus))
            result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM;
    } else if( parentOrOp != NULL && parentOrOp->get_rhs_operand () == astNode) {
        // if the scope status was safe, turn it into unsafe
        if (IsStatusSafe(result.scopeStatus))
            result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS;
    } else if( parentAndOp != NULL && parentAndOp->get_rhs_operand () == astNode)  {
        // if the scope status was safe, turn it into unsafe
        if (IsStatusSafe(result.scopeStatus))
            result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS;
    }
    
    //We can't insert variables before an expression statement that appears inside if(), switch, throw, etc.
    if (isSgExprStatement(astNode) && !isSgBasicBlock(astNode->get_parent())) {
        //We can't insert a variable declaration at these locations. Use the parent statement
    } else if (isSgStatement(astNode)) {
        result.lastStatement = isSgStatement(astNode);
    }

    return result;
}
Esempio n. 11
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;
}  
Esempio n. 12
0
bool
ClastToSage::insertPragmas(SgNode* root)
{
  // 1- Collect the list of outer-parallel loop iterators specified
  // by pluto, as given by the .pragmas file.  Grammar is: 1 line per
  // iterator, "ITER \SPACE PRAGMA STRING \ENDLNE"
  std::ifstream plutofile;
  plutofile.open(".pragmas");
  std::vector<std::string> ompLoopIterators;
  if (plutofile)
    {
      std::string iter;
      char junk[256];
      while (plutofile >> iter)
	{
	  ompLoopIterators.push_back(iter);
	  plutofile.getline(junk, 256);
	}
      plutofile.close();
    }

  // 2- Collect the list of inner-parallel loop iterators specified
  // by pluto, as given by the .vectorize file.  Grammar is: 1 line per
  // iterator, "ITER\ENDLINE"
  plutofile.open(".vectorize");
  std::vector<std::string> simdLoopIterators;
  if (plutofile)
    {
      std::string iter;
      char junk[256];
      while (plutofile >> iter)
	{
	  simdLoopIterators.push_back(iter);
	  plutofile.getline(junk, 256);
	}
      plutofile.close();
    }


  // 3- Collect all for loops.
  std::vector<SgNode*> forLoops =
    NodeQuery::querySubTree(root, V_SgForStatement);

  std::set<std::string>::const_iterator i;
  std::set<std::string> allIterators;
  allIterators.insert(ompLoopIterators.begin(), ompLoopIterators.end());
  allIterators.insert(simdLoopIterators.begin(), simdLoopIterators.end());
  // 4- Iterate on all dimensions to parallelize.
  for (i = allIterators.begin(); i != allIterators.end(); ++i)
    {
      SgName iterName(*i);
      SgSymbol* iterSymb = isSgScopeStatement(root)->lookup_symbol(iterName);

      if (iterSymb == NULL)
	{
	  // The loop iterator symbol does not exist. Typical case
	  // where the tile size exceeds the iteration domain size:
	  // there is only one parallel iteration, thus no loop,
	  // thus no iterator. Safely proceed to the next loop iterator.
	  continue;
	}

      std::vector<SgNode*>::const_iterator j;
      for (j = forLoops.begin(); j != forLoops.end(); ++j)
	{
	  SgForStatement* fornode = isSgForStatement(*j);
	  ROSE_ASSERT(fornode);
	  // Get the loop iterator.
	  SgVariableSymbol* forSymb =
	    SageTools::getLoopIteratorSymbol(fornode);
	  ROSE_ASSERT(forSymb);

	  if (forSymb == iterSymb)
	    {
	      std::string pragmaClause;

	      if (std::find(simdLoopIterators.begin(),
			    simdLoopIterators.end(),*i)
		  != simdLoopIterators.end())
		{
		  // This is a SIMDizable loop.
		  // For a vectorizable and parallelizable dimension,
		  // vectorization has precedence.
		  pragmaClause = "#pragma ivdep\n#pragma vector always";
		}
	      else
		if (std::find(ompLoopIterators.begin(), ompLoopIterators.end(),
			      *i) != ompLoopIterators.end())
		  {
		    // This is an OpenMP parallelizable loop.

		    // Collect all loop iterator names in the enclosed loops
		    std::vector<SgNode*> innerLoops =
		      NodeQuery::querySubTree(fornode->get_loop_body(),
					      V_SgForStatement);

		    // Create the pragma clause.
		    pragmaClause = "#pragma omp parallel for";
		    bool first = true;
		    std::vector<SgNode*>::const_iterator k;
		    std::set<SgVariableSymbol*> loopSymbols;
		    for (k = innerLoops.begin(); k != innerLoops.end(); ++k)
		      loopSymbols.insert(SageTools::getLoopIteratorSymbol
					 (isSgForStatement(*k)));
		    if (loopSymbols.size() > 0)
		      pragmaClause = pragmaClause + " private(";
		    std::set<SgVariableSymbol*>::const_iterator l;
		    for (l = loopSymbols.begin(); l != loopSymbols.end(); ++l)
		      {
			std::string iterName = (*l)->get_name().getString();
			if (first)
			  {
			    pragmaClause = pragmaClause + iterName;
			    first = false;
			  }
			else
			  pragmaClause = pragmaClause + ", " + iterName;

		      }
		    if (loopSymbols.size() > 0)
		      pragmaClause = pragmaClause + ")";
		  }
		else
		  {
		    // Should never occur.
		    ROSE_ASSERT(0);
		  }
	      // Annotate the for node with the pragma clause.
	      SageInterface::attachArbitraryText(fornode, pragmaClause,
						 PreprocessingInfo::before);

	      // Put loop lower bound and upper bound outside the loop
	      // (OpenMp does not like complex loop bounds).
	      /// LNP: FIXME: do it if it becomes needed.
	    }


	}
    }

  return true;

}
Esempio n. 13
0
MySynthesizedAttribute
MyTraversal::evaluateRewriteSynthesizedAttribute (
		SgNode* astNode,
		MyInheritedAttribute inheritedAttribute,
		SubTreeSynthesizedAttributes synthesizedAttributeList )
{
	MySynthesizedAttribute returnAttribute;

	
	switch(astNode->variantT())
	{

		case V_SgForStatement: {
				SgForStatement *forStat = isSgForStatement(astNode); 
				cout << " found V_SgForStatement " << printPosition(astNode) << "" <<  endl;
				for(size_t i=0; i<mAllFors.size(); i++) {
					if((mAllFors[i]->blocked)&&(astNode == mAllFors[i]->forStmt)) {
						ostringstream newFor;
						newFor << "for(";
						newFor << (*(forStat->get_init_stmt().begin()))->unparseToString();
						newFor << forStat->get_test_expr()->unparseToString() << ";" ;
						newFor << mAllFors[i]->varName << "+=" << mAllFors[i]->blockSize << ")\n" ;
						newFor << forStat->get_loop_body()->unparseToString();
						cout << " is blocked loop..." << endl;
						returnAttribute.replace( astNode, newFor.str() );
					}
				}
			} break;

		case V_SgVarRefExp: {
				cout << " found V_SgVarRefExp " << printPosition(astNode) << astNode->unparseToString() <<  endl;
				forBlockVector fors = inheritedAttribute.getForScopes();

				// replace variable occurrences in the loop kernel
				if(inheritedAttribute.getLoopKernel()) {
					for(size_t i=0;i<fors.size(); i++) {
						if( ( strcmp( astNode->unparseToString().c_str(), fors[i]->varName.c_str() )==0 ) &&
								( isSgVarRefExp(astNode)->get_type() == fors[i]->varType )
							) {
							string blockedVarName("blocked_");
							blockedVarName += fors[i]->varName;
							AstRestructure::unparserReplace( isSgVarRefExp(astNode), blockedVarName );
							cout << "   replacing with '"<<blockedVarName<<"' " << endl;
						}
					}
				}
			} break;

		default:
			break;
	} // node type

	bool synth = false;
	for( SubTreeSynthesizedAttributes::iterator i=synthesizedAttributeList.begin();
             i!= synthesizedAttributeList.end(); i++ ) {
                if( (*i).getVarRefFound() ) synth = true;
	}
	if( synth ) {
		returnAttribute.setVarRefFound( true );
		if(isSgStatement( astNode )) {
			cout << "   new statement " << printPosition(astNode) << " : '" << astNode->unparseToString() << "' " << endl;
			returnAttribute.setVarRefFound( false );
			//if(!isSgReturnStmt( astNode )) { // DEBUG, this should work!??!?
			returnAttribute.replace( astNode, astNode->unparseToString(), HighLevelCollectionTypedefs::LocalScope );
			//}
		}
	}

	if(isSgScopeStatement(astNode)) {
		// dont replace variable in higher scopes...
		if(mReplaceVariable > 0) {
			mReplaceVariable--;
			cerr << "end of scope " << mReplaceVariable << endl;
		}
	} 

	//if(astNode == mpLoopBody) { // FIXME why doesnt replace basic block work?
	if( (astNode->get_parent() == mpLoopBody)&&(inheritedAttribute.getLoopKernel()) ) {
		// we're back at the loop kernel block, now replace and insert new loops...
		insertTransformedLoopBody( astNode, returnAttribute, inheritedAttribute.getForScopes() );
	}

	return returnAttribute;
}
Esempio n. 14
0
// Functions required by the tree traversal mechanism
MyInheritedAttribute
MyTraversal::evaluateRewriteInheritedAttribute (
		SgNode* astNode,
		MyInheritedAttribute inheritedAttribute )
{
	MyInheritedAttribute returnAttribute = inheritedAttribute;

	switch(astNode->variantT())
	{

		case V_SgForStatement: {
				cout << " found V_SgForStatement " << printPosition(astNode) << "" <<  endl;
				SgForStatement *forStat = isSgForStatement(astNode); 

				forBlockInfo *inf = new forBlockInfo;
				inf->forStmt = forStat;
				SgInitializedName *varin = isSgInitializedName( forStat->get_traversalSuccessorContainer()[0] //for init
						->get_traversalSuccessorContainer()[0] // var decl
						->get_traversalSuccessorContainer()[0] // initialized name
						);
				assert( varin );
				inf->varName = varin->get_name().str();
				inf->varType = varin->get_type();
				inf->blocked = false;
				inf->blockSize = 0;

				returnAttribute.addForStatement( inf );
				mAllFors.push_back( inf );

				list<SgNode*> forList = NodeQuery::querySubTree( astNode, forStatementNodeQuery );
				if( (forList.size()==1) && // only the current loop?
						(returnAttribute.getForScopes().size()>1) ) {
					cerr << "   it is the innermost for loop " << endl;
					mpLoopBody = forStat->get_loop_body();
				}
			} break;

		default:
			break;
	}

	if(astNode == mpLoopBody) {
		bool loopsValid = true;
		
		// do some basic checks for validity
		forBlockVector fors = returnAttribute.getForScopes();
		for(size_t i=0;i<fors.size(); i++) {
			SgExpression *testExpr = fors[i]->forStmt->get_test_expr();
			SgExpression *incExpr  = fors[i]->forStmt->get_increment_expr();
			if(isSgPlusPlusOp(incExpr) ==NULL)  loopsValid = false;
			if(isSgLessThanOp(testExpr) ==NULL) loopsValid = false;
			else {
				if(! isSgVarRefExp(isSgLessThanOp(testExpr)->get_lhs_operand()) ) loopsValid = false;
			}
		}

		// this is the basic block of the innermost loop
		// only do trafos, if more than two nested loop nests, and we found the inner one
		if(loopsValid) {
			returnAttribute.setLoopKernel( true );
		} else {
			cout << " loop nest not valid, skipping transformation..." << endl;
		}
	}
	
	if(isSgScopeStatement(astNode)) {
		// dont replace variable in higher scopes...
		if(mReplaceVariable > 0) {
			mReplaceVariable++;
			cerr << "nested scope found, #" << mReplaceVariable << endl;
		}
	} 

	return returnAttribute;
}
Esempio n. 15
0
void getSgScopeStatement(SgScopeStatement* scopeStat) {
	VariantT var = scopeStat->variantT();
	std::string scopeStatStr = "";
	switch (var) {
		case V_SgBasicBlock:
			{
			getSgBasicBlock(isSgBasicBlock(scopeStat));
			break;
			}

		case V_SgCatchOptionStmt:
			{
			std::cout << "SgCatchOptionStmt is not yet implemented" << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgDoWhileStmt:
			{
			std::cout << "SgDoWhileStmt is not yet implemented" << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgForStatement:
			{
		//	std::cout << "SgForStatement is not yet implemented" << std::endl;
			#ifdef FORLOOPONCETHROUGH
			forOnceThrough(isSgForStatement(scopeStat));
				
			
			#else
			std::cout << "SgForStatement is not yet implemented" << std::endl;
			ROSE_ASSERT(false);
			#endif
			break;
			}

		case V_SgGlobal:
			{
			std::cout << "SgGlobal is not yet implemented" << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgIfStmt:
			{
			getSgIfStmt(isSgIfStmt(scopeStat));
			break;
			}

		case V_SgSwitchStatement:
			{
			std::cout << "SgSwitchStatement is not yet implemented" << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgWhileStmt:
			{
			std::cout << "SgWhileStmt is not yet implemented" << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgForAllStatement:

			{
			std::cout << "SgForAllStatement is not yet implemented" << std::endl; ;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgAssociateStatement:

			{
			std::cout << "SgAssociateStatement is not yet implemented" << std::endl; ;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgBlockDataStatement:

			{
			std::cout << "SgBlockDataStatement is not yet implemented" << std::endl; ;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgNamespaceDefinitionStatement:

			{
			std::cout << "SgNamespaceDefinitionStatement is not yet implemented" << std::endl; ;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgClassDefinition:
			{
			std::cout << "SgClassDefinition should not be found here! " << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgFunctionDefinition:
			{
			getSgFunctionDefinition(isSgFunctionDefinition(scopeStat));
			break;
			}

		case V_SgCAFWithTeamStatement:
			{
			std::cout << "SgCAFWithTeamStatement should not be found here! " << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgFortranDo:
			{
			std::cout << "SgFortranDo should not be found here! " << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgFortranNonblockedDo:
			{
			std::cout << "SgFortranNonblockedDo should not be found here! " << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgJavaForEachStatement:
			{
			std::cout << "SgJavaForEachStatement should not be found here! " << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgJavaLabelStatement:
			{
			std::cout << "SgJavaLabelStatement should not be found here! " << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		case V_SgUpcForAllStatement:
			{
			std::cout << "SgUpcForAllStatement should not be found here! " << std::endl;
			ROSE_ASSERT(false);
			break;
			}

		default:
			{
			std::cout << " Unknown node type!: " << scopeStat->class_name() << std::endl;
			ROSE_ASSERT(false);
			}
	}
	return;
}