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