// // Method: getUnsafeAllocsFromABC() // // Description: // Find all memory objects that are both allocated on the stack and are not // proven to be indexed in a type-safe manner according to the static array // bounds checking pass. // // Notes: // This method saves its results be remembering the set of DSNodes which are // both on the stack and potentially indexed in a type-unsafe manner. // // FIXME: // This method only considers unsafe GEP instructions; it does not consider // unsafe call instructions or other instructions deemed unsafe by the array // bounds checking pass. // void ConvertUnsafeAllocas::getUnsafeAllocsFromABC(Module & M) { UnsafeAllocaNodeListBuilder Builder(budsPass, unsafeAllocaNodes); Builder.visit(M); #if 0 // Haohui: Disable it right now since nobody using the code std::map<BasicBlock *,std::set<Instruction*>*> UnsafeGEPMap= abcPass->UnsafeGetElemPtrs; std::map<BasicBlock *,std::set<Instruction*>*>::const_iterator bCurrent = UnsafeGEPMap.begin(), bEnd = UnsafeGEPMap.end(); for (; bCurrent != bEnd; ++bCurrent) { std::set<Instruction *> * UnsafeGetElemPtrs = bCurrent->second; std::set<Instruction *>::const_iterator iCurrent = UnsafeGetElemPtrs->begin(), iEnd = UnsafeGetElemPtrs->end(); for (; iCurrent != iEnd; ++iCurrent) { if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(*iCurrent)) { Value *pointerOperand = GEP->getPointerOperand(); DSGraph * TDG = budsPass->getDSGraph(*(GEP->getParent()->getParent())); DSNode *DSN = TDG->getNodeForValue(pointerOperand).getNode(); //FIXME DO we really need this ? markReachableAllocas(DSN); if (DSN && DSN->isAllocaNode() && !DSN->isNodeCompletelyFolded()) { unsafeAllocaNodes.push_back(DSN); } } else { //call instruction add the corresponding *iCurrent->dump(); //FIXME abort(); } } } #endif }
void visitGetElementPtrInst(GetElementPtrInst &GEP) { Value *pointerOperand = GEP.getPointerOperand(); DSGraph * TDG = budsPass->getDSGraph(*(GEP.getParent()->getParent())); DSNode *DSN = TDG->getNodeForValue(pointerOperand).getNode(); //FIXME DO we really need this ? markReachableAllocas(DSN); if (DSN && DSN->isAllocaNode() && !DSN->isNodeCompletelyFolded()) { unsafeAllocaNodes.push_back(DSN); } }
void AllButUnreachableFromMemoryHeuristic::AssignToPools ( const DSNodeList_t &NodesToPA, Function *F, DSGraph* G, std::vector<OnePool> &ResultPools) { // Build a set of all nodes that are reachable from another node in the // graph. Here we ignore scalar nodes that are only globals as they are // often global pointers to big arrays. std::set<const DSNode*> ReachableFromMemory; for (DSGraph::node_iterator I = G->node_begin(), E = G->node_end(); I != E; ++I) { DSNode *N = I; #if 0 // // Ignore nodes that are just globals and not arrays. // if (N->isArray() || N->isHeapNode() || N->isAllocaNode() || N->isUnknownNode()) #endif // If a node is marked, all children are too. if (!ReachableFromMemory.count(N)) { for (DSNode::iterator NI = N->begin(), E = N->end(); NI != E; ++NI) { // // Sometimes this results in a NULL DSNode. Skip it if that is the // case. // if (!(*NI)) continue; // // Do a depth-first iteration over the DSGraph starting with this // child node. // for (df_ext_iterator<const DSNode*> DI = df_ext_begin(*NI, ReachableFromMemory), E = df_ext_end(*NI, ReachableFromMemory); DI != E; ++DI) /*empty*/; } } } // Only pool allocate a node if it is reachable from a memory object (itself // included). for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) if (ReachableFromMemory.count(NodesToPA[i])) ResultPools.push_back(OnePool(NodesToPA[i])); }