Example #1
0
Flow CFAnalysis::WhileAndDoWhileLoopFlow(SgNode* node, 
                                         Flow edgeSet,
                                         EdgeType edgeTypeParam1,
                                         EdgeType edgeTypeParam2) {
  if(!(isSgWhileStmt(node) || isSgDoWhileStmt(node))) {
    throw SPRAY::Exception("Error: WhileAndDoWhileLoopFlow: unsupported loop construct.");
  }
  SgNode* condNode=SgNodeHelper::getCond(node);
  Label condLabel=getLabel(condNode);
  SgNode* bodyNode=SgNodeHelper::getLoopBody(node);
  assert(bodyNode);
  Edge edge=Edge(condLabel,EDGE_TRUE,initialLabel(bodyNode));
  edge.addType(edgeTypeParam1);
  Flow flowB=flow(bodyNode);
  LabelSet finalSetB=finalLabels(bodyNode);
  edgeSet+=flowB;
  edgeSet.insert(edge);
  // back edges in while (forward edges in do-while)
  for(LabelSet::iterator i=finalSetB.begin();i!=finalSetB.end();++i) {
    Edge e;
    if(SgNodeHelper::isCond(labeler->getNode(*i))) {
      e=Edge(*i,EDGE_FALSE,condLabel);
      e.addType(edgeTypeParam2);
    } else {
      e=Edge(*i,edgeTypeParam2,condLabel);
    }
    edgeSet.insert(e);
  }
  return edgeSet;
}
Example #2
0
void CFAnalyzer::intraInterFlow(Flow& flow, InterFlow& interFlow) {
  for(InterFlow::iterator i=interFlow.begin();i!=interFlow.end();++i) {
	if((*i).entry==Labeler::NO_LABEL && (*i).exit==Labeler::NO_LABEL) {
	  Edge externalEdge=Edge((*i).call,EDGE_EXTERNAL,(*i).callReturn);	  
	  flow.insert(externalEdge);
	} else {
	  Edge callEdge=Edge((*i).call,EDGE_CALL,(*i).entry);
	  Edge callReturnEdge=Edge((*i).exit,EDGE_CALLRETURN,(*i).callReturn);
	  Edge localEdge=Edge((*i).call,EDGE_LOCAL,(*i).callReturn);
	  flow.insert(callEdge);
	  flow.insert(callReturnEdge);
	  flow.insert(localEdge);
	}
  }
}
Example #3
0
File: Flow.C Project: 8l/rose
Flow Flow::operator+(Flow& s2) {
  Flow result;
  result=*this;
  for(Flow::iterator i2=s2.begin();i2!=s2.end();++i2)
    result.insert(*i2);
  return result;
}
Example #4
0
File: Flow.C Project: 8l/rose
SPRAY::Flow Flow::reverseFlow() {
  Flow reverseFlow;
  for(Flow::iterator i=begin();i!=end();++i) {
    reverseFlow.insert(Edge((*i).target,(*i).getTypes(),(*i).source));
  }
  return reverseFlow;
}
Example #5
0
Flow CFAnalysis::controlDependenceGraph(Flow& controlFlow) {
  LabelSet condLabels=conditionLabels(controlFlow);
  LabelSet targetLabels;
  Flow controlDependenceEdges;
  for(LabelSet::iterator i=condLabels.begin();i!=condLabels.end();++i) {
    SgNode* condition=getLabeler()->getNode(*i);
    cerr<<"DEBUG: cond:"<<condition->class_name()<<endl;
    SgNode* stmt=SgNodeHelper::getParent(condition);
    cerr<<"DEBUG: stmt:"<<stmt->class_name()<<endl;
    // while/dowhile/for
    if(SgNodeHelper::isLoopCond(condition)) {
      SgNode* loopBody=SgNodeHelper::getLoopBody(stmt);
      cerr<<"DEBUG: loopBody:"<<loopBody->class_name()<<endl;
      LabelSet loopBodyInitLabels=setOfInitialLabelsOfStmtsInBlock(loopBody);
      targetLabels=loopBodyInitLabels;
    }
    // if
    if(isSgIfStmt(stmt)) {
      SgNode* trueBranch=SgNodeHelper::getTrueBranch(stmt);
      LabelSet trueBranchInitLabels=setOfInitialLabelsOfStmtsInBlock(trueBranch);
      SgNode* falseBranch=SgNodeHelper::getFalseBranch(stmt);
      LabelSet falseBranchInitLabels=setOfInitialLabelsOfStmtsInBlock(falseBranch);
      targetLabels=trueBranchInitLabels+falseBranchInitLabels;
    }
    for(LabelSet::iterator j=targetLabels.begin();j!=targetLabels.end();++j) {
      controlDependenceEdges.insert(Edge(*i,EDGE_FORWARD,*j));
    }
  }
  return controlDependenceEdges;
}
Example #6
0
int CFAnalyzer::reduceBlockBeginNodes(Flow& flow) {
  LabelSet labs=flow.nodeLabels();
  int cnt=0;
  for(LabelSet::iterator i=labs.begin();i!=labs.end();++i) {
	if(isSgBasicBlock(getNode(*i))) {
	  cnt++;
	  Flow inFlow=flow.inEdges(*i);
	  Flow outFlow=flow.outEdges(*i);

	  // multiple out-edges not supported yet
	  assert(outFlow.size()<=1); 

	  /* description of essential operations:
	   *   inedges: (n_i,b)
	   *   outedge: (b,n2) 
	   *   remove(n_i,b)
	   *   remove(b,n2)
	   *   insert(n1,n2)
	   */
	  for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
		Edge e1=*initer;
		Edge e2=*outFlow.begin();
		Edge newEdge=Edge(e1.source,e1.types(),e2.target);
		flow.erase(e1);
		flow.erase(e2);
		flow.insert(newEdge);
	  }
	}
  }
  return cnt;
}
Example #7
0
int CFAnalysis::reduceNode(Flow& flow, Label lab) {
  Flow inFlow=flow.inEdges(lab);
  Flow outFlow=flow.outEdges(lab);
  /* description of essential operations:
   *   inedges: (n_i,b)
   *   outedge: (b,n2) 
   *   remove(n_i,b)
   *   remove(b,n2)
   *   insert(n1,n2)
   */
  if(inFlow.size()==0 && outFlow.size()==0)
    return 0;

  if(inFlow.size()==0 || outFlow.size()==0) {
    Flow edges=inFlow+outFlow;
    flow.deleteEdges(edges);
    return 1;
  }

  for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
    for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
      Edge e1=*initer;
      Edge e2=*outiter;
      Edge newEdge=Edge(e1.source,e1.types(),e2.target);
      flow.erase(e1);
      flow.erase(e2);
      flow.insert(newEdge);
    }
  }
  return 1;
}
Example #8
0
File: Flow.C Project: 8l/rose
Flow Flow::edgesOfType(EdgeType edgeType) {
  Flow flow;
  for(Flow::iterator i=begin();i!=end();++i) {
    if((*i).isType(edgeType))
      flow.insert(*i);
  }
  flow.setDotOptionDisplayLabel(_dotOptionDisplayLabel);
  flow.setDotOptionDisplayStmt(_dotOptionDisplayStmt);
  return flow;
}
Example #9
0
File: Flow.C Project: 8l/rose
Flow Flow::inEdges(Label label) {
  Flow flow;
  for(Flow::iterator i=begin();i!=end();++i) {
    if((*i).target==label)
      flow.insert(*i);
  }
  flow.setDotOptionDisplayLabel(_dotOptionDisplayLabel);
  flow.setDotOptionDisplayStmt(_dotOptionDisplayStmt);
  return flow;
}
Example #10
0
File: Flow.C Project: 8l/rose
Flow Flow::outEdges(Label label) {
  Flow flow;
  if(!_boostified) {
    for(Flow::iterator i=begin();i!=end();++i) {
      if((*i).source==label)
        flow.insert(*i);
    }
  } else {
    typedef graph_traits<FlowGraph> GraphTraits;
    //    typename property_map<FlowGraph, vertex_index_t>::type 
    // index = get(vertex_index, _flowGraph);
    GraphTraits::out_edge_iterator out_i, out_end;
    GraphTraits::edge_descriptor e;
    for (tie(out_i, out_end) = out_edges(label.getId(), _flowGraph); 
         out_i != out_end; ++out_i) {
      e = *out_i;
      Label src = source(e, _flowGraph), targ = target(e, _flowGraph);
      flow.insert(Edge(src,_flowGraph[e],targ));
    }
  }
  flow.setDotOptionDisplayLabel(_dotOptionDisplayLabel);
  flow.setDotOptionDisplayStmt(_dotOptionDisplayStmt);
  return flow;
}
Flow* ParProTransitionGraph::toFlowEnumerateStates(NumberGenerator& numGen) {
  Flow* result = new Flow();
  unordered_map<const ParProEState*, Label> eState2Label;
  for (EStateTransitionMap::iterator i=_outEdges.begin(); i!=_outEdges.end(); i++) {
    for (ParProTransitions::iterator k=i->second.begin(); k!=i->second.end(); k++) {
      const ParProEState* source = (*k).source;
      if (eState2Label.find(source) == eState2Label.end()) {
	eState2Label[source] = Label(numGen.next());
      }
      const ParProEState* target = (*k).target;
      if (eState2Label.find(target) == eState2Label.end()) {
	eState2Label[target] = Label(numGen.next());
      }
      Edge e(eState2Label[source], eState2Label[target]);
      e.setAnnotation(k->edge.getAnnotation());
      result->insert(e);
    }
  }
  return result;
}
Example #12
0
int CFAnalysis::reduceBlockBeginNodes(Flow& flow) {
  LabelSet labs=flow.nodeLabels();
  int cnt=0;
  for(LabelSet::iterator i=labs.begin();i!=labs.end();++i) {
    //cout<<"Checking label: "<<(*i)<<" node: "<<getNode(*i)<<" code:"<<getNode(*i)->unparseToString()<<endl;
    if(isSgBasicBlock(getNode(*i))) {
#if 1
      cnt+=reduceNode(flow,*i);
#else
      cnt++;
      Flow inFlow=flow.inEdges(*i);
      Flow outFlow=flow.outEdges(*i);

      // multiple out-edges not supported yet
      assert(outFlow.size()<=1); 

      /* description of essential operations:
       *   inedges: (n_i,b)
       *   outedge: (b,n2) 
       *   remove(n_i,b)
       *   remove(b,n2)
       *   insert(n1,n2)
       */
      for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
        Edge e1=*initer;
        Edge e2=*outFlow.begin();
        Edge newEdge=Edge(e1.source,e1.types(),e2.target);
        flow.erase(e1);
        flow.erase(e2);
        flow.insert(newEdge);
      }
#endif
    }
  }
  return cnt;
}
Example #13
0
Flow CFAnalysis::flow(SgNode* node) {
  assert(node);

  Flow edgeSet;
  if(node==0)
    return edgeSet;
  if(isSgFunctionDeclaration(node)) {
    return edgeSet;
  }

  if(isSgProject(node)||isSgFileList(node)||isSgGlobal(node)||isSgSourceFile(node)) {
    RoseAst ast(node);
    Flow tmpEdgeSet;
    // search for all functions and union flow for all functions
    for(RoseAst::iterator i=ast.begin();i!=ast.end();++i) {
      // schroder3 (2016-07-29): Added " && !isSgTemplateFunctionDefinition(*i)" to prevent
      //  SgTemplateFunctionDefinition nodes from being added to the ICFG. SgTemplateFunctionDefinitions
      //  are never called because they are only used in template declarations (SgTemplateDeclaration)
      //  (and not in template instantiation or specialization declarations (SgTemplateInstantiationFunctionDecl)).
      //  Template instantiation/ specialization declarations have "normal" SgFunctionDefinition nodes as
      //  corresponding definition. Even in case of an implicit instantiation of an implicit specialization ROSE
      //  creates a SgTemplateInstantiationFunctionDecl and copies the body of the SgTemplateFunctionDefinition
      //  to a new SgFunctionDefinition and uses the SgFunctionDefinition as definition.
      if(isSgFunctionDefinition(*i) && !isSgTemplateFunctionDefinition(*i)) {
        // schroder3 (2016-07-12): We can not skip the children of a function definition
        //  because there might be a member function definition inside the function definition.
        //  Example:
        //   int main() {
        //     class A {
        //      public:
        //       void mf() {
        //         int i = 2;
        //       }
        //     };
        //   }
        //
        // i.skipChildrenOnForward();

        //cout << "STATUS: Generating flow for function "<<SgNodeHelper::getFunctionName(*i)<<endl;
        tmpEdgeSet=flow(*i);
        edgeSet+=tmpEdgeSet;
      }
    }
    return edgeSet;
  }
  
  // special case of function call pattern
  if(SgNodeHelper::Pattern::matchFunctionCall(node)) {
    // we add the 'local' edge when intraInter flow is computed (it may also be an 'external' edge)
#if 0
    Label callLabel=labeler->functionCallLabel(node);
    Label callReturnLabel=labeler->functionCallReturnLabel(node);
    edgeSet.insert(Edge(callLabel,EDGE_LOCAL,callReturnLabel));
#endif
    // add special case edge for callReturn to returnNode SgReturnStmt(SgFunctionCallExp) 
    // edge: SgFunctionCallExp.callReturn->init(SgReturnStmt)
    if(SgNodeHelper::Pattern::matchReturnStmtFunctionCallExp(node)) {
      Label callReturnLabel=labeler->functionCallReturnLabel(node);
      Label returnStmtLabel=labeler->functionCallReturnLabel(node)+1;
      edgeSet.insert(Edge(callReturnLabel,EDGE_FORWARD,returnStmtLabel));
    }
    return edgeSet;
  }

  switch (node->variantT()) {
  case V_SgFunctionDefinition: {
    SgBasicBlock* body=isSgFunctionDefinition(node)->get_body();
    Edge edge=Edge(labeler->functionEntryLabel(node),EDGE_FORWARD,initialLabel(body));
    edgeSet.insert(edge);
    Flow bodyFlow=flow(body);
    edgeSet+=bodyFlow;
    /* add explicitly edge from last stmt of function to exit-node
       not that a return at the end of a function is *not* represented in a ROSE AST.
       if return does not exist, we need to add an explicit edge from end of function to exit
       since we create this edge with the computed final node a branch with returns in all branches is
       maintained properly.
       this edge is identical if we have some other branches. Because we maintain the edges as an edge-set
       this operation is always OK.
     */
#if 0
    LabelSet funFinalLabels=finalLabels(node);
#else
    LabelSet funFinalLabels=finalLabels(body);
#endif
    for(LabelSet::iterator i=funFinalLabels.begin();i!=funFinalLabels.end();++i) {
      Edge explicitEdge=Edge(*i,EDGE_FORWARD,labeler->functionExitLabel(node));
      if(SgNodeHelper::isLoopCond(labeler->getNode(*i))) {
        explicitEdge.addType(EDGE_FALSE);
      }
      if(SgNodeHelper::isCond(labeler->getNode(*i))) {
        if(SgIfStmt* ifStmt=isSgIfStmt(labeler->getNode(*i)->get_parent())) {
          if(!SgNodeHelper::getFalseBranch(ifStmt)) {
            // MS: 07/02/2014: in case of empty if-false branch (at end of function), FALSE must be added to explicit node (only if-false can be empty)
            explicitEdge.addType(EDGE_FALSE);
          }
        }
      }
      edgeSet.insert(explicitEdge);
    }
    return edgeSet;
  }
  case V_SgReturnStmt: {
    SgNode* funcDef=SgNodeHelper::correspondingSgFunctionDefinition(node);
    if(!funcDef)
      cerr << "Error: No corresponding function for ReturnStmt found."<<endl;
    assert(isSgFunctionDefinition(funcDef));
    Edge edge=Edge(getLabel(node),EDGE_FORWARD,labeler->functionExitLabel(funcDef));
    edgeSet.insert(edge);
    return edgeSet;
  }
  case V_SgBreakStmt:
  case V_SgInitializedName:
  case V_SgVariableDeclaration:
  case V_SgNullStatement:
  case V_SgPragmaDeclaration:
  case V_SgLabelStatement:
  case V_SgExprStatement:
  case V_SgDefaultOptionStmt:
  case V_SgCaseOptionStmt:
  case V_SgClassDeclaration:
    return edgeSet;
  case V_SgContinueStmt: {
    SgNode* loopStmt=correspondingLoopConstruct(node);
    if(isSgWhileStmt(loopStmt)) {
      // target is condition node
      SgNode* targetNode=SgNodeHelper::getCond(loopStmt);
      ROSE_ASSERT(targetNode);
      Edge edge=Edge(getLabel(node),EDGE_BACKWARD,getLabel(targetNode));
      edgeSet.insert(edge);
    } else if(isSgDoWhileStmt(loopStmt)) {
      // target is condition node
      SgNode* targetNode=SgNodeHelper::getCond(loopStmt);
      ROSE_ASSERT(targetNode);
      Edge edge=Edge(getLabel(node),EDGE_FORWARD,getLabel(targetNode));
      edgeSet.insert(edge);
    } else if(isSgForStatement(loopStmt)) {
      // target is increment expr
      SgExpression* incExp=SgNodeHelper::getForIncExpr(loopStmt);
      if(!incExp)
        throw SPRAY::Exception("CFAnalysis: for-loop: empty incExpr not supported.");
      SgNode* targetNode=incExp;
      ROSE_ASSERT(targetNode);
      Edge edge=Edge(getLabel(node),EDGE_FORWARD,getLabel(targetNode));
      edgeSet.insert(edge);
    } else {
      throw SPRAY::Exception("CFAnalysis: continue in unknown loop construct (not while,do-while, or for).");
    }
    return edgeSet;
  }
  case V_SgIfStmt: {
    SgNode* nodeC=SgNodeHelper::getCond(node);
    Label condLabel=getLabel(nodeC);
    SgNode* nodeTB=SgNodeHelper::getTrueBranch(node);
    Edge edgeTB=Edge(condLabel,EDGE_TRUE,initialLabel(nodeTB));
    edgeTB.addType(EDGE_FORWARD);
    edgeSet.insert(edgeTB);
    Flow flowTB=flow(nodeTB);
    edgeSet+=flowTB;
    if(SgNode* nodeFB=SgNodeHelper::getFalseBranch(node)) {
      Flow flowFB=flow(nodeFB);
      Edge edgeFB=Edge(condLabel,EDGE_FALSE,initialLabel(nodeFB));
      edgeFB.addType(EDGE_FORWARD);
      edgeSet.insert(edgeFB);
      edgeSet+=flowFB;
    }
    return edgeSet;
  }
  case V_SgGotoStatement: {
    SgGotoStatement* gotoStmt=isSgGotoStatement(node);
    SgLabelStatement* targetSgLabelStmt=gotoStmt->get_label();
    ROSE_ASSERT(targetSgLabelStmt);
    // note that the target label is not an element of the finalLabels set.
    Label targetLabel=labeler->getLabel(targetSgLabelStmt);
    edgeSet.insert(Edge(initialLabel(node),EDGE_FORWARD,targetLabel));
    return edgeSet;
  }
  case V_SgSwitchStatement: {
    SgNode* nodeC=SgNodeHelper::getCond(node);
    Label condLabel=getLabel(nodeC);
    SgSwitchStatement* switchStmt=isSgSwitchStatement(node);
    SgStatement* body=switchStmt->get_body();
    SgBasicBlock* block=isSgBasicBlock(body);
    if(!block) {
      cerr<<"Error: CFAnalysis::flow: body of switch is not a basic block. Unknown structure."<<endl;
      exit(1);
    }
    SgStatementPtrList& stmtList=block->get_statements();
    ROSE_ASSERT(stmtList.size()>0);
    SgStatement* prevCaseStmtBody=0;
    for(SgStatementPtrList::iterator i=stmtList.begin();
        i!=stmtList.end();
        ++i) {
      // TODO: revisit this case: this should work for all stmts in the body, when break has its own label as final label.
      //SgDefaultOptionStmt
      if(isSgCaseOptionStmt(*i)||isSgDefaultOptionStmt(*i)) {
        Label caseStmtLab=labeler->getLabel(*i);
        SgStatement* caseBody=getCaseOrDefaultBodyStmt(*i);
        ROSE_ASSERT(caseBody);
        Label caseBodyLab=labeler->getLabel(caseBody);
        edgeSet.insert(Edge(condLabel,EDGE_FORWARD,caseStmtLab));
        edgeSet.insert(Edge(caseStmtLab,EDGE_FORWARD,initialLabel(caseBody)));
        Flow flowStmt=flow(caseBody);
        edgeSet+=flowStmt;
        {
          // create edges from other case stmts to the next case that have no break at the end.
          if(prevCaseStmtBody) {
            LabelSet finalBodyLabels=finalLabels(prevCaseStmtBody);
            for(LabelSet::iterator i=finalBodyLabels.begin();i!=finalBodyLabels.end();++i) {
              if(!isSgBreakStmt(labeler->getNode(*i))) {
                edgeSet.insert(Edge(*i,EDGE_FORWARD,caseBodyLab));
              }
            }
          }
        }
        prevCaseStmtBody=caseBody;
      } else {
        cerr<<"Error: control flow: stmt in switch is not a case or default stmt. Not supported yet."<<endl;
        exit(1);
      }
    }
    return edgeSet;
  }
  case V_SgWhileStmt: 
    return WhileAndDoWhileLoopFlow(node,edgeSet,EDGE_FORWARD,EDGE_BACKWARD);
  case V_SgDoWhileStmt: 
    return WhileAndDoWhileLoopFlow(node,edgeSet,EDGE_BACKWARD,EDGE_FORWARD);
  case V_SgBasicBlock: {
    size_t len=node->get_numberOfTraversalSuccessors();
    if(len==0) {
      // do not generate edge to blockEndLabel
      //Edge edge=Edge(labeler->blockBeginLabel(node),EDGE_FORWARD,labeler->blockEndLabel(node));
      //edgeSet.insert(edge);
      return edgeSet;
    } else {
      if(len==1) {
        SgNode* onlyStmt=node->get_traversalSuccessorByIndex(0);
        Flow onlyFlow=flow(onlyStmt);
        edgeSet+=onlyFlow;
      } else {
        for(size_t i=0;i<len-1;++i) {
          SgNode* childNode1=node->get_traversalSuccessorByIndex(i);
          SgNode* childNode2=node->get_traversalSuccessorByIndex(i+1);
          Flow flow12=flow(childNode1,childNode2);
          edgeSet+=flow12;
        }
      }
    }
    SgNode* firstStmt=node->get_traversalSuccessorByIndex(0);
    Edge edge1=Edge(labeler->blockBeginLabel(node),EDGE_FORWARD,initialLabel(firstStmt));
    edgeSet.insert(edge1);
    ROSE_ASSERT(len>=1);
    // do not generate edges to blockEndLabel
#if 0
    SgNode* lastStmt=node->get_traversalSuccessorByIndex(len-1);
    ROSE_ASSERT(isSgStatement(lastStmt));
    LabelSet lastStmtFinalLabels=finalLabels(lastStmt);
    for(LabelSet::iterator i=lastStmtFinalLabels.begin();i!=lastStmtFinalLabels.end();++i) {
      Edge edge2=Edge(*i,EDGE_FORWARD,labeler->blockEndLabel(node));
      edgeSet.insert(edge2);
    }
#endif
    return edgeSet;
  }

  case V_SgForStatement: {
    SgStatementPtrList& stmtPtrList=SgNodeHelper::getForInitList(node);
    int len=stmtPtrList.size();
    if(len==0) {
      // empty initializer list (hence, an initialization stmt cannot be initial stmt of for)
      cout << "INFO: for-stmt: initializer-list is empty."<<endl;
      cerr << "Error: empty for-stmt initializer not supported yet."<<endl;
      exit(1);
    }
    assert(len>0);
    SgNode* lastNode=0;
    if(len==1) {
      SgNode* onlyStmt=*stmtPtrList.begin();
      Flow onlyFlow=flow(onlyStmt);
      edgeSet+=onlyFlow;
      lastNode=onlyStmt;
    } else {
      assert(stmtPtrList.size()>=2);
      for(SgStatementPtrList::iterator i=stmtPtrList.begin();
          i!=stmtPtrList.end();
          ++i) {
        SgNode* node1=*i;
        SgStatementPtrList::iterator i2=i;
        i2++;
        SgNode* node2=*i2;
        Flow flow12=flow(node1,node2);
        edgeSet+=flow12;
        i2++;
        if(i2==stmtPtrList.end()) {
          lastNode=node2;
          break;
        }        
      }
    }
    SgNode* condNode=SgNodeHelper::getCond(node);
    if(!condNode)
      throw SPRAY::Exception("Error: for-loop: empty condition not supported yet.");
    Flow flowInitToCond=flow(lastNode,condNode);
    edgeSet+=flowInitToCond;
    Label condLabel=getLabel(condNode);
    SgNode* bodyNode=SgNodeHelper::getLoopBody(node);
    assert(bodyNode);
    Edge edge=Edge(condLabel,EDGE_TRUE,initialLabel(bodyNode));
    edge.addType(EDGE_FORWARD);
    Flow flowB=flow(bodyNode);
    edgeSet+=flowB;
    edgeSet.insert(edge);

    // Increment Expression:
    SgExpression* incExp=SgNodeHelper::getForIncExpr(node);
    if(!incExp)
      throw SPRAY::Exception("Error: for-loop: empty incExpr not supported yet.");
    ROSE_ASSERT(incExp);
    Label incExpLabel=getLabel(incExp);
    ROSE_ASSERT(incExpLabel!=Labeler::NO_LABEL);

    // Edges from final labels of for body to the increment expression:
    LabelSet finalSetB=finalLabels(bodyNode);
    for(LabelSet::iterator i=finalSetB.begin();i!=finalSetB.end();++i) {
      Edge edgeToIncExpr=Edge(*i,EDGE_FORWARD,incExpLabel);
      if(SgNodeHelper::isCond(labeler->getNode(*i))) {
        edgeToIncExpr.addType(EDGE_FALSE);
      }
      edgeSet.insert(edgeToIncExpr);
    }

    // Edge from increment expression back to condition:
    Edge backwardEdge = Edge(incExpLabel,EDGE_BACKWARD,condLabel);
    edgeSet.insert(backwardEdge);
    return edgeSet;
  }
  default:
    throw SPRAY::Exception("Unknown node in CFAnalysis::flow: "+node->class_name()+" Problemnode: "+node->unparseToString());
  }
}
Example #14
0
int CFAnalysis::reduceNode(Flow& flow, Label lab) {
  Flow inFlow=flow.inEdges(lab);
  Flow outFlow=flow.outEdges(lab);
  // edge type cleanup
  // if true and false edge exist, remove both (merging true and false branches to a single branch)
  // if forward and backward exist, remove forward (we are not removing the cycle)
  
  /* description of essential operations:
   *   inedges: (n_i,b)
   *   outedge: (b,n2) 
   *   remove(n_i,b)
   *   remove(b,n2)
   *   insert(n1,n2)
   */
  if(inFlow.size()==0 && outFlow.size()==0) {
    return 0;
  } else if(inFlow.size()>0 && outFlow.size()>0) {
    set<Edge> toErase;
    set<Edge> toInsert;
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
        Edge e1=*initer;
        Edge e2=*outiter;
        // preserve edge annotations of ingoing and outgoing edges
        EdgeTypeSet unionEdgeTypeSet;
        EdgeTypeSet edgeTypeSet1=(*initer).types();
        unionEdgeTypeSet.insert(edgeTypeSet1.begin(),edgeTypeSet1.end());
        EdgeTypeSet edgeTypeSet2=(*outiter).types();
        // only copy an edge annotation in the outgoing edge if it is
        // not a true-annotation or a false-annotation
        for(EdgeTypeSet::iterator i=edgeTypeSet2.begin();i!=edgeTypeSet2.end();++i) {
          if(*i!=EDGE_TRUE && *i!=EDGE_FALSE) {
            unionEdgeTypeSet.insert(*i);
          }
        }
        if(unionEdgeTypeSet.find(EDGE_TRUE)!=unionEdgeTypeSet.end()
           && unionEdgeTypeSet.find(EDGE_FALSE)!=unionEdgeTypeSet.end()) {
          unionEdgeTypeSet.erase(EDGE_TRUE);
          unionEdgeTypeSet.erase(EDGE_FALSE);
        }
        if(unionEdgeTypeSet.find(EDGE_FORWARD)!=unionEdgeTypeSet.end()
           && unionEdgeTypeSet.find(EDGE_BACKWARD)!=unionEdgeTypeSet.end()) {
          unionEdgeTypeSet.erase(EDGE_FORWARD);
          // keep backward edge annotation
        }
        
        Edge newEdge=Edge(e1.source(),unionEdgeTypeSet,e2.target());
        toErase.insert(e1);
        toErase.insert(e2);
        if(e1.source()!=e2.target()) {
          toInsert.insert(newEdge);
        }
      }
    }
    for(set<Edge>::iterator i=toErase.begin();i!=toErase.end();++i) {
      flow.erase(*i);
    }
    for(set<Edge>::iterator i=toInsert.begin();i!=toInsert.end();++i) {
      flow.insert(*i);
    }
    return 1;
  } else if(inFlow.size()>0) {
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      Edge e1=*initer;
      flow.erase(e1);
    }
    return 1;
  } else if(outFlow.size()>0) {
    for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
      Edge e2=*outiter;
      flow.erase(e2);
    }
    return 1;
  }
  return 0;
}
Example #15
0
Flow CFAnalyzer::flow(SgNode* node) {
  assert(node);

  Flow edgeSet;
  if(node==0)
	return edgeSet;
  if(isSgFunctionDeclaration(node)) {
	return edgeSet;
  }

  if(isSgProject(node)||isSgFileList(node)||isSgGlobal(node)||isSgSourceFile(node)) {
	RoseAst ast(node);
	Flow tmpEdgeSet;
	// search for all functions and union flow for all functions
	for(RoseAst::iterator i=ast.begin();i!=ast.end();++i) {
	  if(isSgFunctionDefinition(*i)) {
		i.skipChildrenOnForward();
		cout << "STATUS: Generating flow for function "<<SgNodeHelper::getFunctionName(*i)<<endl;
		tmpEdgeSet=flow(*i);
		edgeSet+=tmpEdgeSet;
	  }
	}
	return edgeSet;
  }
  
  // special case of function call pattern
  if(SgNodeHelper::Pattern::matchFunctionCall(node)) {
	// we add the 'local' edge when intraInter flow is computed (it may also be an 'external' edge)
#if 0
	Label callLabel=labeler->functionCallLabel(node);
	Label callReturnLabel=labeler->functionCallReturnLabel(node);
	edgeSet.insert(Edge(callLabel,EDGE_LOCAL,callReturnLabel));
#endif
	// add special case edge for callReturn to returnNode SgReturnStmt(SgFunctionCallExp) 
	// edge: SgFunctionCallExp.callReturn->init(SgReturnStmt)
	if(SgNodeHelper::Pattern::matchReturnStmtFunctionCallExp(node)) {
	  Label callReturnLabel=labeler->functionCallReturnLabel(node);
	  Label returnStmtLabel=labeler->functionCallReturnLabel(node)+1;
	  edgeSet.insert(Edge(callReturnLabel,EDGE_FORWARD,returnStmtLabel));
	}
	return edgeSet;
  }

  switch (node->variantT()) {
  case V_SgFunctionDefinition: {
	SgBasicBlock* body=isSgFunctionDefinition(node)->get_body();
	Edge edge=Edge(labeler->functionEntryLabel(node),EDGE_FORWARD,initialLabel(body));
	edgeSet.insert(edge);
	Flow bodyFlow=flow(body);
	edgeSet+=bodyFlow;
	/* add explicitly edge from last stmt of function to exit-node
	   not that a return at the end of a function is *not* represented in a ROSE AST.
	   if return does not exist, we need to add an explicit edge from end of function to exit
	   since we create this edge with the computed final node a branch with returns in all branches is
	   maintained properly.
	   this edge is identical if we have some other branches. Because we maintain the edges as an edge-set
	   this operation is always OK.
	 */
	LabelSet funFinalLabels=finalLabels(node);
	for(LabelSet::iterator i=funFinalLabels.begin();i!=funFinalLabels.end();++i) {
	  Edge explicitEdge=Edge(*i,EDGE_FORWARD,labeler->functionExitLabel(node));
	  if(SgNodeHelper::isLoopCond(labeler->getNode(*i))) {
		explicitEdge.addType(EDGE_FALSE);
	  }
	  edgeSet.insert(explicitEdge);
	}
	return edgeSet;
  }
  case V_SgReturnStmt: {
	SgNode* funcDef=SgNodeHelper::correspondingSgFunctionDefinition(node);
	if(!funcDef)
	  cerr << "Error: No corresponding function for ReturnStmt found."<<endl;
	assert(isSgFunctionDefinition(funcDef));
	Edge edge=Edge(getLabel(node),EDGE_FORWARD,labeler->functionExitLabel(funcDef));
	edgeSet.insert(edge);
	return edgeSet;
  }
  case V_SgBreakStmt:
  case V_SgInitializedName:
  case V_SgVariableDeclaration:
  case V_SgNullStatement:
  case V_SgLabelStatement:
  case V_SgExprStatement:
	return edgeSet;
  case V_SgIfStmt: {
	SgNode* nodeC=SgNodeHelper::getCond(node);
	Label condLabel=getLabel(nodeC);
	SgNode* nodeTB=SgNodeHelper::getTrueBranch(node);
	Edge edgeTB=Edge(condLabel,EDGE_TRUE,initialLabel(nodeTB));
	edgeTB.addType(EDGE_FORWARD);
	edgeSet.insert(edgeTB);
	Flow flowTB=flow(nodeTB);
	edgeSet+=flowTB;
	if(SgNode* nodeFB=SgNodeHelper::getFalseBranch(node)) {
	  Flow flowFB=flow(nodeFB);
	  Edge edgeFB=Edge(condLabel,EDGE_FALSE,initialLabel(nodeFB));
	  edgeFB.addType(EDGE_FORWARD);
	  edgeSet.insert(edgeFB);
	  edgeSet+=flowFB;
	}
	return edgeSet;
  }
  case V_SgWhileStmt: 
	return WhileAndDoWhileLoopFlow(node,edgeSet,EDGE_FORWARD,EDGE_BACKWARD);
  case V_SgDoWhileStmt: 
	return WhileAndDoWhileLoopFlow(node,edgeSet,EDGE_BACKWARD,EDGE_FORWARD);
  case V_SgBasicBlock: {
	size_t len=node->get_numberOfTraversalSuccessors();
	if(len==0) {
	  return edgeSet;
	} else {
	  if(len==1) {
		SgNode* onlyStmt=node->get_traversalSuccessorByIndex(0);
		Flow onlyFlow=flow(onlyStmt);
		edgeSet+=onlyFlow;
	  } else {
		for(size_t i=0;i<len-1;++i) {
		  SgNode* childNode1=node->get_traversalSuccessorByIndex(i);
		  SgNode* childNode2=node->get_traversalSuccessorByIndex(i+1);
		  Flow flow12=flow(childNode1,childNode2);
		  edgeSet+=flow12;
		}
	  }
	}
	SgNode* firstStmt=node->get_traversalSuccessorByIndex(0);
	Edge edge=Edge(getLabel(node),EDGE_FORWARD,initialLabel(firstStmt));
	edgeSet.insert(edge);
	return edgeSet;
  }

  case V_SgForStatement: {
	SgStatementPtrList& stmtPtrList=SgNodeHelper::getForInitList(node);
	int len=stmtPtrList.size();
	if(len==0) {
	  // empty initializer list (hence, an initialization stmt cannot be initial stmt of for)
	  cout << "INFO: for-stmt: initializer-list is empty."<<endl;
	  cerr << "Error: empty for-stmt initializer not supported yet."<<endl;
	  exit(1);
	}
	assert(len>0);
	SgNode* lastNode=0;
	if(len==1) {
	  SgNode* onlyStmt=*stmtPtrList.begin();
	  Flow onlyFlow=flow(onlyStmt);
	  edgeSet+=onlyFlow;
	  lastNode=onlyStmt;
	} else {
	  assert(stmtPtrList.size()>=2);
	  for(SgStatementPtrList::iterator i=stmtPtrList.begin();
		  i!=stmtPtrList.end();
		  ++i) {
		SgNode* node1=*i;
		SgStatementPtrList::iterator i2=i;
		i2++;
		SgNode* node2=*i2;
		Flow flow12=flow(node1,node2);
		edgeSet+=flow12;
		i2++;
		if(i2==stmtPtrList.end()) {
		  lastNode=node2;
		  break;
		}		
	  }
	}
	SgNode* condNode=SgNodeHelper::getCond(node);
	if(!condNode)
	  throw "Error: for-loop: empty condition not supported yet.";
	Flow flowInitToCond=flow(lastNode,condNode);
	edgeSet+=flowInitToCond;
	Label condLabel=getLabel(condNode);
	SgNode* bodyNode=SgNodeHelper::getLoopBody(node);
	assert(bodyNode);
	Edge edge=Edge(condLabel,EDGE_TRUE,initialLabel(bodyNode));
	edge.addType(EDGE_FORWARD);
	Flow flowB=flow(bodyNode);
	LabelSet finalSetB=finalLabels(bodyNode);
	edgeSet+=flowB;
	edgeSet.insert(edge);
	// back edges
	for(LabelSet::iterator i=finalSetB.begin();i!=finalSetB.end();++i) {
	  SgExpression* incExp=SgNodeHelper::getForIncExpr(node);
	  if(!incExp)
		throw "Error: for-loop: empty incExpr not supported yet.";
	  assert(incExp);
	  Label incExpLabel=getLabel(incExp);
	  assert(incExpLabel!=Labeler::NO_LABEL);
	  Edge e1,e2;
	  if(SgNodeHelper::isCond(labeler->getNode(*i))) {
		e1=Edge(*i,EDGE_FALSE,incExpLabel);
		e1.addType(EDGE_FORWARD);
		e2=Edge(incExpLabel,EDGE_BACKWARD,condLabel);
	  } else {
		e1=Edge(*i,EDGE_FORWARD,incExpLabel);
		e2=Edge(incExpLabel,EDGE_BACKWARD,condLabel);
	  }
	  edgeSet.insert(e1);
	  edgeSet.insert(e2);
	}
	return edgeSet;
  }
	
  default:
	cerr << "Error: Unknown node in CodeThorn::CFAnalyzer::flow: "<<node->sage_class_name()<<endl; 
	cerr << "Problemnode: "<<node->unparseToString()<<endl;
	exit(1);
  }
}
Example #16
0
int CFAnalysis::reduceNode(Flow& flow, Label lab) {
  Flow inFlow=flow.inEdges(lab);
  Flow outFlow=flow.outEdges(lab);
  EdgeTypeSet unionEdgeTypeSets;
  for(Flow::iterator i=inFlow.begin();i!=inFlow.end();++i) {
    EdgeTypeSet edgeTypeSet=(*i).types();
    unionEdgeTypeSets.insert(edgeTypeSet.begin(),edgeTypeSet.end());
  }
  for(Flow::iterator i=outFlow.begin();i!=outFlow.end();++i) {
    EdgeTypeSet edgeTypeSet=(*i).types();
    unionEdgeTypeSets.insert(edgeTypeSet.begin(),edgeTypeSet.end());
  }
  // edge type cleanup
  // if true and false edge exist, remove both (merging true and false branches to a single branch)
  // if forward and backward exist, remove backward (we are removing a cycle)
  if(unionEdgeTypeSets.find(EDGE_TRUE)!=unionEdgeTypeSets.end()
     && unionEdgeTypeSets.find(EDGE_FALSE)!=unionEdgeTypeSets.end()) {
    unionEdgeTypeSets.erase(EDGE_TRUE);
    unionEdgeTypeSets.erase(EDGE_FALSE);
  }
  if(unionEdgeTypeSets.find(EDGE_FORWARD)!=unionEdgeTypeSets.end()
     && unionEdgeTypeSets.find(EDGE_BACKWARD)!=unionEdgeTypeSets.end()) {
    unionEdgeTypeSets.erase(EDGE_FORWARD);
    unionEdgeTypeSets.erase(EDGE_BACKWARD);
  }
  
  /* description of essential operations:
   *   inedges: (n_i,b)
   *   outedge: (b,n2) 
   *   remove(n_i,b)
   *   remove(b,n2)
   *   insert(n1,n2)
   */
  if(inFlow.size()==0 && outFlow.size()==0) {
    return 0;
  } else if(inFlow.size()>0 && outFlow.size()>0) {
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
        Edge e1=*initer;
        Edge e2=*outiter;
        // preserve edge annotations of ingoing and outgoing edges
        Edge newEdge=Edge(e1.source,unionEdgeTypeSets,e2.target);
        flow.erase(e1);
        flow.erase(e2);
        flow.insert(newEdge);
      }
      return 1;
    }
  } else if(inFlow.size()>0) {
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      Edge e1=*initer;
      flow.erase(e1);
    }
    return 1;
  } else if(outFlow.size()>0) {
    for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
      Edge e2=*outiter;
      flow.erase(e2);
    }
    return 1;
  }
  return 0;
}