Beispiel #1
0
// ******************************************
//              MAIN PROGRAM
// ******************************************
int
main( int argc, char * argv[] )
   {
  // Initialize and check compatibility. See rose::initialize
     ROSE_INITIALIZE;

  // Build the AST used by ROSE
     SgProject* project = frontend(argc,argv);
     assert(project != NULL);

     vector<SgType*> memberTypes;
     vector<string>  memberNames;

     string name = "a";
     for (int i = 0; i < 10; i++)
        {
          memberTypes.push_back(SgTypeInt::createType());
          name = "_" + name;
          memberNames.push_back(name);
        }

  // Build the initializer
     SgExprListExp* initializerList = new SgExprListExp(SOURCE_POSITION);
     initializerList->set_endOfConstruct(SOURCE_POSITION);
     SgAggregateInitializer* structureInitializer = new SgAggregateInitializer(SOURCE_POSITION,initializerList);
     structureInitializer->set_endOfConstruct(SOURCE_POSITION);

  // Build the data member initializers for the structure (one SgAssignInitializer for each data member)
     for (unsigned int i = 0; i < memberNames.size(); i++)
        {
       // Set initial value to "i"
          SgIntVal* value = new SgIntVal(SOURCE_POSITION,i);
          value->set_endOfConstruct(SOURCE_POSITION);
          SgAssignInitializer* memberInitializer = new SgAssignInitializer(SOURCE_POSITION,value);
          memberInitializer->set_endOfConstruct(SOURCE_POSITION);
          structureInitializer->append_initializer(memberInitializer);
          memberInitializer->set_parent(structureInitializer);
        }

  // Access the first file and add a struct with data members specified
     SgSourceFile* file = isSgSourceFile((*project)[0]);
     ROSE_ASSERT(file != NULL);
     SgVariableDeclaration* variableDeclaration = buildStructVariable(file->get_globalScope(),memberTypes,memberNames,"X","x",structureInitializer);
     file->get_globalScope()->prepend_declaration(variableDeclaration);
     variableDeclaration->set_parent(file->get_globalScope());

    AstTests::runAllTests(project);
  // Code generation phase (write out new application "rose_<input file name>")
     return backend(project);
   }
// Do finite differencing on one expression within one context.  The expression
// must be defined and valid within the entire body of root.  The rewrite rules
// are used to simplify expressions.  When a variable var is updated from
// old_value to new_value, an expression of the form (var, (old_value,
// new_value)) is created and rewritten.  The rewrite rules may either produce
// an arbitrary expression (which will be used as-is) or one of the form (var,
// (something, value)) (which will be changed to (var = value)).
void doFiniteDifferencingOne(SgExpression* e, 
                             SgBasicBlock* root,
                             RewriteRule* rules)
   {
     SgStatementPtrList& root_stmts = root->get_statements();
     SgStatementPtrList::iterator i;
     for (i = root_stmts.begin(); i != root_stmts.end(); ++i)
        {
          if (expressionComputedIn(e, *i))
               break;
        }
     if (i == root_stmts.end())
          return; // Expression is not used within root, so quit
     vector<SgVariableSymbol*> used_symbols = SageInterface::getSymbolsUsedInExpression(e);
     SgName cachename = "cache_fd__"; cachename << ++SageInterface::gensym_counter;
     SgVariableDeclaration* cachedecl = new SgVariableDeclaration(SgNULL_FILE, cachename, e->get_type(),0 /* new SgAssignInitializer(SgNULL_FILE, e) */);
     SgInitializedName* cachevar = cachedecl->get_variables().back();
     ROSE_ASSERT (cachevar);
     root->get_statements().insert(i, cachedecl);
     cachedecl->set_parent(root);
     cachedecl->set_definingDeclaration(cachedecl);
     cachevar->set_scope(root);
     SgVariableSymbol* sym = new SgVariableSymbol(cachevar);
     root->insert_symbol(cachename, sym);
     SgVarRefExp* vr = new SgVarRefExp(SgNULL_FILE, sym);
     vr->set_endOfConstruct(SgNULL_FILE);
     replaceCopiesOfExpression(e, vr, root);

     vector<SgExpression*> modifications_to_used_symbols;
     FdFindModifyingStatementsVisitor(used_symbols, modifications_to_used_symbols).go(root);

     cachedecl->addToAttachedPreprocessingInfo( 
          new PreprocessingInfo(PreprocessingInfo::CplusplusStyleComment,(string("// Finite differencing: ") + 
               cachename.str() + " is a cache of " + 
               e->unparseToString()).c_str(),"Compiler-Generated in Finite Differencing",0, 0, 0, PreprocessingInfo::before));

     if (modifications_to_used_symbols.size() == 0)
        {
          SgInitializer* cacheinit = new SgAssignInitializer(SgNULL_FILE, e);
          e->set_parent(cacheinit);
          cachevar->set_initializer(cacheinit);
          cacheinit->set_parent(cachevar);
        }
       else
        {
          for (unsigned int i = 0; i < modifications_to_used_symbols.size(); ++i)
             {
               SgExpression* modstmt = modifications_to_used_symbols[i];
#ifdef FD_DEBUG
               cout << "Updating cache after " << modstmt->unparseToString() << endl;
#endif
               SgExpression* updateCache = 0;
               SgVarRefExp* varref = new SgVarRefExp(SgNULL_FILE, sym);
               varref->set_endOfConstruct(SgNULL_FILE);
               SgTreeCopy tc;
               SgExpression* eCopy = isSgExpression(e->copy(tc));
               switch (modstmt->variantT())
                  {
                    case V_SgAssignOp:
                       {
                         SgAssignOp* assignment = isSgAssignOp(modstmt);
                         assert (assignment);
                         SgExpression* lhs = assignment->get_lhs_operand();
                         SgExpression* rhs = assignment->get_rhs_operand();
                         replaceCopiesOfExpression(lhs, rhs, eCopy);
                       }
                    break;

                    case V_SgPlusAssignOp:
                    case V_SgMinusAssignOp:
                    case V_SgAndAssignOp:
                    case V_SgIorAssignOp:
                    case V_SgMultAssignOp:
                    case V_SgDivAssignOp:
                    case V_SgModAssignOp:
                    case V_SgXorAssignOp:
                    case V_SgLshiftAssignOp:
                    case V_SgRshiftAssignOp:
                       {
                         SgBinaryOp* assignment = isSgBinaryOp(modstmt);
                         assert (assignment);
                         SgExpression* lhs = assignment->get_lhs_operand();
                         SgExpression* rhs = assignment->get_rhs_operand();
                         SgTreeCopy tc;
                         SgExpression* rhsCopy = isSgExpression(rhs->copy(tc));
                         SgExpression* newval = 0;
                         switch (modstmt->variantT())
                            {
#define DO_OP(op, nonassignment) \
                              case V_##op: { \
                                   newval = new nonassignment(SgNULL_FILE, lhs, rhsCopy); \
                                   newval->set_endOfConstruct(SgNULL_FILE); \
                              } \
                              break

                              DO_OP(SgPlusAssignOp, SgAddOp);
                              DO_OP(SgMinusAssignOp, SgSubtractOp);
                              DO_OP(SgAndAssignOp, SgBitAndOp);
                              DO_OP(SgIorAssignOp, SgBitOrOp);
                              DO_OP(SgMultAssignOp, SgMultiplyOp);
                              DO_OP(SgDivAssignOp, SgDivideOp);
                              DO_OP(SgModAssignOp, SgModOp);
                              DO_OP(SgXorAssignOp, SgBitXorOp);
                              DO_OP(SgLshiftAssignOp, SgLshiftOp);
                              DO_OP(SgRshiftAssignOp, SgRshiftOp);
#undef DO_OP

                              default: break;
                            }
                         assert (newval);
                         replaceCopiesOfExpression(lhs, newval, eCopy);
                       }
                    break;

                    case V_SgPlusPlusOp:
                       {
                         SgExpression* lhs = isSgPlusPlusOp(modstmt)->get_operand();
                         SgIntVal* one = new SgIntVal(SgNULL_FILE, 1);
                         one->set_endOfConstruct(SgNULL_FILE);
                         SgAddOp* add = new SgAddOp(SgNULL_FILE, lhs, one);
                         add->set_endOfConstruct(SgNULL_FILE);
                         lhs->set_parent(add);
                         one->set_parent(add);
                         replaceCopiesOfExpression(lhs,add,eCopy);
                            }
                    break;

                    case V_SgMinusMinusOp:
                       {
                         SgExpression* lhs = isSgMinusMinusOp(modstmt)->get_operand();
                         SgIntVal* one = new SgIntVal(SgNULL_FILE, 1);
                         one->set_endOfConstruct(SgNULL_FILE);
                         SgSubtractOp* sub = new SgSubtractOp(SgNULL_FILE, lhs, one);
                         sub->set_endOfConstruct(SgNULL_FILE);
                         lhs->set_parent(sub);
                         one->set_parent(sub);
                         replaceCopiesOfExpression(lhs,sub,eCopy);
                       }
                    break;

                    default:
                         cerr << modstmt->sage_class_name() << endl;
                         assert (false);
                         break;
                  }

#ifdef FD_DEBUG
            cout << "e is " << e->unparseToString() << endl;
            cout << "eCopy is " << eCopy->unparseToString() << endl;
#endif
               updateCache = doFdVariableUpdate(rules, varref, e, eCopy);
#ifdef FD_DEBUG
            cout << "updateCache is " << updateCache->unparseToString() << endl;
#endif
               if (updateCache)
                  {
                    ROSE_ASSERT(modstmt != NULL);
                    SgNode* ifp = modstmt->get_parent();
                    SgCommaOpExp* comma = new SgCommaOpExp(SgNULL_FILE, updateCache, modstmt);
                    modstmt->set_parent(comma);
                    updateCache->set_parent(comma);

                    if (ifp == NULL)
                       {
                         printf ("modstmt->get_parent() == NULL modstmt = %p = %s \n",modstmt,modstmt->class_name().c_str());
                         modstmt->get_startOfConstruct()->display("modstmt->get_parent() == NULL: debug");
                       }
                    ROSE_ASSERT(ifp != NULL);
#ifdef FD_DEBUG
                 cout << "New expression is " << comma->unparseToString() << endl;
                 cout << "IFP is " << ifp->sage_class_name() << ": " << ifp->unparseToString() << endl;
#endif
                    if (isSgExpression(ifp))
                       {
                         isSgExpression(ifp)->replace_expression(modstmt, comma);
                         comma->set_parent(ifp);
                       }
                      else
                       {
                      // DQ (12/16/2006): Need to handle cases that are not SgExpression (now that SgExpressionRoot is not used!)
                      // cerr << ifp->sage_class_name() << endl;
                      // assert (!"Bad parent type for inserting comma expression");
                         SgStatement* statement = isSgStatement(ifp);
                         if (statement != NULL)
                            {
#ifdef FD_DEBUG
                              printf ("Before statement->replace_expression(): statement = %p = %s modstmt = %p = %s \n",statement,statement->class_name().c_str(),modstmt,modstmt->class_name().c_str());
                              SgExprStatement* expresionStatement = isSgExprStatement(statement);
                              if (expresionStatement != NULL)
                                 {
                                   SgExpression* expression = expresionStatement->get_expression();
                                   printf ("expressionStatement expression = %p = %s \n",expression,expression->class_name().c_str());
                                 }
#endif
                              statement->replace_expression(modstmt, comma);
                              comma->set_parent(statement);
                            }
                           else
                            {
                              ROSE_ASSERT(ifp != NULL);
                              printf ("Error: parent is neither a SgExpression nor a SgStatement ifp = %p = %s \n",ifp,ifp->class_name().c_str());
                              ROSE_ASSERT(false);
                            }
                       }

#ifdef FD_DEBUG
                    cout << "IFP is now " << ifp->unparseToString() << endl;
#endif
                  }
             }
        }
   }