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; }
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); }
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); }
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 }