Esempio n. 1
0
 static BlkSucc_iterator BlkSucc_begin(BlkT *BB) { return succ_begin(BB); }
 static ChildIteratorType child_begin(const NodeType *N) {
   return succ_begin(N);
 }
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 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);
    }
  }