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