当前位置: 首页>>代码示例>>C++>>正文


C++ TerminatorInst::getSuccessor方法代码示例

本文整理汇总了C++中TerminatorInst::getSuccessor方法的典型用法代码示例。如果您正苦于以下问题:C++ TerminatorInst::getSuccessor方法的具体用法?C++ TerminatorInst::getSuccessor怎么用?C++ TerminatorInst::getSuccessor使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在TerminatorInst的用法示例。


在下文中一共展示了TerminatorInst::getSuccessor方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: MatchOpcodeHeuristic

/// MatchOpcodeHeuristic - Predict that a comparison of an integer for less
/// than zero, less than or equal to zero, or equal to a constant, will
/// fail.
/// @returns a Prediction that is a pair in which the first element is the
/// successor taken, and the second the successor not taken.
Prediction BranchHeuristicsInfo::MatchOpcodeHeuristic(BasicBlock *root) const {
  // Last instruction of basic block.
  TerminatorInst *TI = root->getTerminator();

  // Basic block successors, the true and false branches.
  BasicBlock *trueSuccessor = TI->getSuccessor(0);
  BasicBlock *falseSuccessor = TI->getSuccessor(1);

  // Is the last instruction a Branch Instruction?
  BranchInst *BI = dyn_cast<BranchInst>(TI);
  if (!BI || !BI->isConditional())
    return empty;

  // Conditional instruction.
  Value *cond = BI->getCondition();

  // Heuristics can only apply to integer comparisons.
  ICmpInst *II = dyn_cast<ICmpInst>(cond);
  if (!II)
    return empty;

  // An integer comparison has always to operands.
  Value *operand1 = II->getOperand(0);
  ConstantInt *op1const = dyn_cast<ConstantInt>(operand1);

  Value *operand2 = II->getOperand(1);
  ConstantInt *op2const = dyn_cast<ConstantInt>(operand2);

  // The type of comparison used.
  enum ICmpInst::Predicate pred = II->getUnsignedPredicate();

  // The return successors (the first taken and the second not taken).
  Edge falseEdge = std::make_pair(falseSuccessor, trueSuccessor);
  Edge trueEdge  = std::make_pair(trueSuccessor, falseSuccessor);

  // Check several comparison operators.
  switch (pred) {
    case ICmpInst::ICMP_EQ: // if ($var == constant) or if (constant == $var).
      // If it's a equal comparison against a constant integer, match.
      if (op1const || op2const)
        return falseEdge;

      break;
    case ICmpInst::ICMP_NE: // if ($var != constant) or if (constant != $var).
      // If it's a not equal comparison against a constant integer, match.
      if (op1const || op2const)
        return trueEdge;

      break;
    case ICmpInst::ICMP_SLT: // if ($var < 0) or if (0 < $var).
    case ICmpInst::ICMP_ULT:
      if (!op1const && (op2const && op2const->isZero()))
        return falseEdge;
      else if (!op2const && (op1const && op1const->isZero()))
        return trueEdge;

      break;
    case ICmpInst::ICMP_SLE: // if ($var <= 0) or if (0 <= $var).
    case ICmpInst::ICMP_ULE:
      if (!op1const && (op2const && op2const->isZero()))
        return falseEdge;
      else if (!op2const && (op1const && op1const->isZero()))
        return trueEdge;

      break;
    case ICmpInst::ICMP_SGT: // if ($var > 0) or if (0 > $var).
    case ICmpInst::ICMP_UGT:
      if (!op1const && (op2const && op2const->isZero()))
        return trueEdge;
      else if (!op2const && (op1const && op1const->isZero()))
        return falseEdge;

      break;
    case ICmpInst::ICMP_SGE: // if ($var >= 0) or if (0 >= $var).
    case ICmpInst::ICMP_UGE:
      if (!op1const && (op2const && op2const->isZero()))
        return trueEdge;
      else if (!op2const && (op1const && op1const->isZero()))
        return falseEdge;

      break;
    default: // Do not process any other comparison operators.
      break;
  }

  // Heuristic not matched.
  return empty;
}
开发者ID:pozorvlak,项目名称:llvm-branchpred,代码行数:93,代码来源:BranchHeuristicsInfo.cpp

示例2: MatchGuardHeuristic

/// MatchGuardHeuristic - Predict that a comparison in which a register is
/// an operand, the register is used before being defined in a successor
/// block, and the successor block does not post-dominate will reach the
/// successor block.
/// @returns a Prediction that is a pair in which the first element is the
/// successor taken, and the second the successor not taken.
Prediction BranchHeuristicsInfo::MatchGuardHeuristic(BasicBlock *root) const {
  bool matched = false;
  Prediction pred;

  // Last instruction of basic block.
  TerminatorInst *TI = root->getTerminator();

  // Basic block successors. True and False branches.
  BasicBlock *trueSuccessor = TI->getSuccessor(0);
  BasicBlock *falseSuccessor = TI->getSuccessor(1);

  // Is the last instruction a Branch Instruction?
  BranchInst *BI = dyn_cast<BranchInst>(TI);
  if (!BI || !BI->isConditional())
    return empty;

  // Conditional instruction.
  Value *cond = BI->getCondition();

  // Find if the variable used in the branch instruction is
  // in fact a comparison instruction.
  CmpInst *CI = dyn_cast<CmpInst>(cond);
  if (!CI)
    return empty;

  // Seek over all of the operands of this comparison instruction.
  for (unsigned ops = 0; ops < CI->getNumOperands(); ++ops) {
    // Find the operand.
    Value *operand = CI->getOperand(ops);

    // Check if the operand is neither a function argument or a value.
    if (!isa<Argument>(operand) && !isa<User>(operand))
      continue;

    // Check if this variable was used in the true successor and
    // does not post dominate.
    // Since LLVM is in SSA form, it's impossible for a variable being used
    // before being defined, so that statement is skipped.
    if (operand->isUsedInBasicBlock(trueSuccessor) &&
        !PDT->dominates(trueSuccessor, root)) {
      // If a heuristic was already matched, predict none and abort immediately.
      if (matched)
        return empty;

      matched = true;
      pred = std::make_pair(trueSuccessor, falseSuccessor);
    }

    // Check if this variable was used in the false successor and
    // does not post dominate.
    if (operand->isUsedInBasicBlock(falseSuccessor) &&
        !PDT->dominates(falseSuccessor, root)) {
      // If a heuristic was already matched, predict none and abort immediately.
      if (matched)
        return empty;

      matched = true;
      pred = std::make_pair(falseSuccessor, trueSuccessor);
    }
  }

  return (matched ? pred : empty);
}
开发者ID:pozorvlak,项目名称:llvm-branchpred,代码行数:69,代码来源:BranchHeuristicsInfo.cpp

示例3: emitProfileNotes

void GCOVProfiler::emitProfileNotes() {
  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
  if (!CU_Nodes) return;

  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
    // Each compile unit gets its own .gcno file. This means that whether we run
    // this pass over the original .o's as they're produced, or run it after
    // LTO, we'll generate the same .gcno files.

    DICompileUnit CU(CU_Nodes->getOperand(i));
    std::error_code EC;
    raw_fd_ostream out(mangleName(CU, "gcno"), EC, sys::fs::F_None);
    std::string EdgeDestinations;

    DIArray SPs = CU.getSubprograms();
    unsigned FunctionIdent = 0;
    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
      DISubprogram SP(SPs.getElement(i));
      assert((!SP || SP.isSubprogram()) &&
        "A MDNode in subprograms of a CU should be null or a DISubprogram.");
      if (!SP)
        continue;

      Function *F = SP.getFunction();
      if (!F) continue;
      if (!functionHasLines(F)) continue;

      // gcov expects every function to start with an entry block that has a
      // single successor, so split the entry block to make sure of that.
      BasicBlock &EntryBlock = F->getEntryBlock();
      BasicBlock::iterator It = EntryBlock.begin();
      while (isa<AllocaInst>(*It) || isa<DbgInfoIntrinsic>(*It))
        ++It;
      EntryBlock.splitBasicBlock(It);

      Funcs.push_back(make_unique<GCOVFunction>(SP, &out, FunctionIdent++,
                                                Options.UseCfgChecksum,
                                                Options.ExitBlockBeforeBody));
      GCOVFunction &Func = *Funcs.back();

      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        GCOVBlock &Block = Func.getBlock(BB);
        TerminatorInst *TI = BB->getTerminator();
        if (int successors = TI->getNumSuccessors()) {
          for (int i = 0; i != successors; ++i) {
            Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
          }
        } else if (isa<ReturnInst>(TI)) {
          Block.addEdge(Func.getReturnBlock());
        }

        uint32_t Line = 0;
        for (BasicBlock::iterator I = BB->begin(), IE = BB->end();
             I != IE; ++I) {
          // Debug intrinsic locations correspond to the location of the
          // declaration, not necessarily any statements or expressions.
          if (isa<DbgInfoIntrinsic>(I)) continue;

          const DebugLoc &Loc = I->getDebugLoc();
          if (!Loc)
            continue;

          // Artificial lines such as calls to the global constructors.
          if (Loc.getLine() == 0) continue;

          if (Line == Loc.getLine()) continue;
          Line = Loc.getLine();
          if (SP != getDISubprogram(Loc.getScope()))
            continue;

          GCOVLines &Lines = Block.getFile(SP.getFilename());
          Lines.addLine(Loc.getLine());
        }
      }
      EdgeDestinations += Func.getEdgeDestinations();
    }

    FileChecksums.push_back(hash_value(EdgeDestinations));
    out.write("oncg", 4);
    out.write(ReversedVersion, 4);
    out.write(reinterpret_cast<char*>(&FileChecksums.back()), 4);

    for (auto &Func : Funcs) {
      Func->setCfgChecksum(FileChecksums.back());
      Func->writeOut();
    }

    out.write("\0\0\0\0\0\0\0\0", 8);  // EOF
    out.close();
  }
}
开发者ID:zcourts,项目名称:llvm-1,代码行数:91,代码来源:GCOVProfiling.cpp

示例4: emitProfileArcs

bool GCOVProfiler::emitProfileArcs() {
  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
  if (!CU_Nodes) return false;

  bool Result = false;
  bool InsertIndCounterIncrCode = false;
  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
    DICompileUnit CU(CU_Nodes->getOperand(i));
    DIArray SPs = CU.getSubprograms();
    SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
      DISubprogram SP(SPs.getElement(i));
      assert((!SP || SP.isSubprogram()) &&
        "A MDNode in subprograms of a CU should be null or a DISubprogram.");
      if (!SP)
        continue;
      Function *F = SP.getFunction();
      if (!F) continue;
      if (!functionHasLines(F)) continue;
      if (!Result) Result = true;
      unsigned Edges = 0;
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        TerminatorInst *TI = BB->getTerminator();
        if (isa<ReturnInst>(TI))
          ++Edges;
        else
          Edges += TI->getNumSuccessors();
      }

      ArrayType *CounterTy =
        ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
      GlobalVariable *Counters =
        new GlobalVariable(*M, CounterTy, false,
                           GlobalValue::InternalLinkage,
                           Constant::getNullValue(CounterTy),
                           "__llvm_gcov_ctr");
      CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP));

      UniqueVector<BasicBlock *> ComplexEdgePreds;
      UniqueVector<BasicBlock *> ComplexEdgeSuccs;

      unsigned Edge = 0;
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        TerminatorInst *TI = BB->getTerminator();
        int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
        if (Successors) {
          if (Successors == 1) {
            IRBuilder<> Builder(BB->getFirstInsertionPt());
            Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
                                                                Edge);
            Value *Count = Builder.CreateLoad(Counter);
            Count = Builder.CreateAdd(Count, Builder.getInt64(1));
            Builder.CreateStore(Count, Counter);
          } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
            IRBuilder<> Builder(BI);
            Value *Sel = Builder.CreateSelect(BI->getCondition(),
                                              Builder.getInt64(Edge),
                                              Builder.getInt64(Edge + 1));
            SmallVector<Value *, 2> Idx;
            Idx.push_back(Builder.getInt64(0));
            Idx.push_back(Sel);
            Value *Counter = Builder.CreateInBoundsGEP(Counters->getValueType(),
                                                       Counters, Idx);
            Value *Count = Builder.CreateLoad(Counter);
            Count = Builder.CreateAdd(Count, Builder.getInt64(1));
            Builder.CreateStore(Count, Counter);
          } else {
            ComplexEdgePreds.insert(BB);
            for (int i = 0; i != Successors; ++i)
              ComplexEdgeSuccs.insert(TI->getSuccessor(i));
          }

          Edge += Successors;
        }
      }

      if (!ComplexEdgePreds.empty()) {
        GlobalVariable *EdgeTable =
          buildEdgeLookupTable(F, Counters,
                               ComplexEdgePreds, ComplexEdgeSuccs);
        GlobalVariable *EdgeState = getEdgeStateValue();

        for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
          IRBuilder<> Builder(ComplexEdgePreds[i + 1]->getFirstInsertionPt());
          Builder.CreateStore(Builder.getInt32(i), EdgeState);
        }

        for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
          // Call runtime to perform increment.
          IRBuilder<> Builder(ComplexEdgeSuccs[i+1]->getFirstInsertionPt());
          Value *CounterPtrArray =
            Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
                                               i * ComplexEdgePreds.size());

          // Build code to increment the counter.
          InsertIndCounterIncrCode = true;
          Builder.CreateCall2(getIncrementIndirectCounterFunc(),
                              EdgeState, CounterPtrArray);
        }
      }
//.........这里部分代码省略.........
开发者ID:zcourts,项目名称:llvm-1,代码行数:101,代码来源:GCOVProfiling.cpp

示例5: OptimizeBlock

// In this pass we look for GEP and cast instructions that are used
// across basic blocks and rewrite them to improve basic-block-at-a-time
// selection.
bool CodeGenPrepare::OptimizeBlock(BasicBlock &BB) {
  bool MadeChange = false;

  // Split all critical edges where the dest block has a PHI.
  TerminatorInst *BBTI = BB.getTerminator();
  if (BBTI->getNumSuccessors() > 1 && !isa<IndirectBrInst>(BBTI)) {
    for (unsigned i = 0, e = BBTI->getNumSuccessors(); i != e; ++i) {
      BasicBlock *SuccBB = BBTI->getSuccessor(i);
      if (isa<PHINode>(SuccBB->begin()) && isCriticalEdge(BBTI, i, true))
        SplitEdgeNicely(BBTI, i, BackEdges, this);
    }
  }

  // Keep track of non-local addresses that have been sunk into this block.
  // This allows us to avoid inserting duplicate code for blocks with multiple
  // load/stores of the same address.
  DenseMap<Value*, Value*> SunkAddrs;

  for (BasicBlock::iterator BBI = BB.begin(), E = BB.end(); BBI != E; ) {
    Instruction *I = BBI++;

    if (CastInst *CI = dyn_cast<CastInst>(I)) {
      // If the source of the cast is a constant, then this should have
      // already been constant folded.  The only reason NOT to constant fold
      // it is if something (e.g. LSR) was careful to place the constant
      // evaluation in a block other than then one that uses it (e.g. to hoist
      // the address of globals out of a loop).  If this is the case, we don't
      // want to forward-subst the cast.
      if (isa<Constant>(CI->getOperand(0)))
        continue;

      bool Change = false;
      if (TLI) {
        Change = OptimizeNoopCopyExpression(CI, *TLI);
        MadeChange |= Change;
      }

      if (!Change && (isa<ZExtInst>(I) || isa<SExtInst>(I))) {
        MadeChange |= MoveExtToFormExtLoad(I);
        MadeChange |= OptimizeExtUses(I);
      }
    } else if (CmpInst *CI = dyn_cast<CmpInst>(I)) {
      MadeChange |= OptimizeCmpExpression(CI);
    } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
      if (TLI)
        MadeChange |= OptimizeMemoryInst(I, I->getOperand(0), LI->getType(),
                                         SunkAddrs);
    } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
      if (TLI)
        MadeChange |= OptimizeMemoryInst(I, SI->getOperand(1),
                                         SI->getOperand(0)->getType(),
                                         SunkAddrs);
    } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
      if (GEPI->hasAllZeroIndices()) {
        /// The GEP operand must be a pointer, so must its result -> BitCast
        Instruction *NC = new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
                                          GEPI->getName(), GEPI);
        GEPI->replaceAllUsesWith(NC);
        GEPI->eraseFromParent();
        MadeChange = true;
        BBI = NC;
      }
    } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
      // If we found an inline asm expession, and if the target knows how to
      // lower it to normal LLVM code, do so now.
      if (TLI && isa<InlineAsm>(CI->getCalledValue())) {
        if (TLI->ExpandInlineAsm(CI)) {
          BBI = BB.begin();
          // Avoid processing instructions out of order, which could cause
          // reuse before a value is defined.
          SunkAddrs.clear();
        } else
          // Sink address computing for memory operands into the block.
          MadeChange |= OptimizeInlineAsmInst(I, &(*CI), SunkAddrs);
      } else {
        // Other CallInst optimizations that don't need to muck with the
        // enclosing iterator here.
        MadeChange |= OptimizeCallInst(CI);
      }
    }
  }

  return MadeChange;
}
开发者ID:nickl-,项目名称:xchain-ios,代码行数:87,代码来源:CodeGenPrepare.cpp

示例6: runOnModule

bool LoaderPass::runOnModule(Module &M) {
  ProfileInfoLoader PIL("profile-loader", Filename);

  EdgeInformation.clear();
  std::vector<unsigned> Counters = PIL.getRawEdgeCounts();
  if (Counters.size() > 0) {
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      DEBUG(dbgs() << "Working on " << F->getName() << "\n");
      readEdge(getEdge(0,&F->getEntryBlock()), Counters);
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        TerminatorInst *TI = BB->getTerminator();
        for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
          readEdge(getEdge(BB,TI->getSuccessor(s)), Counters);
        }
      }
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
    NumEdgesRead = ReadCount;
  }

  Counters = PIL.getRawOptimalEdgeCounts();
  if (Counters.size() > 0) {
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      DEBUG(dbgs() << "Working on " << F->getName() << "\n");
      readEdge(getEdge(0,&F->getEntryBlock()), Counters);
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        TerminatorInst *TI = BB->getTerminator();
        if (TI->getNumSuccessors() == 0) {
          readEdge(getEdge(BB,0), Counters);
        }
        for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
          readEdge(getEdge(BB,TI->getSuccessor(s)), Counters);
        }
      }
      while (SpanningTree.size() > 0) {

        unsigned size = SpanningTree.size();

        BBisUnvisited.clear();
        for (std::set<Edge>::iterator ei = SpanningTree.begin(),
             ee = SpanningTree.end(); ei != ee; ++ei) {
          BBisUnvisited.insert(ei->first);
          BBisUnvisited.insert(ei->second);
        }
        while (BBisUnvisited.size() > 0) {
          recurseBasicBlock(*BBisUnvisited.begin());
        }

        if (SpanningTree.size() == size) {
          DEBUG(dbgs()<<"{");
          for (std::set<Edge>::iterator ei = SpanningTree.begin(),
               ee = SpanningTree.end(); ei != ee; ++ei) {
            DEBUG(dbgs()<< *ei <<",");
          }
          assert(0 && "No edge calculated!");
        }

      }
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
    NumEdgesRead = ReadCount;
  }

  BlockInformation.clear();
  Counters = PIL.getRawBlockCounts();
  if (Counters.size() > 0) {
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
        if (ReadCount < Counters.size())
          // Here the data realm changes from the unsigned of the file to the
          // double of the ProfileInfo. This conversion is save because we know
          // that everything thats representable in unsinged is also
          // representable in double.
          BlockInformation[F][BB] = (double)Counters[ReadCount++];
    }
    if (ReadCount != Counters.size()) {
      errs() << "WARNING: profile information is inconsistent with "
             << "the current program!\n";
    }
  }

  FunctionInformation.clear();
  Counters = PIL.getRawFunctionCounts();
  if (Counters.size() > 0) {
    ReadCount = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      if (ReadCount < Counters.size())
//.........这里部分代码省略.........
开发者ID:32bitmicro,项目名称:llvm,代码行数:101,代码来源:ProfileInfoLoaderPass.cpp

示例7: runOnModule

bool EdgeProfiler::runOnModule(Module &M) {
    Function *Main = M.getFunction("main");
    if (Main == 0) {
        errs() << "WARNING: cannot insert edge profiling into a module"
               << " with no main function!\n";
        return false;  // No main, no instrumentation!
    }

    std::set<BasicBlock*> BlocksToInstrument;
    unsigned NumEdges = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
        if (F->isDeclaration()) continue;
        // Reserve space for (0,entry) edge.
        ++NumEdges;
        for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
            // Keep track of which blocks need to be instrumented.  We don't want to
            // instrument blocks that are added as the result of breaking critical
            // edges!
            BlocksToInstrument.insert(BB);
            NumEdges += BB->getTerminator()->getNumSuccessors();
        }
    }

    const Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()), NumEdges);
    GlobalVariable *Counters =
        new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
                           Constant::getNullValue(ATy), "EdgeProfCounters");
    NumEdgesInserted = NumEdges;

    // Instrument all of the edges...
    unsigned i = 0;
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
        if (F->isDeclaration()) continue;
        // Create counter for (0,entry) edge.
        IncrementCounterInBlock(&F->getEntryBlock(), i++, Counters);
        for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
            if (BlocksToInstrument.count(BB)) {  // Don't instrument inserted blocks
                // Okay, we have to add a counter of each outgoing edge.  If the
                // outgoing edge is not critical don't split it, just insert the counter
                // in the source or destination of the edge.
                TerminatorInst *TI = BB->getTerminator();
                for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
                    // If the edge is critical, split it.
                    SplitCriticalEdge(TI, s, this);

                    // Okay, we are guaranteed that the edge is no longer critical.  If we
                    // only have a single successor, insert the counter in this block,
                    // otherwise insert it in the successor block.
                    if (TI->getNumSuccessors() == 1) {
                        // Insert counter at the start of the block
                        IncrementCounterInBlock(BB, i++, Counters);
                    } else {
                        // Insert counter at the start of the block
                        IncrementCounterInBlock(TI->getSuccessor(s), i++, Counters);
                    }
                }
            }
    }

    // Add the initialization call to main.
    InsertProfilingInitCall(Main, "llvm_start_edge_profiling", Counters);
    return true;
}
开发者ID:CyberIntelMafia,项目名称:clamav-devel,代码行数:63,代码来源:EdgeProfiling.cpp

示例8: emitProfileArcs

bool GCOVProfiler::emitProfileArcs() {
  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
  if (!CU_Nodes) return false;

  bool Result = false;  
  bool InsertIndCounterIncrCode = false;
  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
    DICompileUnit CU(CU_Nodes->getOperand(i));
    DIArray SPs = CU.getSubprograms();
    SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
      DISubprogram SP(SPs.getElement(i));
      if (!SP.Verify()) continue;
      Function *F = SP.getFunction();
      if (!F) continue;
      if (!Result) Result = true;
      unsigned Edges = 0;
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        TerminatorInst *TI = BB->getTerminator();
        if (isa<ReturnInst>(TI))
          ++Edges;
        else
          Edges += TI->getNumSuccessors();
      }
      
      ArrayType *CounterTy =
        ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
      GlobalVariable *Counters =
        new GlobalVariable(*M, CounterTy, false,
                           GlobalValue::InternalLinkage,
                           Constant::getNullValue(CounterTy),
                           "__llvm_gcov_ctr");
      CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP));
      
      UniqueVector<BasicBlock *> ComplexEdgePreds;
      UniqueVector<BasicBlock *> ComplexEdgeSuccs;
      
      unsigned Edge = 0;
      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
        TerminatorInst *TI = BB->getTerminator();
        int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
        if (Successors) {
          IRBuilder<> Builder(TI);
          
          if (Successors == 1) {
            Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
                                                                Edge);
            Value *Count = Builder.CreateLoad(Counter);
            Count = Builder.CreateAdd(Count, Builder.getInt64(1));
            Builder.CreateStore(Count, Counter);
          } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
            Value *Sel = Builder.CreateSelect(BI->getCondition(),
                                              Builder.getInt64(Edge),
                                              Builder.getInt64(Edge + 1));
            SmallVector<Value *, 2> Idx;
            Idx.push_back(Builder.getInt64(0));
            Idx.push_back(Sel);
            Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx);
            Value *Count = Builder.CreateLoad(Counter);
            Count = Builder.CreateAdd(Count, Builder.getInt64(1));
            Builder.CreateStore(Count, Counter);
          } else {
            ComplexEdgePreds.insert(BB);
            for (int i = 0; i != Successors; ++i)
              ComplexEdgeSuccs.insert(TI->getSuccessor(i));
          }
          Edge += Successors;
        }
      }
      
      if (!ComplexEdgePreds.empty()) {
        GlobalVariable *EdgeTable =
          buildEdgeLookupTable(F, Counters,
                               ComplexEdgePreds, ComplexEdgeSuccs);
        GlobalVariable *EdgeState = getEdgeStateValue();
        
        for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
          IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator());
          Builder.CreateStore(Builder.getInt32(i), EdgeState);
        }
        for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
          // call runtime to perform increment
          BasicBlock::iterator InsertPt =
            ComplexEdgeSuccs[i+1]->getFirstInsertionPt();
          IRBuilder<> Builder(InsertPt);
          Value *CounterPtrArray =
            Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
                                               i * ComplexEdgePreds.size());

          // Build code to increment the counter.
          InsertIndCounterIncrCode = true;
          Builder.CreateCall2(getIncrementIndirectCounterFunc(),
                              EdgeState, CounterPtrArray);
        }
      }
    }

    insertCounterWriteout(CountersBySP);
    insertFlush(CountersBySP);
  }
//.........这里部分代码省略.........
开发者ID:Arcterus,项目名称:llvm,代码行数:101,代码来源:GCOVProfiling.cpp

示例9: if

/// InsertUniqueBackedgeBlock - This method is called when the specified loop
/// has more than one backedge in it.  If this occurs, revector all of these
/// backedges to target a new basic block and have that block branch to the loop
/// header.  This ensures that loops have exactly one backedge.
///
BasicBlock *
LoopSimplify::InsertUniqueBackedgeBlock(Loop *L, BasicBlock *Preheader) {
  assert(L->getNumBackEdges() > 1 && "Must have > 1 backedge!");

  // Get information about the loop
  BasicBlock *Header = L->getHeader();
  Function *F = Header->getParent();

  // Unique backedge insertion currently depends on having a preheader.
  if (!Preheader)
    return 0;

  // Figure out which basic blocks contain back-edges to the loop header.
  std::vector<BasicBlock*> BackedgeBlocks;
  for (pred_iterator I = pred_begin(Header), E = pred_end(Header); I != E; ++I){
    BasicBlock *P = *I;

    // Indirectbr edges cannot be split, so we must fail if we find one.
    if (isa<IndirectBrInst>(P->getTerminator()))
      return 0;

    if (P != Preheader) BackedgeBlocks.push_back(P);
  }

  // Create and insert the new backedge block...
  BasicBlock *BEBlock = BasicBlock::Create(Header->getContext(),
                                           Header->getName()+".backedge", F);
  BranchInst *BETerminator = BranchInst::Create(Header, BEBlock);

  DEBUG(dbgs() << "LoopSimplify: Inserting unique backedge block "
               << BEBlock->getName() << "\n");

  // Move the new backedge block to right after the last backedge block.
  Function::iterator InsertPos = BackedgeBlocks.back(); ++InsertPos;
  F->getBasicBlockList().splice(InsertPos, F->getBasicBlockList(), BEBlock);

  // Now that the block has been inserted into the function, create PHI nodes in
  // the backedge block which correspond to any PHI nodes in the header block.
  for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
    PHINode *PN = cast<PHINode>(I);
    PHINode *NewPN = PHINode::Create(PN->getType(), PN->getName()+".be",
                                     BETerminator);
    NewPN->reserveOperandSpace(BackedgeBlocks.size());
    if (AA) AA->copyValue(PN, NewPN);

    // Loop over the PHI node, moving all entries except the one for the
    // preheader over to the new PHI node.
    unsigned PreheaderIdx = ~0U;
    bool HasUniqueIncomingValue = true;
    Value *UniqueValue = 0;
    for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
      BasicBlock *IBB = PN->getIncomingBlock(i);
      Value *IV = PN->getIncomingValue(i);
      if (IBB == Preheader) {
        PreheaderIdx = i;
      } else {
        NewPN->addIncoming(IV, IBB);
        if (HasUniqueIncomingValue) {
          if (UniqueValue == 0)
            UniqueValue = IV;
          else if (UniqueValue != IV)
            HasUniqueIncomingValue = false;
        }
      }
    }

    // Delete all of the incoming values from the old PN except the preheader's
    assert(PreheaderIdx != ~0U && "PHI has no preheader entry??");
    if (PreheaderIdx != 0) {
      PN->setIncomingValue(0, PN->getIncomingValue(PreheaderIdx));
      PN->setIncomingBlock(0, PN->getIncomingBlock(PreheaderIdx));
    }
    // Nuke all entries except the zero'th.
    for (unsigned i = 0, e = PN->getNumIncomingValues()-1; i != e; ++i)
      PN->removeIncomingValue(e-i, false);

    // Finally, add the newly constructed PHI node as the entry for the BEBlock.
    PN->addIncoming(NewPN, BEBlock);

    // As an optimization, if all incoming values in the new PhiNode (which is a
    // subset of the incoming values of the old PHI node) have the same value,
    // eliminate the PHI Node.
    if (HasUniqueIncomingValue) {
      NewPN->replaceAllUsesWith(UniqueValue);
      if (AA) AA->deleteValue(NewPN);
      BEBlock->getInstList().erase(NewPN);
    }
  }

  // Now that all of the PHI nodes have been inserted and adjusted, modify the
  // backedge blocks to just to the BEBlock instead of the header.
  for (unsigned i = 0, e = BackedgeBlocks.size(); i != e; ++i) {
    TerminatorInst *TI = BackedgeBlocks[i]->getTerminator();
    for (unsigned Op = 0, e = TI->getNumSuccessors(); Op != e; ++Op)
      if (TI->getSuccessor(Op) == Header)
//.........这里部分代码省略.........
开发者ID:5432935,项目名称:crossbridge,代码行数:101,代码来源:LoopSimplify.cpp

示例10: runOnFunction

bool InstructionGraph::runOnFunction(Function &M) {
    errs()<<"ins grph ";

    // if the function dppcreated, then we skip
    if(M.hasFnAttribute(GENERATEDATTR))
        return false;
    errs()<<"skip check";
    Func = &M;

    ExternalInsNode = getOrInsertInstruction(0);
    //assert(!CallsExternalNode);
    //CallsExternalNode = new CallGraphNode(0);
    Root = ExternalInsNode;
    for(Function::iterator BB=M.begin(), BBE = M.end(); BB != BBE; ++BB)
    {
        TerminatorInst* curBBTerm =  BB->getTerminator();
        unsigned numSuc = curBBTerm->getNumSuccessors();
        for(unsigned sucInd=0; sucInd < numSuc; sucInd++)
        {
            BasicBlock* curSuc = curBBTerm->getSuccessor(sucInd);
            std::vector<BasicBlock*>* curSucPredecessors;
            if(BasicBlock2Predecessors.find(curSuc)==BasicBlock2Predecessors.end())
            {
                curSucPredecessors = new std::vector<BasicBlock*>();
                BasicBlock2Predecessors[curSuc] = curSucPredecessors;
            }
            else
                curSucPredecessors = BasicBlock2Predecessors[curSuc];
            curSucPredecessors->push_back(&(*BB));
        }
    }
    PostDominatorTree* PDT = getAnalysisIfAvailable<PostDominatorTree>();
    LoopInfo* LI = getAnalysisIfAvailable<LoopInfo>();
    for (Function::iterator BB = M.begin(), BBE = M.end(); BB != BBE; ++BB)
    {
        BasicBlock* curBBPtr = &(*BB);
        std::vector<BasicBlock*>* earliestPred=0;
        if(BasicBlock2Predecessors.find(curBBPtr)==BasicBlock2Predecessors.end())
        {
            assert (&(M.getEntryBlock()) == curBBPtr);
        }
        else
        {
          // now we shall search for the actual predicate instruction
            earliestPred = searchEarliestPredicate(curBBPtr, PDT, BasicBlock2Predecessors,LI);
        }
        /*errs()<<"bb:"<<BB->getName() << " has "<<" pred \n";
        for(unsigned k = 0;k < earliestPred->size(); k++)
        {
          errs()<< earliestPred->at(k)->getName()<<"\n";
        }*/

        for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI)
        {
           addToInstructionGraph(BI, earliestPred);
        }
        delete earliestPred;
        errs()<<BB->getName()<<"\t" <<ExternalInsNode->DependentInstructions.size()<<" root dep\n";
    }
    // we should have all the node
    errs()<<InstructionMap.size()<< " instructions added as graph nodes\n";

    return false;
}
开发者ID:sycinf,项目名称:ArchSyn,代码行数:64,代码来源:InstructionGraph.cpp

示例11: runOnFunction

/// \brief Assign DWARF discriminators.
///
/// To assign discriminators, we examine the boundaries of every
/// basic block and its successors. Suppose there is a basic block B1
/// with successor B2. The last instruction I1 in B1 and the first
/// instruction I2 in B2 are located at the same file and line number.
/// This situation is illustrated in the following code snippet:
///
///       if (i < 10) x = i;
///
///     entry:
///       br i1 %cmp, label %if.then, label %if.end, !dbg !10
///     if.then:
///       %1 = load i32* %i.addr, align 4, !dbg !10
///       store i32 %1, i32* %x, align 4, !dbg !10
///       br label %if.end, !dbg !10
///     if.end:
///       ret void, !dbg !12
///
/// Notice how the branch instruction in block 'entry' and all the
/// instructions in block 'if.then' have the exact same debug location
/// information (!dbg !10).
///
/// To distinguish instructions in block 'entry' from instructions in
/// block 'if.then', we generate a new lexical block for all the
/// instruction in block 'if.then' that share the same file and line
/// location with the last instruction of block 'entry'.
///
/// This new lexical block will have the same location information as
/// the previous one, but with a new DWARF discriminator value.
///
/// One of the main uses of this discriminator value is in runtime
/// sample profilers. It allows the profiler to distinguish instructions
/// at location !dbg !10 that execute on different basic blocks. This is
/// important because while the predicate 'if (x < 10)' may have been
/// executed millions of times, the assignment 'x = i' may have only
/// executed a handful of times (meaning that the entry->if.then edge is
/// seldom taken).
///
/// If we did not have discriminator information, the profiler would
/// assign the same weight to both blocks 'entry' and 'if.then', which
/// in turn will make it conclude that the entry->if.then edge is very
/// hot.
///
/// To decide where to create new discriminator values, this function
/// traverses the CFG and examines instruction at basic block boundaries.
/// If the last instruction I1 of a block B1 is at the same file and line
/// location as instruction I2 of successor B2, then it creates a new
/// lexical block for I2 and all the instruction in B2 that share the same
/// file and line location as I2. This new lexical block will have a
/// different discriminator number than I1.
bool AddDiscriminators::runOnFunction(Function &F) {
  // If the function has debug information, but the user has disabled
  // discriminators, do nothing.
  // Simlarly, if the function has no debug info, do nothing.
  // Finally, if this module is built with dwarf versions earlier than 4,
  // do nothing (discriminator support is a DWARF 4 feature).
  if (NoDiscriminators ||
      !hasDebugInfo(F) ||
      F.getParent()->getDwarfVersion() < 4)
    return false;

  bool Changed = false;
  Module *M = F.getParent();
  LLVMContext &Ctx = M->getContext();
  DIBuilder Builder(*M, /*AllowUnresolved*/ false);

  // Traverse all the blocks looking for instructions in different
  // blocks that are at the same file:line location.
  for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
    BasicBlock *B = I;
    TerminatorInst *Last = B->getTerminator();
    DILocation LastDIL = Last->getDebugLoc().get();
    if (!LastDIL)
      continue;

    for (unsigned I = 0; I < Last->getNumSuccessors(); ++I) {
      BasicBlock *Succ = Last->getSuccessor(I);
      Instruction *First = Succ->getFirstNonPHIOrDbgOrLifetime();
      DILocation FirstDIL = First->getDebugLoc().get();
      if (!FirstDIL)
        continue;

      // If the first instruction (First) of Succ is at the same file
      // location as B's last instruction (Last), add a new
      // discriminator for First's location and all the instructions
      // in Succ that share the same location with First.
      if (!FirstDIL->canDiscriminate(*LastDIL)) {
        // Create a new lexical scope and compute a new discriminator
        // number for it.
        StringRef Filename = FirstDIL->getFilename();
        auto *Scope = FirstDIL->getScope();
        auto *File = Builder.createFile(Filename, Scope->getDirectory());

        // FIXME: Calculate the discriminator here, based on local information,
        // and delete MDLocation::computeNewDiscriminator().  The current
        // solution gives different results depending on other modules in the
        // same context.  All we really need is to discriminate between
        // FirstDIL and LastDIL -- a local map would suffice.
        unsigned Discriminator = FirstDIL->computeNewDiscriminator();
//.........这里部分代码省略.........
开发者ID:fran6co,项目名称:llvm,代码行数:101,代码来源:AddDiscriminators.cpp

示例12: runOnModule

bool LoaderPass::runOnModule(Module &M) {
    ProfileInfoLoader PIL("profile-loader", Filename, M);

    EdgeInformation.clear();
    std::vector<unsigned> ECs = PIL.getRawEdgeCounts();
    if (ECs.size() > 0) {
        unsigned ei = 0;
        for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
            if (F->isDeclaration()) continue;
            if (ei < ECs.size())
                EdgeInformation[F][ProfileInfo::getEdge(0, &F->getEntryBlock())] +=
                    ECs[ei++];
            for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
                // Okay, we have to add a counter of each outgoing edge.  If the
                // outgoing edge is not critical don't split it, just insert the counter
                // in the source or destination of the edge.
                TerminatorInst *TI = BB->getTerminator();
                for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
                    if (ei < ECs.size())
                        EdgeInformation[F][ProfileInfo::getEdge(BB, TI->getSuccessor(s))] +=
                            ECs[ei++];
                }
            }
        }
        if (ei != ECs.size()) {
            cerr << "WARNING: profile information is inconsistent with "
                 << "the current program!\n";
        }
    }

    BlockInformation.clear();
    std::vector<unsigned> BCs = PIL.getRawBlockCounts();
    if (BCs.size() > 0) {
        unsigned bi = 0;
        for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
            if (F->isDeclaration()) continue;
            for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
                if (bi < BCs.size())
                    BlockInformation[F][BB] = BCs[bi++];
        }
        if (bi != BCs.size()) {
            cerr << "WARNING: profile information is inconsistent with "
                 << "the current program!\n";
        }
    }

    FunctionInformation.clear();
    std::vector<unsigned> FCs = PIL.getRawFunctionCounts();
    if (FCs.size() > 0) {
        unsigned fi = 0;
        for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
            if (F->isDeclaration()) continue;
            if (fi < FCs.size())
                FunctionInformation[F] = FCs[fi++];
        }
        if (fi != FCs.size()) {
            cerr << "WARNING: profile information is inconsistent with "
                 << "the current program!\n";
        }
    }

    return false;
}
开发者ID:Killfrra,项目名称:llvm-kernel,代码行数:63,代码来源:ProfileInfoLoaderPass.cpp

示例13: analyzeCall


//.........这里部分代码省略.........
                                  SmallPtrSet<BasicBlock *, 16> > BBSetVector;
  BBSetVector BBWorklist;
  BBWorklist.insert(&F.getEntryBlock());
  // Note that we *must not* cache the size, this loop grows the worklist.
  for (unsigned Idx = 0; Idx != BBWorklist.size(); ++Idx) {
    // Bail out the moment we cross the threshold. This means we'll under-count
    // the cost, but only when undercounting doesn't matter.
    if (Cost > (Threshold + VectorBonus))
      break;

    BasicBlock *BB = BBWorklist[Idx];
    if (BB->empty())
      continue;

    // Handle the terminator cost here where we can track returns and other
    // function-wide constructs.
    TerminatorInst *TI = BB->getTerminator();

    // We never want to inline functions that contain an indirectbr.  This is
    // incorrect because all the blockaddress's (in static global initializers
    // for example) would be referring to the original function, and this
    // indirect jump would jump from the inlined copy of the function into the 
    // original function which is extremely undefined behavior.
    // FIXME: This logic isn't really right; we can safely inline functions
    // with indirectbr's as long as no other function or global references the
    // blockaddress of a block within the current function.  And as a QOI issue,
    // if someone is using a blockaddress without an indirectbr, and that
    // reference somehow ends up in another function or global, we probably
    // don't want to inline this function.
    if (isa<IndirectBrInst>(TI))
      return false;

    if (!HasReturn && isa<ReturnInst>(TI))
      HasReturn = true;
    else
      Cost += InlineConstants::InstrCost;

    // Analyze the cost of this block. If we blow through the threshold, this
    // returns false, and we can bail on out.
    if (!analyzeBlock(BB)) {
      if (IsRecursiveCall || ExposesReturnsTwice || HasDynamicAlloca)
        return false;

      // If the caller is a recursive function then we don't want to inline
      // functions which allocate a lot of stack space because it would increase
      // the caller stack usage dramatically.
      if (IsCallerRecursive &&
          AllocatedSize > InlineConstants::TotalAllocaSizeRecursiveCaller)
        return false;

      break;
    }

    // Add in the live successors by first checking whether we have terminator
    // that may be simplified based on the values simplified by this call.
    if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
      if (BI->isConditional()) {
        Value *Cond = BI->getCondition();
        if (ConstantInt *SimpleCond
              = dyn_cast_or_null<ConstantInt>(SimplifiedValues.lookup(Cond))) {
          BBWorklist.insert(BI->getSuccessor(SimpleCond->isZero() ? 1 : 0));
          continue;
        }
      }
    } else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
      Value *Cond = SI->getCondition();
      if (ConstantInt *SimpleCond
            = dyn_cast_or_null<ConstantInt>(SimplifiedValues.lookup(Cond))) {
        BBWorklist.insert(SI->findCaseValue(SimpleCond).getCaseSuccessor());
        continue;
      }
    }

    // If we're unable to select a particular successor, just count all of
    // them.
    for (unsigned TIdx = 0, TSize = TI->getNumSuccessors(); TIdx != TSize;
         ++TIdx)
      BBWorklist.insert(TI->getSuccessor(TIdx));

    // If we had any successors at this point, than post-inlining is likely to
    // have them as well. Note that we assume any basic blocks which existed
    // due to branches or switches which folded above will also fold after
    // inlining.
    if (SingleBB && TI->getNumSuccessors() > 1) {
      // Take off the bonus we applied to the threshold.
      Threshold -= SingleBBBonus;
      SingleBB = false;
    }
  }

  // If this is a noduplicate call, we can still inline as long as 
  // inlining this would cause the removal of the caller (so the instruction
  // is not actually duplicated, just moved).
  if (!OnlyOneCallAndLocalLinkage && ContainsNoDuplicateCall)
    return false;

  Threshold += VectorBonus;

  return Cost < Threshold;
}
开发者ID:baatar,项目名称:llvm-duetto,代码行数:101,代码来源:InlineCost.cpp

示例14: FlattenParallelAndOr


//.........这里部分代码省略.........
    // Only conditional branches are allowed beyond this point.
    assert(PBI->isConditional());

    // Condition's unique use should be the branch instruction.
    Value *PC = PBI->getCondition();
    if (!PC || !PC->hasOneUse())
      return false;

    if (PP && Preds.count(PP)) {
      // These are internal condition blocks to be merged from, e.g.,
      // BB2 in both cases.
      // Should not be address-taken.
      if (Pred->hasAddressTaken())
        return false;

      // Instructions in the internal condition blocks should be safe
      // to hoist up.
      for (BasicBlock::iterator BI = Pred->begin(), BE = PBI->getIterator();
           BI != BE;) {
        Instruction *CI = &*BI++;
        if (isa<PHINode>(CI) || !isSafeToSpeculativelyExecute(CI))
          return false;
      }
    } else {
      // This is the condition block to be merged into, e.g. BB1 in
      // both cases.
      if (FirstCondBlock)
        return false;
      FirstCondBlock = Pred;
    }

    // Find whether BB is uniformly on the true (or false) path
    // for all of its predecessors.
    BasicBlock *PS1 = PBI->getSuccessor(0);
    BasicBlock *PS2 = PBI->getSuccessor(1);
    BasicBlock *PS = (PS1 == BB) ? PS2 : PS1;
    int CIdx = (PS1 == BB) ? 0 : 1;

    if (Idx == -1)
      Idx = CIdx;
    else if (CIdx != Idx)
      return false;

    // PS is the successor which is not BB. Check successors to identify
    // the last conditional branch.
    if (Preds.count(PS) == 0) {
      // Case 2.
      LastCondBlock = Pred;
    } else {
      // Case 1
      BranchInst *BPS = dyn_cast<BranchInst>(PS->getTerminator());
      if (BPS && BPS->isUnconditional()) {
        // Case 1: PS(BB3) should be an unconditional branch.
        LastCondBlock = Pred;
      }
    }
  }

  if (!FirstCondBlock || !LastCondBlock || (FirstCondBlock == LastCondBlock))
    return false;

  TerminatorInst *TBB = LastCondBlock->getTerminator();
  BasicBlock *PS1 = TBB->getSuccessor(0);
  BasicBlock *PS2 = TBB->getSuccessor(1);
  BranchInst *PBI1 = dyn_cast<BranchInst>(PS1->getTerminator());
  BranchInst *PBI2 = dyn_cast<BranchInst>(PS2->getTerminator());
开发者ID:bkaradzic,项目名称:SwiftShader,代码行数:67,代码来源:FlattenCFG.cpp

示例15: NormalizeLandingPads

/// NormalizeLandingPads - Normalize and discover landing pads, noting them
/// in the LandingPads set.  A landing pad is normal if the only CFG edges
/// that end at it are unwind edges from invoke instructions. If we inlined
/// through an invoke we could have a normal branch from the previous
/// unwind block through to the landing pad for the original invoke.
/// Abnormal landing pads are fixed up by redirecting all unwind edges to
/// a new basic block which falls through to the original.
bool DwarfEHPrepare::NormalizeLandingPads() {
  bool Changed = false;

  const MCAsmInfo *MAI = TM->getMCAsmInfo();
  bool usingSjLjEH = MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;

  for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
    TerminatorInst *TI = I->getTerminator();
    if (!isa<InvokeInst>(TI))
      continue;
    BasicBlock *LPad = TI->getSuccessor(1);
    // Skip landing pads that have already been normalized.
    if (LandingPads.count(LPad))
      continue;

    // Check that only invoke unwind edges end at the landing pad.
    bool OnlyUnwoundTo = true;
    bool SwitchOK = usingSjLjEH;
    for (pred_iterator PI = pred_begin(LPad), PE = pred_end(LPad);
         PI != PE; ++PI) {
      TerminatorInst *PT = (*PI)->getTerminator();
      // The SjLj dispatch block uses a switch instruction. This is effectively
      // an unwind edge, so we can disregard it here. There will only ever
      // be one dispatch, however, so if there are multiple switches, one
      // of them truly is a normal edge, not an unwind edge.
      if (SwitchOK && isa<SwitchInst>(PT)) {
        SwitchOK = false;
        continue;
      }
      if (!isa<InvokeInst>(PT) || LPad == PT->getSuccessor(0)) {
        OnlyUnwoundTo = false;
        break;
      }
    }

    if (OnlyUnwoundTo) {
      // Only unwind edges lead to the landing pad.  Remember the landing pad.
      LandingPads.insert(LPad);
      continue;
    }

    // At least one normal edge ends at the landing pad.  Redirect the unwind
    // edges to a new basic block which falls through into this one.

    // Create the new basic block.
    BasicBlock *NewBB = BasicBlock::Create(F->getContext(),
                                           LPad->getName() + "_unwind_edge");

    // Insert it into the function right before the original landing pad.
    LPad->getParent()->getBasicBlockList().insert(LPad, NewBB);

    // Redirect unwind edges from the original landing pad to NewBB.
    for (pred_iterator PI = pred_begin(LPad), PE = pred_end(LPad); PI != PE; ) {
      TerminatorInst *PT = (*PI++)->getTerminator();
      if (isa<InvokeInst>(PT) && PT->getSuccessor(1) == LPad)
        // Unwind to the new block.
        PT->setSuccessor(1, NewBB);
    }

    // If there are any PHI nodes in LPad, we need to update them so that they
    // merge incoming values from NewBB instead.
    for (BasicBlock::iterator II = LPad->begin(); isa<PHINode>(II); ++II) {
      PHINode *PN = cast<PHINode>(II);
      pred_iterator PB = pred_begin(NewBB), PE = pred_end(NewBB);

      // Check to see if all of the values coming in via unwind edges are the
      // same.  If so, we don't need to create a new PHI node.
      Value *InVal = PN->getIncomingValueForBlock(*PB);
      for (pred_iterator PI = PB; PI != PE; ++PI) {
        if (PI != PB && InVal != PN->getIncomingValueForBlock(*PI)) {
          InVal = 0;
          break;
        }
      }

      if (InVal == 0) {
        // Different unwind edges have different values.  Create a new PHI node
        // in NewBB.
        PHINode *NewPN = PHINode::Create(PN->getType(),
                                         PN->getNumIncomingValues(),
                                         PN->getName()+".unwind", NewBB);
        // Add an entry for each unwind edge, using the value from the old PHI.
        for (pred_iterator PI = PB; PI != PE; ++PI)
          NewPN->addIncoming(PN->getIncomingValueForBlock(*PI), *PI);

        // Now use this new PHI as the common incoming value for NewBB in PN.
        InVal = NewPN;
      }

      // Revector exactly one entry in the PHI node to come from NewBB
      // and delete all other entries that come from unwind edges.  If
      // there are both normal and unwind edges from the same predecessor,
      // this leaves an entry for the normal edge.
//.........这里部分代码省略.........
开发者ID:Sciumo,项目名称:llvm,代码行数:101,代码来源:DwarfEHPrepare.cpp


注:本文中的TerminatorInst::getSuccessor方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。