Beispiel #1
0
static void
run(Compass::Parameters parameters, Compass::OutputObject* output)
{
  // We only care about source code in the user's space, not,
  // for example, Boost or system files.
  string target_directory =
      parameters["general::target_directory"].front();
  CompassAnalyses::NoRand::source_directory.assign(target_directory);

  // Use the pre-built ROSE AST
  SgProject* sageProject = Compass::projectPrerequisite.getProject();
  SgNode* root_node = (SgNode*) sageProject;

  // perform AST matching
  AstMatching matcher;

  MatchResult matches = matcher.performMatching("$r=SgFunctionRefExp",
                                                root_node);

  BOOST_FOREACH(SingleMatchVarBindings match, matches)
  {
    SgFunctionRefExp *function = (SgFunctionRefExp *)match["$r"];
    std::string fncName = function->get_symbol()->get_name().getString();

    if( fncName.find( "rand", 0, 4) != std::string::npos)
    {
      output->addOutput(
          new CompassAnalyses::NoRand::CheckerOutput(function));
    }
  }
VariableId LoopInfo::iterationVariableId(SgForStatement* forStmt, VariableIdMapping* variableIdMapping) {
  VariableId varId;
  AstMatching m;
  // operator '#' is used to ensure no nested loop is matched ('#' cuts off subtrees of 4th element (loop body)).
  string matchexpression="SgForStatement(_,_,SgPlusPlusOp($ITERVAR=SgVarRefExp)|SgMinusMinusOp($ITERVAR=SgVarRefExp),..)";
  MatchResult r=m.performMatching(matchexpression,forStmt);
  if(r.size()>1) {
    //ROSE_ASSERT(r.size()==1);
    for(MatchResult::iterator i=r.begin();i!=r.end();++i) {
      SgVarRefExp* node=isSgVarRefExp((*i)["$ITERVAR"]);
      varId=variableIdMapping->variableId(node);
      return varId;
    }
  } else {
    cout<<"WARNING: no match!"<<endl;
  }
  return varId;
}
int Specialization::substituteConstArrayIndexExprsWithConst(VariableIdMapping* variableIdMapping, ExprAnalyzer* exprAnalyzer, const EState* estate, SgNode* root) {
  typedef pair<SgExpression*,int> SubstitutionPair;
  typedef list<SubstitutionPair > SubstitutionList;
  SubstitutionList substitutionList;
  AstMatching m;
  MatchResult res;
  int numConstExprElim=0;
#pragma omp critical(EXPRSUBSTITUTION)
  {
    res=m.performMatching("SgPntrArrRefExp(_,$ArrayIndexExpr)",root);
  }
  if(res.size()>0) {
     for(MatchResult::iterator i=res.begin();i!=res.end();++i) {
         // match found
       SgExpression* arrayIndexExpr=isSgExpression((*i)["$ArrayIndexExpr"]);
       if(arrayIndexExpr) {
         // avoid substituting a constant by a constant
         if(!isSgIntVal(arrayIndexExpr)) {
           list<SingleEvalResultConstInt> evalResultList=exprAnalyzer->evalConstInt(arrayIndexExpr,*estate,true, true);
           // only when we get exactly one result it is considered for substitution
           // there can be multiple const-results which do not allow to replace it with a single const
           if(evalResultList.size()==1) {
             list<SingleEvalResultConstInt>::iterator i=evalResultList.begin();
             ROSE_ASSERT(evalResultList.size()==1);
             AValue varVal=(*i).value();
             if(varVal.isConstInt()) {
               int varIntValue=varVal.getIntValue();
               //cout<<"INFO: const: "<<varIntValue<<" substituting: "<<arrayIndexExpr->unparseToString()<<endl;
               SgNodeHelper::replaceExpression(arrayIndexExpr,SageBuilder::buildIntVal(varIntValue),false);
               numConstExprElim++;
             }
           }
         }
       }
     }
   }
   return numConstExprElim;
 }
LoopInfoSet EquivalenceChecking::determineLoopInfoSet(SgNode* root, VariableIdMapping* variableIdMapping, Labeler* labeler) {
    cout<<"INFO: loop info set and determine iteration vars."<<endl;
    ForStmtToOmpPragmaMap forStmtToPragmaMap=createOmpPragmaForStmtMap(root);
    cout<<"INFO: found "<<forStmtToPragmaMap.size()<<" omp/simd loops."<<endl;
    LoopInfoSet loopInfoSet;
    RoseAst ast(root);
    AstMatching m;

    // (i) match all for-stmts and (ii) filter canonical ones
    string matchexpression="$FORSTMT=SgForStatement(_,_,..)";
    MatchResult r=m.performMatching(matchexpression,root);
    cout << "DEBUG: Matched for loops: "<<r.size()<<endl;
    for(MatchResult::iterator i=r.begin(); i!=r.end(); ++i) {
        LoopInfo loopInfo;
        SgNode* forNode=(*i)["$FORSTMT"];
        cout << "DEBUG: Detected for loops: "<<forNode->unparseToString()<<endl;

        cout<<"DEBUG: MATCH: "<<forNode->unparseToString()<<AstTerm::astTermWithNullValuesToString(forNode)<<endl;
        ROSE_ASSERT(isSgForStatement(forNode));
        SgInitializedName* ivar=0;
        SgExpression* lb=0;
        SgExpression* ub=0;
        SgExpression* step=0;
        SgStatement* body=0;
        bool hasIncrementalIterationSpace=false;
        bool isInclusiveUpperBound=false;
        bool isCanonicalOmpForLoop=SageInterface::isCanonicalForLoop(forNode, &ivar, &lb, &ub, &step, &body, &hasIncrementalIterationSpace, &isInclusiveUpperBound);
        if(isCanonicalOmpForLoop) {
            ROSE_ASSERT(ivar);
            SgInitializedName* node=0;
            if(isCanonicalOmpForLoop) {
                node=ivar;
            }
            ROSE_ASSERT(node);
#if 0
            // WORKAROUND 1
            // TODO: investigate why the for pointer is not stored in the same match-result
            if(forNode==0) {
                forNode=node; // init
                while(!isSgForStatement(forNode)||isSgProject(forNode))
                    forNode=forNode->get_parent();
            }
            ROSE_ASSERT(!isSgProject(forNode));
#endif
            loopInfo.iterationVarId=variableIdMapping->variableId(node);
            loopInfo.forStmt=isSgForStatement(forNode);
            loopInfo.iterationVarType=isOmpParallelFor(loopInfo.forStmt,forStmtToPragmaMap)?ITERVAR_PAR:ITERVAR_SEQ;
            if(loopInfo.forStmt) {
                const SgStatementPtrList& stmtList=loopInfo.forStmt->get_init_stmt();
                ROSE_ASSERT(stmtList.size()==1);
                loopInfo.initStmt=stmtList[0];
                loopInfo.condExpr=loopInfo.forStmt->get_test_expr();
                loopInfo.computeLoopLabelSet(labeler);
                loopInfo.computeOuterLoopsVarIds(variableIdMapping);
                loopInfo.isOmpCanonical=true;
            } else {
                cerr<<"WARNING: no for statement found."<<endl;
                if(forNode) {
                    cerr<<"for-loop:"<<forNode->unparseToString()<<endl;
                } else {
                    cerr<<"for-loop: 0"<<endl;
                }
            }
        } else {
            loopInfo.forStmt=isSgForStatement(forNode);
            loopInfo.isOmpCanonical=false;
        }
        loopInfoSet.push_back(loopInfo);
    }
    cout<<"INFO: found "<<forStmtToPragmaMap.size()<<" omp/simd loops."<<endl;
    cout<<"INFO: found "<<Specialization::numParLoops(loopInfoSet,variableIdMapping)<<" parallel loops."<<endl;
    return loopInfoSet;
}
Beispiel #5
0
MatchResult& SPRAY::ProcessQuery::operator()(std::string query, SgNode* root)
{
  AstMatching m;
  match_result = m.performMatching(query, root);
  return match_result;
}
void Specialization::transformArrayProgram(SgProject* root, Analyzer* analyzer) {
  // 1) transform initializers of global variables : a[]={1,2,3} ==> int a_0=1;int a_1=2;int a_2=3;
  // 2) eliminate initializers of pointer variables: int p* = a; ==> \eps
  // 3) replace uses of p[k]: with a_k (where k is a constant)

  //ad 1 and 2)
  VariableIdMapping* variableIdMapping=analyzer->getVariableIdMapping();
  Analyzer::VariableDeclarationList usedGlobalVariableDeclarationList=analyzer->computeUsedGlobalVariableDeclarationList(root);
  cout<<"STATUS: number of used global variables: "<<usedGlobalVariableDeclarationList.size()<<endl;
  list<pair<SgNode*,string> > toReplaceArrayInitializations;
  list<SgVariableDeclaration*> toDeleteDeclarations;
  typedef map<VariableId,VariableId> ArrayPointerMapType;
  ArrayPointerMapType arrayPointer; // var,arrayName
  for(Analyzer::VariableDeclarationList::iterator i=usedGlobalVariableDeclarationList.begin();
      i!=usedGlobalVariableDeclarationList.end();
      ++i) {
    SgVariableDeclaration* decl=*i;
    //cout<<"DEBUG: variableDeclaration:"<<decl->unparseToString()<<endl;
    SgNode* initName0=decl->get_traversalSuccessorByIndex(1); // get-InitializedName
    ROSE_ASSERT(initName0);
    if(SgInitializedName* initName=isSgInitializedName(initName0)) {
      // array initializer
      SgInitializer* arrayInitializer=initName->get_initializer();
      //string arrayName=variableIdMapping->variableName(variableIdMapping->variableId(*i));
      if(isSgAggregateInitializer(arrayInitializer)) {
        string transformedArrayInitializer=flattenArrayInitializer(decl,variableIdMapping);
        toReplaceArrayInitializations.push_back(make_pair(decl,transformedArrayInitializer));
        //SgNodeHelper::replaceAstWithString(decl,transformedArrayInitializer);
      } else {
        //cout<<"initName:"<<astTermWithNullValuesToString(initName)<<endl;
        VariableId lhsVarId=variableIdMapping->variableId(*i);
        string lhsVariableName=variableIdMapping->variableName(lhsVarId);
        SgType* type=variableIdMapping->getType(variableIdMapping->variableId(*i));
        // match: SgInitializedName(SgAssignInitializer(SgVarRefExp))
        // variable on lhs
        // check if variable is a pointer variable
        if(isSgPointerType(type)) {
          AstMatching m;
          MatchResult res;
          res=m.performMatching("SgInitializedName(SgAssignInitializer($varRef=SgVarRefExp))|SgInitializedName(SgAssignInitializer(SgAddressOfOp($varRef=SgVarRefExp)))",initName);
          if(res.size()==1) {
            toDeleteDeclarations.push_back(decl);
            MatchResult::iterator j=res.begin();
            SgVarRefExp* rhsVarRef=isSgVarRefExp((*j)["$varRef"]);
            VariableId rhsVarId=variableIdMapping->variableId(rhsVarRef);
            arrayPointer[lhsVarId]=rhsVarId;
            //cout<<"Inserted pair "<<variableName<<":"<<rhsVarName<<endl;
          }
        }
      }
    }
  }

  typedef list<pair<SgPntrArrRefExp*,ArrayElementAccessData> > ArrayAccessInfoType;
  ArrayAccessInfoType arrayAccesses;
  RoseAst ast(root);
  for(RoseAst::iterator i=ast.begin();i!=ast.end();++i) {
    SgExpression* exp=isSgExpression(*i);
    if(exp) {
      if(SgPntrArrRefExp* arrAccess=isSgPntrArrRefExp(exp)) {
        ArrayElementAccessData aead(arrAccess,analyzer->getVariableIdMapping());
        ROSE_ASSERT(aead.isValid());
        //VariableId arrayVar=aead.varId;
        //cout<<"array-element: "<<variableIdMapping->variableName(arrayVar);
        if(aead.subscripts.size()==1) {
          //cout<<" ArrayIndex:"<<*aead.subscripts.begin();
          arrayAccesses.push_back(make_pair(arrAccess,aead));
        } else {
          cout<<"Error: ArrayIndex: unknown (dimension>1)";
          exit(1);
        }          
      }
    }
  }
#if 0
  cout<<"Array-Pointer Map:"<<endl;
  for(ArrayPointerMapType::iterator i=arrayPointer.begin();i!=arrayPointer.end();++i) {
    cout<<(*i).first.toString()<<":"<<(*i).second.toString()<<endl;
  }
#endif
  cout<<"STATUS: Replacing array-initializations."<<endl;
  for(list<pair<SgNode*,string> >::iterator i=toReplaceArrayInitializations.begin();i!=toReplaceArrayInitializations.end();++i) {
    //cout<<(*i).first->unparseToString()<<":\n"<<(*i).second<<endl;
    SgNodeHelper::replaceAstWithString((*i).first,"\n"+(*i).second);
  }
  cout<<"STATUS: Transforming pointer declarations."<<endl;
  for(list<SgVariableDeclaration*>::iterator i=toDeleteDeclarations.begin();i!=toDeleteDeclarations.end();++i) {
    //cout<<(*i)->unparseToString()<<endl;
    VariableId declaredPointerVar=variableIdMapping->variableId(*i);
    SgNode* initName0=(*i)->get_traversalSuccessorByIndex(1); // get-InitializedName
    ROSE_ASSERT(initName0);
    if(SgInitializedName* initName=isSgInitializedName(initName0)) {
      // initializer
      SgInitializer* initializer=initName->get_initializer();
      if(SgAssignInitializer* assignInitializer=isSgAssignInitializer(initializer)) {
        //cout<<"var-initializer:"<<initializer->unparseToString()<<astTermWithNullValuesToString(initializer)<<endl;
        SgExpression* assignInitOperand=assignInitializer->get_operand_i();
        if(isSgAddressOfOp(assignInitOperand)) {
          assignInitOperand=isSgExpression(SgNodeHelper::getFirstChild(assignInitOperand));
          ROSE_ASSERT(assignInitOperand);
        }
        if(SgVarRefExp* rhsInitVar=isSgVarRefExp(assignInitOperand)) {
          VariableId arrayVar=variableIdMapping->variableId(rhsInitVar);
          SgExpressionPtrList& arrayInitializerList=variableIdMapping->getInitializerListOfArrayVariable(arrayVar);
          //cout<<"DEBUG: rhs array:"<<arrayInitializerList.size()<<" elements"<<endl;
          int num=0;
          stringstream ss;
          for(SgExpressionPtrList::iterator j=arrayInitializerList.begin();j!=arrayInitializerList.end();++j) {
            ss<<"int "<<variableIdMapping->variableName(declaredPointerVar)<<"_"<<num<<" = "
              <<(*j)->unparseToString()
              <<";\n"
              ;
            num++;
          }
          SgNodeHelper::replaceAstWithString(*i,"\n"+ss.str());
        }
      }
    }
#if 0
    ArrayElementAccessData arrayAccess=
    ROSE_ASSERT(arrayAccess.getDimensions()==1);
    VariableId accessVar=arrayAccess.getVariable();
    int accessSubscript=arrayAccess.getSubscript(0);
#endif
    //SageInterface::removeStatement(*i);
    
    //SgNodeHelper::replaceAstWithString((*i),"POINTER-INIT-ARRAY:"+(*i)->unparseToString()+"...;");
  }
  
  //list<pair<SgPntrArrRefExp*,ArrayElementAccessData> > 
  cout<<"STATUS: Replacing Expressions ... ";
  for(RoseAst::iterator i=ast.begin();i!=ast.end();++i) {
    if(isSgAssignOp(*i)) {
      if(SgVarRefExp* lhsVar=isSgVarRefExp(SgNodeHelper::getLhs(*i))) {
        if(SgNodeHelper::isPointerVariable(lhsVar)) {
          //cout<<"DEBUG: pointer var on lhs :"<<(*i)->unparseToString()<<endl;

          SgExpression* rhsExp=isSgExpression(SgNodeHelper::getRhs(*i));
          ROSE_ASSERT(rhsExp);
          if(isSgAddressOfOp(rhsExp)) {
            rhsExp=isSgExpression(SgNodeHelper::getFirstChild(rhsExp));
            ROSE_ASSERT(rhsExp);
          }
          if(SgVarRefExp* rhsVar=isSgVarRefExp(rhsExp)) {
            VariableId lhsVarId=variableIdMapping->variableId(lhsVar);
            VariableId rhsVarId=variableIdMapping->variableId(rhsVar);
            SgExpressionPtrList& arrayInitializerList=variableIdMapping->getInitializerListOfArrayVariable(rhsVarId);
            //cout<<"DEBUG: rhs array:"<<arrayInitializerList.size()<<" elements"<<endl;
            int num=0;
            stringstream ss;
            for(SgExpressionPtrList::iterator j=arrayInitializerList.begin();j!=arrayInitializerList.end();++j) {
              ss<<variableIdMapping->variableName(lhsVarId)<<"_"<<num<<" = "
                <<(*j)->unparseToString();

              // workaround for the fact that the ROSE unparser generates a "\n;" for a replaced assignment
              {
                SgExpressionPtrList::iterator j2=j;
                j2++;
                if(j2!=arrayInitializerList.end())
                  ss<<";\n";
              }

              num++;
            }
            SgNodeHelper::replaceAstWithString(*i,ss.str());
            //SgNodeHelper::replaceAstWithString(*i,"COPY-ARRAY("+lhsVar->unparseToString()+"<="+rhsVar->unparseToString()+")");
          }
        } else {
          RoseAst subAst(*i);
          for(RoseAst::iterator j=subAst.begin();j!=subAst.end();++j) {
            if(SgNodeHelper::isArrayAccess(*j)) {
              //cout<<"DEBUG: arrays access on rhs of assignment :"<<(*i)->unparseToString()<<endl;
              transformArrayAccess(*j,analyzer->getVariableIdMapping());
            }
          }
        }
      }
    }
    if(SgNodeHelper::isCond(*i)) {
      RoseAst subAst(*i);
      for(RoseAst::iterator j=subAst.begin();j!=subAst.end();++j) {
        if(SgNodeHelper::isArrayAccess(*j)) {
          transformArrayAccess(*j,analyzer->getVariableIdMapping());
        }
      }
    }
  }
  cout<<" done."<<endl;
#if 0
  for(ArrayAccessInfoType::iterator i=arrayAccesses.begin();i!=arrayAccesses.end();++i) {
    //cout<<(*i).first->unparseToString()<<":"/*<<(*i).second.xxxx*/<<endl;
    ArrayElementAccessData arrayAccess=(*i).second;
    ROSE_ASSERT(arrayAccess.getDimensions()==1);
    VariableId accessVar=arrayAccess.getVariable();
    int accessSubscript=arrayAccess.getSubscript(0);
    // expression is now: VariableId[subscript]
    // information available is: arrayPointer map: VariableId:pointer -> VariableId:array
    // pointerArray

    // if the variable is not a pointer var it will now be added to the stl-map but with
    // a default VariableId. Default variableIds are not valid() IDs.
    // therefor this becomes a cheap check, whether we need to replace the expression or not.
    VariableId mappedVar=arrayPointer[accessVar];
    if(mappedVar.isValid()) {
      // need to replace
      stringstream newAccess;
#if 0
      newAccess<<variableIdMapping->variableName(mappedVar)<<"["<<accessSubscript<<"]";
#else
      newAccess<<variableIdMapping->variableName(accessVar)<<"_"<<accessSubscript<<" ";
#endif
      cout<<"to replace: @"<<(*i).first<<":"<<(*i).first->unparseToString()<<" ==> "<<newAccess.str()<<endl;
      SgNodeHelper::replaceAstWithString((*i).first,newAccess.str());
    }
  }
#endif
  Analyzer::VariableDeclarationList unusedGlobalVariableDeclarationList=analyzer->computeUnusedGlobalVariableDeclarationList(root);
  cout<<"STATUS: deleting unused global variables."<<endl;
  for(Analyzer::VariableDeclarationList::iterator i=unusedGlobalVariableDeclarationList.begin();
      i!=unusedGlobalVariableDeclarationList.end();
      ++i) {
    SgVariableDeclaration* decl=*i;
    SageInterface::removeStatement(decl);
  }
      
}
 // rewrites an AST
 // requirements: all variables have been replaced by constants
 // uses AstMatching to match patterns.
void RewriteSystem::rewriteAst(SgNode*& root, VariableIdMapping* variableIdMapping, bool rewriteTrace, bool ruleAddReorder, bool performCompoundAssignmentsElimination) {
   //  cout<<"Rewriting AST:"<<endl;
   bool someTransformationApplied=false;
   bool transformationApplied=false;
   AstMatching m;
   // outer loop (overall fixpoint on all transformations)
   /* Transformations:
      1) eliminate unary operator -(integer) in tree
      2) normalize expressions (reordering of inner nodes and leave nodes)
      3) constant folding (leave nodes)
   */

   if(performCompoundAssignmentsElimination)
   {
     rewriteCompoundAssignments(root,variableIdMapping);
   }

   do{
     someTransformationApplied=false;


 do {
     // Rewrite-rule 1: $UnaryOpSg=MinusOp($IntVal1=SgIntVal) => SgIntVal.val=-$Intval.val
     transformationApplied=false;
     MatchResult res=m.performMatching(
                                       "$UnaryOp=SgMinusOp($IntVal=SgIntVal)\
                                       ",root);
     if(res.size()>0) {
       for(MatchResult::iterator i=res.begin();i!=res.end();++i) {
         // match found
         SgExpression* op=isSgExpression((*i)["$UnaryOp"]);
         SgIntVal* val=isSgIntVal((*i)["$IntVal"]);
         //cout<<"FOUND UNARY CONST: "<<op->unparseToString()<<endl;
         int rawval=val->get_value();
         // replace with folded value (using integer semantics)
         switch(op->variantT()) {
         case V_SgMinusOp:
           SgNodeHelper::replaceExpression(op,SageBuilder::buildIntVal(-rawval),false);
           break;
         default:
           cerr<<"Error: rewrite phase: unsopported operator in matched unary expression. Bailing out."<<endl;
           exit(1);
         }
         transformationApplied=true;
         someTransformationApplied=true;
         dump1_stats.numElimMinusOperator++;
       }
     }
  } while(transformationApplied); // a loop will eliminate -(-(5)) to 5

 if(ruleAddReorder) {
   do {
     // the following rules guarantee convergence
     
     // REWRITE: re-ordering (normalization) of expressions
     // Rewrite-rule 1: SgAddOp(SgAddOp($Remains,$Other),$IntVal=SgIntVal) => SgAddOp(SgAddOp($Remains,$IntVal),$Other) 
     //                 where $Other!=SgIntVal && $Other!=SgFloatVal && $Other!=SgDoubleVal; ($Other notin {SgIntVal,SgFloatVal,SgDoubleVal})
     transformationApplied=false;
     MatchResult res=m.performMatching("$BinaryOp1=SgAddOp(SgAddOp($Remains,$Other),$IntVal=SgIntVal)",root);
     if(res.size()>0) {
       for(MatchResult::iterator i=res.begin();i!=res.end();++i) {
         // match found
         SgExpression* other=isSgExpression((*i)["$Other"]);
         if(other) {
           if(!isSgIntVal(other) && !isSgFloatVal(other) && !isSgDoubleVal(other)) {
             //SgNode* op1=(*i)["$BinaryOp1"];
             SgExpression* val=isSgExpression((*i)["$IntVal"]);
             //cout<<"FOUND: "<<op1->unparseToString()<<endl;
             if(rewriteTrace)
               cout<<"Rule AddOpReorder: "<<((*i)["$BinaryOp1"])->unparseToString()<<" => ";
             // replace op1-rhs with op2-rhs
             SgExpression* other_copy=SageInterface::copyExpression(other);
             SgExpression* val_copy=SageInterface::copyExpression(val);
             SgNodeHelper::replaceExpression(other,val_copy,false);
             SgNodeHelper::replaceExpression(val,other_copy,false);
             //cout<<"REPLACED: "<<op1->unparseToString()<<endl;
             transformationApplied=true;
             someTransformationApplied=true;
             if(rewriteTrace)
               cout<<((*i)["$BinaryOp1"])->unparseToString()<<endl;
             dump1_stats.numAddOpReordering++;
           }       
         }
       }
     }
   } while(transformationApplied);
 }

   // REWRITE: constant folding of constant integer (!) expressions
   // we intentionally avoid folding of float values
 do {
     // Rewrite-rule 2: SgAddOp($IntVal1=SgIntVal,$IntVal2=SgIntVal) => SgIntVal
     //                 where SgIntVal.val=$IntVal1.val+$IntVal2.val
     transformationApplied=false;
     MatchResult res=m.performMatching(
                                       "$BinaryOp1=SgAddOp($IntVal1=SgIntVal,$IntVal2=SgIntVal)\
                                       |$BinaryOp1=SgSubtractOp($IntVal1=SgIntVal,$IntVal2=SgIntVal)\
                                       |$BinaryOp1=SgMultiplyOp($IntVal1=SgIntVal,$IntVal2=SgIntVal)\
                                       |$BinaryOp1=SgDivideOp($IntVal1=SgIntVal,$IntVal2=SgIntVal)\
                                       ",root);
     if(res.size()>0) {
       for(MatchResult::iterator i=res.begin();i!=res.end();++i) {
         // match found
         SgExpression* op1=isSgExpression((*i)["$BinaryOp1"]);
         SgIntVal* val1=isSgIntVal((*i)["$IntVal1"]);
         SgIntVal* val2=isSgIntVal((*i)["$IntVal2"]);
         //cout<<"FOUND CONST: "<<op1->unparseToString()<<endl;
         int rawval1=val1->get_value();
         int rawval2=val2->get_value();
         // replace with folded value (using integer semantics)
         switch(op1->variantT()) {
         case V_SgAddOp:
           SgNodeHelper::replaceExpression(op1,SageBuilder::buildIntVal(rawval1+rawval2),false);
           break;
         case V_SgSubtractOp:
           SgNodeHelper::replaceExpression(op1,SageBuilder::buildIntVal(rawval1-rawval2),false);
           break;
         case V_SgMultiplyOp:
           SgNodeHelper::replaceExpression(op1,SageBuilder::buildIntVal(rawval1*rawval2),false);
           break;
         case V_SgDivideOp:
           SgNodeHelper::replaceExpression(op1,SageBuilder::buildIntVal(rawval1/rawval2),false);
           break;
         default:
           cerr<<"Error: rewrite phase: unsopported operator in matched expression. Bailing out."<<endl;
           exit(1);
         }
         transformationApplied=true;
         someTransformationApplied=true;
         dump1_stats.numConstantFolding++;
       }
     }
  } while(transformationApplied);
 //if(someTransformationApplied) cout<<"DEBUG: transformed: "<<root->unparseToString()<<endl;
   } while(someTransformationApplied);
}
Beispiel #8
0
int main (int argc, char* argv[])
{
  rose::global_options.set_frontend_notes(false);
  rose::global_options.set_frontend_warnings(false);
  rose::global_options.set_backend_warnings(false);

  vector<string> argvList(argv, argv+argc);
  argvList.push_back("-rose:skipfinalCompileStep");
  // Build the AST used by ROSE
  //SgProject* sageProject = frontend(argc,argv);
  SgProject* sageProject=frontend (argvList); 

  
  // Run internal consistency tests on AST
  //AstTests::runAllTests(sageProject);
  //AstDOTGeneration dotGen;
  //dotGen.generate(sageProject,"matcher",AstDOTGeneration::TOPDOWN);
  SgNode* root;
  root=sageProject;
#if 0
  std::cout << "TERM INFO OUTPUT: START\n";
  std::cout << astTermToMultiLineString(root,0);
  std::cout << "TERM INFO OUTPUT: END\n";
#endif
  RoseAst ast(root);
  std::string matchexpression="$Root=SgAssignOp($LHS=SgPntrArrRefExp(SgPntrArrRefExp(SgArrowExp($WORK,$DS),$E1),$E2),$RHS)";
  AstMatching m;
  MatchResult r=m.performMatching(matchexpression,root);
  // print result in readable form for demo purposes
  std::cout << "Number of matched patterns with bound variables: " << r.size() << std::endl;
  for(MatchResult::iterator i=r.begin();i!=r.end();++i) {
    std::cout << "MATCH: \n"; 
    //SgNode* n=(*i)["X"];
    for(SingleMatchVarBindings::iterator vars_iter=(*i).begin();vars_iter!=(*i).end();++vars_iter) {
      SgNode* matchedTerm=(*vars_iter).second;
      std::cout << "  VAR: " << (*vars_iter).first << "=" << SPRAY::AstTerm::astTermWithNullValuesToString(matchedTerm) << " @" << matchedTerm << std::endl;
    }
    cout<< "WORK:"<<(*i)["$WORK"]<<" : "<<(*i)["$WORK"]->unparseToString()<<endl;
    cout<< "DS:"<<(*i)["$DS"]<<" : "<<(*i)["$DS"]->unparseToString()<<endl;
    cout<< "E1:"<<(*i)["$E1"]<<" : "<<(*i)["$E1"]->unparseToString()<<endl;
    cout<< "E2:"<<(*i)["$E2"]<<" : "<<(*i)["$E2"]->unparseToString()<<endl;
    cout<< "RHS:"<<(*i)["$RHS"]<<" : "<<(*i)["$RHS"]->unparseToString()<<endl;
    
    // work -> dV[E1][E2] = RHS; ==> work -> dV.set(E1,E2,RHS);
    string work=(*i)["$WORK"]->unparseToString();
    string ds=(*i)["$DS"]->unparseToString();
    string e1=(*i)["$E1"]->unparseToString();
    string e2=(*i)["$E2"]->unparseToString();
    string rhs=(*i)["$RHS"]->unparseToString();
    string oldCode0=(*i)["$Root"]->unparseToString();
    string oldCode="/* OLD: "+oldCode0+"; */\n";
    string newCode0=work+" -> "+ds+".set("+e1+","+e2+","+rhs+")";
    string newCode="      /* NEW: */"+newCode0; // ';' is unparsed as part of the statement that contains the assignop
    SgNodeHelper::replaceAstWithString((*i)["$Root"], oldCode+newCode);
    std::cout << std::endl;
    std::string lineCol=SgNodeHelper::sourceLineColumnToString((*i)["$Root"]);
    cout <<"TRANSFORMATION: "<<lineCol<<" OLD:"<<oldCode0<<endl;
    cout <<"TRANSFORMATION: "<<lineCol<<" NEW:"<<newCode0<<endl;
  }
  m.printMarkedLocations();
  m.printMatchOperationsSequence();
  write_file("astterm.txt",SPRAY::AstTerm::astTermToMultiLineString(root,2));
  write_file("astterm.dot",SPRAY::AstTerm::astTermWithNullValuesToDot(root));
  backend(sageProject);
}
Beispiel #9
0
int main( int argc, char * argv[] ) {

  std::string matchexpression;
  std::cout<<"Enter match-expression: ";
  std::getline(std::cin, matchexpression);

  bool measurementmode=false;
  if(matchexpression[0]=='.') measurementmode=true;

  // Build the AST used by ROSE
  SgProject* sageProject = frontend(argc,argv);
  
  // Run internal consistency tests on AST
  AstTests::runAllTests(sageProject);
  AstDOTGeneration dotGen;
  dotGen.generate(sageProject,"matcher_demo",AstDOTGeneration::TOPDOWN);

  SgNode* root;
  //root=sageProject->get_traversalSuccessorByIndex(0)->get_traversalSuccessorByIndex(0)->get_traversalSuccessorByIndex(0)->get_traversalSuccessorByIndex(0);
  root=sageProject;
#if 0
  std::cout << "TERM INFO OUTPUT: START\n";
  std::cout << astTermToMultiLineString(root,0);
  std::cout << "TERM INFO OUTPUT: END\n";
#endif
  RoseAst ast(root);

#if 0
  int k=0;
  std::cout << "ITERATOR: Check1\n";
  RoseAst::iterator t1=ast.begin();  
  t1.print_top_element();
  RoseAst::iterator t0=ast.end();  
  t0.print_top_element();
  std::cout << "ITERATOR: Check2\n";
  *t1;
  std::cout << "ITERATOR: Check3\n";
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.1\n";
  t1++;
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.1\n";
  t1++;
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.2\n";
  t1++;
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.3\n";
  t1++;
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.4\n";
  t1++;
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.5\n";
  t1++;
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.6\n";
  t1++;
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.6\n";
  t1++;
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.6\n";
  t1++;
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.6\n";
  t1++;
  t1.print_top_element();
  std::cout << "ITERATOR: Check7.6\n";
  std::cout << "ITERATOR: START\n";
  for(RoseAst::iterator i=ast.begin().enableNullNodes();i!=ast.end();++i) {
    if(i.stack_size()==0) {
      std::cout << "\nDEBUG: Error found: empty stack, but we are still iterating:\n";
      std::cout << "i  :" << i.stack_size() << std::endl;
      std::cout << "end:" << ast.end().stack_size() << std::endl;
      std::cout << (i!=ast.end()) << std::endl;
    }
    //i.print_top_element(); std::cout << " :: ";
    std::cout << i.stack_size() << ":";
    if(*i)
      std::cout << k++ << ":"<< typeid(**i).name() << ";";
    else
      std::cout << k++ << ":null;";
    std::cout<<std::endl;
  }
  std::cout << "\nITERATOR: END"<<std::endl;
#endif


  Timer timer;
  timer.start();
  long num1=0,num2=0;
  for(RoseAst::iterator i=ast.begin().withNullValues();i!=ast.end();++i) {
    num1++;
  }
  timer.stop();
  double iteratorMeasurementTime=timer.getElapsedTimeInMilliSec();

  timer.start();
  for(RoseAst::iterator i=ast.begin().withoutNullValues();i!=ast.end();++i) {
    num2++;
  }
  timer.stop();
  double iteratorMeasurementTimeWithoutNull=timer.getElapsedTimeInMilliSec();

  std::cout << "Iteration Length: with    null: " << num1 << std::endl;
  std::cout << "Iteration Length: without null: " << num2 << std::endl;
  
#if 1
  AstMatching m;
  if(!measurementmode) {
    timer.start();
    MatchResult r=m.performMatching(matchexpression,root);
    timer.stop();
    double matchingMeasurementTime=timer.getElapsedTimeInMilliSec();
    // print result in readable form for demo purposes
    std::cout << "Number of matched patterns with bound variables: " << r.size() << std::endl;
    for(MatchResult::iterator i=r.begin();i!=r.end();++i) {
      std::cout << "MATCH: \n"; 
      //SgNode* n=(*i)["X"];
      for(SingleMatchVarBindings::iterator vars_iter=(*i).begin();vars_iter!=(*i).end();++vars_iter) {
        SgNode* matchedTerm=(*vars_iter).second;
        std::cout << "  VAR: " << (*vars_iter).first << "=" << astTermWithNullValuesToString(matchedTerm) << " @" << matchedTerm << std::endl;
      }
      std::cout << std::endl;
      std::cout << "Matching time: "<<matchingMeasurementTime<<endl;
    }
    m.printMarkedLocations();
    m.printMatchOperationsSequence();
    write_file("astterm.txt",astTermToMultiLineString(root,2));
    write_file("astterm.dot",astTermWithNullValuesToDot(root));
  } else {
    std::string measurement_matchexpressions[]={"SgAssignOp","$X=SgAssignOp","_(_,_)","null","$X=SgAssignOp($Y,$Z=SgAddOp)","_($X,..)","_(#$X,..)"};
    int measurement_test_cases_num=7;
    double measurementTimes[7];

    for(int i=0;i<measurement_test_cases_num;i++) {
      timer.start();
      m.performMatching(measurement_matchexpressions[i],root);
      timer.stop();
      measurementTimes[i]=timer.getElapsedTimeInMilliSec();
    }

    TestTraversal tt;
    timer.start();
    tt.traverse(root, preorder);
    timer.stop();
    double ttm=timer.getElapsedTimeInMilliSec();
    std::cout << "Measurement:\n";
    std::cout << "Trav:"<<ttm << ";";
    std::cout << "iter:"<<iteratorMeasurementTime << ";";
    std::cout << "iter0:"<<iteratorMeasurementTimeWithoutNull << ";";
    for(int i=0;i<measurement_test_cases_num;i++) {
      //measurement_matchexpressions[i]
      std::cout << measurementTimes[i] << ";";
    }
    std::cout << std::endl;
  }
#endif
}