void initialize(const Module *M, const DataStructures *DS) { parseValue(M); assert(V && "Failed to parse value?"); if (isa<GlobalValue>(V)) { DSGraph *G = DS->getGlobalsGraph(); assert(G->hasNodeForValue(V) && "Node not in specified graph!"); NH = G->getNodeForValue(V); } else { assert(F && "No function?"); DSGraph *G = DS->getDSGraph(*F); assert(G->hasNodeForValue(V) && "Node not in specified graph!"); NH = G->getNodeForValue(V); } // Handle offsets, if any // For each offset in the offsets vector, follow the link at that offset for (OffsetVectorTy::const_iterator I = offsets.begin(), E = offsets.end(); I != E; ++I ) { assert(!NH.isNull() && "Null NodeHandle?"); assert(NH.hasLink(*I) && "Handle doesn't have link?"); // Follow the offset NH = NH.getLink(*I); } }
void BUDataStructures::CloneAuxIntoGlobal(DSGraph* G) { DSGraph* GG = G->getGlobalsGraph(); ReachabilityCloner RC(GG, G, 0); for(DSGraph::afc_iterator ii = G->afc_begin(), ee = G->afc_end(); ii != ee; ++ii) { //cerr << "Pushing " << ii->getCallSite().getInstruction()->getOperand(0) << "\n"; //If we can, merge with an existing call site for this instruction if (GG->hasNodeForValue(ii->getCallSite().getInstruction()->getOperand(0))) { DSGraph::afc_iterator GGii; for(GGii = GG->afc_begin(); GGii != GG->afc_end(); ++GGii) if (GGii->getCallSite().getInstruction()->getOperand(0) == ii->getCallSite().getInstruction()->getOperand(0)) break; if (GGii != GG->afc_end()) RC.cloneCallSite(*ii).mergeWith(*GGii); else GG->addAuxFunctionCall(RC.cloneCallSite(*ii)); } else { GG->addAuxFunctionCall(RC.cloneCallSite(*ii)); } } }
// // Method: CloneAuxIntoGlobal() // // Description: // This method takes the specified graph and processes each unresolved call // site (a call site for which all targets are not yet known). For each // unresolved call site, it adds it to the globals graph and merges // information about the call site if the globals graph already had the call // site in its own list of unresolved call sites. // void BUDataStructures::CloneAuxIntoGlobal(DSGraph* G) { // // If this DSGraph has no unresolved call sites, do nothing. We do enough // work that wastes time even when the list is empty that this extra check // is probably worth it. // if (G->afc_begin() == G->afc_end()) return; DSGraph* GG = G->getGlobalsGraph(); ReachabilityCloner RC(GG, G, 0); // // Determine which called values are both within the local graph DSCallsites // and the global graph DSCallsites. Note that we require that the global // graph have a DSNode for the called value. // std::map<Value *, DSCallSite *> CommonCallValues; for (DSGraph::afc_iterator ii = G->afc_begin(), ee = G->afc_end(); ii != ee; ++ii) { // // If the globals graph has a DSNode for the LLVM value used in the local // unresolved call site, then it might have a DSCallSite for it, too. // Record this call site as a potential call site that will need to be // merged. // // Otherwise, just add the call site to the globals graph. // Value * V = ii->getCallSite().getCalledValue(); if (GG->hasNodeForValue(V)) { DSCallSite & DS = *ii; CommonCallValues[V] = &DS; } else { GG->addAuxFunctionCall(RC.cloneCallSite(*ii)); } } // // Scan through all the unresolved call sites in the globals graph and see if // the local graph has a call using the same LLVM value. If so, merge the // call sites. // DSGraph::afc_iterator GGii = GG->afc_begin(); for (; GGii != GG->afc_end(); ++GGii) { // // Determine if this unresolved call site is also in the local graph. // If so, then merge it. // Value * CalledValue = GGii->getCallSite().getCalledValue(); std::map<Value *, DSCallSite *>::iterator v; v = CommonCallValues.find (CalledValue); if (v != CommonCallValues.end()) { // // Merge the unresolved call site into the globals graph. // RC.cloneCallSite(*(v->second)).mergeWith(*GGii); // // Mark that this call site was merged by removing the called LLVM value // from the set of values common to both the local and global DSGraphs. // CommonCallValues.erase (v); } } // // We've now merged all DSCallSites that were known both to the local graph // and the globals graph. Now, there are still some local call sites that // need to be *added* to the globals graph; they are in DSCallSites remaining // in CommonCallValues. // std::map<Value *, DSCallSite *>::iterator v = CommonCallValues.begin (); for (; v != CommonCallValues.end(); ++v) { GG->addAuxFunctionCall(RC.cloneCallSite(*(v->second))); } return; }
void StdLibDataStructures::processFunction(int x, Function *F) { for (Value::use_iterator ii = F->use_begin(), ee = F->use_end(); ii != ee; ++ii) if (CallInst* CI = dyn_cast<CallInst>(*ii)){ if (CI->getCalledValue() == F) { DSGraph* Graph = getDSGraph(*CI->getParent()->getParent()); // // Set the read, write, and heap markers on the return value // as appropriate. // if(isa<PointerType>((CI)->getType())){ if(Graph->hasNodeForValue(CI)){ if (recFuncs[x].action.read[0]) Graph->getNodeForValue(CI).getNode()->setReadMarker(); if (recFuncs[x].action.write[0]) Graph->getNodeForValue(CI).getNode()->setModifiedMarker(); if (recFuncs[x].action.heap[0]) Graph->getNodeForValue(CI).getNode()->setHeapMarker(); } } // // Set the read, write, and heap markers on the actual arguments // as appropriate. // for (unsigned y = 0; y < CI->getNumArgOperands(); ++y) if (isa<PointerType>(CI->getArgOperand(y)->getType())){ if (Graph->hasNodeForValue(CI->getArgOperand(y))){ if (recFuncs[x].action.read[y + 1]) Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setReadMarker(); if (recFuncs[x].action.write[y + 1]) Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setModifiedMarker(); if (recFuncs[x].action.heap[y + 1]) Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setHeapMarker(); } } // // Merge the DSNoes for return values and parameters as // appropriate. // std::vector<DSNodeHandle> toMerge; if (recFuncs[x].action.mergeNodes[0]) if (isa<PointerType>(CI->getType())) if (Graph->hasNodeForValue(CI)) toMerge.push_back(Graph->getNodeForValue(CI)); for (unsigned y = 0; y < CI->getNumArgOperands(); ++y) if (recFuncs[x].action.mergeNodes[y + 1]) if (isa<PointerType>(CI->getArgOperand(y)->getType())) if (Graph->hasNodeForValue(CI->getArgOperand(y))) toMerge.push_back(Graph->getNodeForValue(CI->getArgOperand(y))); for (unsigned y = 1; y < toMerge.size(); ++y) toMerge[0].mergeWith(toMerge[y]); // // Collapse (fold) the DSNode of the return value and the actual // arguments if directed to do so. // if (!noStdLibFold && recFuncs[x].action.collapse) { if (isa<PointerType>(CI->getType())){ if (Graph->hasNodeForValue(CI)) Graph->getNodeForValue(CI).getNode()->foldNodeCompletely(); NumNodesFoldedInStdLib++; } for (unsigned y = 0; y < CI->getNumArgOperands(); ++y){ if (isa<PointerType>(CI->getArgOperand(y)->getType())){ if (Graph->hasNodeForValue(CI->getArgOperand(y))){ Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->foldNodeCompletely(); NumNodesFoldedInStdLib++; } } } } } } else if (InvokeInst* CI = dyn_cast<InvokeInst>(*ii)){ if (CI->getCalledValue() == F) { DSGraph* Graph = getDSGraph(*CI->getParent()->getParent()); // // Set the read, write, and heap markers on the return value // as appropriate. // if(isa<PointerType>((CI)->getType())){ if(Graph->hasNodeForValue(CI)){ if (recFuncs[x].action.read[0]) Graph->getNodeForValue(CI).getNode()->setReadMarker(); if (recFuncs[x].action.write[0]) Graph->getNodeForValue(CI).getNode()->setModifiedMarker(); if (recFuncs[x].action.heap[0]) Graph->getNodeForValue(CI).getNode()->setHeapMarker(); } } // // Set the read, write, and heap markers on the actual arguments // as appropriate. // for (unsigned y = 0; y < CI->getNumArgOperands(); ++y) if (isa<PointerType>(CI->getArgOperand(y)->getType())){ if (Graph->hasNodeForValue(CI->getArgOperand(y))){ if (recFuncs[x].action.read[y + 1]) Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setReadMarker(); if (recFuncs[x].action.write[y + 1]) Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setModifiedMarker(); if (recFuncs[x].action.heap[y + 1]) Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setHeapMarker(); } } // // Merge the DSNoes for return values and parameters as // appropriate. // std::vector<DSNodeHandle> toMerge; if (recFuncs[x].action.mergeNodes[0]) if (isa<PointerType>(CI->getType())) if (Graph->hasNodeForValue(CI)) toMerge.push_back(Graph->getNodeForValue(CI)); for (unsigned y = 0; y < CI->getNumArgOperands(); ++y) if (recFuncs[x].action.mergeNodes[y + 1]) if (isa<PointerType>(CI->getArgOperand(y)->getType())) if (Graph->hasNodeForValue(CI->getArgOperand(y))) toMerge.push_back(Graph->getNodeForValue(CI->getArgOperand(y))); for (unsigned y = 1; y < toMerge.size(); ++y) toMerge[0].mergeWith(toMerge[y]); // // Collapse (fold) the DSNode of the return value and the actual // arguments if directed to do so. // if (!noStdLibFold && recFuncs[x].action.collapse) { if (isa<PointerType>(CI->getType())){ if (Graph->hasNodeForValue(CI)) Graph->getNodeForValue(CI).getNode()->foldNodeCompletely(); NumNodesFoldedInStdLib++; } for (unsigned y = 0; y < CI->getNumArgOperands(); ++y){ if (isa<PointerType>(CI->getArgOperand(y)->getType())){ if (Graph->hasNodeForValue(CI->getArgOperand(y))){ Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->foldNodeCompletely(); NumNodesFoldedInStdLib++; } } } } } } else if(ConstantExpr *CE = dyn_cast<ConstantExpr>(*ii)) { if(CE->isCast()) for (Value::use_iterator ci = CE->use_begin(), ce = CE->use_end(); ci != ce; ++ci) { if (CallInst* CI = dyn_cast<CallInst>(*ci)){ if (CI->getCalledValue() == CE) { DSGraph* Graph = getDSGraph(*CI->getParent()->getParent()); // // Set the read, write, and heap markers on the return value // as appropriate. // if(isa<PointerType>((CI)->getType())){ if(Graph->hasNodeForValue(CI)){ if (recFuncs[x].action.read[0]) Graph->getNodeForValue(CI).getNode()->setReadMarker(); if (recFuncs[x].action.write[0]) Graph->getNodeForValue(CI).getNode()->setModifiedMarker(); if (recFuncs[x].action.heap[0]) Graph->getNodeForValue(CI).getNode()->setHeapMarker(); } } // // Set the read, write, and heap markers on the actual arguments // as appropriate. // for (unsigned y = 0; y < CI->getNumArgOperands(); ++y) if (recFuncs[x].action.read[y + 1]){ if (isa<PointerType>(CI->getArgOperand(y)->getType())){ if (Graph->hasNodeForValue(CI->getArgOperand(y))) Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setReadMarker(); if (Graph->hasNodeForValue(CI->getArgOperand(y))) Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setModifiedMarker(); if (Graph->hasNodeForValue(CI->getArgOperand(y))) Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setHeapMarker(); } } // // Merge the DSNoes for return values and parameters as // appropriate. // std::vector<DSNodeHandle> toMerge; if (recFuncs[x].action.mergeNodes[0]) if (isa<PointerType>(CI->getType())) if (Graph->hasNodeForValue(CI)) toMerge.push_back(Graph->getNodeForValue(CI)); for (unsigned y = 0; y < CI->getNumArgOperands(); ++y) if (recFuncs[x].action.mergeNodes[y + 1]) if (isa<PointerType>(CI->getArgOperand(y)->getType())) if (Graph->hasNodeForValue(CI->getArgOperand(y))) toMerge.push_back(Graph->getNodeForValue(CI->getArgOperand(y))); for (unsigned y = 1; y < toMerge.size(); ++y) toMerge[0].mergeWith(toMerge[y]); // // Collapse (fold) the DSNode of the return value and the actual // arguments if directed to do so. // if (!noStdLibFold && recFuncs[x].action.collapse) { if (isa<PointerType>(CI->getType())){ if (Graph->hasNodeForValue(CI)) Graph->getNodeForValue(CI).getNode()->foldNodeCompletely(); NumNodesFoldedInStdLib++; } for (unsigned y = 0; y < CI->getNumArgOperands(); ++y) if (isa<PointerType>(CI->getArgOperand(y)->getType())){ if (Graph->hasNodeForValue(CI->getArgOperand(y))){ DSNode * Node=Graph->getNodeForValue(CI->getArgOperand(y)).getNode(); Node->foldNodeCompletely(); NumNodesFoldedInStdLib++; } } } } } } } // // Pretend that this call site does not call this function anymore. // eraseCallsTo(F); }