SgExpression* doFdVariableUpdate(
    RewriteRule* rules,
    SgExpression* cache,
    SgExpression* old_val /* Cannot be referenced in output tree w/o copying */,
    SgExpression* new_val)
   {
#ifdef FD_DEBUG
  cout << "Trying to convert from " << old_val->unparseToString() << " to " << new_val->unparseToString() << ", using cache " << cache->unparseToString() << endl;
#endif
     SgTreeCopy tc;
     SgExpression* old_valCopy = isSgExpression(old_val->copy(tc));
     ROSE_ASSERT (old_valCopy);
     SgCommaOpExp* innerComma = new SgCommaOpExp(SgNULL_FILE, old_valCopy, new_val);
     old_valCopy->set_parent(innerComma);
     new_val->set_parent(innerComma);
     SgExpression* expr = new SgCommaOpExp(SgNULL_FILE,cache,innerComma);
     cache->set_parent(expr);
     innerComma->set_parent(expr);
     // This is done so rewrite's expression replacement code will never find a
     // NULL parent for the expression being replaced
     SgExprStatement* dummyExprStatement =
       new SgExprStatement(SgNULL_FILE, expr);
     expr->set_parent(dummyExprStatement);
     SgNode* exprCopyForRewrite = expr;
     rewrite(rules, exprCopyForRewrite); // This might modify exprCopyForRewrite
     ROSE_ASSERT (isSgExpression(exprCopyForRewrite));
     expr = isSgExpression(exprCopyForRewrite);
     expr->set_parent(NULL);
     dummyExprStatement->set_expression(NULL);
     delete dummyExprStatement;
     SgExpression* expr2 = expr;
     ROSE_ASSERT (expr2);
     if (// The rewrite rules may have changed the form of expr to something other than a comma pair
        isSgCommaOpExp(expr2) &&
        isSgCommaOpExp(isSgCommaOpExp(expr2)->get_rhs_operand()))
        {
          SgExpression* cache2 = isSgCommaOpExp(expr2)->get_lhs_operand();
          SgCommaOpExp* rhs = isSgCommaOpExp(isSgCommaOpExp(expr2)->get_rhs_operand());
       // SgExpression* old_val2 = rhs->get_lhs_operand();
          SgExpression* new_val2 = rhs->get_rhs_operand();
       // return new SgAssignOp(SgNULL_FILE, cache2, new_val2);
          cache2->set_lvalue(true);
          SgAssignOp* assignmentOperator = new SgAssignOp(SgNULL_FILE, cache2, new_val2);
          cache2->set_parent(assignmentOperator);
          new_val2->set_parent(assignmentOperator);

#ifdef FD_DEBUG
          printf ("In doFdVariableUpdate(): assignmentOperator = %p \n",assignmentOperator);
#endif

          return assignmentOperator;
        }
       else
        {
          return expr2;
        }
   }
Example #2
0
     virtual void visit(SgNode* n)
        {
          SgReturnStmt* rs = isSgReturnStmt(n);
          if (rs)
             {
               // std::cout << "Converting return statement " << rs->unparseToString();
               // std::cout << " into possible assignment to " << where_to_write_answer->unparseToString();
               // std::cout << " and jump to " << label->get_name().getString() << std::endl;
               SgExpression* return_expr = rs->get_expression();
               SgBasicBlock* block = SageBuilder::buildBasicBlock();
            // printf ("Building IR node #1: new SgBasicBlock = %p \n",block);
               if (return_expr)
                  {
                    SgExpression* assignment = generateAssignmentMaybe(where_to_write_answer,return_expr);
                    if (where_to_write_answer)
                      where_to_write_answer->set_parent(assignment);
                    if (return_expr != assignment)
                      return_expr->set_parent(assignment);
                    SgStatement* assign_stmt = SageBuilder::buildExprStatement(assignment);
                    SageInterface::appendStatement(assign_stmt, block);
                  }

            // block->get_statements().push_back(new SgGotoStatement(SgNULL_FILE, label));
               SgGotoStatement* gotoStatement = new SgGotoStatement(SgNULL_FILE, label);
               gotoStatement->set_endOfConstruct(SgNULL_FILE);
               ROSE_ASSERT(n->get_parent() != NULL);
               SageInterface::appendStatement(gotoStatement, block);
               isSgStatement(n->get_parent())->replace_statement(rs, block);
               block->set_parent(n->get_parent());
               ROSE_ASSERT(gotoStatement->get_parent() != NULL);
             }
        }
Example #3
0
File: f2cArray.C Project: 8l/rose
void Fortran_to_C::linearizeArrayDeclaration(SgArrayType* originalArrayType)
{
  // Get dim_info
  SgExprListExp* dimInfo = originalArrayType->get_dim_info();
  // Get dim list
  SgExpressionPtrList dimExpressionPtrList = dimInfo->get_expressions();

  SgExpression* newDimExpr; 
  Rose_STL_Container<SgExpression*>::iterator j =  dimExpressionPtrList.begin();
  while(j != dimExpressionPtrList.end())
  {
    SgExpression* indexExpression = getFortranDimensionSize(*j);

    /*
      Total array size is equal to the multiplication of all individual dimension size.
    */
    if(j != dimExpressionPtrList.begin()){
        newDimExpr = buildMultiplyOp(newDimExpr, indexExpression);
    }
    else
    /*
      If it's first dimension, array size is just its first dimension size.
    */
    {
      newDimExpr = indexExpression;
    }
    ++j;
  }
  // calling set_index won't replace the default index expression.  I have to delete the default manually.
  removeList.push_back(originalArrayType->get_index());
  originalArrayType->set_index(newDimExpr);
  newDimExpr->set_parent(originalArrayType);
  originalArrayType->set_rank(1); 
}
void replaceCopiesOfExpression(SgExpression* src, SgExpression* tgt, 
                               SgNode* root) {
#ifdef FD_DEBUG
  cout << "replaceCopiesOfExpression: src = " << src->unparseToString() << ", tgt = " << tgt->unparseToString() << ", root = " << root->unparseToString() << endl;
#endif
  vector<SgExpression*> copies_of_src;
#ifdef FD_DEBUG
  cout << "---" << endl;
#endif
  FdFindCopiesVisitor(src, copies_of_src).traverse(root, preorder);
#ifdef FD_DEBUG
  cout << copies_of_src.size() << " copy(ies) found." << endl;
#endif
  for (unsigned int i = 0; i < copies_of_src.size(); ++i) {
    SgTreeCopy tc;
    SgExpression* copy = isSgExpression(tgt->copy(tc));
    SgExpression* parent = isSgExpression(copies_of_src[i]->get_parent());
    assert (parent);
    parent->replace_expression(copies_of_src[i], copy);
    copy->set_parent(parent);
  }
#ifdef FD_DEBUG
  cout << "result is " << root->unparseToString() << endl;
#endif
}
/*
Given a node in the AST, it replaces all function calls with the corresponding expression from the fct2Var mapping.
Since we traverse in order of function evaluation, all nodes that are lower in the subtree are supposed to
have been mapped, since they have already appeared in the list. Also, we only replace the shallowest level of
function calls in the surrent subtree, since we assume that replaceFunctionCallsInExpression  has already been called
for each of the subtrees rooted at the shallowest function calls lower than the current node:

E.g.: f(g(h(i))) + 5
has the AST:
     +
    / \
  fc1  5
  / \
 f  fc2
    / \
   g  fc3 
      / \
     h   i
where fc? represents an SgFunctionCallExpression. Order of function evaluation is h(i), g(_), f(_).

Calling 'replaceFunctionCallsInExpression' on '+' will generate
                     temp_var + 5
but calling the same function on 'fc2' will generate
                     f(temp_var) + 5
*/
void
FunctionCallNormalization::replaceFunctionCallsInExpression( SgNode *root,
                                                             map<SgFunctionCallExp *, SgExpression *> fct2Var )
   {
     if ( !root )
       return;

     if ( NodeQuery::querySubTree( root, V_SgFunctionCallExp ).size() > 0 )
       {
         list<SgNode *> toVisit;
         toVisit.push_back( root );

         while ( !toVisit.empty() )
           {
             SgNode *crt = toVisit.front();

             // will visit every node above an function call exp, but not below
             // also, we will replace function call expressions found
             if ( !isSgFunctionCallExp( crt ) )
               {
                 vector<SgNode *> succ = ( crt )->get_traversalSuccessorContainer();
                 for ( vector<SgNode *>::iterator succIt = succ.begin(); succIt != succ.end(); succIt++ )
                   if ( isSgNode ( *succIt ) )
                     toVisit.push_back( *succIt );
               }
             else
               {
                 SgFunctionCallExp *call = isSgFunctionCallExp( crt );
                 ROSE_ASSERT ( call );
                 
                 map<SgFunctionCallExp *, SgExpression *>::iterator mapIter;
                 mapIter = fct2Var.find( call );
                 if ( mapIter == fct2Var.end() )
                   cout << "NOT FOUND " << call->unparseToString() << "\t" << call << "\n";

                 // a mapping for function call exps in the subtree must already exist ( postorder traversal )
                 ROSE_ASSERT ( mapIter != fct2Var.end() && mapIter->second );

                 // duplicate the variable
                 SgTreeCopy treeCopy;
                 SgExpression *scnd = mapIter->second;
                 ROSE_ASSERT ( isSgExpression( scnd ) );
                 SgExpression *newVar = isSgExpression( scnd->copy( treeCopy ) );
                 ROSE_ASSERT ( newVar );

                 SgExpression *parent = isSgExpression( call->get_parent() );
                 ROSE_ASSERT ( parent );

                 // replace the node in the AST
                 newVar->set_parent( parent );
                 int k = parent->replace_expression( call, newVar );
                 ROSE_ASSERT ( k == 1 );
                 delete call;
               }
             toVisit.pop_front();
           }
       }
   }
Example #6
0
    virtual void visit(SgNode* n) {
        if (isSgBasicBlock(n)) {
            SgBasicBlock* bb = isSgBasicBlock(n);
            SgStatementPtrList& stmts = bb->get_statements();
            size_t initi;
            for (size_t decli = 0; decli < stmts.size(); ++decli) {
                if (isSgVariableDeclaration(stmts[decli])) {
                    SgVariableDeclaration* decl = isSgVariableDeclaration(stmts[decli]);
                    SgInitializedNamePtrList& vars = decl->get_variables();
                    for (size_t vari = 0; vari != vars.size(); ++vari) {
                        SgInitializedName* in = vars[vari];
                        if (in->get_initializer() == 0) {
                            bool used = false;
                            for (initi = decli + 1; initi < stmts.size();
                                    used |= containsVariableReference(stmts[initi], in),
                                    ++initi) {
                                SgExprStatement* initExprStmt = isSgExprStatement(stmts[initi]);
                                if (initExprStmt) {
                                    SgExpression* top = initExprStmt->get_expression();
                                    if (isSgAssignOp(top)) {
                                        SgVarRefExp* vr = isSgVarRefExp(isSgAssignOp(top)->get_lhs_operand());
                                        ROSE_ASSERT(isSgAssignOp(top) != NULL);
                                        SgExpression* newinit = isSgAssignOp(top)->get_rhs_operand();
                                        if (!used && vr && vr->get_symbol()->get_declaration() == in) {
                                            ROSE_ASSERT(newinit != NULL);
                                            // printf ("MoveDeclarationsToFirstUseVisitor::visit(): newinit = %p = %s \n",newinit,newinit->class_name().c_str());
                                            ROSE_ASSERT(newinit->get_type() != NULL);
                                            SgAssignInitializer* i = new SgAssignInitializer(SgNULL_FILE,newinit,newinit->get_type());
                                            i->set_endOfConstruct(SgNULL_FILE);
                                            // printf ("Built a SgAssignInitializer #1 \n");
                                            vars[vari]->set_initializer(i);
                                            stmts[initi] = decl;
                                            newinit->set_parent(i);

                                            // DQ (6/23/2006): Set the parent and file_info pointers
                                            // printf ("Setting parent of i = %p = %s to parent = %p = %s \n",i,i->class_name().c_str(),in,in->class_name().c_str());
                                            i->set_parent(in);
                                            ROSE_ASSERT(i->get_parent() != NULL);

                                            i->set_file_info(new Sg_File_Info(*(newinit->get_file_info())));
                                            ROSE_ASSERT(i->get_file_info() != NULL);

                                            // Assumes only one var per declaration FIXME
                                            ROSE_ASSERT (vars.size() == 1);
                                            stmts.erase(stmts.begin() + decli);
                                            --decli; // To counteract ++decli in loop header
                                            break; // To get out of initi loop
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
// Propagate definitions of a variable to its uses.
// Assumptions: var is only assigned at the top level of body
//              nothing var depends on is assigned within body
// Very simple algorithm designed to only handle simplest cases
void simpleUndoFiniteDifferencingOne(SgBasicBlock* body, SgExpression* var)
   {
     SgExpression* value = 0;
     SgStatementPtrList& stmts = body->get_statements();
     vector<SgStatement*> stmts_to_remove;

     for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i)
        {
       // cout << "Next statement: value = " << (value ? value->unparseToString() : "(null)") << endl;
       // cout << (*i)->unparseToString() << endl;
          if (isSgExprStatement(*i) && isSgAssignOp(isSgExprStatement(*i)->get_expression()))
             {
               SgAssignOp* assignment = isSgAssignOp(isSgExprStatement(*i)->get_expression());
            // cout << "In assignment statement " << assignment->unparseToString() << endl;
               if (value)
                    replaceCopiesOfExpression(var, value, assignment->get_rhs_operand());
               if (isSgVarRefExp(assignment->get_lhs_operand()) && isSgVarRefExp(var))
                  {
                    SgVarRefExp* vr = isSgVarRefExp(assignment->get_lhs_operand());
                    if (vr->get_symbol()->get_declaration() == isSgVarRefExp(var)->get_symbol()->get_declaration())
                       {
                         value = assignment->get_rhs_operand();
                         stmts_to_remove.push_back(*i);
                       }
                  }
             }
            else
             {
               if (value)
                    replaceCopiesOfExpression(var, value, *i);
             }
        }

     for (vector<SgStatement*>::iterator i = stmts_to_remove.begin(); i != stmts_to_remove.end(); ++i) {
          stmts.erase(std::find(stmts.begin(), stmts.end(), *i));
     }

     if (value)
        {
       // DQ (12/17/2006): Separate out the construction of the SgAssignOp from the SgExprStatement to support debugging and testing.
       // stmts.push_back(new SgExprStatement(SgNULL_FILE, new SgAssignOp(SgNULL_FILE, var, value)));
          var->set_lvalue(true);
          SgAssignOp* assignmentOperator = new SgAssignOp(SgNULL_FILE, var, value);
          var->set_parent(assignmentOperator);
          value->set_parent(assignmentOperator);

          printf ("In simpleUndoFiniteDifferencingOne(): assignmentOperator = %p \n",assignmentOperator);

       // DQ: Note that the parent of the SgExprStatement will be set in AST post-processing (or it should be).
          SgExprStatement* es = new SgExprStatement(SgNULL_FILE, assignmentOperator);
          assignmentOperator->set_parent(es);
          stmts.push_back(es);
          es->set_parent(body);
        }
   }
Example #8
0
/// \brief   replace old with repl, and delete subtree rooted in old.
/// \return  old's operand
static
SgExpression& extractOperand(SgUnaryOp& old)
{
  SgExpression* op = old.get_operand();
  SgExpression* emptydummy = SB::buildIntVal(0);

  SI::replaceExpression(op, emptydummy, keep_old_tree);

  op->set_parent(NULL);
  return *op;
}
Example #9
0
File: f2cArray.C Project: 8l/rose
void Fortran_to_C::translateArrayDeclaration(SgArrayType* originalArrayType)
{
  // Get dim_info
  SgExprListExp* dimInfo = originalArrayType->get_dim_info();
  // Get dim list
  SgExpressionPtrList dimExpressionPtrList = dimInfo->get_expressions();
  // Get array base_type
  SgType* baseType = originalArrayType->get_base_type();

  Rose_STL_Container<SgExpression*>::iterator j =  dimExpressionPtrList.begin();
  SgExpression* indexExpression = getFortranDimensionSize(*j);
  //std::cout << "array rank:" << originalArrayType->get_rank() << std::endl;
  if(originalArrayType->get_rank() == 1)
  {
    originalArrayType->set_base_type(baseType);
    originalArrayType->set_index(indexExpression);
    indexExpression->set_parent(originalArrayType);
    constantFolding(indexExpression);
  }
  else
  {
    SgArrayType* newType = buildArrayType(baseType,indexExpression);
    baseType->set_parent(newType);
    j = j + 1;
    for(; j< (dimExpressionPtrList.end()-1); ++j)
    {
      indexExpression = getFortranDimensionSize(*j);
      baseType = newType;
      newType = buildArrayType(baseType,indexExpression);
      baseType->set_parent(newType);
    }
    j = dimExpressionPtrList.end()-1;
    indexExpression = getFortranDimensionSize(*j);
    originalArrayType->set_base_type(newType);
    originalArrayType->set_index(indexExpression);
    indexExpression->set_parent(originalArrayType);
  }
}
Example #10
0
// Do partial redundancy elimination, looking for copies of one expression expr
// within the basic block root.  A control flow graph for root must be provided
// in cfg, with a map from nodes to their statements in node_statements, a map
// from edges to their CFG edge types in edge_type, and a map from edges to
// their insertion points in edge_insertion_point.  The algorithm used is that
// of Paleri, Srikant, and Shankar ("Partial redundancy elimination: a simple,
// pragmatic, and provably correct algorithm", Science of Computer Programming
// 48 (2003) 1--20).
void PRE::partialRedundancyEliminationOne( SgExpression* expr, SgBasicBlock* root, const myControlFlowGraph& cfg)
{
    // SgBasicBlock* myFunctionBody = getFunctionDefinition(expr)->get_body();

    // DQ (3/16/2006): Added assertions
    ROSE_ASSERT(expr != NULL);
    ROSE_ASSERT(root != NULL);

    vector<SgVariableSymbol*> symbols_in_expression = SageInterface::getSymbolsUsedInExpression(expr);

    if (anyOfListPotentiallyModifiedIn(symbols_in_expression, expr))
    {
        // This expression updates its own arguments, and so is not idempotent
        // Return immediately
        return;
    }

    // Simple or not user-definable expressions
    if (isSgVarRefExp(expr)) return;
    if (isSgValueExp(expr)) return;
    if (isSgFunctionRefExp(expr)) return;
    if (isSgExprListExp(expr)) return;
    if (isSgInitializer(expr)) return;
#if 0
    if ( (isSgAddOp(expr) || isSgSubtractOp(expr)) &&
            (isSgVarRefExp(isSgBinaryOp(expr)->get_lhs_operand()) ||
             isSgValueExp(isSgBinaryOp(expr)->get_lhs_operand())) &&
            (isSgVarRefExp(isSgBinaryOp(expr)->get_rhs_operand()) ||
             isSgValueExp(isSgBinaryOp(expr)->get_rhs_operand())))
        return;
#endif

    // Expressions which do not keep a consistent value each time they are used
    if (!expressionTreeEqual(expr, expr))
        return;

    // cerr << "Trying to do PRE using expression " << expr->unparseToString() << " whose type is " << expr->sage_class_name() << endl;

    VertexIter i   = cfg.graph.vertices().begin(),
               end = cfg.graph.vertices().end();

    // cerr << "CFG has " << distance(i, end) << " nodes" << endl;

    bool needToMakeCachevar = false;
    set<SgNode*> replacements;
    vector<pair<SgNode*, bool /* before */> > insertions;

    vector<bool> transp(cfg.graph.vertices().size()),
           comp(cfg.graph.vertices().size()),
           antloc(cfg.graph.vertices().size());

    vector<SgNode*> first_computation(cfg.graph.vertices().size()),
           last_computation(cfg.graph.vertices().size());

    // Set values of local node properties
    for (i = cfg.graph.vertices().begin(); i != end; ++i)
    {
        const vector<SgNode*>& stmts = cfg.node_statements[*i];

        // Precompute test values for each statement
        vector<bool> argumentsModifiedInStatement(stmts.size());
        vector<int> expressionComputedInStatement(stmts.size());
        for (unsigned int j = 0; j < stmts.size(); ++j)
        {
            if (anyOfListPotentiallyModifiedIn(symbols_in_expression, stmts[j]))
                argumentsModifiedInStatement[j] = true;
            expressionComputedInStatement[j] = countComputationsOfExpressionIn(expr, stmts[j]);
        }

        // Compute transp
        transp[*i] = true;
        for (unsigned int j = 0; j < stmts.size(); ++j)
            if (argumentsModifiedInStatement[j])
                transp[*i] = false;

        // Compute comp and do local redundancy elimination
        comp[*i] = false;
        SgNode* firstComputationInChain = 0;
        bool needToInsertComputation = false;
        bool computationInsertedOrUsed = false;
        // cout << "In node " << *i << endl;
        for (unsigned int j = 0; j < stmts.size(); ++j)
        {
            // cout << "In stmt " << j << ", expressionComputedInStatement = " << expressionComputedInStatement[j]
            //      << ", argumentsModifiedInStatement = " << argumentsModifiedInStatement[j] << endl;
            if (expressionComputedInStatement[j] && !argumentsModifiedInStatement[j] && comp[*i] /* from last iter */)
            {
                // Do local redundancy elimination
                if (firstComputationInChain && needToInsertComputation)
                {
                    insertions.push_back(make_pair(firstComputationInChain, true));
                    replacements.insert(firstComputationInChain);
                    needToInsertComputation = false;
                }
                replacements.insert(stmts[j]);
                computationInsertedOrUsed = true;
                needToMakeCachevar = true;
            }
            if (expressionComputedInStatement[j])
            {
                comp[*i] = true;
                if (!firstComputationInChain)
                {
                    firstComputationInChain = stmts[j];
                    needToInsertComputation = true;
                    if (expressionComputedInStatement[j] >= 2)
                    {
                        insertions.push_back(make_pair(stmts[j], true));
                        needToMakeCachevar = true;
                        needToInsertComputation = false;
                        computationInsertedOrUsed = true;
                        replacements.insert(stmts[j]);
                    }
                }
                last_computation[*i] = stmts[j];
            }
            if (argumentsModifiedInStatement[j])
            {
                comp[*i] = false; // Must come after expressionComputedInStatement check
                firstComputationInChain = 0;
                needToInsertComputation = false;
            }
        }

        assert (!computationInsertedOrUsed || needToMakeCachevar);

        // Compute antloc
        antloc[*i] = false;
        for (unsigned int j = 0; j < stmts.size(); ++j)
        {
            if (expressionComputedInStatement[j] && !argumentsModifiedInStatement[j])
            {
                antloc[*i] = true;
                first_computation[*i] = stmts[j];
                break;
            }
            if (argumentsModifiedInStatement[j])
            {
                antloc[*i] = false;
                break;
            }
        }
    }

// #define PRINT_PROPERTY(p) // for (i = cfg.graph.vertices().begin(); i != end; ++i) if (p[*i]) cerr << #p ": " << *i << endl;
#define PRINT_PROPERTY(p) // for (i = cfg.graph.vertices().begin(); i != end; ++i) if (p[*i]) cerr << #p ": " << *i << endl;
    PRINT_PROPERTY(transp);
    PRINT_PROPERTY(comp);
    PRINT_PROPERTY(antloc);

    int (simpleGraph::*source_ptr)(int) const = &simpleGraph::source;
    int (simpleGraph::*target_ptr)(int) const = &simpleGraph::target;

    vector<bool> avin(cfg.graph.vertices().size(), true);
    vector<bool> avout(cfg.graph.vertices().size(), true);
    FIXPOINT_BEGIN(cfg)
    FIXPOINT_OUTPUT_BEGIN(avin, cfg);
    FIXPOINT_OUTPUT_BEGIN(avout, cfg);
    avin[v] = accumulate_neighbors(cfg, v, avout,cfg.graph.in_edges(v),&simpleGraph::source, logical_and<bool>(), true, false);
    avout[v] = comp[v] || (avin[v] && transp[v]);
    FIXPOINT_OUTPUT_END(avout, <=, cfg);
    FIXPOINT_OUTPUT_END(avin, <=, cfg);
    FIXPOINT_END(cfg, out_edges, OutEdgeIter)

    PRINT_PROPERTY(avin);
    PRINT_PROPERTY(avout);

    vector<bool> antin(cfg.graph.vertices().size(), true);
    vector<bool> antout(cfg.graph.vertices().size(), true);
    FIXPOINT_BEGIN(cfg)
    FIXPOINT_OUTPUT_BEGIN(antin, cfg);
    FIXPOINT_OUTPUT_BEGIN(antout, cfg);
    antout[v] = accumulate_neighbors(cfg, v, antin, cfg.graph.out_edges(v), target_ptr, logical_and<bool>(), true, false);
    antin[v] = antloc[v] || (antout[v] && transp[v]);
    FIXPOINT_OUTPUT_END(antout, <=, cfg);
    FIXPOINT_OUTPUT_END(antin, <=, cfg);
    FIXPOINT_END(cfg, in_edges, InEdgeIter)

    PRINT_PROPERTY(antin);
    PRINT_PROPERTY(antout);

    vector<bool> safein(cfg.graph.vertices().size()), safeout(cfg.graph.vertices().size());

    for (i = cfg.graph.vertices().begin(); i != end; ++i)
    {
        safein[*i] = avin[*i] || antin[*i];
        safeout[*i] = avout[*i] || antout[*i];
    }

    PRINT_PROPERTY(safein);
    PRINT_PROPERTY(safeout);

    vector<bool> spavin(cfg.graph.vertices().size(), false);
    vector<bool> spavout(cfg.graph.vertices().size(), false);
    FIXPOINT_BEGIN(cfg)
    FIXPOINT_OUTPUT_BEGIN(spavin, cfg);
    FIXPOINT_OUTPUT_BEGIN(spavout, cfg);
    spavin[v] = safein[v] && accumulate_neighbors(cfg, v, spavout, cfg.graph.in_edges(v), source_ptr, logical_or<bool>(), false, false);
    spavout[v] = safeout[v] && (comp[v] || (spavin[v] && transp[v]));
    FIXPOINT_OUTPUT_END(spavout, >=, cfg);
    FIXPOINT_OUTPUT_END(spavin, >=, cfg);
    FIXPOINT_END(cfg, out_edges, OutEdgeIter)

    PRINT_PROPERTY(spavin);
    PRINT_PROPERTY(spavout);

    vector<bool> spantin(cfg.graph.vertices().size(), false);
    vector<bool> spantout(cfg.graph.vertices().size(), false);
    FIXPOINT_BEGIN(cfg)
    FIXPOINT_OUTPUT_BEGIN(spantin, cfg);
    FIXPOINT_OUTPUT_BEGIN(spantout, cfg);
    spantout[v] = safeout[v] && accumulate_neighbors(cfg, v, spantin, cfg.graph.out_edges(v), target_ptr, logical_or<bool>(), false, false);
    spantin[v] = safein[v] && (antloc[v] || (spantout[v] && transp[v]));
    FIXPOINT_OUTPUT_END(spantout, >=, cfg);
    FIXPOINT_OUTPUT_END(spantin, >=, cfg);
    FIXPOINT_END(cfg, in_edges, InEdgeIter)

    PRINT_PROPERTY(spantin);
    PRINT_PROPERTY(spantout);
#undef PRINT_PROPERTY

    vector<bool> node_insert(cfg.graph.vertices().size());
    vector<bool> replacef(cfg.graph.vertices().size());
    vector<bool> replacel(cfg.graph.vertices().size());

    // printf ("Intermediate test 1: needToMakeCachevar = %s \n",needToMakeCachevar ? "true" : "false");

    for (i = cfg.graph.vertices().begin(); i != end; ++i)
    {
        node_insert[*i] = comp[*i] && spantout[*i] && (!transp[*i] || !spavin[*i]);
        replacef[*i] = antloc[*i] && (spavin[*i] || (transp[*i] && spantout[*i]));
        replacel[*i] = comp[*i] && (spantout[*i] || (transp[*i] && spavin[*i]));

        if (node_insert[*i])
        {
            needToMakeCachevar = true;
            insertions.push_back(make_pair(last_computation[*i], true));
            // cerr << "Insert computation of " << expr->unparseToString() << " just before last computation in " << *i << endl;
        }

        if (replacef[*i])
        {
            needToMakeCachevar = true;
            replacements.insert(first_computation[*i]);
            // cerr << "Replace first computation of " << *i << endl;
        }

        if (replacel[*i])
        {
            needToMakeCachevar = true;
            replacements.insert(last_computation[*i]);
            // cerr << "Replace last computation of " << *i << endl;
        }
    }

    vector<bool> edge_insert(cfg.graph.edges().size());

    // printf ("Intermediate test 2: needToMakeCachevar = %s \n",needToMakeCachevar ? "true" : "false");

    EdgeIter j = cfg.graph.edges().begin(), jend = cfg.graph.edges().end();
    for (; j != jend; ++j)
    {
        edge_insert[*j] = !spavout[cfg.graph.source(*j)] && spavin[cfg.graph.target(*j)] && spantin[cfg.graph.target(*j)];

        // printf ("edge_insert[*j] = %s \n",edge_insert[*j] ? "true" : "false");
        if (edge_insert[*j])
        {
            needToMakeCachevar = true;
            // cerr << "Insert computation of " << expr->unparseToString() << " on edge from "
            //      << cfg.graph.source(*j) << " to " << cfg.graph.target(*j) << endl;
        }
    }

    // printf ("Before final test: needToMakeCachevar = %s \n",needToMakeCachevar ? "true" : "false");

    // Add cache variable if necessary
    SgVarRefExp* cachevar = 0;
    if (needToMakeCachevar)
    {
        SgName cachevarname = "cachevar__";
        cachevarname << ++SageInterface::gensym_counter;

        // printf ("Building variable name = %s \n",cachevarname.str());

        SgType* type = expr->get_type();
        if (isSgArrayType(type))
            type = new SgPointerType(isSgArrayType(type)->get_base_type());
        assert (SageInterface::isDefaultConstructible(type));
        // FIXME: assert (isAssignable(type));
        SgVariableDeclaration* decl = new SgVariableDeclaration(SgNULL_FILE, cachevarname, type, NULL);
        decl->set_definingDeclaration(decl);
        SgInitializedName* initname = decl->get_variables().back();

        // DQ (10/5/2007): Added an assertion.
        ROSE_ASSERT(initname != NULL);

        decl->addToAttachedPreprocessingInfo(
            new PreprocessingInfo(PreprocessingInfo::CplusplusStyleComment,
                                  (string("// Partial redundancy elimination: ") + cachevarname.str() +
                                   " is a cache of " + expr->unparseToString()).c_str(),
                                  "Compiler-Generated in PRE", 0, 0, 0, PreprocessingInfo::before));
        SgVariableSymbol* cachevarsym = new SgVariableSymbol(initname);
        decl->set_parent(root);

        // DQ (10/5/2007): Added scope (suggested by Jeremiah).
        initname->set_scope(root);

        root->get_statements().insert(root->get_statements().begin(),decl);

        root->insert_symbol(cachevarname, cachevarsym);
        cachevar = new SgVarRefExp(SgNULL_FILE, cachevarsym);
        cachevar->set_endOfConstruct(SgNULL_FILE);
    }

    // Do expression computation replacements
    for (set<SgNode*>::iterator i = replacements.begin(); i != replacements.end(); ++i)
    {
        ReplaceExpressionWithVarrefVisitor(expr, cachevar).traverse(*i, postorder);
    }

    // Do edge insertions
    // int count = 0;
    bool failAtEndOfFunction = false;
    for (j = cfg.graph.edges().begin(); j != jend; ++j)
    {
        // printf ("Build the insertion list! count = %d \n",count++);
        if (edge_insert[*j])
        {
#if 0
            // DQ (3/13/2006): Compiler warns that "src" is unused, so I have commented it out!
            Vertex src = cfg.graph.source(*j), tgt = cfg.graph.target(*j);
            cerr << "Doing insertion between " << src << " and " << tgt << endl;
#endif
            pair<SgNode*, bool> insert_point = cfg.edge_insertion_point[*j];
            if (insert_point.first)
            {
                insertions.push_back(insert_point);
            }
            else
            {
                // DQ (3/16/2006): This is a visited when we fixup the NULL pointer to the initializer in a SgForStatment.
                cerr << "Warning: no insertion point found" << endl; //FIXME was assert
                printf ("Need to figure out what to do here! cfg.edge_insertion_point[*j] = %p \n",&(cfg.edge_insertion_point[*j]));

                failAtEndOfFunction = true;
                ROSE_ASSERT(false);
            }
        }
    }

    // Do within-node insertions
    // printf ("At start of loop: insertions.size() = %zu \n",insertions.size());
    for (vector<pair<SgNode*, bool> >::iterator i = insertions.begin(); i != insertions.end(); ++i)
    {
        SgTreeCopy tc1, tc2;
        SgVarRefExp* cachevarCopy = isSgVarRefExp(cachevar->copy(tc1));
        ROSE_ASSERT (cachevarCopy);
        cachevarCopy->set_lvalue(true);
        SgExpression* operation = new SgAssignOp(SgNULL_FILE, cachevarCopy, isSgExpression(expr->copy(tc2)));
#if 0
        printf ("Inside of loop: insertions.size() = %zu \n",insertions.size());
        printf ("\n\ni->first = %p = %s = %s \n",i->first,i->first->class_name().c_str(),i->first->unparseToString().c_str());
        printf ("operation = %p = %s = %s \n",operation,operation->class_name().c_str(),operation->unparseToString().c_str());
#endif
        if (isSgExpression(i->first) && !i->second)
        {
            SgNode* ifp = i->first->get_parent();
            SgCommaOpExp* comma = new SgCommaOpExp(SgNULL_FILE, isSgExpression(i->first), operation);
            operation->set_parent(comma);
            comma->set_parent(ifp);
            i->first->set_parent(comma);
            if (isSgForStatement(ifp))
            {
                isSgForStatement(ifp)->set_increment(comma);
            }
            else if (isSgBinaryOp(ifp) && isSgBinaryOp(ifp)->get_lhs_operand() == i->first)
            {
                isSgBinaryOp(ifp)->set_lhs_operand(comma);
            }
            else if (isSgBinaryOp(ifp) && isSgBinaryOp(ifp)->get_rhs_operand() == i->first)
            {
                isSgBinaryOp(ifp)->set_rhs_operand(comma);
            }
            else if (isSgUnaryOp(ifp) && isSgUnaryOp(ifp)->get_operand() == i->first)
            {
                isSgUnaryOp(ifp)->set_operand(comma);
            }
            else
            {
                cerr << ifp->sage_class_name() << endl;
                assert (!"Bad parent type for inserting comma expression");
            }
        }
        else
        {
            SgStatement* the_computation = new SgExprStatement(SgNULL_FILE, operation);
            operation->set_parent(the_computation);
            // printf ("In pre.C: the_computation = %p = %s \n",the_computation,the_computation->class_name().c_str());

            if (isSgBasicBlock(i->first) && i->second)
            {
                isSgBasicBlock(i->first)->get_statements().insert(isSgBasicBlock(i->first)->get_statements().begin(),the_computation);
                the_computation->set_parent(i->first);
            }
            else
            {
#if 0
                // DQ (3/14/2006): Bug here when SgExprStatement from SgForStatement test is used here!
                printf ("Bug here when SgExprStatement from SgForStatement test is used: i->first = %s \n",i->first->class_name().c_str());
                i->first->get_file_info()->display("Location i->first");
                printf ("Bug here when SgExprStatement from SgForStatement test is used: TransformationSupport::getStatement(i->first) = %s \n",
                        TransformationSupport::getStatement(i->first)->class_name().c_str());
                printf ("Bug here when SgExprStatement from SgForStatement test is used: the_computation = %s \n",the_computation->class_name().c_str());
                the_computation->get_file_info()->display("Location the_computation: debug");
                ROSE_ASSERT(i->first != NULL);
                ROSE_ASSERT(i->first->get_parent() != NULL);
                printf ("i->first->get_parent() = %s \n",i->first->get_parent()->class_name().c_str());
                i->first->get_file_info()->display("Location i->first: debug");
#endif

                SgForStatement*  forStatement = isSgForStatement(i->first->get_parent());
                if (forStatement != NULL)
                {
                    // Make sure that both pointers are not equal because they are both NULL!
                    ROSE_ASSERT(forStatement->get_test() != NULL);
                    SgExprStatement* possibleTest = isSgExprStatement(i->first);
                    if ( forStatement->get_test() == possibleTest )
                    {
                        // This is a special case of a SgExpressionStatement as a target in a SgForStatement
                        // printf ("Found special case of target being the test of a SgForStatement \n");
                        forStatement->set_test(the_computation);
                        the_computation->set_parent(forStatement);
                    }
                }
                else
                {
                    SgForInitStatement*  forInitStatement = isSgForInitStatement(i->first->get_parent());
                    if (forInitStatement != NULL)
                    {
                        // printf ("Found the SgForInitStatement \n");
                        SgVariableDeclaration* possibleVariable = isSgVariableDeclaration(i->first);
                        SgExprStatement* possibleExpression = isSgExprStatement(i->first);
                        SgStatementPtrList & statementList = forInitStatement->get_init_stmt();
                        SgStatementPtrList::iterator i = statementList.begin();
                        bool addToForInitList = false;
                        while ( (addToForInitList == false) && (i != statementList.end()) )
                        {
                            // if ( *i == possibleVariable )
                            if ( *i == possibleVariable || *i == possibleExpression )
                            {
                                // This is a special case of a SgExpressionStatement as a target in a SgForStatement
                                // printf ("Found special case of SgForInitStatement transformation \n");
                                addToForInitList = true;
                            }
                            i++;
                        }

                        // Only modify the STL list outside of the loop over the list to avoid interator invalidation
                        if (addToForInitList == true)
                        {
                            // Add the the_computation statment to the list in the SgForInitStatement.
                            // Later if we abandon the SgForInitStatement then we would have to add it to
                            // the list of SgInitializedName objects in the SgVariableDeclaration OR modify
                            // the expression list to handle the extra expression (but I think this case in
                            // handled above).
                            // printf ("Adding the_computation to the list in the SgForInitStatement \n");
                            statementList.push_back(the_computation);
                            the_computation->set_parent(forInitStatement);
                        }
                    }
                    else
                    {
                        myStatementInsert(TransformationSupport::getStatement(i->first),the_computation,i->second,true);
                        the_computation->set_parent(TransformationSupport::getStatement(i->first));
                    }
                }
            }
        }
    }

    // DQ (3/16/2006): debugging code to force failure at inspection point
    if (failAtEndOfFunction == true)
    {
        printf ("Error: internal error detected \n");
        ROSE_ASSERT(false);
    }
}
Example #11
0
void
RemoveConstantFoldedValueViaParent::visit ( SgNode* node )
   {
  // This is an alternative implementation that allows us to handle expression that are not 
  // traversed in the AST (e.g. types like SgArrayType which can contain expressions).

     ROSE_ASSERT(node != NULL);

  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
#if 0
     printf ("In RemoveConstantFoldedValueViaParent::visit(): node = %p = %s \n",node,node->class_name().c_str());
#endif

  // DQ (10/12/2012): Turn this on so that we can detect failing IR nodes (failing later) that have valid originalExpressionTrees.
  // DQ (10/12/2012): Turn this back off because it appears to fail...
#if 0
     SgExpression* exp = isSgExpression(node);
     if (exp != NULL)
        {
          SgExpression* originalExpressionTree = exp->get_originalExpressionTree();
          if (originalExpressionTree != NULL)
             {
               SgNode* parent = exp->get_parent();
               if (parent != NULL)
                  {
                    printf ("Current IR node with SgExpression parent = %p = %s child = %p = %s originalExpressionTree = %p = %s \n",parent,parent->class_name().c_str(),node,node->class_name().c_str(),originalExpressionTree,originalExpressionTree->class_name().c_str());
                    bool traceReplacement = true;
                    ConstantFoldedValueReplacer r(traceReplacement, exp);
                    parent->processDataMemberReferenceToPointers(&r);
                 // node->processDataMemberReferenceToPointers(&r);
                  }

            // Set the originalExpressionTree to NULL.
               exp->set_originalExpressionTree(NULL);

            // Set the parent of originalExpressionTree to be the parent of exp.
               originalExpressionTree->set_parent(parent);

            // And then delete the folded constant.
               SageInterface::deleteAST(exp);
             }
        }
#endif

     SgArrayType* arrayType = isSgArrayType(node);
     if (arrayType != NULL)
        {
#if 0
          printf ("Found an array type arrayType = %p arrayType->get_index() = %p \n",arrayType,arrayType->get_index());
#endif
          SgExpression* index = arrayType->get_index();
          if (index != NULL)
             {
#if 0
               printf ("Fixup array index = %p = %s (traverse index AST subtree) \n",index,index->class_name().c_str());
#endif
               RemoveConstantFoldedValue astFixupTraversal;
               astFixupTraversal.traverse(index);
#if 0
               printf ("DONE: Fixup array index = %p (traverse index AST) \n\n\n\n",index);
#endif
#if 0
               printf ("Found an array index = %p (fixup index directly) \n",index);
#endif
            // Handle the case where the original expression tree is at the root of the subtree.
               SgExpression* originalExpressionTree = index->get_originalExpressionTree();
               if (originalExpressionTree != NULL)
                  {
#if 0
                    printf ("Found an originalExpressionTree in the array index originalExpressionTree = %p \n",originalExpressionTree);
#endif
                 // DQ (6/12/2013): This appears to be a problem in EDG 4.7 (see test2011_117.C).
                    std::vector<SgExpression*> redundantChainOfOriginalExpressionTrees;
                    if (originalExpressionTree->get_originalExpressionTree() != NULL)
                       {
#if 0
                         printf ("Detected originalExpressionTree nested directly within the originalExpressionTree \n",
                              originalExpressionTree,originalExpressionTree->class_name().c_str(),
                              originalExpressionTree->get_originalExpressionTree(),originalExpressionTree->get_originalExpressionTree()->class_name().c_str());
#endif
                      // Loop to the end of the chain of original expressions (which EDG 4.7 should never have constructed).
                         while (originalExpressionTree->get_originalExpressionTree() != NULL)
                            {
#if 0
                              printf ("Looping through a chain of originalExpressionTrees \n");
#endif
                           // Save the list of redundnat nodes so that we can delete them properly.
                              redundantChainOfOriginalExpressionTrees.push_back(originalExpressionTree);

                              originalExpressionTree = originalExpressionTree->get_originalExpressionTree();
                            }
#if 0
                         printf ("Exiting as a test! \n");
                         ROSE_ASSERT(false);
#endif
                       }

                    arrayType->set_index(originalExpressionTree);
                    originalExpressionTree->set_parent(arrayType);

                    index->set_originalExpressionTree(NULL);

                 // printf ("DEBUGING: skip delete of index in array type \n");
                    delete index;

                 // DQ (6/12/2013): Delete the nodes that we had to skip over (caused by chain of redundant entries from EDG 4.7).
                    std::vector<SgExpression*>::iterator i = redundantChainOfOriginalExpressionTrees.begin();
                    while (i != redundantChainOfOriginalExpressionTrees.end())
                       {
#if 0
                         printf ("deleting the redundnat originalExpressionTree chain caused by EDG 4.7 (delete %p = %s) \n",*i,(*i)->class_name().c_str());
#endif
                         delete *i;
                         i++;
                       }

                    index = NULL;
                  }
             }
        }

     SgVariableDefinition* variableDefinition = isSgVariableDefinition(node);
     if (variableDefinition != NULL)
        {
#if 0
          printf ("Found a SgVariableDefinition \n");
#endif
          SgExpression* bitfieldExp = variableDefinition->get_bitfield();
          if (bitfieldExp != NULL)
             {
#if 0
               printf ("Fixup bitfieldExp = %p (traverse bitfieldExp AST subtree) \n",bitfieldExp);
#endif
               RemoveConstantFoldedValue astFixupTraversal;
               astFixupTraversal.traverse(bitfieldExp);

            // Handle the case where the original expression tree is at the root of the subtree.
               SgExpression* originalExpressionTree = bitfieldExp->get_originalExpressionTree();
               if (originalExpressionTree != NULL)
                  {
#if 0
                 // DQ (9/18/2011): This code will not work since the bitfile data member in SgVariableDefinition is a SgUnsignedLongVal instead of a SgExpression.
                    variableDefinition->set_bitfield(originalExpressionTree);
                    originalExpressionTree->set_parent(variableDefinition);

                    bitfieldExp->set_originalExpressionTree(NULL);
                    delete bitfieldExp;
                    bitfieldExp = NULL;
#else
                 // The ROSE AST needs to be fixed to handle more general expressions for bitfield widths (this does not effect the CFG).
                 // TODO: Change the data type of the bitfield data member in SgVariableDefinition.

                 // DQ (1/20/2014): This has been done now.
                 // printf ("Member data bitfield widths need to be changed (in the ROSE IR) to support more general expressions (can't fix this original expression tree) \n");
#endif
#if 0
                 // This case is not handled yet!
                    printf ("Found an original expression tree in a bitfield expression \n");
                    ROSE_ASSERT(false);
#endif
                  }
             }
        }
   }
Example #12
0
void
ConstantFoldedValueReplacer::operator()(SgNode*& key, const SgName & debugStringName, bool /* traverse */ traceReplacement)
   {
  // This function is used to replace the expression in an AST node and avoids explicitly handling all of the cases 
  // of where an IR node can exist in the AST (in this case expressions containing an opriginal expression tree could 
  // be in a lot of locations).

  // Note that the key will be a reference to the pointer for each data member of the IR node where: 
  //      node->processDataMemberReferenceToPointers(&r);
  // is called.

#if 0
     printf ("Inside of ConstantFoldedValueReplacer::operator() key = %p = %s = %s node = %p = %s = %s \n",
          key,(key != NULL) ? key->class_name().c_str() : "NULL",(key != NULL) ? SageInterface::get_name(key).c_str() : "NULL",
          targetNode,(targetNode != NULL) ? targetNode->class_name().c_str() : "NULL",(targetNode != NULL) ? SageInterface::get_name(targetNode).c_str() : "NULL");
#endif

     if (key != NULL)
        {
       // Now reset the pointer to the subtree identified as redundent with a
       // subtree in the original AST to the subtree in the original (merged) AST.

       // Note: targetNode is the IR node to be replaced (set in the ConstantFoldedValueReplacer constructor call).
          if (key == targetNode)
             {
#if 0
               printf ("Note that key == originalNode \n");
#endif
               SgExpression* keyExpression = isSgExpression(key);

            // DQ (9/17/2011): We don't want to eliminate references to enum values (see test2005_194.C).
            // Though I wonder if it could be that we are not distinguishing the enum value and the 
            // values of the enum variables (the order of the fields in the enum declaration).
               if (isSgEnumVal(keyExpression) == NULL)
                  {
                    if (keyExpression != NULL)
                       {
#if 0
                         printf ("Note that key is a valid expression keyExpression->get_originalExpressionTree() = %p \n",keyExpression->get_originalExpressionTree());
#endif
                         if (keyExpression->get_originalExpressionTree() != NULL)
                            {
#if 0
                              printf ("key contains a originalExpressionTree = %p = %s \n",keyExpression->get_originalExpressionTree(),keyExpression->get_originalExpressionTree()->class_name().c_str());
#endif

                           // DQ (10/8/2011): Added support for chains of expression trees.
                           // while (keyExpression->get_originalExpressionTree()->get_originalExpressionTree() != NULL)
                              while (keyExpression->get_originalExpressionTree()->get_originalExpressionTree() != NULL && isSgEnumVal(keyExpression->get_originalExpressionTree()) == NULL)
                                 {
                                   SgExpression* nestedOriginalExpressionTree = keyExpression->get_originalExpressionTree();
                                   ROSE_ASSERT(nestedOriginalExpressionTree != NULL);
#if 0
                                   printf ("Found a chain of original expression trees (iterate to find the end of the chain: keyExpression = %p = %s keyExpression->get_originalExpressionTree() = %p = %s \n",
                                        keyExpression,keyExpression->class_name().c_str(),nestedOriginalExpressionTree,nestedOriginalExpressionTree->class_name().c_str());
#endif
                                   keyExpression = nestedOriginalExpressionTree;
                                 }

                           // If this is an enum value, then we don't want the original expression tree (which 
                           // will otherwise be substituted into such places as SgCaseOptionStmt nodes, etc.).
                              SgEnumVal* enumValue = isSgEnumVal(keyExpression->get_originalExpressionTree());
                              if (enumValue != NULL)
                                 {
#if 0
                                   printf ("Detected case of enumValue = %p \n",enumValue);
#endif
                                   if (enumValue->get_originalExpressionTree())
                                      {
#if 0
                                        printf ("Deleting the original expression in the nested enumValue \n");
#endif
                                        deleteOriginalExpressionTree(enumValue->get_originalExpressionTree());
                                        enumValue->set_originalExpressionTree(NULL);
                                      }
                                 }

                              ROSE_ASSERT(keyExpression->get_originalExpressionTree() != NULL);
                              key = keyExpression->get_originalExpressionTree();
                              ROSE_ASSERT(key != NULL);

                           // Set the parent node
                              ROSE_ASSERT(keyExpression->get_originalExpressionTree() != NULL);
                              keyExpression->get_originalExpressionTree()->set_parent(targetNode->get_parent());

                              SgExpression* targetExpression = isSgExpression(targetNode);

                           // Clear the originalExpressionTree
                              targetExpression->set_originalExpressionTree(NULL);
                              ROSE_ASSERT(targetExpression->get_originalExpressionTree() == NULL);

                              targetExpression->set_parent(NULL);

                           // DQ (9/24/2011): This can be an expression tree (more than just a single IR node (see test2011_140.C).
                           // delete targetNode;
                              SageInterface::deleteAST(targetExpression);

                           // Reset the pointer to avoid any dangling pointer problems.
                              targetNode = NULL;
                            }
                       }
                      else
                       {
#if 0
                         printf ("key is not a SgExpression \n");
#endif
                       }
                  }
                 else
                  {
                 // For the case of a SgEnumVal, don't use the original expression tree (see test2005_194.C)
                 // The original expression tree holds the value used for the enum field, instead of the 
                 // reference to the correct enum field).
#if 0
                    printf ("ENUM VALUE special handling: we call deleteOriginalExpressionTree(keyExpression = %p) \n",keyExpression);
#endif
                    deleteOriginalExpressionTree(keyExpression);
                  }
             }
            else
             {
#if 0
               printf ("key != originalNode \n");
#endif
             }
        }
       else
        {
#if 0
          printf ("key == NULL \n");
#endif
        }

#if 0
     printf ("Leaving ConstantFoldedValueReplacer::operator() new reset key = %p = %s \n",key,(key != NULL) ? key->class_name().c_str() : "NULL");
#endif
   }
Example #13
0
File: f2cArray.C Project: 8l/rose
void Fortran_to_C::translateArraySubscript(SgPntrArrRefExp* pntrArrRefExp)
{
  // get lhs operand
  SgVarRefExp*  arrayName = isSgVarRefExp(pntrArrRefExp->get_lhs_operand());
  SgExpression* baseExp = isSgExpression(arrayName);
  // get array symbol
  SgVariableSymbol* arraySymbol = arrayName->get_symbol();
  // get array type and dim_info
  SgArrayType* arrayType = isSgArrayType(arraySymbol->get_type());
  ROSE_ASSERT(arrayType);
  SgExprListExp* dimInfo = arrayType->get_dim_info();

  // get rhs operand
  SgExprListExp*  arraySubscript = isSgExprListExp(pntrArrRefExp->get_rhs_operand());
  if(arrayType->findBaseType()->variantT() == V_SgTypeString)
  {
    arraySubscript->prepend_expression(buildIntVal(1));
  }
  /*
    No matter it is single or multi dimensional array,  pntrArrRefExp always has a
    child, SgExprListExp, to store the subscript information.
  */
  if(arraySubscript != NULL)
  {
    // get the list of subscript
    SgExpressionPtrList subscriptExprList = arraySubscript->get_expressions();
    // get the list of dimension inforamtion from array definition.
    SgExpressionPtrList dimExpressionPtrList = dimInfo->get_expressions();

    // Create new SgExpressionPtrList for the linearalized array subscript. 
    SgExpressionPtrList newSubscriptExprList;

    // rank info has to match between subscripts and dim_info
    ROSE_ASSERT(arraySubscript->get_expressions().size() == dimInfo->get_expressions().size());

    if(subscriptExprList.size() == 1)
    {
      Rose_STL_Container<SgExpression*>::iterator j1 =  subscriptExprList.begin();
      Rose_STL_Container<SgExpression*>::iterator j2 =  dimExpressionPtrList.begin();
      SgExpression* newIndexExp = get0basedIndex(*j1, *j2);
      pntrArrRefExp->set_rhs_operand(newIndexExp);
    }
    else
    {
      Rose_STL_Container<SgExpression*>::reverse_iterator j1 =  subscriptExprList.rbegin();
      Rose_STL_Container<SgExpression*>::reverse_iterator j2 =  dimExpressionPtrList.rbegin();
      SgExpression* newIndexExp = get0basedIndex(*j1, *j2);
      SgPntrArrRefExp* newPntrArrRefExp = buildPntrArrRefExp(baseExp, newIndexExp);
      baseExp->set_parent(newPntrArrRefExp);
      j1 = j1 + 1;
      j2 = j2 + 1;
      for(; j1< (subscriptExprList.rend()-1); ++j1, ++j2)
      {
        SgExpression* newIndexExp = get0basedIndex(*j1, *j2);
        baseExp = isSgExpression(newPntrArrRefExp);
        newPntrArrRefExp = buildPntrArrRefExp(baseExp, newIndexExp);
        baseExp->set_parent(newPntrArrRefExp);
      }
      newIndexExp = get0basedIndex(*j1, *j2);
      pntrArrRefExp->set_lhs_operand(newPntrArrRefExp);
      pntrArrRefExp->set_rhs_operand(newIndexExp);
      newIndexExp->set_parent(pntrArrRefExp);
    }
  }
}
Example #14
0
int main( int argc, char * argv[] )
{
// Option to linearize the array.
  Rose_STL_Container<std::string> localCopy_argv = CommandlineProcessing::generateArgListFromArgcArgv(argc, argv);
  int newArgc;
  char** newArgv = NULL;
  vector<string> argList = localCopy_argv;
  if (CommandlineProcessing::isOption(argList,"-f2c:","linearize",true) == true)
  {
    isLinearlizeArray = true;
  }
  CommandlineProcessing::generateArgcArgvFromList(argList,newArgc, newArgv);
// Build the AST used by ROSE
  SgProject* project = frontend(newArgc,newArgv);
  AstTests::runAllTests(project);   

  if (SgProject::get_verbose() > 2)
    generateAstGraph(project,8000,"_orig");
  
  // Traversal with Memory Pool to search for variableDeclaration
  variableDeclTraversal translateVariableDeclaration;
  traverseMemoryPoolVisitorPattern(translateVariableDeclaration);
  for(vector<SgVariableDeclaration*>::iterator dec=variableDeclList.begin(); dec!=variableDeclList.end(); ++dec)
  {
    /*
       For the Fortran AST, a single variableDeclaration can be shared by multiple variables.
       This violated the normalization rules for C unparser.  Therefore, we have to transform it.
    */
    SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(*dec);
    ROSE_ASSERT(variableDeclaration);
    if((variableDeclaration->get_variables()).size() != 1)
    {
      updateVariableDeclarationList(variableDeclaration);
      statementList.push_back(variableDeclaration);
      removeList.push_back(variableDeclaration);
    }
  }

  // reset the vector that collects all variable declaration. We need to walk through memory pool again to find types
  
  variableDeclList.clear();
  traverseMemoryPoolVisitorPattern(translateVariableDeclaration);
  for(vector<SgVariableDeclaration*>::iterator dec=variableDeclList.begin(); dec!=variableDeclList.end(); ++dec)
  {
    SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(*dec);
    ROSE_ASSERT(variableDeclaration);
    SgInitializedNamePtrList initializedNameList = variableDeclaration->get_variables();
    for(SgInitializedNamePtrList::iterator i=initializedNameList.begin(); i!=initializedNameList.end();++i)
    {
      SgInitializedName* initiallizedName = isSgInitializedName(*i);
      SgType* baseType = initiallizedName->get_type();
      if(baseType->variantT() == V_SgArrayType)
      {
        SgArrayType* arrayBase = isSgArrayType(baseType);
        // At this moment, we are still working on the Fortran-stype AST.  Therefore, there is no nested types for multi-dim array.
        if(arrayBase->findBaseType()->variantT() == V_SgTypeString)
        {
          arrayBase->reset_base_type(translateType(arrayBase->findBaseType()));
          arrayBase->set_rank(arrayBase->get_rank()+1);
        }
      }
      else
      {
        initiallizedName->set_type(translateType(baseType));
      }
    }
  }

  // replace the AttributeSpecificationStatement 
  Rose_STL_Container<SgNode*> AttributeSpecificationStatement = NodeQuery::querySubTree (project,V_SgAttributeSpecificationStatement);
  for (Rose_STL_Container<SgNode*>::iterator i = AttributeSpecificationStatement.begin(); i != AttributeSpecificationStatement.end(); i++)
  {
    SgAttributeSpecificationStatement* attributeSpecificationStatement = isSgAttributeSpecificationStatement(*i);
    ROSE_ASSERT(attributeSpecificationStatement);
    translateAttributeSpecificationStatement(attributeSpecificationStatement);
    statementList.push_back(attributeSpecificationStatement);
    removeList.push_back(attributeSpecificationStatement);
  }

  // replace the parameter reference
  parameterTraversal translateParameterRef;
  traverseMemoryPoolVisitorPattern(translateParameterRef);
  for(vector<SgVarRefExp*>::iterator i=parameterRefList.begin(); i!=parameterRefList.end(); ++i)
  {
    SgVarRefExp* parameterRef = isSgVarRefExp(*i);
    if(parameterSymbolList.find(parameterRef->get_symbol()) != parameterSymbolList.end())
    {
      SgExpression* newExpr = isSgExpression(deepCopy(parameterSymbolList.find(parameterRef->get_symbol())->second));
      ROSE_ASSERT(newExpr);
      newExpr->set_parent(parameterRef->get_parent());
      replaceExpression(parameterRef,
                        newExpr,
                        false);
    }
  }

  /*
     Parameters will be replaced by #define, all the declarations should be removed
  */
  for(map<SgVariableSymbol*,SgExpression*>::iterator i=parameterSymbolList.begin();i!=parameterSymbolList.end();++i)
  {
    SgVariableSymbol* symbol = i->first;
    SgInitializedName* initializedName = symbol->get_declaration();
    SgVariableDeclaration* decl = isSgVariableDeclaration(initializedName->get_parent());
    statementList.push_back(decl);
    removeList.push_back(decl);
  }


  // Traversal with Memory Pool to search for arrayType
  arrayTypeTraversal translateArrayType;
  traverseMemoryPoolVisitorPattern(translateArrayType);
  for(vector<SgArrayType*>::iterator i=arrayTypeList.begin(); i!=arrayTypeList.end(); ++i)
  {
    if(isLinearlizeArray)
    {
      linearizeArrayDeclaration(*i);
    }
    else
    {
      translateArrayDeclaration(*i);
    }
  }

  // Traversal with Memory Pool to search for pntrArrRefExp
  pntrArrRefTraversal translatePntrArrRefExp;
  traverseMemoryPoolVisitorPattern(translatePntrArrRefExp);
  for(vector<SgPntrArrRefExp*>::iterator i=pntrArrRefList.begin(); i!=pntrArrRefList.end(); ++i)
  {
    if(isLinearlizeArray)
    {
      linearizeArraySubscript(*i);
    }
    else
    {
      translateArraySubscript(*i);
    }
  }


  Rose_STL_Container<SgNode*> functionList = NodeQuery::querySubTree (project,V_SgFunctionDeclaration);
  for (Rose_STL_Container<SgNode*>::iterator i = functionList.begin(); i != functionList.end(); i++)
  {
    if((isSgProcedureHeaderStatement(*i) != NULL) ||
       (isSgProgramHeaderStatement(*i) != NULL)){
      SgFunctionDeclaration* functionBody = isSgFunctionDeclaration(*i);
      bool hasReturnVal = false;
      if(isSgProcedureHeaderStatement(functionBody))
      {
        hasReturnVal = isSgProcedureHeaderStatement(functionBody)->isFunction();
      }
      fixFortranSymbolTable(functionBody->get_definition(),hasReturnVal);
    }
  } 

  // Traversal with Memory Pool to search for equivalenceStatement
  equivalencelTraversal translateEquivalenceStmt;
  traverseMemoryPoolVisitorPattern(translateEquivalenceStmt);
  for(vector<SgEquivalenceStatement*>::iterator i=equivalenceList.begin(); i!=equivalenceList.end(); ++i)
  {
    SgEquivalenceStatement* equivalenceStatement = isSgEquivalenceStatement(*i);
    ROSE_ASSERT(equivalenceStatement);
    translateEquivalenceStatement(equivalenceStatement);
    statementList.push_back(equivalenceStatement);
    removeList.push_back(equivalenceStatement);
  }



  // Simple traversal, bottom-up, to translate the rest
  f2cTraversal f2c;
  f2c.traverseInputFiles(project,postorder);

  // removing all the unsed statement from AST
  for(vector<SgStatement*>::iterator i=statementList.begin(); i!=statementList.end(); ++i)
  {
    removeStatement(*i);
    (*i)->set_parent(NULL);
  }
      
  // deepDelete the removed nodes 
  for(vector<SgNode*>::iterator i=removeList.begin(); i!=removeList.end(); ++i)
  {
    deepDelete(*i);
  }
      
/*
  1. There should be no Fortran-specific AST nodes in the whole
     AST graph after the translation. 
  
  TODO: make sure translator generating clean AST 
*/
    //generateDOT(*project);
  if (SgProject::get_verbose() > 2)
    generateAstGraph(project,8000);
  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
                  }
             }
        }
   }