bool printDataflowInfoPass::transfer(const Function& func, const DataflowNode& n, NodeState& state, const vector<Lattice*>& dfInfo) { Dbg::dbg << "-----#############################--------\n"; Dbg::dbg << "Node: ["<<Dbg::escape(n.getNode()->unparseToString())<<" | "<< n.getNode()->class_name()<<"]\n"; // print out all the dataflow facts associated with analysis at this node const /*map <int, NodeFact*>*/vector<NodeFact*> facts = state.getFacts(analysis); int i=0; for(/*map <int, NodeFact*>*/vector<NodeFact*>::const_iterator it = facts.begin(); it!=facts.end(); it++, i++) { //Dbg::dbg << "Fact "<<it->first<<": \n "<<it->second->str(" ")<<endl; Dbg::dbg << "Fact "<<i<<": \n "<<(*it)->str(" ")<<endl; } const vector<Lattice*> dfInfoAbove = state.getLatticeAbove((Analysis*)analysis); const vector<Lattice*> dfInfoBelow = state.getLatticeBelow((Analysis*)analysis); vector<Lattice*>::const_iterator itA, itB; for(itA = dfInfoAbove.begin(), itB = dfInfoBelow.begin(); itA != dfInfoAbove.end() && itB != dfInfoBelow.end(); itA++, itB++) { Dbg::dbg << " Lattice Above "<<*itA<<": \n "<<(*itA)->str(" ")<<endl; Dbg::dbg << " Lattice Below "<<*itB<<": \n "<<(*itB)->str(" ")<<endl; } return dynamic_cast<BoolAndLattice*>(dfInfo[0])->set(true); }
void NodePainter:: drawFilledConnectionPoints(QPainter* painter, NodeGeometry const& geom, NodeState const& state) { painter->setPen(Qt::cyan); painter->setBrush(Qt::cyan); auto diameter = geom.connectionPointDiameter(); auto drawPoints = [&](PortType portType) { size_t n = state.getEntries(portType).size(); for (size_t i = 0; i < n; ++i) { QPointF p = geom.connectionPointScenePosition(i, portType); if (!state.connectionID(portType, i).isNull()) { painter->drawEllipse(p, diameter * 0.4, diameter * 0.4); } } }; drawPoints(PortType::OUT); drawPoints(PortType::IN); }
AnchorLine::AnchorLine(const NodeState &nodeState, Type type) : m_internalNodeState(nodeState.internalNodeState()), m_internalNode(nodeState.internalNode()), m_model(nodeState.model()), m_anchorType(type) { }
void unionDFAnalysisStatePartitions::visit(const Function& func, const DataflowNode& n, NodeState& state) { //printf("unionDFAnalysisStatePartitions::visit() function %s() node=<%s | %s>\n", func.get_name().str(), n.getNode()->class_name().c_str(), n.getNode()->unparseToString().c_str()); const vector<Lattice*>& masterLatBel = state.getLatticeBelow(master); //printf(" master=%p, masterLatBel.size()=%d\n", master, masterLatBel.size()); state.unionLattices(unionSet, master); }
MemLocObjectPtr PointsToAnalysis::Expr2MemLoc(SgNode* sgn, PartEdgePtr pedge) { scope reg(txt()<<"PointsToAnalysis::Expr2MemLoc(sgn=" << SgNode2Str(sgn) << ")", scope::medium, ptaDebugLevel, 1); if(ptaDebugLevel>=1) dbg << "pedge=" << pedge->str() << endl; // NOTE: source and target of edge are not wildcard if(pedge->source() && pedge->target()) { NodeState* state = NodeState::getNodeState(this, pedge->source()); if(ptaDebugLevel>=1) dbg << "state="<<state->str(this)<<endl; AbstractObjectMap* aom = dynamic_cast<AbstractObjectMap*>(state->getLatticeBelow(this, pedge, 0)); assert(aom); boost::shared_ptr<AbstractObjectSet> aos = getPointsToSet(sgn, pedge, aom); return boost::dynamic_pointer_cast<MemLocObject>(Expr2PointsToMLPtr(sgn, pedge, aos)); } // NOTE: merge information across all outgoing edges // target of this edge is wildcard else if(pedge->source()) { NodeState* state = NodeState::getNodeState(this, pedge->source()); //dbg << "state="<<state->str(this)<<endl; // Merge the lattices along all the outgoing edges map<PartEdgePtr, std::vector<Lattice*> >& e2lats = state->getLatticeBelowAllMod(this); assert(e2lats.size()>=1); boost::shared_ptr<AbstractObjectSet> mergedSet = boost::make_shared<AbstractObjectSet>(pedge, getComposer(), this, AbstractObjectSet::may); for(map<PartEdgePtr, std::vector<Lattice*> >::iterator lats=e2lats.begin(); lats!=e2lats.end(); lats++) { PartEdge* edgePtr = lats->first.get(); assert(edgePtr->source() == pedge.get()->source()); AbstractObjectMap* aom = dynamic_cast<AbstractObjectMap*>(state->getLatticeBelow(this, lats->first, 0)); assert(aom); if(ptaDebugLevel>=1) dbg << "aom="<<aom->str()<<endl; boost::shared_ptr<AbstractObjectSet> aos = getPointsToSet(sgn, pedge, aom); // NOTE: It can be empty if no entry was found in AbstractObjectMap // Safe approximation : merge only if it contains pointsTo information along this particular edge // if(aos.get()) mergedSet->meetUpdate(aos.get()); } return boost::dynamic_pointer_cast<MemLocObject>(Expr2PointsToMLPtr(sgn, pedge, mergedSet)); } // source of this edge is a wildcard else if(pedge->target()) { NodeState* state = NodeState::getNodeState(this, pedge->target()); if(ptaDebugLevel>=1) dbg << "state="<<state->str()<<endl; AbstractObjectMap* aom = dynamic_cast<AbstractObjectMap*>(state->getLatticeAbove(this, NULLPartEdge, 0)); assert(aom); boost::shared_ptr<AbstractObjectSet> aos = getPointsToSet(sgn, pedge, aom); return boost::dynamic_pointer_cast<MemLocObject>(Expr2PointsToMLPtr(sgn, pedge, aos)); } else { assert(false); return PointsToMLPtr(); } }
void NodePainter:: drawEntryLabels(QPainter * painter, NodeGeometry const & geom, NodeState const & state, NodeDataModel const * model) { QFontMetrics const & metrics = painter->fontMetrics(); for(PortType portType: {PortType::Out, PortType::In}) { auto const &nodeStyle = model->nodeStyle(); auto& entries = state.getEntries(portType); size_t n = entries.size(); for (size_t i = 0; i < n; ++i) { QPointF p = geom.portScenePosition(i, portType); if (entries[i].empty()) painter->setPen(nodeStyle.FontColorFaded); else painter->setPen(nodeStyle.FontColor); QString s; if (model->portCaptionVisible(portType, i)) { s = model->portCaption(portType, i); } else { s = model->dataType(portType, i).name; } auto rect = metrics.boundingRect(s); p.setY(p.y() + rect.height() / 4.0); switch (portType) { case PortType::In: p.setX(5.0); break; case PortType::Out: p.setX(geom.width() - 5.0 - rect.width()); break; default: break; } painter->drawText(p, s); } } }
void placeUniqueIDs::visit(const Function& func, const DataflowNode& n, NodeState& state) { //printf("placeUniqueIDs: node=<%s | %s>\n", n.getNode()->class_name().c_str(), n.getNode()->unparseToString().c_str()); NodeID* newID = new NodeID(curID); state.addFact(this, 0, newID); curID++; }
void NodePainter:: drawConnectionPoints(QPainter* painter, NodeGeometry const& geom, NodeState const& state) { painter->setBrush(QColor(Qt::darkGray)); auto diameter = geom.connectionPointDiameter(); auto reducedDiameter = diameter * 0.6; auto drawPoints = [&](PortType portType) { size_t n = state.getEntries(portType).size(); for (size_t i = 0; i < n; ++i) { QPointF p = geom.connectionPointScenePosition(i, portType); double r = 1.0; if (state.isReacting() && state.getEntries(portType)[i].isNull()) { auto diff = geom.draggingPos() - p; double dist = std::sqrt(QPointF::dotProduct(diff, diff)); double const thres = 40.0; r = (dist < thres) ? (2.0 - dist / thres ) : 1.0; } painter->drawEllipse(p, reducedDiameter * r, reducedDiameter * r); } }; drawPoints(PortType::OUT); drawPoints(PortType::IN); }
void InitDataflowState::visit(const Function& func, const DataflowNode& n, NodeState& state) { SgNode* sgn = n.getNode(); if(analysisDebugLevel>=2) Dbg::dbg << "InitDataflowState::visit() sgn="<<sgn<<"["<<sgn->class_name()<<" | "<<Dbg::escape(sgn->unparseToString())<<"], dfAnalysis="<<dfAnalysis<<endl; // generate a new initial state for this node vector<Lattice*> initLats; vector<NodeFact*> initFacts; dfAnalysis->genInitState(func, n, state, initLats, initFacts); /*if(analysisDebugLevel>=2){ int i=0; for(vector<Lattice*>::iterator l=initLats.begin(); l!=initLats.end(); l++, i++) Dbg::dbg << "Lattice "<<i<<": "<<(*l)->str(" ")<<endl; i=0; for(vector<NodeFact*>::iterator f=initFacts.begin(); f!=initFacts.end(); f++, i++) Dbg::dbg << "Lattice "<<i<<": "<<(*f)->str(" ")<<endl; }*/ //Dbg::dbg << "InitDataflowState::visit() calling state.setLattices()"<<endl; state.setLattices((Analysis*)dfAnalysis, initLats); state.setFacts((Analysis*)dfAnalysis, initFacts); if(analysisDebugLevel>=2){ Dbg::dbg << " state="<<state.str((Analysis*)dfAnalysis, " ")<<endl; } /*vector<Lattice*> initState = dfAnalysis->genInitState(func, n, state); Dbg::dbg << "InitDataflowState::visit() 1"<<endl; for(int i=0; i<initState.size(); i++) { Dbg::dbg << " i="<<i<<", initState[i]="<<initState[i]->str("")<<endl; state.addLattice((Analysis*)dfAnalysis, i, initState[i]); Dbg::dbg << " state->getLatticeAbove((Analysis*)dfAnalysis).size()="<<state.getLatticeAbove((Analysis*)dfAnalysis).size()<<endl, ); //Dbg::dbg << printf(" state->getLatticeBelow((Analysis*)dfAnalysis).size()="<<state.getLatticeBelow((Analysis*)dfAnalysis).size()<<endl; }*/ //const vector<Lattice*>& masterLatBel = state.getLatticeBelow((Analysis*)dfAnalysis); //printf(" creator=%p, state=%p, masterLatBel.size()=%d\n", (Analysis*)dfAnalysis, &state, masterLatBel.size()); }
void NodePainter:: drawFilledConnectionPoints(QPainter * painter, NodeGeometry const & geom, NodeState const & state, NodeDataModel const * model) { NodeStyle const& nodeStyle = model->nodeStyle(); auto const & connectionStyle = StyleCollection::connectionStyle(); auto diameter = nodeStyle.ConnectionPointDiameter; for(PortType portType: {PortType::Out, PortType::In}) { size_t n = state.getEntries(portType).size(); for (size_t i = 0; i < n; ++i) { QPointF p = geom.portScenePosition(i, portType); if (!state.getEntries(portType)[i].empty()) { auto const & dataType = model->dataType(portType, i); if (connectionStyle.useDataDefinedColors()) { QColor const c = connectionStyle.normalColor(dataType.id); painter->setPen(c); painter->setBrush(c); } else { painter->setPen(nodeStyle.FilledConnectionPointColor); painter->setBrush(nodeStyle.FilledConnectionPointColor); } painter->drawEllipse(p, diameter * 0.4, diameter * 0.4); } } } }
// This will be visited only once? Not sure, better check void analysisStatesToDOT::visit(const Function& func, const DataflowNode& n, NodeState& state) { std::string state_str = state.str( lda, " "); printNode(n, state_str); std::vector < DataflowEdge> outEdges = n.outEdges(); for (unsigned int i = 0; i < outEdges.size(); ++i) { printEdge(outEdges[i]); } }
void MergeAllReturnStates::visit(const Function& func, const DataflowNode& n, NodeState& state) { SgNode* sgn = n.getNode(); if(analysisDebugLevel>=1) Dbg::dbg << "MergeAllReturnStates::visit() func="<<func.get_name().getString()<<"() sgn="<<sgn<<"["<<Dbg::escape(sgn->unparseToString())<<" | "<<sgn->class_name()<<"]\n"; //Dbg::dbg << "visit {{{: modified="<<modified<<endl; // If this is an explicit return statement if(isSgReturnStmt(sgn)) { if(analysisDebugLevel>=1) Dbg::dbg << "MergeAllReturnStates::visit() isSgReturnStmt(sgn)->get_expression()="<<isSgReturnStmt(sgn)->get_expression()<<"["<<Dbg::escape(isSgReturnStmt(sgn)->get_expression()->unparseToString())<<" | "<<isSgReturnStmt(sgn)->get_expression()->class_name()<<"]\n"; ROSE_ASSERT(NodeState::getNodeStates(n).size()==1); NodeState* state = *(NodeState::getNodeStates(n).begin()); // Incorporate the entire dataflow state at the return statement if(analysisDebugLevel>=1) Dbg::dbg << " Merging dataflow state at return statement\n"; modified = mergeLats(mergedLatsRetStmt, state->getLatticeAbove(analysis)) || modified; // Incorporate just the portion of the dataflow state that corresponds to the value being returned, // assuming that any information is available vector<Lattice*> exprLats; for(vector<Lattice*>::const_iterator l=state->getLatticeAbove(analysis).begin(); l!=state->getLatticeAbove(analysis).end(); l++) exprLats.push_back((*l)->project(isSgReturnStmt(sgn)->get_expression())); if(analysisDebugLevel>=1) Dbg::dbg << " Merging dataflow state of return value\n"; modified = mergeLats(mergedLatsRetVal, exprLats) || modified; } // If this is the end of a function, which is an implicit return that has no return value else if(isSgFunctionDefinition(sgn)) { if(analysisDebugLevel>=1) Dbg::dbg << "MergeAllReturnStates::visit() isSgFunctionDefinition\n"; ROSE_ASSERT(NodeState::getNodeStates(n).size()==1); NodeState* state = *(NodeState::getNodeStates(n).begin()); // Incorporate the entire dataflow state at the implicit return statement modified = mergeLats(mergedLatsRetStmt, state->getLatticeAbove(analysis)) || modified; } //Dbg::dbg << "visit >>>: modified="<<modified<<endl; }
void TaintAnalysis::genInitState(const Function& func, const DataflowNode& node, const NodeState& state, std::vector<Lattice*>& initLattices, std::vector<NodeFact*>& initFacts) { if (debug) { *debug <<"TaintAnalysis::genInitState(func=" <<func.get_name() <<",\n" <<" node={" <<StringUtility::makeOneLine(node.toString()) <<"},\n" <<" state={" <<StringUtility::makeOneLine(state.str(this, "")) <<"},\n" <<" initLattice[" <<initLattices.size() <<"]={...},\n" <<" initFacts[" <<initFacts.size() <<"]={...})\n"; } map<varID, Lattice*> emptyM; FiniteVarsExprsProductLattice *prodLat = new FiniteVarsExprsProductLattice(new TaintLattice, emptyM, (Lattice*)NULL, ldv_analysis, node, state); assert(prodLat!=NULL); magic_tainted(node.getNode(), prodLat); // certain names are considered to be always tainted initLattices.push_back(prodLat); }
void NodePainter:: drawEntryLabels(QPainter* painter, NodeGeometry const& geom, NodeState const& state, std::unique_ptr<NodeDataModel> const & model) { QFontMetrics const & metrics = painter->fontMetrics(); auto drawPoints = [&](PortType portType) { auto& entries = state.getEntries(portType); size_t n = entries.size(); for (size_t i = 0; i < n; ++i) { QPointF p = geom.connectionPointScenePosition(i, portType); if (entries[i].isNull()) painter->setPen(Qt::darkGray); else painter->setPen(QColor(Qt::lightGray).lighter()); QString s = model->data(portType, i)->name(); auto rect = metrics.boundingRect(s); p.setY(p.y() + rect.height() / 4.0); if (portType == PortType::IN) p.setX(5.0); else p.setX(geom.width() - 5.0 - rect.width()); painter->drawText(p, s); } }; drawPoints(PortType::OUT); drawPoints(PortType::IN); }
void visit(const Function& func, const DataflowNode& n, NodeState& state) { printf("checkAllDataflow: node=<%s | %s>\n", n.getNode()->class_name().c_str(), n.getNode()->unparseToString().c_str()); /*stringWrapper* s0 = (stringWrapper*)state.getFact(creator, 0); stringWrapper* s1 = (stringWrapper*)state.getFact(creator, 1); printf(" fact=<%p | %p>\n", s0, s1); printf(" fact=<%s | %s>\n", s0->myStr.c_str(), s1->myStr.c_str());* / if(n.getNode()->class_name() != s0->myStr.c_str()) { printf("ERROR in checkAllDataflow: Expected class name \"%s\" but the saved class name is \"%s\"\n", n.getNode()->class_name().c_str(), s0->myStr.c_str()); numFails++; } if(n.getNode()->unparseToString() != s1->myStr.c_str()) { printf("ERROR in checkAllDataflow: Expected class name \"%s\" but the saved class name is \"%s\"\n", n.getNode()->unparseToString().c_str(), s0->myStr.c_str()); numFails++; }*/ printf(" lattice0 = %s\n", state.getLatticeBelow(creator, 0)->str().c_str()); printf(" lattice1 = %s\n", state.getLatticeBelow(creator, 1)->str().c_str()); }
bool TaskConnect::execute(Worker* worker) { Engine& engine = Engine::get_instance(); NodeConf* config = (NodeConf*) engine.get_component(COMP_SERVERCONF).get(); connection_ptr conn = engine.open_connection(host, port); if (conn == NULL) { DLOG(ERROR) << "Can not connect to manager server"; engine.stop(); return true; } config->man_connection = conn; /* send hello message to manager server */ uint64_t msg_id = engine.next_message_id(); HelloRequest request; request.set_id(config->server_id); message_ptr msg = Message::pb_encode(request, MessageType::HELLO_REQ, msg_id, 0); boost::scoped_ptr<ReplyContext> context(new ReplyContext(msg_id)); engine.save_context(context.get()); conn->send_message(msg); context->wait(); engine.release_context(context.get()); /* get reply from manager server */ if (context->done) { HelloReply reply; Message::pb_decode(reply, context->get_reply()); if (reply.code() == ErrorCode::OK) { for (int i = 0; i < reply.nodes_size(); i++) { HelloReply::Nodes n = reply.nodes(i); servernode_ptr node = boost::make_shared<ServerNode>(n.id(), n.name(), n.type(), n.host(), n.port()); config->nodes[n.id()] = node; config->ring->add_node(node); if (n.id() == config->server_id) config->me = node; if (n.online()) { //connect to server if (!server_connect(node, config->server_id)) { DLOG(ERROR) << "Can not connect to server:" << node->get_id(); return true; } } } if (config->me == NULL) { DLOG(ERROR) << "Server node list must contain this node"; return true; } engine.listen_connection(config->me->get_ip(), config->me->get_port()); server_connect(config->me, config->server_id); /* send node state to Manager server */ NodeState state; state.set_id(config->server_id); state.set_state(NodeState::READY); message_ptr msg = Message::pb_encode(state, MessageType::NODE_STATE, 0, 0); conn->send_message(msg); return true; } } DLOG(ERROR) << "Error in get node list from manager server"; return true; }
// Splits the given dataflow analysis partition into several partitions, one for each given checkpoint. // The partition origA will be assigned the last checkpoint in partitionChkpts. // If newSplit==true, this split operation creates a new split within origA's current split and place // the newly-generated partitions into this split. // If newSplit==false, the newly-generated partitions will be added to origA's current split. // If newPartActive==true, the newly-generated partitions will be made initially active. If not, // they will start out in joined status. // Returns the set of newly-created partitions. set<IntraPartitionDataflow*> PartitionedAnalysis::split(IntraPartitionDataflow* origA, vector<IntraPartitionDataflowCheckpoint*> partitionChkpts, const Function& func, NodeState* fState, bool newSplit, bool newPartActive) { /*printf("PartitionedAnalysis::split() origA=%p\n", origA); for(vector<IntraPartitionDataflowCheckpoint*>::iterator it = partitionChkpts.begin(); it!=partitionChkpts.end(); it++) { printf(" chkpt=%s\n", (*it)->str(" ").c_str()); }*/ ROSE_ASSERT(partitionChkpts.size()>0); if(analysisDebugLevel>=1) { printf("@ SPLIT @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); printf("PartitionedAnalysis::split() before: activeParts.size()=%d\n", activeParts.size()); } // Only partitions that are either active or joined may call split. Joined partitions may do so during the joining process, // which can result in the creation of new partitions. ROSE_ASSERT(activeParts.find(origA) != activeParts.end() || joinParts.find(origA) != joinParts.end()); if(analysisDebugLevel>=1) if(origA->partitionCond != NULL) cout << "origA->partitionCond = "<<origA->partitionCond->str()<<"\n"; partSplit* split=NULL; if(newSplit) split = new partSplit(origA); else split = *(parts2splits[origA].rbegin()); if(analysisDebugLevel>=1) cout << "split = "<<split->str()<<", partitionChkpts.size()="<<partitionChkpts.size()<<"\n"; fflush(stdout); set<IntraPartitionDataflow*> newParts; // Generate the new analysis partitions. The last checkpoint goes to the master // partition and we create fresh partitions for the other checkpoints for(vector<IntraPartitionDataflowCheckpoint*>::iterator it = partitionChkpts.begin(); it!=partitionChkpts.end(); ) { IntraPartitionDataflowCheckpoint* chkpt = *it; IntraPartitionDataflow* curPartA; if(analysisDebugLevel>=1) { cout << " chkpt->partitionCond="<<chkpt->partitionCond<<"\n"; fflush(stdout); } it++; if(it != partitionChkpts.end()) { curPartA = origA->copy(); split->addChild(curPartA); newParts.insert(curPartA); parts2chkpts[curPartA] = chkpt; // Create a splits list for this newly-created partition // The splits list only contains the split (which may be newly-created or a copy of parts2splits[origA]) // since it will cease to exist after the next successful join of split list<partSplit*> splitsList; splitsList.push_back(split); parts2splits[curPartA] = splitsList; // Set the current partition's logical condition (can't AND it because the variables involved in // the condition may have changed between the two split points) curPartA->partitionCond = chkpt->partitionCond; /*if(origA->partitionCond != NULL) curPartA->partitionCond->andUpd(*(origA->partitionCond));*/ if(analysisDebugLevel>=1) //{ printf(" Creating analysis partition %p (master = %p), condition = %s\n", curPartA, origA, curPartA->partitionCond->str("").c_str()); } { printf(" Creating analysis partition %p (master = %p)\n", curPartA, origA); } // create a copy of the original partition's dataflow state for the new partition partitionDFAnalysisState pdfas(origA, curPartA); pdfas.runAnalysis(func, fState); // add the newly-created partition to the list of active partitions if(newPartActive) activeParts.insert(curPartA); else joinParts.insert(curPartA); } else { //// AND this the first partition's new logical condition to the original partition's condition // set the first partition's logical condition (can't AND it because the variables involved in the condition // may have changed between the two split points) /*printf("origA->partitionCond=%p\n", origA->partitionCond); printf(" partitionChkpts[0]=%s\n", partitionChkpts[0]->str(" ").c_str());*/ //if(parts2chkpts[origA] != NULL) /*if(origA->partitionCond != NULL) { //parts2chkpts[origA]->partitionCond->andUpd(*(partitionChkpts[0]->partitionCond)); origA->partitionCond->andUpd(*(partitionChkpts[0]->partitionCond)); if(parts2chkpts[origA]) delete parts2chkpts[origA]; parts2chkpts[origA] = partitionChkpts[0]; // we already have a checkpoint object for the origA partition, so we can delete this new checkpoint // and its internals (i.e. the partitionCond object) //delete partitionChkpts[0]; } else {*/ origA->partitionCond = chkpt->partitionCond; // Delete the previous checkpoint, assuming that one exists AND we're not reusing the // old checkpoint as the new checkpoint if(parts2chkpts[origA] && parts2chkpts[origA]!=chkpt) delete parts2chkpts[origA]; parts2chkpts[origA] = chkpt; curPartA = origA; //} /*if(analysisDebugLevel>=1) { printf(" Master partition %p, condition = %s\n", origA, origA->partitionCond->str("").c_str()); }*/ } if(analysisDebugLevel>=1) { cout << "Updating current partition's dataflow state, parts2chkpts[curPartA]->joinNodes.size()="<<parts2chkpts[curPartA]->joinNodes.size()<<"\n"; cout << " curPartA->partitionCond="<<curPartA->partitionCond<<"\n"; fflush(stdout); } // ----------------------------------------------------------------------------------------------- // Update the current partition's current dataflow state (state at the nodes in its joinNodes set) // with its new partition condition // joinNodes /* cout << "parts2chkpts[curPartA]->joinNodes.size()=" << parts2chkpts[curPartA]->joinNodes.size() << "\n"; for(set<DataflowNode>::iterator itJN=parts2chkpts[curPartA]->joinNodes.begin(); itJN!=parts2chkpts[curPartA]->joinNodes.end(); itJN++) cout << " itJN = "<<(*itJN).getNode()->unparseToString()<<"\n";*/ for(set<DataflowNode>::iterator itJN=parts2chkpts[curPartA]->joinNodes.begin(); itJN!=parts2chkpts[curPartA]->joinNodes.end(); ) { DataflowNode n = *itJN; if(analysisDebugLevel>=1) { cout << " joinNode "<<n.getNode()->unparseToString()<<"\n"; fflush(stdout); } const vector<NodeState*> nodeStates = NodeState::getNodeStates(n); //for(vector<NodeState*>::const_iterator itS = nodeStates.begin(); itS!=nodeStates.end(); ) vector<NodeState*>::const_iterator itS = nodeStates.begin(); { NodeState* state = *itS; Analysis* a = curPartA; curPartA->initDFfromPartCond(func, n, *state, state->getLatticeBelow(a), state->getFacts(a), curPartA->partitionCond); } itJN++; } // Current Node if(parts2chkpts[curPartA]->curNode) { DataflowNode n = *(parts2chkpts[curPartA]->curNode); if(analysisDebugLevel>=1) cout << " curNode "<<n.getNode()->unparseToString()<<"\n"; const vector<NodeState*> nodeStates = NodeState::getNodeStates(n); //for(vector<NodeState*>::const_iterator itS = nodeStates.begin(); itS!=nodeStates.end(); ) vector<NodeState*>::const_iterator itS = nodeStates.begin(); { NodeState* state = *itS; Analysis* a = curPartA; /*ConstrGraph* cg = dynamic_cast<ConstrGraph*>(state->getLatticeBelow(a).front()); cout << "Pre-initDFfromPartCond CG="<<cg->str()<<"\n";*/ curPartA->initDFfromPartCond(func, n, *state, state->getLatticeBelow(a), state->getFacts(a), curPartA->partitionCond); } } } //printf(" partitionChkpts[0]=%s\n", partitionChkpts[0]->str(" ").c_str()); //printf(" parts2chkpts[origA]=%s\n", parts2chkpts[origA]->str(" ").c_str()); // add the new split to the original partition's list of splits if(newSplit) parts2splits[origA].push_back(split); /*for(set<IntraPartitionDataflow*>::iterator it=split->splitSet.begin(); it!=split->splitSet.end(); it++) printf(" partition %p, partitionCond=%p\n", *it, parts2chkpts[*it]->partitionCond);*/ if(analysisDebugLevel>=1) { printf("PartitionedAnalysis::split() after: activeParts.size()=%d\n", activeParts.size()); printf("@ SPLIT @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); } if(analysisDebugLevel>=1) cout << "newParts.size()=="<<newParts.size()<<"\n"; return newParts; }
// Returns the Unique ID recorded in the given NodeState int getNodeID(const NodeState& state) { ROSE_ASSERT(puids); NodeID* id = (NodeID*)state.getFact(puids, 0); return id->getID(); }
void evaluateAnalysisStates::visit(const Function& func, const DataflowNode& n, NodeState& state) { SgFunctionCallExp *fnCall = isSgFunctionCallExp(n.getNode()); if (!fnCall) return; if (!fnCall->getAssociatedFunctionSymbol()) return; string funcName = fnCall->getAssociatedFunctionSymbol()->get_name().getString(); if (funcName.find("testFunc") == string::npos) return; FiniteVarsExprsProductLattice *lat = dynamic_cast<FiniteVarsExprsProductLattice *>(state.getLatticeAbove(div)[0]); cout << indent << "Lattice before call to " << funcName << ": " << lat->str() << endl; set<varID> allVars = lat->getAllVars(); for (set<varID>::iterator i = allVars.begin(); i != allVars.end(); ++i) { string name = i->str(); cout << "Variable " << name << " "; if (expectations[funcName].find(name) == expectations[funcName].end()) { cout << "unspecified" << endl; continue; } Lattice *got = lat->getVarLattice(*i); ROSE_ASSERT(got); if (expectations[funcName][name] != got) { cout << "mismatched: " << got->str() << " was not the expected " << expectations[funcName][name].str(); numFails++; } else { cout << "matched"; numPass++; } cout << endl; } }
void NodePainter:: drawConnectionPoints(QPainter* painter, NodeGeometry const& geom, NodeState const& state, NodeDataModel const * model, FlowScene const & scene) { NodeStyle const& nodeStyle = model->nodeStyle(); auto const &connectionStyle = StyleCollection::connectionStyle(); float diameter = nodeStyle.ConnectionPointDiameter; auto reducedDiameter = diameter * 0.6; for(PortType portType: {PortType::Out, PortType::In}) { size_t n = state.getEntries(portType).size(); for (unsigned int i = 0; i < n; ++i) { QPointF p = geom.portScenePosition(i, portType); auto const & dataType = model->dataType(portType, i); bool canConnect = (state.getEntries(portType)[i].empty() || (portType == PortType::Out && model->portOutConnectionPolicy(i) == NodeDataModel::ConnectionPolicy::Many) ); double r = 1.0; if (state.isReacting() && canConnect && portType == state.reactingPortType()) { auto diff = geom.draggingPos() - p; double dist = std::sqrt(QPointF::dotProduct(diff, diff)); bool typeConvertable = false; { if (portType == PortType::In) { typeConvertable = scene.registry().getTypeConverter(state.reactingDataType(), dataType) != nullptr; } else { typeConvertable = scene.registry().getTypeConverter(dataType, state.reactingDataType()) != nullptr; } } if (state.reactingDataType().id == dataType.id || typeConvertable) { double const thres = 40.0; r = (dist < thres) ? (2.0 - dist / thres ) : 1.0; } else { double const thres = 80.0; r = (dist < thres) ? (dist / thres) : 1.0; } } if (connectionStyle.useDataDefinedColors()) { painter->setBrush(connectionStyle.normalColor(dataType.id)); } else { painter->setBrush(nodeStyle.ConnectionPointColor); } painter->drawEllipse(p, reducedDiameter * r, reducedDiameter * r); } }; }
bool TaintAnalysis::transfer(const Function& func, const DataflowNode& node_, NodeState& state, const std::vector<Lattice*>& dfInfo) { static size_t ncalls = 0; if (debug) { *debug <<"TaintAnalysis::transfer-" <<++ncalls <<"(func=" <<func.get_name() <<",\n" <<" node={" <<StringUtility::makeOneLine(node_.toString()) <<"},\n" <<" state={" <<state.str(this, " ") <<",\n" <<" dfInfo[" <<dfInfo.size() <<"]={...})\n"; } SgNode *node = node_.getNode(); assert(!dfInfo.empty()); FiniteVarsExprsProductLattice *prodLat = dynamic_cast<FiniteVarsExprsProductLattice*>(dfInfo.front()); bool modified = magic_tainted(node, prodLat); // some values are automatically tainted based on their name // Process AST nodes that transfer taintedness. Most of these operations have one or more inputs from which a result // is always calculated the same way. So we just gather up the inputs and do the calculation at the very end of this // function. The other operations are handled individually within their "if" bodies. TaintLattice *result = NULL; // result pointer into the taint lattice std::vector<TaintLattice*> inputs; // input pointers into the taint lattice if (isSgAssignInitializer(node)) { // as in "int a = b" SgAssignInitializer *xop = isSgAssignInitializer(node); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop->get_operand()))); inputs.push_back(in1); } else if (isSgAggregateInitializer(node)) { // as in "int a[1] = {b}" SgAggregateInitializer *xop = isSgAggregateInitializer(node); const SgExpressionPtrList &exprs = xop->get_initializers()->get_expressions(); for (size_t i=0; i<exprs.size(); ++i) { varID in_id = SgExpr2Var(exprs[i]); TaintLattice *in = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in_id)); inputs.push_back(in); } } else if (isSgInitializedName(node)) { SgInitializedName *xop = isSgInitializedName(node); if (xop->get_initializer()) { varID in1_id = SgExpr2Var(xop->get_initializer()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } } else if (isSgValueExp(node)) { // numeric and character constants SgValueExp *xop = isSgValueExp(node); result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop))); if (result) modified = result->set_vertex(TaintLattice::VERTEX_UNTAINTED); } else if (isSgAddressOfOp(node)) { // as in "&x". The result taintedness has nothing to do with the value in x. /*void*/ } else if (isSgBinaryOp(node)) { // as in "a + b" SgBinaryOp *xop = isSgBinaryOp(node); varID in1_id = SgExpr2Var(isSgExpression(xop->get_lhs_operand())); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); varID in2_id = SgExpr2Var(isSgExpression(xop->get_rhs_operand())); TaintLattice *in2 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in2_id)); inputs.push_back(in2); if (isSgAssignOp(node)) { // copy the rhs lattice to the lhs lattice (as well as the entire '=' expression result) assert(in1 && in2); modified = in1->meetUpdate(in2); } } else if (isSgUnaryOp(node)) { // as in "-a" SgUnaryOp *xop = isSgUnaryOp(node); varID in1_id = SgExpr2Var(xop->get_operand()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } else if (isSgReturnStmt(node)) { // as in "return a". The result will always be dead, so we're just doing this to get some debugging output. Most // of our test inputs are functions, and the test examines the function's returned taintedness. SgReturnStmt *xop = isSgReturnStmt(node); varID in1_id = SgExpr2Var(xop->get_expression()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } // Update the result lattice (unless dead) with the inputs (unless dead) by using the meedUpdate() method. All this // means is that the new result will be the maximum of the old result and all inputs, where "maximum" is defined such // that "tainted" is greater than "untainted" (and both of them are greater than bottom/unknown). for (size_t i=0; i<inputs.size(); ++i) if (debug) *debug <<"TaintAnalysis::transfer: input " <<(i+1) <<" is " <<lattice_info(inputs[i]) <<"\n"; if (!result && varID::isValidVarExp(node)) { varID result_id(node); // NOTE: constructor doesn't handle all SgExpression nodes, thus the next "if" result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id)); } if (!result && isSgExpression(node)) { varID result_id = SgExpr2Var(isSgExpression(node)); result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id)); } if (result) { for (size_t i=0; i<inputs.size(); ++i) { if (inputs[i]) modified = result->meetUpdate(inputs[i]) || modified; } } if (debug) *debug <<"TaintAnalysis::transfer: result is " <<lattice_info(result) <<(modified?" (modified)":" (not modified)") <<"\n"; return modified; }