Ejemplo n.º 1
0
int main(int argc, char* argv[]) {
    cout << "INIT: Parsing and creating AST."<<endl;
    SgProject* sageProject = frontend(argc,argv);
    VariableIdMapping variableIdMapping;
    variableIdMapping.computeVariableSymbolMapping(sageProject);
    Labeler labeler(sageProject,&variableIdMapping);
    CFAnalyzer cfanalyzer(&labeler);
    RDAnalyzer rdAnalyzer(&cfanalyzer);
    rdAnalyzer.initialize();
    rdAnalyzer.run();
    return 0;
}
Ejemplo n.º 2
0
void checkLargeSets() {
  VariableIdMapping variableIdMapping;
  VariableId var_x=variableIdMapping.createUniqueTemporaryVariableId("x");
  AType::ConstIntLattice i;
  using namespace AType;
  set<CppCapsuleConstIntLattice> cilSet;
  cilSet.insert(CppCapsuleConstIntLattice(ConstIntLattice(Bot())));
  cilSet.insert(CppCapsuleConstIntLattice(ConstIntLattice(Top())));
  for(int i=-10;i<10;i++) {
	cilSet.insert(CppCapsuleConstIntLattice(ConstIntLattice(i)));
  }
  check("integer set: bot,-10, ... ,+10,top",cilSet.size()==22); // 1+20+1
}
Ejemplo n.º 3
0
Archivo: woodpecker.C Proyecto: 8l/rose
void printCodeStatistics(SgNode* root) {
  SgProject* project=isSgProject(root);
  VariableIdMapping variableIdMapping;
  variableIdMapping.computeVariableSymbolMapping(project);
  VariableIdSet setOfUsedVars=AnalysisAbstractionLayer::usedVariablesInsideFunctions(project,&variableIdMapping);
  DeadCodeElimination dce;
  cout<<"----------------------------------------------------------------------"<<endl;
  cout<<"Statistics:"<<endl;
  cout<<"Number of empty if-statements: "<<dce.listOfEmptyIfStmts(root).size()<<endl;
  cout<<"Number of functions          : "<<SgNodeHelper::listOfFunctionDefinitions(project).size()<<endl;
  cout<<"Number of global variables   : "<<SgNodeHelper::listOfGlobalVars(project).size()<<endl;
  cout<<"Number of used variables     : "<<setOfUsedVars.size()<<endl;
  cout<<"----------------------------------------------------------------------"<<endl;
  cout<<"VariableIdMapping-size       : "<<variableIdMapping.getVariableIdSet().size()<<endl;
  cout<<"----------------------------------------------------------------------"<<endl;
}
Ejemplo n.º 4
0
VariableValuePair FIConstAnalysis::analyzeVariableDeclaration(SgVariableDeclaration* decl,VariableIdMapping& varIdMapping) {
    SgNode* initName0=decl->get_traversalSuccessorByIndex(1); // get-InitializedName
    if(initName0) {
        if(SgInitializedName* initName=isSgInitializedName(initName0)) {
            SgSymbol* initDeclVar=initName->search_for_symbol_from_symbol_table();
            assert(initDeclVar);
            VariableId initDeclVarId=varIdMapping.variableId(initDeclVar);
            SgInitializer* initializer=initName->get_initializer();
            SgAssignInitializer* assignInitializer=0;
            if(initializer && (assignInitializer=isSgAssignInitializer(initializer))) {
                if(detailedOutput) cout << "initializer found:"<<endl;
                SgExpression* rhs=assignInitializer->get_operand_i();
                assert(rhs);
                return VariableValuePair(initDeclVarId,analyzeAssignRhs(rhs));
            } else {
                if(detailedOutput) cout << "no initializer (OK)."<<endl;
                return VariableValuePair(initDeclVarId,AType::Top());
            }
        } else {
            cerr << "Error: in declaration (@initializedName) no variable found ... bailing out."<<endl;
            exit(1);
        }
    } else {
        cerr << "Error: in declaration: no variable found ... bailing out."<<endl;
        exit(1);
    }
}
VariableIdSet AnalysisAbstractionLayer::astSubTreeVariables(SgNode* node, VariableIdMapping& vidm) {
  VariableIdSet vset;
  RoseAst ast(node);
  for(RoseAst::iterator i=ast.begin();i!=ast.end();++i) {
    VariableId vid; // default creates intentionally an invalid id.
    if(SgVariableDeclaration* varDecl=isSgVariableDeclaration(*i)) {
      vid=vidm.variableId(varDecl);
    } else if(SgVarRefExp* varRefExp=isSgVarRefExp(*i)) {
      vid=vidm.variableId(varRefExp);
    } else if(SgInitializedName* initName=isSgInitializedName(*i)) {
      vid=vidm.variableId(initName);
    }
    if(vid.isValid())
      vset.insert(vid);
  }
  return vset;
}
Ejemplo n.º 6
0
void DefUseVarsInfo::addAllArrayElements(SgInitializedName* array_name, VariableIdMapping& vidm, bool def)
{
  assert(array_name);
  VariableId array_var_id = vidm.variableId(array_name);
  SgArrayType* array_type = isSgArrayType(array_name->get_type());
  if (!array_type)
    return;
  int elements = vidm.getArrayElementCount(array_type);
  if (!elements)
    elements = vidm.getArrayDimensionsFromInitializer(isSgAggregateInitializer(array_name->get_initializer()));
  VarsInfo& info = (def ? def_vars_info : use_vars_info);
  VariableIdTypeInfo sgn_type_info_elem = getVariableIdTypeInfo(array_var_id, vidm);
  for (int e = 0; e < elements; e++) {
    VariableId element_id = vidm.variableIdOfArrayElement(array_var_id, e);
    info.first.insert(VariableIdInfo(element_id, sgn_type_info_elem));
  }
}
Ejemplo n.º 7
0
bool FIConstAnalysis::determineVariable(SgNode* node, VariableId& varId, VariableIdMapping& _variableIdMapping) {
    assert(node);
    if(SgVarRefExp* varref=isSgVarRefExp(node)) {
        // found variable
        //assert(_variableIdMapping);
#if 1
        SgSymbol* sym=varref->get_symbol();
        ROSE_ASSERT(sym);
        varId=_variableIdMapping.variableId(sym);
#else
        // MS: to investigate: even with the new var-sym-only case this does not work
        // MS: investigage getSymbolOfVariable
        varId=_variableIdMapping.variableId(varref);
#endif
        return true;
    } else {
        VariableId defaultVarId;
        varId=defaultVarId;
        return false;
    }
}
Ejemplo n.º 8
0
std::string SPRAY::VariableIdSetPrettyPrint::str(VariableIdSet& vset, VariableIdMapping& vidm)
{
  std::ostringstream ostr;
  ostr << "[";
  VariableIdSet::iterator it = vset.begin();
  for( ; it != vset.end(); )
  {
    ostr << "<" << (*it).toString() << ", " << vidm.variableName(*it)  << ">";
    it++;
    if(it != vset.end())
      ostr << ", ";
  }
  ostr << "]";
  return ostr.str();
}
Ejemplo n.º 9
0
VarConstSetMap FIConstAnalysis::computeVarConstValues(SgProject* project, SgFunctionDefinition* mainFunctionRoot, VariableIdMapping& variableIdMapping) {
    VarConstSetMap varConstIntMap;

    VariableIdSet varIdSet=AnalysisAbstractionLayer::usedVariablesInsideFunctions(project,&variableIdMapping);

    // initialize map such that it is resized to number of variables of interest
    for(VariableIdSet::iterator i=varIdSet.begin(); i!=varIdSet.end(); ++i) {
        set<CppCapsuleConstIntLattice> emptySet;
        varConstIntMap[*i]=emptySet;
    }
    cout<<"STATUS: Initialized const map for "<<varConstIntMap.size()<< " variables."<<endl;

    cout << "STATUS: Number of global variables: ";
    list<SgVariableDeclaration*> globalVars=SgNodeHelper::listOfGlobalVars(project);
    cout << globalVars.size()<<endl;
    VariableIdSet setOfUsedVars=AnalysisAbstractionLayer::usedVariablesInsideFunctions(project,&variableIdMapping);
    cout << "STATUS: Number of used variables: "<<setOfUsedVars.size()<<endl;
#if 0
    int filteredVars=0;
    set<CppCapsuleConstIntLattice> emptySet;
    for(list<SgVariableDeclaration*>::iterator i=globalVars.begin(); i!=globalVars.end(); ++i) {
        VariableId globalVarId=variableIdMapping.variableId(*i);
        if(setOfUsedVars.find(globalVarId)!=setOfUsedVars.end()) {
            VariableValuePair p=analyzeVariableDeclaration(*i,variableIdMapping);
            ConstIntLattice varValue=p.varValue;
            varConstIntMap[p.varId]=emptySet; // create mapping
            varConstIntMap[p.varId].insert(CppCapsuleConstIntLattice(varValue));
            variablesOfInterest.insert(p.varId);
            //set<CppCapsuleConstIntLattice>& myset=varConstIntMap[p.varId];
        } else {
            filteredVars++;
        }
    }
    cout << "STATUS: Number of filtered variables for initial state: "<<filteredVars<<endl;
#endif
    variablesOfInterest=setOfUsedVars;
    if(mainFunctionRoot!=0) {
        determineVarConstValueSet(mainFunctionRoot,variableIdMapping,varConstIntMap);
    } else {
        // compute value-sets for entire program (need to cover all functions without inlining)
        determineVarConstValueSet(project,variableIdMapping,varConstIntMap);
    }
    return varConstIntMap;
}
Ejemplo n.º 10
0
VariableIdTypeInfo getVariableIdTypeInfo(VariableId vid, VariableIdMapping& vidm)
{
  SgSymbol* symb = vidm.getSymbol(vid); ROSE_ASSERT(symb);
  SgType* sgn_type = symb->get_type();
  VariableIdTypeInfo sgn_type_info;

  if(isSgArrayType(sgn_type))
    sgn_type_info = arrayType;
  else if(isSgPointerType(sgn_type))
    sgn_type_info = pointerType;
  else if(isSgReferenceType(sgn_type))
    sgn_type_info = referenceType;
  else if(isSgClassType(sgn_type))
    sgn_type_info = classType;
  else
    sgn_type_info = variableType;

  return sgn_type_info;
}
Ejemplo n.º 11
0
std::string DefUseVarsInfo::varsInfoPrettyPrint(VarsInfo& vars_info, VariableIdMapping& vidm)
{
  std::ostringstream oss;
  oss << "[" << (vars_info.second? "true" : "false") << ", ";
  oss << "{";
  VariableIdInfoMap::iterator it = vars_info.first.begin();
  for( ; it != vars_info.first.end();  )
  {
    // oss << "<" << (*it).first.toString() << ", " << vidm.variableName((*it).first) << ", ";
    oss << "<" << vidm.uniqueShortVariableName((*it).first) << ", " << variableIdTypeInfoToString((*it).second);
    oss <<">";
    it++;
    if(it != vars_info.first.end())
      oss << ", ";
  }
  oss << "}";
  oss <<"]";
  return oss.str();
}
Ejemplo n.º 12
0
Archivo: woodpecker.C Proyecto: 8l/rose
void printResult(VariableIdMapping& variableIdMapping, VarConstSetMap& map) {
  cout<<"Result:"<<endl;
  VariableConstInfo vci(&variableIdMapping, &map);
  for(VarConstSetMap::iterator i=map.begin();i!=map.end();++i) {
    VariableId varId=(*i).first;
    //string variableName=variableIdMapping.uniqueShortVariableName(varId);
    string variableName=variableIdMapping.variableName(varId);
    set<ConstIntLattice> valueSet=(*i).second;
    stringstream setstr;
    setstr<<"{";
    for(set<ConstIntLattice>::iterator i=valueSet.begin();i!=valueSet.end();++i) {
      if(i!=valueSet.begin())
        setstr<<",";
      setstr<<(*i).toString();
    }
    setstr<<"}";
    cout<<variableName<<"="<<setstr.str()<<";";
#if 1
    cout<<"Range:"<<VariableConstInfo::createVariableValueRangeInfo(varId,map).toString();
    cout<<" width: "<<VariableConstInfo::createVariableValueRangeInfo(varId,map).width().toString();
    cout<<" top: "<<VariableConstInfo::createVariableValueRangeInfo(varId,map).isTop();
    cout<<endl;
#endif
    cout<<" isAny:"<<vci.isAny(varId)
        <<" isUniqueConst:"<<vci.isUniqueConst(varId)
        <<" isMultiConst:"<<vci.isMultiConst(varId);
    if(vci.isUniqueConst(varId)||vci.isMultiConst(varId)) {
      cout<<" width:"<<vci.width(varId);
    } else {
      cout<<" width:unknown";
    }
    cout<<" Test34:"<<vci.isInConstSet(varId,34);
    cout<<endl;
  }
  cout<<"---------------------"<<endl;
}
Ejemplo n.º 13
0
int main( int argc, char * argv[] )
   {
  // If we want this translator to take specific options (beyond those defined 
  // by ROSE) then insert command line processing for new options here.

  // To better support the stencil specification that might benifit from constant 
  // folding, I have turned this ON is hte frontend.  By default it is OFF so that
  // we can preserve source code as much as possible (original expression trees).
  // The Stencil DSL can be made to work in eithr setting, but this make sure that
  // dimension dependent processing of the stencil coeficients will be evaluated 
  // to constants.  I will turn this off (and thus use a less blunt axe) when the new
  // constant expression evaluation in ROSE is fixed to support more general types
  // than integer expresion (should be done by JP later today).
  // bool frontendConstantFolding = true;
     bool frontendConstantFolding = false;

  // Generate the ROSE AST.
     SgProject* project = frontend(argc,argv,frontendConstantFolding);
     ROSE_ASSERT(project != NULL);

     try
        {
          variableIdMapping.computeVariableSymbolMapping(project);
        }
     catch(char* str)
        {
          cout << "*Exception raised: " << str << endl;
        } 
     catch(const char* str) 
        {
          cout << "Exception raised: " << str << endl;
        } 
     catch(string str)
        {
          cout << "Exception raised: " << str << endl;
        }

  // variableIdMapping.toStream(cout);

#if 1
     printf ("variableIdMapping.getVariableIdSet().size() = %zu \n",variableIdMapping.getVariableIdSet().size());
     ROSE_ASSERT(variableIdMapping.getVariableIdSet().size() > 0);
#endif

#if 0
     printf ("Exiting as a test after calling variableIdMapping.computeVariableSymbolMapping(project) \n");
     ROSE_ASSERT(false);
#endif

#if 0
     printf ("Calling constant folding \n");
     ConstantFolding::constantFoldingOptimization(project,false);

#if 0
     printf ("Exiting as a test after calling ConstantFolding::constantFoldingOptimization() \n");
     ROSE_ASSERT(false);
#endif
#endif

  // DQ (2/8/2015): Find the associated SgFile so we can restrict processing to the current file.
     ROSE_ASSERT(project->get_fileList().empty() == false);
     SgFile* firstFile = project->get_fileList()[0];
     ROSE_ASSERT(firstFile != NULL);

#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen;
     astdotgen.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_before_transformation");
#endif
#if DEBUG_USING_DOT_GRAPHS && 1
     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 12000;
#endif
#if DEBUG_USING_DOT_GRAPHS && 1
  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
     generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_before");
#endif

  // Build the inherited attribute
     Detection_InheritedAttribute inheritedAttribute;

  // Define the traversal
     DetectionTraversal shiftCalculus_DetectionTraversal;

#if 1
     printf ("Call the Detection traversal starting at the project (root) node of the AST \n");
#endif

  // Call the traversal starting at the project (root) node of the AST
  // Detection_SynthesizedAttribute result = shiftCalculus_DetectionTraversal.traverse(project,inheritedAttribute);
     Detection_SynthesizedAttribute result = shiftCalculus_DetectionTraversal.traverseWithinFile(firstFile,inheritedAttribute);
#if 0
     printf ("Stencil Operator was transformed: %s \n",result.get_stencilOperatorTransformed() ? "true" : "false");
#endif
     ROSE_ASSERT(result.get_stencilOperatorTransformed() == false);

#if 1
     printf ("DONE: Call the Detection traversal starting at the project (root) node of the AST \n");
#endif
#if 0
     shiftCalculus_DetectionTraversal.display();
#endif
#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen_2;
     astdotgen_2.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_after_DSL_detection");
#endif
#if 0
     printf ("Exiting after the initial traversal to detect the stencil useage. \n");
     ROSE_ASSERT(false);
#endif

  // Build the inherited attribute
     StencilEvaluation_InheritedAttribute inheritedAttribute_stencilEval;

  // Define the traversal
  // StencilEvaluationTraversal shiftCalculus_StencilEvaluationTraversal(shiftCalculus_DetectionTraversal);
     StencilEvaluationTraversal shiftCalculus_StencilEvaluationTraversal;

#if 1
     printf ("Call the StencilEvaluation traversal starting at the project (root) node of the AST \n");
#endif

  // Call the traversal starting at the project (root) node of the AST
  // StencilEvaluation_SynthesizedAttribute result_stencilEval = shiftCalculus_StencilEvaluationTraversal.traverse(project,inheritedAttribute_stencilEval);
     StencilEvaluation_SynthesizedAttribute result_stencilEval = shiftCalculus_StencilEvaluationTraversal.traverseWithinFile(firstFile,inheritedAttribute_stencilEval);

#if 0
     printf ("Stencil Evaluation was transformed: %s \n",result_stencilEval.get_stencilOperatorTransformed() ? "true" : "false");
#endif
     ROSE_ASSERT(result_stencilEval.get_stencilOperatorTransformed() == false);

#if 1
     printf ("DONE: Call the StencilEvaluation traversal starting at the project (root) node of the AST \n");
#endif
#if 1
     shiftCalculus_StencilEvaluationTraversal.displayStencil("After evaluation of stencil");
#endif
#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen_3;
     astdotgen_3.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_after_DSL_evaluation");
#endif

#if 1
     printf ("Call generateStencilCode to generate example code \n");
#endif

#if 0
     printf ("Exiting after the second traversal to evaluate the stencils. \n");
     ROSE_ASSERT(false);
#endif

  // Generate code from stencil data structure.
     bool generateLowlevelCode = true;
     generateStencilCode(shiftCalculus_StencilEvaluationTraversal,generateLowlevelCode);

#if 1
     printf ("DONE: Call generateStencilCode to generate example code \n");
#endif

#if 0
     printf ("Exiting after call to generateStencilCode() \n");
     ROSE_ASSERT(false);
#endif

  // AST consistency tests (optional for users, but this enforces more of our tests)
     AstTests::runAllTests(project);

#if DEBUG_USING_DOT_GRAPHS
     printf ("Write out the DOT file after the transformation \n");
  // generateDOTforMultipleFile(*project,"after_transformation");
     generateDOT(*project,"_after_transformation");
     printf ("DONE: Write out the DOT file after the transformation \n");
#endif
#if DEBUG_USING_DOT_GRAPHS && 0
  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
  // const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 10000;
     generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_after");
#endif

  // Regenerate the source code but skip the call the to the vendor compiler.
     return backend(project);
   }
Ejemplo n.º 14
0
void checkTypes() {
  VariableIdMapping variableIdMapping;
  PState s1;
  cout << "RUNNING CHECKS:"<<endl;
  {
    // check temporary variables (create and delete)
    VariableId var_tmp=variableIdMapping.createUniqueTemporaryVariableId("tmp");
    variableIdMapping.deleteUniqueTemporaryVariableId(var_tmp);
  }

  {
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR BOOLLATTICE TYPE:"<<endl;
    AType::BoolLattice a;
    a=true;
    check("a=true => isTrue",a.isTrue());
    AType::BoolLattice b;
    b=false;
    check("b=false => isFalse",b.isFalse());
    AType::BoolLattice c=a||b;
    check("c=a||b => c isTrue ",c.isTrue());
    AType::Top e;
    AType::BoolLattice d;
    d=e;
    check("Top e; d=e => d isTop",d.isTop());
    c=c||d;
    check("c=c||d: true",c.isTrue());
    AType::BoolLattice f=AType::Bot();
    d=AType::Bot();
    check("d=bot: bot",d.isBot());
    check("f=bot: bot",f.isBot());
    a=d&&f;
    check("a=d&&f => a isBot",a.isBot());
    f=false;
    check("f=false => f isFalse",f.isFalse());
    a=d&&f;
    check("a=d&&f: a isFalse (we define it this way)",a.isFalse());
  }

  {
    cout << "RUNNING CHECKS FOR CONSTINT LATTICE TYPE:"<<endl;
    AType::ConstIntLattice a;
    a=true;
    check("a=true => isTrue",a.isTrue());
    check("a=true => !isFalse",!a.isFalse());
    AType::ConstIntLattice b;
    b=false;
    check("b=false => isFalse",b.isFalse());
    check("b=false => !isTrue",!b.isTrue());
    AType::ConstIntLattice c=a.operatorOr(b);
    check("c=a.operatorOr(b): ",c.isTrue());
    AType::Top e;
    AType::ConstIntLattice d;
    d=e;
    check("Top e; d=e; d isTop ",d.isTop());
    c=c.operatorOr(d);
    check("c=c.operatorOr(d) => c isTrue ",c.isTrue());
    AType::ConstIntLattice f=AType::Bot();
    d=AType::Bot();
    
    a=d.operatorAnd(f);
    check("d=bot;f=bot;a=d.operatorAnd(f); => a isBot",a.isBot());
    f=false;
    a=d.operatorAnd(f);
    check("f=false; a=d.operatorAnd(f); => a isFalse",a.isFalse());
    a=5;
    check("a=5; a.isTrue()==true",a.isTrue()==true);
    check("a=5; a.isFalse()==false",a.isFalse()==false);

    a=0;
    check("a=0; a.isTrue()==false",a.isTrue()==false);
    check("a=0; a.isFalse())==true",a.isFalse()==true);
  }

  {
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR CONSTRAINT TYPE:"<<endl;
    VariableId var_x=variableIdMapping.createUniqueTemporaryVariableId("x");
    VariableId var_y=variableIdMapping.createUniqueTemporaryVariableId("y");
    cout << "P1"<<endl;
    Constraint c1(Constraint::EQ_VAR_CONST,var_x,1);
    cout << "P2"<<endl;
    Constraint c2(Constraint::NEQ_VAR_CONST,var_y,2);
    cout << "P3"<<endl;
    Constraint c3=DISEQUALITYCONSTRAINT;
    cout << "P4"<<endl;
    Constraint c4=Constraint(Constraint::EQ_VAR_CONST,var_y,2);
    cout << "P5"<<endl;
    ConstraintSet cs;
    cout << "P6"<<endl;
    cs.addConstraint(c1);
    cout << "P7"<<endl;
    cout << "CS1:"<<cs.toString()<<endl;
    cs.addConstraint(c2);
    cout << "CS2:"<<cs.toString()<<endl;
    check("inserted 2 different constraints, size of constraint set == 3",cs.size()==2);
    check("c1:constraintExists(EQ_VAR_CONST,x,1) == true",cs.constraintExists(Constraint::EQ_VAR_CONST,var_x,1));
    check("c1:constraintExists(NEQ_VAR_CONST,x,1) == false",!cs.constraintExists(Constraint::NEQ_VAR_CONST,var_x,1));
    check("c2:constraintExists(NEQ_VAR_CONST,y,2) == true",cs.constraintExists(Constraint::NEQ_VAR_CONST,var_y,2));
    check("c3:isDisequality==false",cs.disequalityExists()==false);
    cout << "CS3:"<<cs.toString()<<endl;
    cs.addConstraint(c4);
    cout << "CS4:"<<cs.toString()<<endl;
    cout << "P8"<<endl;
    //cout << "CS:"<<cs.toString()<<endl;
    check("insert y==2; => disequalityExists() == true",cs.disequalityExists());
    cout << "P9"<<endl;
    cs.addConstraint(c3);
    check("added disequality => disequalityExists() == true",cs.disequalityExists());
    check("Disequality exists <=> size()==1",cs.size()==1);
    check("c1!=c2",c1!=c2);
    check("c1!=c3",c1!=c3);
    check("c2!=c3",c2!=c3);

    {
      // check for equalities 
      {
        Constraint c1(Constraint::EQ_VAR_CONST,var_x,1);
        Constraint c2=Constraint(Constraint::EQ_VAR_CONST,var_y,2);
        ConstraintSet cs1;
        cs1.addConstraint(c1);
        cs1.addConstraint(c2);
        Constraint c5(Constraint::EQ_VAR_VAR,var_x,var_y);
        cs1.addConstraint(c5);
        check("cs1.disequalityExists()==true",cs1.disequalityExists());
      }
      {
        Constraint c1(Constraint::NEQ_VAR_CONST,var_x,1);
        Constraint c2=Constraint(Constraint::NEQ_VAR_CONST,var_x,2);
        Constraint c3=Constraint(Constraint::NEQ_VAR_CONST,var_y,3);
        ConstraintSet cs1;
        cs1.addConstraint(c1);
        cs1.addConstraint(c2);
        cs1.addConstraint(c3);
        Constraint c5(Constraint::EQ_VAR_VAR,var_x,var_y);
        cs1.addConstraint(c5);
        check("c5:constraintExists(EQ_VAR_VAR,x,y) == true",cs1.constraintExists(Constraint(Constraint::EQ_VAR_VAR,var_x,var_y)));    

        check("c1:constraintExists(EQ_VAR_CONST,x,1) == false",cs1.constraintExists(Constraint::EQ_VAR_CONST,var_x,1)==false);
        check("c1:constraintExists(NEQ_VAR_CONST,x,1) == true",cs1.constraintExists(Constraint::NEQ_VAR_CONST,var_x,1)==true);
        check("c1:constraintExists(EQ_VAR_CONST,y,2) == false",cs1.constraintExists(Constraint::EQ_VAR_CONST,var_y,2)==false);
        check("c1:constraintExists(NEQ_VAR_CONST,y,2) == true",cs1.constraintExists(Constraint::NEQ_VAR_CONST,var_y,2)==true);
        cs1.removeAllConstraintsOfVar(var_x);
        cs1.removeAllConstraintsOfVar(var_y);
        cs1.removeAllConstraintsOfVar(var_x);
      }
    }
    ConstraintSet cs1;
    cs1.addConstraint(c1);
    ConstraintSet cs2;
    cs2.addConstraint(c2);
    check("cs1!=cs2)",cs1!=cs2);

    {
      Constraint c1(Constraint::NEQ_VAR_CONST,var_y,1);
      Constraint c2(Constraint::NEQ_VAR_CONST,var_y,3);
      Constraint c3(Constraint::NEQ_VAR_CONST,var_y,5);
      Constraint c4a(Constraint::EQ_VAR_CONST,var_y,6);
      Constraint c4b(Constraint::EQ_VAR_CONST,var_y,3);
      ConstraintSet cs1;
      ConstraintSet cs2;
      PState s;
      cs1.addConstraint(c1);
      cs1.addConstraint(c2);
      cs1.addConstraint(c3);
      cs2.addConstraint(c1);
      cs2.addConstraint(c3);
      check("cs1!=cs2",cs1!=cs2);
      check("!(cs1==cs2)",!(cs1==cs2));
      check("!(cs1<cs2)",!(cs1<cs2));
      check("cs1>cs2",(cs2<cs1));
      EStateSet es;
      EState es1=EState(1,&s,&cs1);
      es.processNewOrExisting(es1);
      EState es2=EState(1,&s,&cs2);
      es.processNewOrExisting(es2);
      check("es.size()==2",es.size()==2);
      {
      Constraint c5(Constraint::EQ_VAR_CONST,var_y,10);
      cs1.addConstraint(c5);
      check("constraintExists(NEQ_VAR_CONST,y,1) == false",cs1.constraintExists(Constraint::NEQ_VAR_CONST,var_y,1)==false);
      check("constraintExists(NEQ_VAR_CONST,y,3) == false",cs1.constraintExists(Constraint::NEQ_VAR_CONST,var_y,3)==false);
      check("constraintExists(NEQ_VAR_CONST,y,5) == false",cs1.constraintExists(Constraint::NEQ_VAR_CONST,var_y,5)==false);
      check("cs1.size()==1",cs1.size()==1);
      }
    }
  }
  {  
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR CONSTINTLATTICE (formerly CPPCAPSULE):"<<endl;
    AType::ConstIntLattice cint1(1);
    check("cint1 == 1",cint1.getIntValue()==1);
    AType::ConstIntLattice cint2=AType::Top();
    AType::ConstIntLattice cint3;
    cint3=AType::Top();
    check("cint2 isTop",cint2.isTop());
    check("cint3 isTop",cint3.isTop());
    check("!(cint1 == cint3)",!(cint1==cint3)); // strictly weak ordering test
    check("cint2 == cint3",cint2==cint3); // strictly weak ordering test
  }
  {
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR PSTATE AND PSTATESET:"<<endl;
    VariableIdMapping variableIdMapping;
    EState es1;
    EState es2;
    PState s0;
    PState s1;
    PState s2;
    PState s3;
    PState s5;
    AValue valtop=AType::Top();
    AValue val1=500;
    AValue val2=501;
    PStateSet pstateSet;
    VariableId x=variableIdMapping.createUniqueTemporaryVariableId("x");
    VariableId y=variableIdMapping.createUniqueTemporaryVariableId("y");
    check("var x not in pstate1",s1.varExists(x)==false);
    check("var y not in pstate2",s2.varExists(y)==false);
    s1[x]=val1;
    s2[y]=val2;
    s3[x]=val2;
    s5[x]=valtop;
    s5[y]=valtop;
    check("var x exists in pstate s1",s1.varExists(x)==true);
    check("var x==500",((s1[x].operatorEq(val1)).isTrue())==true);
    check("var y exists in pstate s2",s2.varExists(y)==true);
    check("var y==501",((s2[y].operatorEq(val2)).isTrue())==true);
    //check("s0 < s1",(s0<s1)==true);
    //check("s0 < s2",(s0<s2)==true);
    check("!(s1 == s2)",(s1==s2)==false);
    check("s1<s2 xor s2<s1)",(s1<s2)^(s2<s1));
    check("var x in pstate s3",s3.varExists(x)==true);
    check("s3[x]==501",((s3[x].operatorEq(val2)).isTrue())==true);
    check("!(s1==s2)",(!(s1==s2))==true);
    check("!(s1==s3)",(!(s1==s3))==true);
    check("!(s2==s3)",(!(s2==s3))==true);
    PState s4=s1;
    check("s1==s4",(s1==s4)==true);

    s1[x]=val2;
    check("s1.size()==1",s1.size()==1);

    pstateSet.process(s0);
    check("empty pstate s0 inserted in pstateSet => size of pstateSet == 1",pstateSet.size()==1);
    pstateSet.process(s1);
    check("s1 inserted in pstateSet => size of pstateSet == 2",pstateSet.size()==2);
    pstateSet.process(s1);
    check("s1 reinserted in pstateSet => size remains the same",pstateSet.size()==2);
    pstateSet.process(s2);
    check("s2 inserted => size of pstateSet == 3",pstateSet.size()==3);

    const PState* pstateptr0=pstateSet.processNewOrExisting(s0); // version 1
    check("obtain pointer to s0 from pstateSet and check !=0",pstateptr0!=0);
    check("check pointer refers indeed to s0 (operator==)",(*pstateptr0)==s0);
    const PState* pstateptr1=pstateSet.processNewOrExisting(s1); // version 1
    check("obtain pointer to s1 from pstateSet and check !=0",pstateptr1!=0);
    const PState* pstateptr2=pstateSet.processNewOrExisting(s2); // version 1
    check("obtain pointer to s2 from pstateSet and check !=0",pstateptr2!=0);
    check("check pstate.exists(s0)",pstateSet.exists(s0));
    check("check pstate.exists(s1)",pstateSet.exists(s1));
    check("check pstate.exists(s2)",pstateSet.exists(s2));
    check("check !pstate.exists(s5) [s5 does not exist]",!pstateSet.exists(s5));
    check("constint-strictWeak-equality-1",strictWeakOrderingIsEqual(val1,val2)==false);
    check("constint-strictWeak-smaller-1",strictWeakOrderingIsSmaller(val1,val2)==true);

    s4[x]=valtop;
    check("created s4; inserted x=top; s4[x].isTop",s4[x].isTop());    
    pstateSet.processNewOrExisting(s4);
    check("inserted s4 => size of pstateSet == 4",pstateSet.size()==4);    
    const PState* pstateptr4=pstateSet.processNewOrExisting(s4); // version 1
    check("obtain pointer to s4 from pstateSet and check !=0",pstateptr4!=0);

#if 1
    EStateSet eStateSet;
    EState es3;
    ConstraintSetMaintainer csm;

    ConstraintSet cs1;
    cs1.addConstraint(Constraint(Constraint::NEQ_VAR_CONST,x,1));
    const ConstraintSet* cs1ptr=csm.processNewOrExisting(cs1);
    es1=EState(1,pstateptr1,cs1ptr);
    
    ConstraintSet cs2;
    cs2.addConstraint(Constraint(Constraint::EQ_VAR_CONST,x,1));
    const ConstraintSet* cs2ptr=csm.processNewOrExisting(cs2);
    es2=EState(1,pstateptr1,cs2ptr);

    ConstraintSet cs3;
    cs3.addConstraint(Constraint(Constraint::NEQ_VAR_CONST,x,1));
    const ConstraintSet* cs3ptr=csm.processNewOrExisting(cs3);
    es3=EState(3,pstateptr4,cs3ptr);

    check("check es1 does not exist in eStateSet",eStateSet.exists(es1)==0);
    check("check es2 does not exist in eStateSet",eStateSet.exists(es2)==0);
    check("check es3 does not exist in eStateSet",eStateSet.exists(es3)==0);

    check("es1!=es2",es1!=es2);
    check("es2!=es3",es1!=es3);
    check("es1!=es3",es2!=es3);
#ifdef ESTATE_MAINTAINER_LIST
    nocheck("es1<es2",es2<es1);
    nocheck("!(es2<es1)",!(es1<es2));
#endif
#ifdef ESTATE_MAINTAINER_SET
    check("es1<es2",es1<es2);
    check("!(es2<es1)",!(es2<es1));
#endif

    check("!(es1==es2)",!(es1==es2));

#ifdef ESTATE_MAINTAINER_LIST
    nocheck("es1<es3",es1<es3);
    nocheck("es2<es3",es2<es3);
#endif
#ifdef ESTATE_MAINTAINER_SET
    check("es1<es3",es1<es3);
    check("es2<es3",es2<es3);
#endif

    check("es2==es2",es2==es2);
    check("=> eStateSet.size() == 0",eStateSet.size() == 0);

    check("es1 does not exist in eStateSet",!eStateSet.exists(es2));
    eStateSet.processNewOrExisting(es1);
    const EState* estateptr1=eStateSet.processNewOrExisting(es1);
    check("add es1 and obtain pointer to es1 from eStateSet and check !=0",estateptr1!=0);
    check("es1 exists in eStateSet",eStateSet.exists(es1));
    check("=> eStateSet.size() == 1",eStateSet.size() == 1);

    check("es2 does not exist in eStateSet",!eStateSet.exists(es2));
    eStateSet.processNewOrExisting(es2);
    const EState* estateptr2=eStateSet.processNewOrExisting(es2);
    check("add es2 and obtain pointer to es2 from eStateSet and check !=0",estateptr2!=0);
    check("es2 exists in eStateSet",eStateSet.exists(es2));
    check("=> eStateSet.size() == 2",eStateSet.size() == 2);

    check("es3 does not exist in eStateSet",!eStateSet.exists(es3));
    eStateSet.processNewOrExisting(es3);
    const EState* estateptr3=eStateSet.processNewOrExisting(es3);
    check("add es3 and obtain pointer to es3 from eStateSet and check !=0",estateptr3!=0);
    check("es3 exists in eStateSet",eStateSet.exists(es3));
    check("=> eStateSet.size() == 3",eStateSet.size() == 3);
    checkLargeSets();
#endif
 }
#if 0
  // MS: TODO: rewrite the following test to new check format
  {
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR COMBINED TYPES:"<<endl;
    EState es1;
    EState es2;
    cout << "EState created. "<<endl;
    cout << "empty EState: "<<es1.toString()<<endl;
    es1.setLabel(1);
    VariableId var_x=variableIdMapping.createUniqueTemporaryVariableId("x");
    es1.constraints.addConstraint(Constraint(Constraint::EQ_VAR_CONST,var_x,1));
    es2.setLabel(1);
    es2.constraints.addConstraint(Constraint(Constraint::NEQ_VAR_CONST,var_x,1));
    cout << "empty EState with label and constraint es1: "<<es1.toString()<<endl;
    cout << "empty EState with label and constraint es2: "<<es2.toString()<<endl;
    PState s;
    es1.setPState(&s);
    es2.setPState(&s);
    cout << "empty EState with label, empty pstate, and constraint es1: "<<es1.toString()<<endl;
    cout << "empty EState with label, empty pstate, and constraint es2: "<<es2.toString()<<endl;
    bool testres=(es1==es2);
    if(testres)
      cout << "es1==es2: "<<testres<< "(not as expected: FAIL)"<<endl;
    else
      cout << "es1==es2: "<<testres<< "(as expected: PASS)"<<endl;
  }
#endif

  // check stream operators
  {
    cout << "------------------------------------------"<<endl;
    cout << "RUNNING CHECKS FOR INPUT/OUTPUT STREAM OPs"<<endl;

    stringstream ss2;
    ss2<<"test1";
    check("Parse: Testing test2 on test1.",!SPRAY::Parse::checkWord("test2",ss2));
    //cout << "Remaing stream: "<<ss2.str()<<endl;
    stringstream ss3;
    ss3<<"test1";
    check("Parse: Testing test1 on test1.",SPRAY::Parse::checkWord("test1",ss3));
    //cout << "Remaing stream: "<<ss3.str()<<endl;

    CodeThorn::AType::ConstIntLattice x;
    stringstream ss4;
    ss4<<"top";
    x.fromStream(ss4);
    check("ConstIntLattice: streaminput: top",x.toString()=="top");
    stringstream ss5;
    ss5<<"12";
    x.fromStream(ss5);
    check("ConstIntLattice: streaminput: 12",x.toString()=="12");
    stringstream ss6;
    ss6<<"15top16";
    ss6>>x;
    check("ConstIntLattice: streaminput: 15",x.toString()=="15");
    ss6>>x;
    check("ConstIntLattice: streaminput: top",x.toString()=="top");
    ss6>>x;
    check("ConstIntLattice: streaminput: 16",x.toString()=="16");

    {
      PState ps;
      stringstream ss1;
      string pstateString="{}";
      ss1<<pstateString;
      ps.fromStream(ss1);
      string checkString=(string("stream input PState: ")+pstateString);
      bool checkresult=(ps.toString()==pstateString);
      check(checkString,checkresult);
      if(checkresult==false) {
        cout << "Error: input stream result: "<<ps.toString()<<endl;
      }
    }
    {
      PState ps;
      stringstream ss0;
      string pstateString="{(V0,5),(V1,top),(V2,bot)}";
      ss0<<pstateString;
      ss0>>ps;
      string checkString=(string("stream input PState: ")+pstateString);
      bool checkresult=(ps.toString()==pstateString);
      check(checkString,checkresult);
      if(checkresult==false) {
        cout << "pstateString :"<<pstateString<<":"<<endl;
        cout << "ps.toString():"<<ps.toString()<<":"<<endl;
      }
    }
    {
      stringstream ss;
      string s="aaabbb";
      ss<<s;
      string parseString="aaa";
      SPRAY::Parse::parseString(parseString,ss); // throws exception if it fails
      char next;
      ss>>next;
      check(string("Parsing: ")+parseString+" from:"+s+" Next:"+next,true);      
    }
    {
      Constraint cs;
      stringstream ss;
      stringstream ssout;
      string cstring="V1==V2";
      ss<<cstring;
      cs.fromStream(ss);
      cs.toStream(ssout);
      check("Stream I/O constraint: "+cstring,ssout.str()==cstring);
    }
    {
      Constraint cs;
      stringstream ss;
      stringstream ssout;
      string cstring="V3!=4";
      ss<<cstring;
      cs.fromStream(ss);
      cs.toStream(ssout);
      check("Stream I/O constraint: "+cstring,ssout.str()==cstring);
    }
    {
      Constraint cs;
      cs=DISEQUALITYCONSTRAINT;
      stringstream ss;
      stringstream ssout;
      string cstring=cs.toString();
      ss<<cstring;
      cs.fromStream(ss);
      cs.toStream(ssout);
      check("Stream I/O DEQ constraint: "+cstring,ssout.str()==cstring);
    }
#ifndef EXCLUDE_RDANALYSIS
    {
      RDLattice a;
      VariableId var1;
      var1.setIdCode(1);
      VariableId var2;
      var2.setIdCode(2);
      a.insertPair(1,var1);
      RDLattice b;
      b.insertPair(1,var1);
      b.insertPair(2,var2);
      //a.toStream(cout);cout<<endl;
      //b.toStream(cout);cout<<endl;
      check("a ApproximatedBy b",a.approximatedBy(b)==true);
      check("not (b ApproximatedBy a)",b.approximatedBy(a)==false);
    }
#endif
  } // end of stream operator checks
}
Ejemplo n.º 15
0
Archivo: woodpecker.C Proyecto: 8l/rose
int main(int argc, char* argv[]) {
  try {
    if(argc==1) {
      cout << "Error: wrong command line options."<<endl;
      exit(1);
    }
#if 0
    if(argc==3) {
      csvAssertFileName=argv[2];
      argc=2; // don't confuse ROSE command line
      cout<< "INIT: CSV-output file: "<<csvAssertFileName<<endl;
    }
#endif
  // Command line option handling.
    namespace po = boost::program_options;
  po::options_description desc
    ("Woodpecker V0.1\n"
     "Written by Markus Schordan\n"
     "Supported options");
  
  desc.add_options()
    ("help,h", "produce this help message.")
    ("rose-help", "show help for compiler frontend options.")
    ("version,v", "display the version.")
    ("stats", "display code statistics.")
    ("normalize", po::value< string >(), "normalize code (eliminate compound assignment operators).")
    ("inline",po::value< string >(), "perform inlining ([yes]|no).")
    ("eliminate-empty-if",po::value< string >(), "eliminate if-statements with empty branches in main function ([yes]/no).")
    ("eliminate-dead-code",po::value< string >(), "eliminate dead code (variables and expressions) ([yes]|no).")
    ("csv-const-result",po::value< string >(), "generate csv-file [arg] with const-analysis data.")
    ("generate-transformed-code",po::value< string >(), "generate transformed code with prefix rose_ ([yes]|no).")
    ("verbose",po::value< string >(), "print detailed output during analysis and transformation (yes|[no]).")
    ("generate-conversion-functions","generate code for conversion functions between variable names and variable addresses.")
    ("csv-assert",po::value< string >(), "name of csv file with reachability assert results'")
    ("enable-multi-const-analysis",po::value< string >(), "enable multi-const analysis.")
    ("transform-thread-variable", "transform code to use additional thread variable.")
    ;
  //    ("int-option",po::value< int >(),"option info")


  po::store(po::command_line_parser(argc, argv).
            options(desc).allow_unregistered().run(), args);
  po::notify(args);

  if (args.count("help")) {
    cout << "woodpecker <filename> [OPTIONS]"<<endl;
    cout << desc << "\n";
    return 0;
  }
  if (args.count("rose-help")) {
    argv[1] = strdup("--help");
  }

  if (args.count("version")) {
    cout << "Woodpecker version 0.1\n";
    cout << "Written by Markus Schordan 2013\n";
    return 0;
  }
  if (args.count("csv-assert")) {
    csvAssertFileName=args["csv-assert"].as<string>().c_str();
  }
  if (args.count("csv-const-result")) {
    csvConstResultFileName=args["csv-const-result"].as<string>().c_str();
  }
  
  boolOptions.init(argc,argv);
  // temporary fake optinos
  boolOptions.registerOption("arith-top",false); // temporary
  boolOptions.registerOption("semantic-fold",false); // temporary
  boolOptions.registerOption("post-semantic-fold",false); // temporary
  // regular options
  boolOptions.registerOption("normalize",false);
  boolOptions.registerOption("inline",true);
  boolOptions.registerOption("eliminate-empty-if",true);
  boolOptions.registerOption("eliminate-dead-code",true);
  boolOptions.registerOption("generate-transformed-code",true);
  boolOptions.registerOption("enable-multi-const-analysis",false);
  boolOptions.registerOption("verbose",false);
  boolOptions.processOptions();

  if(boolOptions["verbose"])
    detailedOutput=1;

  // clean up string-options in argv
  for (int i=1; i<argc; ++i) {
    if (string(argv[i]) == "--csv-assert" 
        || string(argv[i]) == "--csv-const-result"
        ) {
      // do not confuse ROSE frontend
      argv[i] = strdup("");
      assert(i+1<argc);
        argv[i+1] = strdup("");
    }
  }

  global_option_multiconstanalysis=boolOptions["enable-multi-const-analysis"];
#if 0
  if(global_option_multiconstanalysis) {
    cout<<"INFO: Using flow-insensitive multi-const-analysis."<<endl;
  } else {
    cout<<"INFO: Using flow-insensitive unique-const-analysis."<<endl;
  }
#endif

  cout << "INIT: Parsing and creating AST started."<<endl;
  SgProject* root = frontend(argc,argv);
  //  AstTests::runAllTests(root);
  // inline all functions
  cout << "INIT: Parsing and creating AST finished."<<endl;

  if(args.count("stats")) {
    printCodeStatistics(root);
    exit(0);
  }

  VariableIdMapping variableIdMapping;
  variableIdMapping.computeVariableSymbolMapping(root);

  if(args.count("transform-thread-variable")) {
    Threadification* threadTransformation=new Threadification(&variableIdMapping);
    threadTransformation->transform(root);
    root->unparse(0,0);
    delete threadTransformation;
    cout<<"STATUS: generated program with introduced thread-variable."<<endl;
    exit(0);
  }

  SgFunctionDefinition* mainFunctionRoot=0;
  if(boolOptions["inline"]) {
    cout<<"STATUS: eliminating non-called trivial functions."<<endl;
    // inline functions
    TrivialInlining tin;
    tin.setDetailedOutput(detailedOutput);
    tin.inlineFunctions(root);
    DeadCodeElimination dce;
    // eliminate non called functions
    int numEliminatedFunctions=dce.eliminateNonCalledTrivialFunctions(root);
    cout<<"STATUS: eliminated "<<numEliminatedFunctions<<" functions."<<endl;
  } else {
    cout<<"INFO: Inlining: turned off."<<endl;
  }

  if(boolOptions["eliminate-empty-if"]) {
    DeadCodeElimination dce;
    cout<<"STATUS: Eliminating empty if-statements."<<endl;
    size_t num=0;
    size_t numTotal=num;
    do {
      num=dce.eliminateEmptyIfStmts(root);
      cout<<"INFO: Number of if-statements eliminated: "<<num<<endl;
      numTotal+=num;
    } while(num>0);
    cout<<"STATUS: Total number of empty if-statements eliminated: "<<numTotal<<endl;
  }

  if(boolOptions["normalize"]) {
    cout <<"STATUS: Normalization started."<<endl;
    RewriteSystem rewriteSystem;
    rewriteSystem.resetStatistics();
    rewriteSystem.rewriteCompoundAssignmentsInAst(root,&variableIdMapping);
    cout <<"STATUS: Normalization finished."<<endl;

  }
 
  cout<<"STATUS: performing flow-insensitive const analysis."<<endl;
  VarConstSetMap varConstSetMap;
  VariableIdSet variablesOfInterest;
  FIConstAnalysis fiConstAnalysis(&variableIdMapping);
  fiConstAnalysis.setOptionMultiConstAnalysis(global_option_multiconstanalysis);
  fiConstAnalysis.setDetailedOutput(detailedOutput);
  fiConstAnalysis.runAnalysis(root, mainFunctionRoot);
  variablesOfInterest=fiConstAnalysis.determinedConstantVariables();
  cout<<"INFO: variables of interest: "<<variablesOfInterest.size()<<endl;
  if(detailedOutput)
    printResult(variableIdMapping,varConstSetMap);

  if(csvConstResultFileName) {
    VariableIdSet setOfUsedVarsInFunctions=AnalysisAbstractionLayer::usedVariablesInsideFunctions(root,&variableIdMapping);
    VariableIdSet setOfUsedVarsGlobalInit=AnalysisAbstractionLayer::usedVariablesInGlobalVariableInitializers(root,&variableIdMapping);
    VariableIdSet setOfAllUsedVars = setOfUsedVarsInFunctions;
    setOfAllUsedVars.insert(setOfUsedVarsGlobalInit.begin(), setOfUsedVarsGlobalInit.end());
    cout<<"INFO: number of used vars inside functions: "<<setOfUsedVarsInFunctions.size()<<endl;
    cout<<"INFO: number of used vars in global initializations: "<<setOfUsedVarsGlobalInit.size()<<endl;
    cout<<"INFO: number of vars inside functions or in global inititializations: "<<setOfAllUsedVars.size()<<endl;
    fiConstAnalysis.filterVariables(setOfAllUsedVars);
    fiConstAnalysis.writeCvsConstResult(variableIdMapping, string(csvConstResultFileName));
  }

  if(args.count("generate-conversion-functions")) {
    string conversionFunctionsFileName="conversionFunctions.C";
    ConversionFunctionsGenerator gen;
    set<string> varNameSet;
    std::list<SgVariableDeclaration*> globalVarDeclList=SgNodeHelper::listOfGlobalVars(root);
    for(std::list<SgVariableDeclaration*>::iterator i=globalVarDeclList.begin();i!=globalVarDeclList.end();++i) {
      SgInitializedNamePtrList& initNamePtrList=(*i)->get_variables();
      for(SgInitializedNamePtrList::iterator j=initNamePtrList.begin();j!=initNamePtrList.end();++j) {
	      SgInitializedName* initName=*j;
        if ( true || isSgArrayType(initName->get_type()) ) {  // optional filter (array variables only)
	        SgName varName=initName->get_name();
	        string varNameString=varName; // implicit conversion
	        varNameSet.insert(varNameString);
        }
      }
    }
    string code=gen.generateCodeForGlobalVarAdressMaps(varNameSet);
    ofstream myfile;
    myfile.open(conversionFunctionsFileName.c_str());
    myfile<<code;
    myfile.close();
  }

  VariableConstInfo vci=*(fiConstAnalysis.getVariableConstInfo());
  DeadCodeElimination dce;
  if(boolOptions["eliminate-dead-code"]) {
    cout<<"STATUS: performing dead code elimination."<<endl;
    dce.setDetailedOutput(detailedOutput);
    dce.setVariablesOfInterest(variablesOfInterest);
    dce.eliminateDeadCodePhase1(root,&variableIdMapping,vci);
    cout<<"STATUS: Eliminated "<<dce.numElimVars()<<" variable declarations."<<endl;
    cout<<"STATUS: Eliminated "<<dce.numElimAssignments()<<" variable assignments."<<endl;
    cout<<"STATUS: Replaced "<<dce.numElimVarUses()<<" uses of variables with constant."<<endl;
    cout<<"STATUS: Eliminated "<<dce.numElimVars()<<" dead variables."<<endl;
    cout<<"STATUS: Dead code elimination phase 1: finished."<<endl;
    cout<<"STATUS: Performing condition const analysis."<<endl;
  } else {
    cout<<"STATUS: Dead code elimination: turned off."<<endl;
  }
  if(csvAssertFileName) {
    cout<<"STATUS: performing flow-insensensitive condition-const analysis."<<endl;
    Labeler labeler(root);
    fiConstAnalysis.performConditionConstAnalysis(&labeler);
    cout<<"INFO: Number of true-conditions     : "<<fiConstAnalysis.getTrueConditions().size()<<endl;
    cout<<"INFO: Number of false-conditions    : "<<fiConstAnalysis.getFalseConditions().size()<<endl;
    cout<<"INFO: Number of non-const-conditions: "<<fiConstAnalysis.getNonConstConditions().size()<<endl;
    cout<<"STATUS: performing flow-insensensitive reachability analysis."<<endl;
    ReachabilityAnalysis ra;
    PropertyValueTable reachabilityResults=ra.fiReachabilityAnalysis(labeler, fiConstAnalysis);
    cout<<"STATUS: generating file "<<csvAssertFileName<<endl;
    reachabilityResults.writeFile(csvAssertFileName,true);
  }
#if 0
  rdAnalyzer->determineExtremalLabels(startFunRoot);
  rdAnalyzer->run();
#endif
  cout << "INFO: Remaining functions in program: "<<numberOfFunctions(root)<<endl;
  if(boolOptions["generate-transformed-code"]) {
    cout << "STATUS: generating transformed source code."<<endl;
    root->unparse(0,0);
  }

  std::list<int> fakelist;
  fakelist.push_back(1);
  std::list<int>::iterator myit=fakelist.begin();
  fakelist.erase(myit);
  cout<< "STATUS: finished."<<endl;

  // main function try-catch
  } catch(char* str) {
    cerr << "*Exception raised: " << str << endl;
    return 1;
  } catch(const char* str) {
    cerr << "Exception raised: " << str << endl;
    return 1;
  } catch(string str) {
    cerr << "Exception raised: " << str << endl;
    return 1;
  }
  return 0;
}
Ejemplo n.º 16
0
void runAnalyses(SgProject* root, Labeler* labeler, VariableIdMapping* variableIdMapping) {

  SPRAY::DFAnalysisBase::normalizeProgram(root);

  if(option_fi_constanalysis) {
    VarConstSetMap varConstSetMap;
    FIConstAnalysis fiConstAnalysis(variableIdMapping);
    fiConstAnalysis.runAnalysis(root);
    fiConstAnalysis.attachAstAttributes(labeler,"const-analysis-inout"); // not iolabeler
    if(csvConstResultFileName) {
      cout<<"INFO: generating const CSV file "<<option_prefix+csvConstResultFileName<<endl;
      fiConstAnalysis.writeCvsConstResult(*variableIdMapping, option_prefix+csvConstResultFileName);
    }
    cout << "INFO: annotating analysis results as comments."<<endl;
    AstAnnotator ara(labeler);
    ara.annotateAstAttributesAsCommentsBeforeStatements(root, "const-analysis-inout");
    ara.annotateAstAttributesAsCommentsAfterStatements(root, "const-analysis-inout");
  }

  if(option_at_analysis) {
    cout<<"STATUS: running address taken analysis."<<endl;
    cout << "STATUS: computing variable and function mappings."<<endl;
    // compute variableId mappings
    VariableIdMapping variableIdMapping;
    variableIdMapping.computeVariableSymbolMapping(root);
    // Compute function id mappings:
    FunctionIdMapping functionIdMapping;
    functionIdMapping.computeFunctionSymbolMapping(root);

    if(option_trace) {
      std::cout << std::endl << "TRACE: Variable Id Mapping:" << std::endl;
      variableIdMapping.toStream(std::cout);
      std::cout << std::endl << "TRACE: Function Id Mapping:" << std::endl;
      functionIdMapping.toStream(std::cout);
    }

    cout << "STATUS: computing address taken sets."<<endl;
    SPRAY::FIPointerAnalysis fipa(&variableIdMapping, &functionIdMapping, root);
    fipa.initialize();
    fipa.run();

    //cout << "STATUS: computed address taken sets:"<<endl;
    //fipa.getFIPointerInfo()->printInfoSets();

    bool createCsv = false;
    ofstream addressTakenCsvFile;
    if(csvAddressTakenResultFileName) {
      std::string addressTakenCsvFileName = option_prefix;
      addressTakenCsvFileName += csvAddressTakenResultFileName;
      addressTakenCsvFile.open(addressTakenCsvFileName.c_str());
      createCsv = true;
    }

    cout << "INFO: annotating declarations of address taken variables and functions."<<endl;

    // Annotate declarations/definitions of variables from which the address was taken:
    VariableIdSet addressTakenVariableIds = fipa.getAddressTakenVariables();
    for(VariableIdSet::const_iterator idIter = addressTakenVariableIds.begin(); idIter != addressTakenVariableIds.end(); ++idIter) {
      // Determine the variable declaration/definition:
      SgLocatedNode* decl = variableIdMapping.getVariableDeclaration(*idIter);
      if(!decl) {
        // The current variable is presumably a function parameter: Try to get the initialized name:
        SgVariableSymbol* varSymbol = isSgVariableSymbol(variableIdMapping.getSymbol(*idIter));
        ROSE_ASSERT(varSymbol);
        SgInitializedName* paramDecl = isSgInitializedName(varSymbol->get_declaration());
        // We should not have a real variable declaration for the parameter:
        ROSE_ASSERT(isSgFunctionParameterList(paramDecl->get_declaration()));

        // Use the InitializedName:
        decl = paramDecl;
      }

      if(decl) {
        // Create the comment:
        ostringstream commentStream;
        commentStream << "/* Address of \"" << variableIdMapping.variableName(*idIter) << "\" is "
                      << "presumably taken.*/";

        // Annotate first declaration:
        insertComment(commentStream.str(), PreprocessingInfo::before, decl);
        // TODO: Annotate other declarations too!

        // Annotate definition if available (e.g. not available in case of parameter):
        if(SgDeclarationStatement* variableDeclaration = isSgDeclarationStatement(decl)) {
          if(SgDeclarationStatement* definingDeclaration = variableDeclaration->get_definingDeclaration()) {
            insertComment(commentStream.str(), PreprocessingInfo::before, definingDeclaration);
          }
        }

        if(createCsv) {
          // Write variable info to csv:
          addressTakenCsvFile << VariableId::idKindIndicator << ","
                              // The id of the variable (id codes are influenced by the used system headers
                              //  and are therefore not stable/portable):
                              << (option_csv_stable ? string("<unstable>") : int_to_string((*idIter).getIdCode())) << ","
                              // Name of the variable:
                              << variableIdMapping.variableName(*idIter) << ","

                              // TODO: Mangled scope and type are currently not stable/portable
                              //  (see comments in getScopeAsMangledStableString(...))
                              // Mangled type of the variable (non-mangled type may contain commas (e.g. "A<int,bool>"):
                              << (option_csv_stable ? string("<unstable>") : variableIdMapping.getType(*idIter)->get_mangled().getString()) << ","
                              // Mangled scope of the variable:
                              << (option_csv_stable ? string("<unstable>") : getScopeAsMangledStableString(decl)) << ","

                              // Is the address taken? (currently only address taken variables are output to csv)
                              << "1" << endl;
        }
      }
      else {
        cout << "ERROR: No declaration for " << variableIdMapping.uniqueShortVariableName(*idIter) << " available." << endl;
        ROSE_ASSERT(false);
      }
    }

    // Annotate declarations and definitions of functions from which the address was taken:
    FunctionIdSet addressTakenFunctionIds = fipa.getAddressTakenFunctions();
    for(FunctionIdSet::const_iterator idIter = addressTakenFunctionIds.begin(); idIter != addressTakenFunctionIds.end(); ++idIter) {

      if(SgFunctionDeclaration* decl = functionIdMapping.getFunctionDeclaration(*idIter)) {
        // Create the comment:
        ostringstream commentStream;
        commentStream << "/* Address of \"" << functionIdMapping.getFunctionNameFromFunctionId(*idIter) << "(...)\" is "
                      << "presumably taken.*/";

        // Annotate first declaration:
        insertComment(commentStream.str(), PreprocessingInfo::before, decl);
        // TODO: Annotate other declarations too!

        // Annotate definition if available:
        if(SgDeclarationStatement* definingDeclaration = decl->get_definingDeclaration()) {
          insertComment(commentStream.str(), PreprocessingInfo::before, definingDeclaration);
        }

        if(createCsv) {
          addressTakenCsvFile << FunctionId::idKindIndicator << ","
                              // The id of the function (id codes are influenced by the used system headers
                              //  and are therefore not stable/portable):
                              << (option_csv_stable ? string("<unstable>") : int_to_string((*idIter).getIdCode())) << ","
                              // Name of the function:
                              << functionIdMapping.getFunctionNameFromFunctionId(*idIter) << ","

                              // TODO: Mangled scope and type are currently not stable/portable
                              //  (see comments in getScopeAsMangledStableString(...))
                              // Mangled type of the function (non-mangled type may contain commas (e.g. "void (A<int,bool>)"):
                              << (option_csv_stable ? string("<unstable>") : functionIdMapping.getTypeFromFunctionId(*idIter)->get_mangled().getString()) << ","
                              // Mangled scope of the function:
                              << (option_csv_stable ? string("<unstable>") :getScopeAsMangledStableString(decl)) << ","

                              // Is the address taken? (currently only address taken functions are output to csv)
                              << "1" << endl;
        }
      }
      else {
        cout << "ERROR: No declaration for " << functionIdMapping.getUniqueShortNameFromFunctionId(*idIter) << " available." << endl;
        ROSE_ASSERT(false);
      }
    }

    if(createCsv) {
      addressTakenCsvFile.close();
    }

#if 0
    VariableIdSet vidset=fipa.getModByPointer();
    cout<<"mod-set: "<<SPRAY::VariableIdSetPrettyPrint::str(vidset,variableIdMapping)<<endl;
#endif
  }
  
  if(option_interval_analysis) {
    cout << "STATUS: creating interval analyzer."<<endl;
    SPRAY::IntervalAnalysis* intervalAnalyzer=new SPRAY::IntervalAnalysis();
    cout << "STATUS: initializing interval analyzer."<<endl;
    intervalAnalyzer->setNoTopologicalSort(option_no_topological_sort);
    intervalAnalyzer->initialize(root);
    cout << "STATUS: running pointer analysis."<<endl;
    ROSE_ASSERT(intervalAnalyzer->getVariableIdMapping());
    SPRAY::FIPointerAnalysis* fipa=new FIPointerAnalysis(intervalAnalyzer->getVariableIdMapping(), intervalAnalyzer->getFunctionIdMapping(), root);
    fipa->initialize();
    fipa->run();
    intervalAnalyzer->setPointerAnalysis(fipa);
    cout << "STATUS: initializing interval transfer functions."<<endl;
    intervalAnalyzer->initializeTransferFunctions();
    cout << "STATUS: initializing interval global variables."<<endl;
    intervalAnalyzer->initializeGlobalVariables(root);
      
    intervalAnalyzer->setSolverTrace(option_trace);
    std::string funtofind="main";
    RoseAst completeast(root);
    SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind);
    intervalAnalyzer->determineExtremalLabels(startFunRoot);
    intervalAnalyzer->run();

#if 0
    intervalAnalyzer->attachInInfoToAst("iv-analysis-in");
    intervalAnalyzer->attachOutInfoToAst("iv-analysis-out");
    AstAnnotator ara(intervalAnalyzer->getLabeler(),intervalAnalyzer->getVariableIdMapping());
    ara.annotateAstAttributesAsCommentsBeforeStatements(root, "iv-analysis-in");
    ara.annotateAstAttributesAsCommentsAfterStatements(root, "iv-analysis-out");
#else
    AnalysisAstAnnotator ara(intervalAnalyzer->getLabeler(),intervalAnalyzer->getVariableIdMapping());
    ara.annotateAnalysisPrePostInfoAsComments(root,"iv-analysis",intervalAnalyzer);
#endif
    if(option_check_static_array_bounds) {
      checkStaticArrayBounds(root,intervalAnalyzer);
    }
    // schroder3 (2016-08-08): Generate csv-file that contains unreachable statements:
    if(csvDeadCodeUnreachableFileName) {
      // Generate file name and open file:
      std::string deadCodeCsvFileName = option_prefix;
      deadCodeCsvFileName += csvDeadCodeUnreachableFileName;
      ofstream deadCodeCsvFile;
      deadCodeCsvFile.open(deadCodeCsvFileName.c_str());
      // Iteratate over all CFG nodes/ labels:
      for(Flow::const_node_iterator i = intervalAnalyzer->getFlow()->nodes_begin(); i != intervalAnalyzer->getFlow()->nodes_end(); ++i) {
        const Label& label = *i;
        // Do not output a function call twice (only the function call label and not the function call return label):
        if(!intervalAnalyzer->getLabeler()->isFunctionCallReturnLabel(label)) {
          /*const*/ IntervalPropertyState& intervalsLattice = *static_cast<IntervalPropertyState*>(intervalAnalyzer->getPreInfo(label.getId()));
          if(intervalsLattice.isBot()) {
            // Unreachable statement found:
            const SgNode* correspondingNode = intervalAnalyzer->getLabeler()->getNode(label);
            ROSE_ASSERT(correspondingNode);
            // Do not output scope statements ({ }, ...)
            if(!isSgScopeStatement(correspondingNode)) {
              deadCodeCsvFile << correspondingNode->get_file_info()->get_line()
                              << "," << SPRAY::replace_string(correspondingNode->unparseToString(), ",", "/*comma*/")
                              << endl;
            }
          }
        }
      }
      deadCodeCsvFile.close();
    }

    delete fipa;
  }

  if(option_lv_analysis) {
    cout << "STATUS: creating LV analysis."<<endl;
    SPRAY::LVAnalysis* lvAnalysis=new SPRAY::LVAnalysis();
    cout << "STATUS: initializing LV analysis."<<endl;
    lvAnalysis->setBackwardAnalysis();
    lvAnalysis->setNoTopologicalSort(option_no_topological_sort);
    lvAnalysis->initialize(root);
    cout << "STATUS: running pointer analysis."<<endl;
    ROSE_ASSERT(lvAnalysis->getVariableIdMapping());
    SPRAY::FIPointerAnalysis* fipa = new FIPointerAnalysis(lvAnalysis->getVariableIdMapping(), lvAnalysis->getFunctionIdMapping(), root);
    fipa->initialize();
    fipa->run();
    lvAnalysis->setPointerAnalysis(fipa);
    cout << "STATUS: initializing LV transfer functions."<<endl;
    lvAnalysis->initializeTransferFunctions();
    cout << "STATUS: initializing LV global variables."<<endl;
    lvAnalysis->initializeGlobalVariables(root);
    std::string funtofind="main";
    RoseAst completeast(root);
    SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind);
    cout << "generating icfg_backward.dot."<<endl;
    write_file("icfg_backward.dot", lvAnalysis->getFlow()->toDot(lvAnalysis->getLabeler()));

    lvAnalysis->determineExtremalLabels(startFunRoot);
    lvAnalysis->run();
    cout << "INFO: attaching LV-data to AST."<<endl;
#if 0
    lvAnalysis->attachInInfoToAst("lv-analysis-in");
    lvAnalysis->attachOutInfoToAst("lv-analysis-out");
    AstAnnotator ara(lvAnalysis->getLabeler(),lvAnalysis->getVariableIdMapping());
    ara.annotateAstAttributesAsCommentsBeforeStatements(root, "lv-analysis-in");
    ara.annotateAstAttributesAsCommentsAfterStatements(root, "lv-analysis-out");
#else
    AnalysisAstAnnotator ara(lvAnalysis->getLabeler(),lvAnalysis->getVariableIdMapping());
    ara.annotateAnalysisPrePostInfoAsComments(root,"lv-analysis",lvAnalysis);
#endif

    // schroder3 (2016-08-15): Generate csv-file that contains dead assignments/ initializations:
    if(csvDeadCodeDeadStoreFileName) {
      // Generate file name and open file:
      std::string deadCodeCsvFileName = option_prefix;
      deadCodeCsvFileName += csvDeadCodeDeadStoreFileName;
      ofstream deadCodeCsvFile;
      deadCodeCsvFile.open(deadCodeCsvFileName.c_str());
      if(option_trace) {
        cout << "TRACE: checking for dead stores." << endl;
      }
      // Iteratate over all CFG nodes/ labels:
      for(Flow::const_node_iterator labIter = lvAnalysis->getFlow()->nodes_begin(); labIter != lvAnalysis->getFlow()->nodes_end(); ++labIter) {
        const Label& label = *labIter;
        // Do not output a function call twice (only the function call return label and not the function call label):
        if(!lvAnalysis->getLabeler()->isFunctionCallLabel(label)) {
          /*const*/ SgNode* correspondingNode = lvAnalysis->getLabeler()->getNode(label);
          ROSE_ASSERT(correspondingNode);
          if(/*const*/ SgExprStatement* exprStmt = isSgExprStatement(correspondingNode)) {
            correspondingNode = exprStmt->get_expression();
          }
          /*const*/ SgNode* association = 0;
          // Check if the corresponding node is an assignment or an initialization:
          if(isSgAssignOp(correspondingNode)) {
            association = correspondingNode;
          }
          else if(SgVariableDeclaration* varDecl = isSgVariableDeclaration(correspondingNode)) {
            SgInitializedName* initName = SgNodeHelper::getInitializedNameOfVariableDeclaration(varDecl);
            ROSE_ASSERT(initName);
            // Check whether there is an initialization that can be eliminated (reference initialization can not be eliminated).
            if(!SgNodeHelper::isReferenceType(initName->get_type()) && initName->get_initializer()) {
              association = correspondingNode;
            }
          }

          if(association) {
            if(option_trace) {
              cout << endl << "association: " << association->unparseToString() << endl;
            }
            VariableIdSet assignedVars = AnalysisAbstractionLayer::defVariables(association, *lvAnalysis->getVariableIdMapping(), fipa);
            /*const*/ LVLattice& liveVarsLattice = *static_cast<LVLattice*>(lvAnalysis->getPreInfo(label.getId()));
            if(option_trace) {
              cout << "live: " << liveVarsLattice.toString(lvAnalysis->getVariableIdMapping()) << endl;
              cout << "assigned: " << endl;
            }
            bool minOneIsLive = false;
            for(VariableIdSet::const_iterator assignedVarIter = assignedVars.begin(); assignedVarIter != assignedVars.end(); ++assignedVarIter) {
              if(option_trace) {
                cout << (*assignedVarIter).toString(*lvAnalysis->getVariableIdMapping()) << endl;
              }
              if(liveVarsLattice.exists(*assignedVarIter)) {
                minOneIsLive = true;
                break;
              }
            }
            if(!minOneIsLive) {
              if(option_trace) {
                cout << "association is dead." << endl;
              }
              // assignment to only dead variables found:
              deadCodeCsvFile << correspondingNode->get_file_info()->get_line()
                              << "," << SPRAY::replace_string(correspondingNode->unparseToString(), ",", "/*comma*/")
                              << endl;
            }
          }
        }
      }
      deadCodeCsvFile.close();
    }
    delete lvAnalysis;
  }

  if(option_rd_analysis) {
      cout << "STATUS: creating RD analyzer."<<endl;
      SPRAY::RDAnalysis* rdAnalysis=new SPRAY::RDAnalysis();
      cout << "STATUS: initializing RD analyzer."<<endl;
      rdAnalysis->setNoTopologicalSort(option_no_topological_sort);
      rdAnalysis->initialize(root);
      cout << "STATUS: initializing RD transfer functions."<<endl;
      rdAnalysis->initializeTransferFunctions();
      cout << "STATUS: initializing RD global variables."<<endl;
      rdAnalysis->initializeGlobalVariables(root);
      
      cout << "generating icfg_forward.dot."<<endl;
      write_file("icfg_forward.dot", rdAnalysis->getFlow()->toDot(rdAnalysis->getLabeler()));
    
      std::string funtofind="main";
      RoseAst completeast(root);
      SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind);
      rdAnalysis->determineExtremalLabels(startFunRoot);
      rdAnalysis->run();
    
      cout << "INFO: attaching RD-data to AST."<<endl;
      rdAnalysis->attachInInfoToAst("rd-analysis-in");
      rdAnalysis->attachOutInfoToAst("rd-analysis-out");
      //printAttributes<RDAstAttribute>(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping(),"rd-analysis-in");
      cout << "INFO: annotating analysis results as comments."<<endl;
      ROSE_ASSERT(rdAnalysis->getVariableIdMapping());
#if 0
      AstAnnotator ara(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping());
      ara.annotateAstAttributesAsCommentsBeforeStatements(root, "rd-analysis-in");
      ara.annotateAstAttributesAsCommentsAfterStatements(root, "rd-analysis-out");
#else
      AnalysisAstAnnotator ara(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping());
      ara.annotateAnalysisPrePostInfoAsComments(root,"rd-analysis",rdAnalysis);
#endif

#if 0
      cout << "INFO: substituting uses with rhs of defs."<<endl;
      substituteUsesWithAvailableExpRhsOfDef("ud-analysis", root, rdAnalysis->getLabeler(), rdAnalysis->getVariableIdMapping());
#endif
      if(option_ud_analysis) {
        ROSE_ASSERT(option_rd_analysis);
        cout << "INFO: generating and attaching UD-data to AST."<<endl;
        createUDAstAttributeFromRDAttribute(rdAnalysis->getLabeler(),"rd-analysis-in", "ud-analysis");
        Flow* flow=rdAnalysis->getFlow();
        cout<<"Flow label-set size: "<<flow->nodeLabels().size()<<endl;
        CFAnalysis* cfAnalyzer0=rdAnalysis->getCFAnalyzer();
        int red=cfAnalyzer0->reduceBlockBeginNodes(*flow);
        cout<<"INFO: eliminated "<<red<<" block-begin nodes in ICFG."<<endl;
        
#if 0
        cout << "INFO: computing program statistics."<<endl;
        ProgramStatistics ps(rdAnalysis->getVariableIdMapping(),
                             rdAnalysis->getLabeler(), 
                             rdAnalysis->getFlow(),
                             "ud-analysis");
        ps.computeStatistics();
        //ps.printStatistics();
        cout << "INFO: generating resource usage visualization."<<endl;
        ps.setGenerateWithSource(false);
        ps.generateResourceUsageICFGDotFile("resourceusageicfg.dot");
        flow->resetDotOptions();
#endif
        cout << "INFO: generating visualization data."<<endl;
        // generate ICFG visualization
        cout << "generating icfg.dot."<<endl;
        write_file("icfg.dot", flow->toDot(rdAnalysis->getLabeler()));
        
        //  cout << "INFO: generating control dependence graph."<<endl;
        //Flow cdg=rdAnalysis->getCFAnalyzer()->controlDependenceGraph(*flow);

        cout << "generating datadependencegraph.dot."<<endl;
        DataDependenceVisualizer ddvis0(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        //printAttributes<UDAstAttribute>(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping(),"ud-analysis");
        //ddvis._showSourceCode=false; // for large programs
        ddvis0.generateDefUseDotGraph(root,"datadependencegraph.dot");
        flow->resetDotOptions();
        
        cout << "generating icfgdatadependencegraph.dot."<<endl;
        DataDependenceVisualizer ddvis1(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        ddvis1.includeFlowGraphEdges(flow);
        ddvis1.generateDefUseDotGraph(root,"icfgdatadependencegraph.dot");
        flow->resetDotOptions();
        
        cout << "generating icfgdatadependencegraph_clustered.dot."<<endl;
        DataDependenceVisualizer ddvis2(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        ddvis2.generateDotFunctionClusters(root,rdAnalysis->getCFAnalyzer(),"icfgdatadependencegraph_clustered.dot",true);
        
        cout << "generating icfg_clustered.dot."<<endl;
        DataDependenceVisualizer ddvis3(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        ddvis3.generateDotFunctionClusters(root,rdAnalysis->getCFAnalyzer(),"icfg_clustered.dot",false);
        
      }
    }
}
Ejemplo n.º 17
0
int main(int argc, char* argv[]) {
  try {
    if(argc==1) {
      cout << "Error: wrong command line options."<<endl;
      exit(1);
    }
     // Command line option handling.
    namespace po = boost::program_options;
    po::options_description desc
      ("analyterix V0.2\n"
       "Written by Markus Schordan\n"
       "Supported options");
  
    desc.add_options()
      ("help,h", "produce this help message.")
      ("rose-help", "show help for compiler frontend options.")
      ("version,v", "display the version.")
      ("stats", "display code statistics.")
      ("fi-constanalysis", "perform flow-insensitive constant analysis.")
      ("csv-fi-constanalysis",po::value< string >(), "generate csv-file [arg] with const-analysis data.")
      ("rd-analysis", "perform reaching definitions analysis.")
      ("rose-rd-analysis", "perform rose reaching definitions analysis.")
      ("lv-analysis", "perform live variables analysis.")
      ("ud-analysis", "use-def analysis.")
      ("at-analysis", "address-taken analysis.")
      ("icfg-dot", "generates the ICFG as dot file.")
      ("interval-analysis", "perform interval analysis.")
      ("trace", "show operations as performed by selected solver.")
      ("print-varidmapping", "prints variableIdMapping")
      ("print-varidmapping-array", "prints variableIdMapping with array element varids.")
      ("prefix",po::value< string >(), "set prefix for all generated files.")
      ;
  //    ("int-option",po::value< int >(),"option info")

    po::store(po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(), args);
    po::notify(args);

    if (args.count("help")) {
      cout << "analyterix <filename> [OPTIONS]"<<endl;
      cout << desc << "\n";
      return 0;
    }
    if (args.count("version")) {
      cout << "analyterix version 0.1\n";
      cout << "Written by Markus Schordan 2014\n";
      return 0;
    }
    if (args.count("rose-help")) {
      argv[1] = strdup("--help");
    }
    if (args.count("prefix")) {
      option_prefix=args["prefix"].as<string>().c_str();
    }

    if (args.count("trace")) {
      option_trace=true;
    }
    if(args.count("stats")) {
      option_stats=true;
    }
    if(args.count("rd-analysis")) {
      option_rd_analysis=true;
    }
    if(args.count("lv-analysis")) {
      option_lv_analysis=true;
    }
    if(args.count("interval-analysis")) {
      option_interval_analysis=true;
    }
    if(args.count("ud-analysis")) {
      option_rd_analysis=true; // required
      option_ud_analysis=true;
    }
    if(args.count("rose-rd-analysis")) {
      option_rose_rd_analysis=true;
    }
    if(args.count("fi-constanalysis")) {
      option_fi_constanalysis=true;
    }
    if (args.count("csv-fi-constanalysis")) {
      csvConstResultFileName=args["csv-fi-constanalysis"].as<string>().c_str();
      option_fi_constanalysis=true;
    }
    if(args.count("at-analysis")) {
      option_at_analysis=true;
    }
    // clean up string-options in argv
    for (int i=1; i<argc; ++i) {
      if (string(argv[i]) == "--prefix" 
          || string(argv[i]) == "--csv-const-result"
          ) {
        // do not confuse ROSE frontend
        argv[i] = strdup("");
        assert(i+1<argc);
        argv[i+1] = strdup("");
      }
    }

    cout << "INIT: Parsing and creating AST."<<endl;
    boolOptions.registerOption("semantic-fold",false); // temporary
    boolOptions.registerOption("post-semantic-fold",false); // temporary
    SgProject* root = frontend(argc,argv);
    //  AstTests::runAllTests(root);

   if(option_stats) {
      SPRAY::ProgramStatistics::printBasicCodeInfo(root);
    }

  cout<<"STATUS: computing variableid mapping"<<endl;
  VariableIdMapping variableIdMapping;
  if (args.count("print-varidmapping-array")) {
    variableIdMapping.setModeVariableIdForEachArrayElement(true);
  }
  variableIdMapping.computeVariableSymbolMapping(root);
  cout<<"VariableIdMapping size: "<<variableIdMapping.getVariableIdSet().size()<<endl;
  Labeler* labeler=new Labeler(root);
  //cout<<"Labelling:\n"<<labeler->toString()<<endl;

#if 0
  IOLabeler* iolabeler=new IOLabeler(root,&variableIdMapping);
  //cout<<"IOLabelling:\n"<<iolabeler->toString()<<endl;
#endif

  if (args.count("print-varidmapping")||args.count("print-varidmapping-array")) {
    variableIdMapping.toStream(cout);
  }

  runAnalyses(root, labeler, &variableIdMapping);

  cout << "INFO: generating annotated source code."<<endl;
  root->unparse(0,0);

  if(option_rose_rd_analysis) {
    Experimental::RoseRDAnalysis::generateRoseRDDotFiles(labeler,root);
  }

  cout<< "STATUS: finished."<<endl;

  // main function try-catch
  } catch(char* str) {
    cerr << "*Exception raised: " << str << endl;
    return 1;
  } catch(const char* str) {
    cerr << "Exception raised: " << str << endl;
    return 1;
  } catch(string str) {
    cerr << "Exception raised: " << str << endl;
    return 1;
  }
  return 0;
}
Ejemplo n.º 18
0
int main( int argc, char * argv[] )
   {
  // If we want this translator to take specific options (beyond those defined 
  // by ROSE) then insert command line processing for new options here.

  // To better support the stencil specification that might benifit from constant 
  // folding, I have turned this ON is hte frontend.  By default it is OFF so that
  // we can preserve source code as much as possible (original expression trees).
  // The Stencil DSL can be made to work in eithr setting, but this make sure that
  // dimension dependent processing of the stencil coeficients will be evaluated 
  // to constants.  I will turn this off (and thus use a less blunt axe) when the new
  // constant expression evaluation in ROSE is fixed to support more general types
  // than integer expresion (should be done by JP later today).
  // bool frontendConstantFolding = true;
     bool frontendConstantFolding = false;

// Liao, support a flag to control if CUDA code should be generated
// ./shiftCalculusCompiler -rose:dslcompiler:cuda  -c input_file
    std::vector <std::string> argvList (argv, argv + argc);
    if (CommandlineProcessing::isOption (argvList,"-rose:dslcompiler:","cuda",true))
    {
      std::cout<<"Turning on CUDA code generation ..."<<std::endl;
      b_gen_cuda = true;
      // avoid invoking the built in lowering, just create AST
      //argvList.push_back("-rose:openmp:ast_only");
      //argvList.push_back("-rose:openmp:lowering");
      //OmpSupport::enable_accelerator = true;
    }
    else
      b_gen_cuda = false;
// Pei-Hung, enable loop collapsing
    if (CommandlineProcessing::isOption (argvList,"-rose:dslcompiler:","collapse",true))
    {
      std::cout<<"Turning on OpenMP loop collapsing ..."<<std::endl;
      b_enable_collapse = true;
//      argvList.push_back("-rose:openmp:lowering");
    }
    else
      b_enable_collapse = false;
// Pei-Hung, code generation to fulfill polyopt 
    if (CommandlineProcessing::isOption (argvList,"-rose:dslcompiler:","polyopt",true))
    {
      std::cout<<"Generating code for PolyOpt  ..."<<std::endl;
      b_enable_polyopt = true;
//      argvList.push_back("-rose:openmp:lowering");
    }
    else
      b_enable_polyopt = false;

// Pei-Hung, code generation to vectorization 
    if (CommandlineProcessing::isOption (argvList,"-rose:dslcompiler:","vectorization",true))
    {
      std::cout<<"Generating code for vectorization  ..."<<std::endl;
      b_gen_vectorization = true;
//      argvList.push_back("-rose:openmp:lowering");
    }
    else
      b_gen_vectorization = false;
// If MPI code generation is turned on
    if (CommandlineProcessing::isOption (argvList,"-rose:dslcompiler:","mpi",true))
    {
      std::cout<<"Turning on MPI code generation ..."<<std::endl;
      b_gen_mpi = true;
//      argvList.push_back("-rose:openmp:lowering");
    }
    else
      b_gen_mpi = false;

      
  // Generate the ROSE AST.
     //SgProject* project = frontend(argc,argv,frontendConstantFolding);
     SgProject* project = frontend(argvList,frontendConstantFolding);
     ROSE_ASSERT(project != NULL);

     try
        {
          variableIdMapping.computeVariableSymbolMapping(project);
        }
     catch(char* str)
        {
          cout << "*Exception raised: " << str << endl;
        } 
     catch(const char* str) 
        {
          cout << "Exception raised: " << str << endl;
        } 
     catch(string str)
        {
          cout << "Exception raised: " << str << endl;
        }

  // variableIdMapping.toStream(cout);

#if 1
     printf ("variableIdMapping.getVariableIdSet().size() = %zu \n",variableIdMapping.getVariableIdSet().size());
     ROSE_ASSERT(variableIdMapping.getVariableIdSet().size() > 0);
#endif

#if 0
     printf ("Exiting as a test after calling variableIdMapping.computeVariableSymbolMapping(project) \n");
     ROSE_ASSERT(false);
#endif

#if 0
     printf ("Calling constant folding \n");
     ConstantFolding::constantFoldingOptimization(project,false);

#if 0
     printf ("Exiting as a test after calling ConstantFolding::constantFoldingOptimization() \n");
     ROSE_ASSERT(false);
#endif
#endif

  // DQ (2/8/2015): Find the associated SgFile so we can restrict processing to the current file.
     ROSE_ASSERT(project->get_fileList().empty() == false);
     SgFile* firstFile = project->get_fileList()[0];
     ROSE_ASSERT(firstFile != NULL);

#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen;
     astdotgen.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_before_transformation");
#endif
#if DEBUG_USING_DOT_GRAPHS && 1
     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 12000;
#endif
#if DEBUG_USING_DOT_GRAPHS && 1
  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
     generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_before");
#endif

  // Build the inherited attribute
     Detection_InheritedAttribute inheritedAttribute;

  // Define the traversal
     DetectionTraversal shiftCalculus_DetectionTraversal;

#if 1
     printf ("Call the Detection traversal starting at the project (root) node of the AST \n");
#endif

  // Call the traversal starting at the project (root) node of the AST
  // Detection_SynthesizedAttribute result = shiftCalculus_DetectionTraversal.traverse(project,inheritedAttribute);
     Detection_SynthesizedAttribute result = shiftCalculus_DetectionTraversal.traverseWithinFile(firstFile,inheritedAttribute);
#if 0
     printf ("Stencil Operator was transformed: %s \n",result.get_stencilOperatorTransformed() ? "true" : "false");
#endif
     ROSE_ASSERT(result.get_stencilOperatorTransformed() == false);

#if 1
     printf ("DONE: Call the Detection traversal starting at the project (root) node of the AST \n");
#endif
#if 0
     shiftCalculus_DetectionTraversal.display();
#endif
#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen_2;
     astdotgen_2.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_after_DSL_detection");
#endif
#if 0
     printf ("Exiting after the initial traversal to detect the stencil useage. \n");
     ROSE_ASSERT(false);
#endif

  // Build the inherited attribute
     StencilEvaluation_InheritedAttribute inheritedAttribute_stencilEval;

  // Define the traversal
  // StencilEvaluationTraversal shiftCalculus_StencilEvaluationTraversal(shiftCalculus_DetectionTraversal);
     StencilEvaluationTraversal shiftCalculus_StencilEvaluationTraversal;

#if 1
     printf ("Call the StencilEvaluation traversal starting at the project (root) node of the AST \n");
#endif

  // Call the traversal starting at the project (root) node of the AST
  // StencilEvaluation_SynthesizedAttribute result_stencilEval = shiftCalculus_StencilEvaluationTraversal.traverse(project,inheritedAttribute_stencilEval);
     StencilEvaluation_SynthesizedAttribute result_stencilEval = shiftCalculus_StencilEvaluationTraversal.traverseWithinFile(firstFile,inheritedAttribute_stencilEval);

#if 0
     printf ("Stencil Evaluation was transformed: %s \n",result_stencilEval.get_stencilOperatorTransformed() ? "true" : "false");
#endif
     ROSE_ASSERT(result_stencilEval.get_stencilOperatorTransformed() == false);

#if 1
     printf ("DONE: Call the StencilEvaluation traversal starting at the project (root) node of the AST \n");
#endif
#if 1
     shiftCalculus_StencilEvaluationTraversal.displayStencil("After evaluation of stencil");
#endif
#if DEBUG_USING_DOT_GRAPHS
  // generateDOTforMultipleFile(*project);
  // generateDOT(*project,"_before_transformation");
     AstDOTGeneration astdotgen_3;
     astdotgen_3.generateWithinFile(firstFile,DOTGeneration<SgNode*>::TOPDOWNBOTTOMUP,"_after_DSL_evaluation");
#endif

#if 1
     printf ("Call generateStencilCode to generate example code \n");
#endif

#if 0
     printf ("Exiting after the second traversal to evaluate the stencils. \n");
     ROSE_ASSERT(false);
#endif

  // Generate code from stencil data structure.
     bool generateLowlevelCode = true;
     generateStencilCode(shiftCalculus_StencilEvaluationTraversal,generateLowlevelCode);

#if 1
     printf ("DONE: Call generateStencilCode to generate example code \n");
#endif

   ROSE_ASSERT (project->get_fileList().size() ==1);
   SgFile * cur_file = project->get_fileList()[0];

   // Generate MPI specific code
   if (b_gen_mpi)
   { 
     //#include "mpi.h" 
     SageInterface::insertHeader (isSgSourceFile(cur_file), "libxomp_mpi.h", false);
     SageInterface::insertHeader (isSgSourceFile(cur_file), "mpi.h", false);
     SgFunctionDeclaration* main_decl = findMain(cur_file); 
     ROSE_ASSERT (main_decl != NULL);
     SgFunctionDefinition* main_def = main_decl->get_definition();
     ROSE_ASSERT (main_def != NULL);
     SgBasicBlock* func_body = main_def->get_body();
     ROSE_ASSERT (func_body != NULL);

     // Setup MPI
     SgStatement* decl_rank = buildStatementFromString("int _xomp_rank;", func_body); 
     prependStatement(decl_rank, func_body);

     SgStatement* decl_nprocs= buildStatementFromString("int _xomp_nprocs;", func_body); 
     prependStatement(decl_nprocs, func_body);

     // xomp_init_mpi (&argc, &argv, &_xomp_rank, &_xomp_nprocs);
     SgExprListExp * para_list = buildExprListExp (buildAddressOfOp (buildVarRefExp("argc", func_body)), 
                      buildAddressOfOp (buildVarRefExp("argv", func_body)),
                      buildAddressOfOp (buildVarRefExp("_xomp_rank", func_body)),
                      buildAddressOfOp (buildVarRefExp("_xomp_nprocs", func_body))
                      );
     SgExprStatement* mpi_init_stmt = buildFunctionCallStmt ("xomp_init_mpi", buildIntType(), para_list, func_body);
//     SgStatement* last_decl = findLastDeclarationStatement (func_body);
     insertStatementAfter (decl_rank, mpi_init_stmt);

   }

   // Further generate CUDA code if requested
   if (b_gen_cuda)
   {
     // We only process one single input file at a time

     OmpSupport::enable_accelerator = true;
     cur_file->set_openmp_lowering(true);
     cur_file->set_openmp(true);
     cur_file->set_openmp_parse_only(false);
     // process OpenMP directives, including omp target
     // This will translate inserted pragmas again
     OmpSupport::processOpenMP(isSgSourceFile(cur_file));

#if 0 // use rose:output instead to control this
     // rename output file to have .cu suffice
     // change .c suffix to .cu suffix
     std::string orig_name = cur_file->get_file_info()->get_filenameString();
     std::string file_suffix = StringUtility::fileNameSuffix(orig_name);
     // We only allow C file to be compatible with nvcc CUDA compiler
     //ROSE_ASSERT (CommandlineProcessing::isCFileNameSuffix(file_suffix));
     orig_name = StringUtility::stripPathFromFileName(orig_name);
     std::string naked_name = StringUtility::stripFileSuffixFromFileName(orig_name);
     cur_file->set_unparse_output_filename("rose_"+naked_name+".cu");
#endif
   }

#if 0
     printf ("Exiting after call to generateStencilCode() \n");
     ROSE_ASSERT(false);
#endif

  // AST consistency tests (optional for users, but this enforces more of our tests)
     AstTests::runAllTests(project);

#if DEBUG_USING_DOT_GRAPHS
     printf ("Write out the DOT file after the transformation \n");
  // generateDOTforMultipleFile(*project,"after_transformation");
     generateDOT(*project,"_after_transformation");
     printf ("DONE: Write out the DOT file after the transformation \n");
#endif
#if DEBUG_USING_DOT_GRAPHS && 0
  // Output an optional graph of the AST (the whole graph, of bounded complexity, when active)
  // const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 10000;
     generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_after");
#endif

  // Regenerate the source code but skip the call the to the vendor compiler.
     return backend(project);
   }
Ejemplo n.º 19
0
/* format: varname, isAny, isUniqueconst, isMultiConst, width(>=1 or 0 or -1 (for any)), min, max, numBits, "{...}"
*/
void FIConstAnalysis::writeCvsConstResult(VariableIdMapping& variableIdMapping, string filename) {
    ofstream myfile;
    myfile.open(filename.c_str());

    //  cout<<"Result:"<<endl;
    //VariableConstInfo vci(&variableIdMapping, &map);
    for(VarConstSetMap::iterator i=_varConstSetMap.begin(); i!=_varConstSetMap.end(); ++i) {
        VariableId varId=(*i).first;
        //string variableName=variableIdMapping.uniqueShortVariableName(varId);
        string variableName=variableIdMapping.variableName(varId);
        myfile<<variableName;
        myfile<<",";
        myfile<<global_variableConstInfo->isAny(varId);
        myfile<<",";
        myfile<<global_variableConstInfo->isUniqueConst(varId);
        myfile<<",";
        myfile<<global_variableConstInfo->isMultiConst(varId);
        myfile<<",";
        if(global_variableConstInfo->isUniqueConst(varId)||global_variableConstInfo->isMultiConst(varId)) {
            myfile<<global_variableConstInfo->minConst(varId);
            myfile<<",";
            myfile<<global_variableConstInfo->maxConst(varId);
            size_t mywidth=global_variableConstInfo->width(varId);
            assert(mywidth==(size_t)global_variableConstInfo->maxConst(varId)-global_variableConstInfo->minConst(varId)+1);
            int mylog2=log2(mywidth);
            // compute upper whole number
            int bits=-1;

            // casts on pow args to ensure that the correct overloaded C++ cmath function is selected
            if(mywidth==static_cast<size_t>(pow(2.0,(double)mylog2))) {
                if(mylog2==0)
                    bits=1;
                else
                    bits=mylog2;
            } else {
                bits=mylog2+1;
            }
            assert(bits!=-1);
            myfile<<",";
            myfile<<bits;
        } else {
            myfile<<INT_MIN
                  <<","
                  <<INT_MAX
                  <<","
                  <<sizeof(int)*8;
        }
        myfile<<",";

        // TODO: print array size
        // myfile<<",";
        SgType* varType=variableIdMapping.getType(varId);
        if(isSgArrayType(varType))
            myfile<<"CA_ARRAY";
        else if(isSgPointerType(varType))
            myfile<<"CA_PTR";
        else if(isSgTypeInt(varType))
            myfile<<"CA_INT";
        else
            myfile<<"CA_UNKNOWN";
        myfile<<",";
        //myfile<<arraySize<<",";
#if 1
        set<CppCapsuleConstIntLattice> valueSet=(*i).second;
        stringstream setstr;
        myfile<<"{";
        for(set<CppCapsuleConstIntLattice>::iterator i=valueSet.begin(); i!=valueSet.end(); ++i) {
            if(i!=valueSet.begin())
                myfile<<",";
            myfile<<(*i).getValue().toString();
        }
        myfile<<"}";
#endif
        myfile<<endl;
    }
    myfile.close();
}
Ejemplo n.º 20
0
void runAnalyses(SgProject* root, Labeler* labeler, VariableIdMapping* variableIdMapping) {

  SPRAY::DFAnalysisBase::normalizeProgram(root);

  if(option_fi_constanalysis) {
    VarConstSetMap varConstSetMap;
    FIConstAnalysis fiConstAnalysis(variableIdMapping);
    fiConstAnalysis.runAnalysis(root);
    fiConstAnalysis.attachAstAttributes(labeler,"const-analysis-inout"); // not iolabeler
    if(csvConstResultFileName) {
      cout<<"INFO: generating const CSV file "<<option_prefix+csvConstResultFileName<<endl;
      fiConstAnalysis.writeCvsConstResult(*variableIdMapping, option_prefix+csvConstResultFileName);
    }
    cout << "INFO: annotating analysis results as comments."<<endl;
    AstAnnotator ara(labeler);
    ara.annotateAstAttributesAsCommentsBeforeStatements(root, "const-analysis-inout");
    ara.annotateAstAttributesAsCommentsAfterStatements(root, "const-analysis-inout");
  }

  if(option_at_analysis) {
    cout<<"STATUS: running address taken analysis."<<endl;
    // compute variableId mappings
    VariableIdMapping variableIdMapping;
    variableIdMapping.computeVariableSymbolMapping(root);
    SPRAY::FIPointerAnalysis fipa(&variableIdMapping,root);
    fipa.initialize();
    fipa.run();
#if 0
    VariableIdSet vidset=fipa.getModByPointer();
    cout<<"mod-set: "<<SPRAY::VariableIdSetPrettyPrint::str(vidset,variableIdMapping)<<endl;
#endif
  }
  
  if(option_interval_analysis) {
    cout << "STATUS: creating interval analyzer."<<endl;
    SPRAY::IntervalAnalysis* intervalAnalyzer=new SPRAY::IntervalAnalysis();
    cout << "STATUS: initializing interval analyzer."<<endl;
    intervalAnalyzer->initialize(root);
    cout << "STATUS: initializing interval transfer functions."<<endl;
    intervalAnalyzer->initializeTransferFunctions();
    cout << "STATUS: initializing interval global variables."<<endl;
    intervalAnalyzer->initializeGlobalVariables(root);
      
    intervalAnalyzer->setSolverTrace(option_trace);
    std::string funtofind="main";
    RoseAst completeast(root);
    SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind);
    intervalAnalyzer->determineExtremalLabels(startFunRoot);
    intervalAnalyzer->run();
#if 0
    intervalAnalyzer->attachInInfoToAst("iv-analysis-in");
    intervalAnalyzer->attachOutInfoToAst("iv-analysis-out");
    AstAnnotator ara(intervalAnalyzer->getLabeler(),intervalAnalyzer->getVariableIdMapping());
    ara.annotateAstAttributesAsCommentsBeforeStatements(root, "iv-analysis-in");
    ara.annotateAstAttributesAsCommentsAfterStatements(root, "iv-analysis-out");
#else
    AnalysisAstAnnotator ara(intervalAnalyzer->getLabeler(),intervalAnalyzer->getVariableIdMapping());
    ara.annotateAnalysisPrePostInfoAsComments(root,"iv-analysis",intervalAnalyzer);
#endif

  }

  if(option_lv_analysis) {
    cout << "STATUS: creating LV analysis."<<endl;
    SPRAY::LVAnalysis* lvAnalysis=new SPRAY::LVAnalysis();
    cout << "STATUS: initializing LV analysis."<<endl;
    lvAnalysis->setBackwardAnalysis();
    lvAnalysis->initialize(root);
    cout << "STATUS: initializing LV transfer functions."<<endl;
    lvAnalysis->initializeTransferFunctions();
    cout << "STATUS: initializing LV global variables."<<endl;
    lvAnalysis->initializeGlobalVariables(root);
    std::string funtofind="main";
    RoseAst completeast(root);
    SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind);
    cout << "generating icfg_backward.dot."<<endl;
    write_file("icfg_backward.dot", lvAnalysis->getFlow()->toDot(lvAnalysis->getLabeler()));

    lvAnalysis->determineExtremalLabels(startFunRoot);
    lvAnalysis->run();
    cout << "INFO: attaching LV-data to AST."<<endl;
#if 0
    lvAnalysis->attachInInfoToAst("lv-analysis-in");
    lvAnalysis->attachOutInfoToAst("lv-analysis-out");
    AstAnnotator ara(lvAnalysis->getLabeler(),lvAnalysis->getVariableIdMapping());
    ara.annotateAstAttributesAsCommentsBeforeStatements(root, "lv-analysis-in");
    ara.annotateAstAttributesAsCommentsAfterStatements(root, "lv-analysis-out");
#else
    AnalysisAstAnnotator ara(lvAnalysis->getLabeler(),lvAnalysis->getVariableIdMapping());
    ara.annotateAnalysisPrePostInfoAsComments(root,"lv-analysis",lvAnalysis);
#endif
    delete lvAnalysis;
  }

  if(option_rd_analysis) {
      cout << "STATUS: creating RD analyzer."<<endl;
      SPRAY::RDAnalysis* rdAnalysis=new SPRAY::RDAnalysis();
      cout << "STATUS: initializing RD analyzer."<<endl;
      rdAnalysis->initialize(root);
      cout << "STATUS: initializing RD transfer functions."<<endl;
      rdAnalysis->initializeTransferFunctions();
      cout << "STATUS: initializing RD global variables."<<endl;
      rdAnalysis->initializeGlobalVariables(root);
      
      cout << "generating icfg_forward.dot."<<endl;
      write_file("icfg_forward.dot", rdAnalysis->getFlow()->toDot(rdAnalysis->getLabeler()));
    
      std::string funtofind="main";
      RoseAst completeast(root);
      SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind);
      rdAnalysis->determineExtremalLabels(startFunRoot);
      rdAnalysis->run();
    
      cout << "INFO: attaching RD-data to AST."<<endl;
      rdAnalysis->attachInInfoToAst("rd-analysis-in");
      rdAnalysis->attachOutInfoToAst("rd-analysis-out");
      //printAttributes<RDAstAttribute>(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping(),"rd-analysis-in");
      cout << "INFO: annotating analysis results as comments."<<endl;
      ROSE_ASSERT(rdAnalysis->getVariableIdMapping());
#if 0
      AstAnnotator ara(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping());
      ara.annotateAstAttributesAsCommentsBeforeStatements(root, "rd-analysis-in");
      ara.annotateAstAttributesAsCommentsAfterStatements(root, "rd-analysis-out");
#else
      AnalysisAstAnnotator ara(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping());
      ara.annotateAnalysisPrePostInfoAsComments(root,"rd-analysis",rdAnalysis);
#endif

#if 0
      cout << "INFO: substituting uses with rhs of defs."<<endl;
      substituteUsesWithAvailableExpRhsOfDef("ud-analysis", root, rdAnalysis->getLabeler(), rdAnalysis->getVariableIdMapping());
#endif
      if(option_ud_analysis) {
        ROSE_ASSERT(option_rd_analysis);
        cout << "INFO: generating and attaching UD-data to AST."<<endl;
        createUDAstAttributeFromRDAttribute(rdAnalysis->getLabeler(),"rd-analysis-in", "ud-analysis");
        Flow* flow=rdAnalysis->getFlow();
        cout<<"Flow label-set size: "<<flow->nodeLabels().size()<<endl;
        CFAnalysis* cfAnalyzer0=rdAnalysis->getCFAnalyzer();
        int red=cfAnalyzer0->reduceBlockBeginNodes(*flow);
        cout<<"INFO: eliminated "<<red<<" block-begin nodes in ICFG."<<endl;
        
#if 0
        cout << "INFO: computing program statistics."<<endl;
        ProgramStatistics ps(rdAnalysis->getVariableIdMapping(),
                             rdAnalysis->getLabeler(), 
                             rdAnalysis->getFlow(),
                             "ud-analysis");
        ps.computeStatistics();
        //ps.printStatistics();
        cout << "INFO: generating resource usage visualization."<<endl;
        ps.setGenerateWithSource(false);
        ps.generateResourceUsageICFGDotFile("resourceusageicfg.dot");
        flow->resetDotOptions();
#endif
        cout << "INFO: generating visualization data."<<endl;
        // generate ICFG visualization
        cout << "generating icfg.dot."<<endl;
        write_file("icfg.dot", flow->toDot(rdAnalysis->getLabeler()));
        
        //  cout << "INFO: generating control dependence graph."<<endl;
        //Flow cdg=rdAnalysis->getCFAnalyzer()->controlDependenceGraph(*flow);

        cout << "generating datadependencegraph.dot."<<endl;
        DataDependenceVisualizer ddvis0(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        //printAttributes<UDAstAttribute>(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping(),"ud-analysis");
        //ddvis._showSourceCode=false; // for large programs
        ddvis0.generateDefUseDotGraph(root,"datadependencegraph.dot");
        flow->resetDotOptions();
        
        cout << "generating icfgdatadependencegraph.dot."<<endl;
        DataDependenceVisualizer ddvis1(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        ddvis1.includeFlowGraphEdges(flow);
        ddvis1.generateDefUseDotGraph(root,"icfgdatadependencegraph.dot");
        flow->resetDotOptions();
        
        cout << "generating icfgdatadependencegraph_clustered.dot."<<endl;
        DataDependenceVisualizer ddvis2(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        ddvis2.generateDotFunctionClusters(root,rdAnalysis->getCFAnalyzer(),"icfgdatadependencegraph_clustered.dot",true);
        
        cout << "generating icfg_clustered.dot."<<endl;
        DataDependenceVisualizer ddvis3(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        ddvis3.generateDotFunctionClusters(root,rdAnalysis->getCFAnalyzer(),"icfg_clustered.dot",false);
        
      }
    }
}
Ejemplo n.º 21
0
string
VariableId::toString(VariableIdMapping& vim) const {
  return vim.uniqueShortVariableName(*this);
}