static ChildIteratorType child_end(const NodeType *N) { return succ_end(N); }
static BlkSucc_iterator BlkSucc_end(BlkT *BB) { return succ_end(BB); }
bool EscapeAnalysis::runOnFunction(Function& F) { return false; // This analysis is currently broken and not maintained if (VERBOSITY("opt") >= 1) outs() << "Running escape analysis on " << F.getName() << '\n'; for (inst_iterator inst_it = inst_begin(F), _inst_end = inst_end(F); inst_it != _inst_end; ++inst_it) { CallInst* alloc = dyn_cast<CallInst>(&*inst_it); if (!alloc || !isAllocCall(alloc)) continue; ChainInfo* chain = new ChainInfo(alloc); chains.push_back(chain); if (VERBOSITY("opt") >= 2) { errs() << "Found chain " << chain << " starting at " << *alloc; } // Calculating derived pointers, and finding escape points { // Instructions in the queue to be visited: std::deque<Instruction*> queue; // Instructions we've fully visited: std::unordered_set<Instruction*> checked; queue.push_back(alloc); while (queue.size()) { Instruction* next = queue.back(); queue.pop_back(); if (checked.count(next)) continue; checked.insert(next); for (User* user : next->users()) { if (GetElementPtrInst* gep = dyn_cast<GetElementPtrInst>(user)) { queue.push_back(gep); chain->derived.insert(gep); chain_by_pointer[gep] = chain; continue; } if (CastInst* bc = dyn_cast<CastInst>(user)) { queue.push_back(bc); chain->derived.insert(bc); chain_by_pointer[bc] = chain; continue; } if (PHINode* phi = dyn_cast<PHINode>(user)) { queue.push_back(phi); chain->derived.insert(phi); chain_by_pointer[phi] = chain; continue; } if (isa<LoadInst>(user)) { continue; } if (ReturnInst* ret = dyn_cast<ReturnInst>(user)) { if (VERBOSITY() >= 2) errs() << "Not dead; used here: " << *ret << '\n'; chain->escape_points.insert(ret); continue; } if (StoreInst* si = dyn_cast<StoreInst>(user)) { if (si->getPointerOperand() == next) { } else { assert(si->getValueOperand() == next); if (VERBOSITY() >= 2) errs() << "Escapes here: " << *si << '\n'; chain->escape_points.insert(si); } continue; } if (llvm::isa<CallInst>(user) || llvm::isa<InvokeInst>(user)) { if (VERBOSITY() >= 2) errs() << "Escapes here: " << *user << '\n'; chain->escape_points.insert(dyn_cast<Instruction>(user)); continue; } user->dump(); RELEASE_ASSERT(0, ""); } } } // Calculating BB-level escape-ness { std::deque<const BasicBlock*> queue; for (const auto I : chain->escape_points) { chain->bb_escapes[I->getParent()] = BBPartialEscape; queue.insert(queue.end(), succ_begin(I->getParent()), succ_end(I->getParent())); } while (queue.size()) { const BasicBlock* bb = queue.back(); queue.pop_back(); if (chain->bb_escapes[bb] == BBFullEscape) continue; chain->bb_escapes[bb] = BBFullEscape; queue.insert(queue.end(), succ_begin(bb), succ_end(bb)); } for (BasicBlock& bb : F) { if (chain->bb_escapes.count(&bb) == 0) chain->bb_escapes[&bb] = BBNoEscape; // outs() << bb.getName() << ' ' << chain->bb_escapes[&bb] << '\n'; } } } return false; }
void VeryBusyAnalysisPass::dataFlowAnalysis() { this->createUniverse(); ///initialize all blocks sets for(Function::iterator BBI = this->currentFunction->begin(), BBE = this->currentFunction->end(); BBI != BBE; BBI++) { ///in of the block is universe BasicBlock* BB = &*BBI; this->BB_VB_IN->insert(PairBBAndRCS(BB, universe)); } int i = 0; bool isChanged = true; while(isChanged) { isChanged = false; ///go throught all of the blocks // errs() << "******************* ROUND " << i << "*************************\n"; for (Function::iterator BBI = this->currentFunction->begin(), BBE = this->currentFunction->end(); BBI != BBE; BBI++) { BasicBlock* BB = &*BBI; // errs() << "Basic Block: " << BB->getName() << "\n"; ListRCS succsRCS; ///get a list of range check sets for(succ_iterator SBBI = succ_begin(BB), SBBE = succ_end(BB); SBBI != SBBE; SBBI++){ succsRCS.push_back((*BB_VB_IN)[*SBBI]); } ///calculate the OUT of the block, by intersecting all successors IN's RangeCheckSet *C_OUT = SetsMeet(&succsRCS, SetIntersection); // errs() << "OUT = "; C_OUT->println(); ///calculate the IN of the block, running the functions we already created RangeCheckSet *C_IN = this->getVBIn(BB, C_OUT); // errs() << "IN = "; C_IN->println(); RangeCheckSet *C_IN_P = BB_VB_IN->find(BB)->second; // errs() << "IN_PREV = "; C_IN_P->println(); BB_VB_IN->erase(BB); // compare C_IN with our previous C_IN if(!C_IN_P->equal(C_IN)) { isChanged = true; // errs() << "changed\n"; } else { // errs() << "unchanged\n"; } BB_VB_IN->insert(PairBBAndRCS(BB, C_IN)); // errs() << "\n"; } // errs() << "***************************************************\n"; i++; } }
void ProfileVerifierPassT<FType, BType>::recurseBasicBlock(const BType *BB) { // Break the recursion by remembering all visited blocks. if (BBisVisited.find(BB) != BBisVisited.end()) return; // Use a data structure to store all the information, this can then be handed // to debug printers. DetailedBlockInfo DI; DI.BB = BB; DI.outCount = DI.inCount = 0; DI.inWeight = DI.outWeight = 0; // Read predecessors. std::set<const BType*> ProcessedPreds; const_pred_iterator bpi = pred_begin(BB), bpe = pred_end(BB); // If there are none, check for (0,BB) edge. if (bpi == bpe) { DI.inWeight += ReadOrAssert(PI->getEdge(0,BB)); DI.inCount++; } for (;bpi != bpe; ++bpi) { if (ProcessedPreds.insert(*bpi).second) { DI.inWeight += ReadOrAssert(PI->getEdge(*bpi,BB)); DI.inCount++; } } // Read successors. std::set<const BType*> ProcessedSuccs; succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB); // If there is an (0,BB) edge, consider it too. (This is done not only when // there are no successors, but every time; not every function contains // return blocks with no successors (think loop latch as return block)). double w = PI->getEdgeWeight(PI->getEdge(BB,0)); if (w != ProfileInfoT<FType, BType>::MissingValue) { DI.outWeight += w; DI.outCount++; } for (;bbi != bbe; ++bbi) { if (ProcessedSuccs.insert(*bbi).second) { DI.outWeight += ReadOrAssert(PI->getEdge(BB,*bbi)); DI.outCount++; } } // Read block weight. DI.BBWeight = PI->getExecutionCount(BB); CheckValue(DI.BBWeight == ProfileInfoT<FType, BType>::MissingValue, "BasicBlock has missing value", &DI); CheckValue(DI.BBWeight < 0, "BasicBlock has negative value", &DI); // Check if this block is a setjmp target. bool isSetJmpTarget = false; if (DI.outWeight > DI.inWeight) { for (typename BType::const_iterator i = BB->begin(), ie = BB->end(); i != ie; ++i) { if (const CallInst *CI = dyn_cast<CallInst>(&*i)) { FType *F = CI->getCalledFunction(); if (F && (F->getName() == "_setjmp")) { isSetJmpTarget = true; break; } } } } // Check if this block is eventually reaching exit. bool isExitReachable = false; if (DI.inWeight > DI.outWeight) { for (typename BType::const_iterator i = BB->begin(), ie = BB->end(); i != ie; ++i) { if (const CallInst *CI = dyn_cast<CallInst>(&*i)) { FType *F = CI->getCalledFunction(); if (F) { FisVisited.clear(); isExitReachable |= exitReachable(F); } else { // This is a call to a pointer, all bets are off... isExitReachable = true; } if (isExitReachable) break; } } } if (DI.inCount > 0 && DI.outCount == 0) { // If this is a block with no successors. if (!isSetJmpTarget) { CheckValue(!Equals(DI.inWeight,DI.BBWeight), "inWeight and BBWeight do not match", &DI); } } else if (DI.inCount == 0 && DI.outCount > 0) { // If this is a block with no predecessors. if (!isExitReachable) CheckValue(!Equals(DI.BBWeight,DI.outWeight), "BBWeight and outWeight do not match", &DI); } else { // If this block has successors and predecessors. if (DI.inWeight > DI.outWeight && !isExitReachable) CheckValue(!Equals(DI.inWeight,DI.outWeight), "inWeight and outWeight do not match", &DI); if (DI.inWeight < DI.outWeight && !isSetJmpTarget) CheckValue(!Equals(DI.inWeight,DI.outWeight), "inWeight and outWeight do not match", &DI); } // Mark this block as visited, rescurse into successors. BBisVisited.insert(BB); for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB); bbi != bbe; ++bbi ) { recurseBasicBlock(*bbi); } }