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


C++ SwitchInst类代码示例

本文整理汇总了C++中SwitchInst的典型用法代码示例。如果您正苦于以下问题:C++ SwitchInst类的具体用法?C++ SwitchInst怎么用?C++ SwitchInst使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


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

示例1: assert

/// buildCFICheck - emits __cfi_check for the current module.
void CrossDSOCFI::buildCFICheck() {
  // FIXME: verify that __cfi_check ends up near the end of the code section,
  // but before the jump slots created in LowerBitSets.
  llvm::DenseSet<uint64_t> BitSetIds;
  NamedMDNode *BitSetNM = M->getNamedMetadata("llvm.bitsets");

  if (BitSetNM)
    for (unsigned I = 0, E = BitSetNM->getNumOperands(); I != E; ++I)
      if (ConstantInt *TypeId = extractBitSetTypeId(BitSetNM->getOperand(I)))
        BitSetIds.insert(TypeId->getZExtValue());

  LLVMContext &Ctx = M->getContext();
  Constant *C = M->getOrInsertFunction(
      "__cfi_check",
      FunctionType::get(
          Type::getVoidTy(Ctx),
          {Type::getInt64Ty(Ctx), PointerType::getUnqual(Type::getInt8Ty(Ctx))},
          false));
  Function *F = dyn_cast<Function>(C);
  F->setAlignment(4096);
  auto args = F->arg_begin();
  Argument &CallSiteTypeId = *(args++);
  CallSiteTypeId.setName("CallSiteTypeId");
  Argument &Addr = *(args++);
  Addr.setName("Addr");
  assert(args == F->arg_end());

  BasicBlock *BB = BasicBlock::Create(Ctx, "entry", F);

  BasicBlock *TrapBB = BasicBlock::Create(Ctx, "trap", F);
  IRBuilder<> IRBTrap(TrapBB);
  Function *TrapFn = Intrinsic::getDeclaration(M, Intrinsic::trap);
  llvm::CallInst *TrapCall = IRBTrap.CreateCall(TrapFn);
  TrapCall->setDoesNotReturn();
  TrapCall->setDoesNotThrow();
  IRBTrap.CreateUnreachable();

  BasicBlock *ExitBB = BasicBlock::Create(Ctx, "exit", F);
  IRBuilder<> IRBExit(ExitBB);
  IRBExit.CreateRetVoid();

  IRBuilder<> IRB(BB);
  SwitchInst *SI = IRB.CreateSwitch(&CallSiteTypeId, TrapBB, BitSetIds.size());
  for (uint64_t TypeId : BitSetIds) {
    ConstantInt *CaseTypeId = ConstantInt::get(Type::getInt64Ty(Ctx), TypeId);
    BasicBlock *TestBB = BasicBlock::Create(Ctx, "test", F);
    IRBuilder<> IRBTest(TestBB);
    Function *BitsetTestFn =
        Intrinsic::getDeclaration(M, Intrinsic::bitset_test);

    Value *Test = IRBTest.CreateCall(
        BitsetTestFn, {&Addr, MetadataAsValue::get(
                                  Ctx, ConstantAsMetadata::get(CaseTypeId))});
    BranchInst *BI = IRBTest.CreateCondBr(Test, ExitBB, TrapBB);
    BI->setMetadata(LLVMContext::MD_prof, VeryLikelyWeights);

    SI->addCase(CaseTypeId, TestBB);
    ++TypeIds;
  }
}
开发者ID:2asoft,项目名称:freebsd,代码行数:61,代码来源:CrossDSOCFI.cpp

示例2: adjustFpuPrecision

static Value* adjustFpuPrecision(BasicBlock *&b, Value *fpuval)
{
    // We only expect to be called on native FPU types that need to be
    // adjusted.
    NASSERT(fpuval->getType()->isX86_FP80Ty());

    // Read precision flag.
    // switch (pc) 
    // case 0: single precision
    // case 2: double precision
    // default: double extended (native x86)

    Value *pc = F_READ(b, "FPU_PC");

    CREATE_BLOCK(native_precision, b);
    CREATE_BLOCK(single_precision, b);
    CREATE_BLOCK(double_precision, b);
    CREATE_BLOCK(done_adjusting, b);

    SwitchInst *pcSwitch = SwitchInst::Create(pc, block_native_precision, 3, b);
    pcSwitch->addCase(CONST_V<2>(b, 0), block_single_precision);
    pcSwitch->addCase(CONST_V<2>(b, 2), block_double_precision);
    pcSwitch->addCase(CONST_V<2>(b, 3), block_native_precision);

    // Populate native block - no adjustment needed.
    BranchInst::Create(block_done_adjusting, block_native_precision);

    // Populate single precision - convert to single precision type,
    // convert back to native precision, return.
    Value *singlep = new FPTruncInst(fpuval, 
        llvm::Type::getFloatTy(block_single_precision->getContext()), 
        "", block_single_precision);
    Value *single_ton = new FPExtInst(singlep,
        llvm::Type::getX86_FP80Ty(block_single_precision->getContext()), 
        "", block_single_precision);
    BranchInst::Create(block_done_adjusting, block_single_precision);

    // Populate double precision - convert to double and then back to native.
    Value *doublep = new FPTruncInst(fpuval, 
        llvm::Type::getDoubleTy(block_double_precision->getContext()), 
        "", block_double_precision);
    Value *double_ton = new FPExtInst(doublep,
        llvm::Type::getX86_FP80Ty(block_double_precision->getContext()), 
        "", block_double_precision);
    BranchInst::Create(block_done_adjusting, block_double_precision);

    // Populate done_adjusting block.
    PHINode *adjustedVal =
        PHINode::Create(Type::getX86_FP80Ty(block_done_adjusting->getContext()),
                        3,
                        "fpu_precision_adjust",
                        block_done_adjusting);

    adjustedVal->addIncoming(fpuval, block_native_precision);
    adjustedVal->addIncoming(single_ton, block_single_precision);
    adjustedVal->addIncoming(double_ton, block_double_precision);

    b = block_done_adjusting;
    return adjustedVal;
}
开发者ID:Sineaggi,项目名称:mcsema,代码行数:60,代码来源:x86Instrs_fpu.cpp

示例3: visitSwitchInst

/*
 * Instrument switch instructions to log the index of the taken branch.
 */
void PandaInstrumentVisitor::visitSwitchInst(SwitchInst &I){
    SExtInst *SEI;
    CallInst *CI;
    std::vector<Value*> argValues;
    Function *F = mod->getFunction("log_dynval");
    if (!F) {
        printf("Instrumentation function not found\n");
        assert(1==0);
    }
    if (I.getCondition()->getType() != wordType){
        SEI = static_cast<SExtInst*>(IRB.CreateSExt(I.getCondition(), wordType));
        argValues.push_back(ConstantInt::get(ptrType, (uintptr_t)dynval_buffer));
        argValues.push_back(ConstantInt::get(intType, SWITCHENTRY));
        argValues.push_back(ConstantInt::get(intType, SWITCH));
        argValues.push_back(static_cast<Value*>(SEI));
        CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
        CI->insertBefore(static_cast<Instruction*>(&I));
        SEI->insertBefore(static_cast<Instruction*>(CI));
    }
    else {
        argValues.push_back(ConstantInt::get(ptrType, (uintptr_t)dynval_buffer));
        argValues.push_back(ConstantInt::get(intType, SWITCHENTRY));
        argValues.push_back(ConstantInt::get(intType, SWITCH));
        argValues.push_back(static_cast<Value*>(I.getCondition()));
        CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
        CI->insertBefore(static_cast<Instruction*>(&I));
    }
}
开发者ID:idkwim,项目名称:panda,代码行数:31,代码来源:panda_dynval_inst.cpp

示例4: visitSwitchInst

bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
  // We model unconditional switches as free, see the comments on handling
  // branches.
  return isa<ConstantInt>(SI.getCondition()) ||
         dyn_cast_or_null<ConstantInt>(
             SimplifiedValues.lookup(SI.getCondition()));
}
开发者ID:adevress,项目名称:root-1,代码行数:7,代码来源:InlineCost.cpp

示例5: doJumpIndexTableViaSwitch

void doJumpIndexTableViaSwitch(
        BasicBlock *&block, 
        InstPtr ip)
{
    Function *F = block->getParent();
    Module *M = F->getParent();
    // we know this conforms to
    // movzx reg32, [base+disp]

    // sanity check
    const MCInst &inst = ip->get_inst();
    const MCOperand& dest = OP(0);
    const MCOperand& base = OP(1);

    TASSERT(base.isReg(), "Conformant jump index tables need base to be a register");
    TASSERT(dest.isReg(), "Conformant jump index tables need to write to a register");

    JumpIndexTablePtr idxptr = ip->get_jump_index_table();

    // to ensure no negative entries
    Value *adjustment = CONST_V<32>(block, idxptr->getInitialEntry());
    Value *reg_val = R_READ<32>(block, base.getReg());
    Value *real_index = 
        BinaryOperator::Create(Instruction::Add, adjustment, reg_val, "", block);
   
    BasicBlock *continueBlock = 
        BasicBlock::Create(block->getContext(), "", F, 0);

    // create a default block that just traps
    BasicBlock *defaultBlock = 
        BasicBlock::Create(block->getContext(), "", F, 0);
    Function *trapFn = Intrinsic::getDeclaration(M, Intrinsic::trap);
    CallInst::Create(trapFn, "", defaultBlock);
    BranchInst::Create(continueBlock, defaultBlock);
    // end default block

    const std::vector<uint8_t> &idxblocks = idxptr->getJumpIndexTable();


    // create a switch inst
    SwitchInst *theSwitch = SwitchInst::Create(
            real_index, 
            defaultBlock,
            idxblocks.size(),
            block);

    // populate switch
    int myindex = 0;
    for(std::vector<uint8_t>::const_iterator itr = idxblocks.begin();
        itr != idxblocks.end();
        itr++) 
    {
        BasicBlock *writeBl = emitJumpIndexWrite(F, *itr, dest.getReg(), continueBlock );
        theSwitch->addCase(CONST_V<32>(block, myindex), writeBl);
        ++myindex;
    }

    // new block to write to is continue block
    block = continueBlock;
}
开发者ID:Sineaggi,项目名称:mcsema,代码行数:60,代码来源:JumpTables.cpp

示例6: visitSwitchInst

bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
  // We model unconditional switches as free, see the comments on handling
  // branches.
  if (isa<ConstantInt>(SI.getCondition()))
    return true;
  if (Value *V = SimplifiedValues.lookup(SI.getCondition()))
    if (isa<ConstantInt>(V))
      return true;

  // Otherwise, we need to accumulate a cost proportional to the number of
  // distinct successor blocks. This fan-out in the CFG cannot be represented
  // for free even if we can represent the core switch as a jumptable that
  // takes a single instruction.
  //
  // NB: We convert large switches which are just used to initialize large phi
  // nodes to lookup tables instead in simplify-cfg, so this shouldn't prevent
  // inlining those. It will prevent inlining in cases where the optimization
  // does not (yet) fire.
  SmallPtrSet<BasicBlock *, 8> SuccessorBlocks;
  SuccessorBlocks.insert(SI.getDefaultDest());
  for (auto I = SI.case_begin(), E = SI.case_end(); I != E; ++I)
    SuccessorBlocks.insert(I.getCaseSuccessor());
  // Add cost corresponding to the number of distinct destinations. The first
  // we model as free because of fallthrough.
  Cost += (SuccessorBlocks.size() - 1) * InlineConstants::InstrCost;
  return false;
}
开发者ID:A2-Collaboration,项目名称:root,代码行数:27,代码来源:InlineCost.cpp

示例7: doJumpTableViaSwitch

void doJumpTableViaSwitch(
        NativeModulePtr natM, 
        BasicBlock *& block, 
        InstPtr ip, 
        MCInst &inst)
{

    llvm::dbgs() << __FUNCTION__ << ": Doing jumpt table via switch\n";
    Function *F = block->getParent();
    Module *M = F->getParent();
    // we know this conforms to
    // jmp [reg*4+displacement]

    // sanity check
    const MCOperand& scale = OP(1);
    const MCOperand& index = OP(2);

    TASSERT(index.isReg(), "Conformant jump tables need index to be a register");
    TASSERT(scale.isImm() && scale.getImm() == 4, "Conformant jump tables have scale == 4");

    MCSJumpTablePtr jmpptr = ip->get_jump_table();

    // to ensure no negative entries
    Value *adjustment = CONST_V<32>(block, jmpptr->getInitialEntry());
    Value *reg_val = R_READ<32>(block, index.getReg());
    Value *real_index = 
        BinaryOperator::Create(Instruction::Add, adjustment, reg_val, "", block);
   
    // create a default block that just traps
    BasicBlock *defaultBlock = 
        BasicBlock::Create(block->getContext(), "", block->getParent(), 0);
    Function *trapFn = Intrinsic::getDeclaration(M, Intrinsic::trap);
    CallInst::Create(trapFn, "", defaultBlock);
    ReturnInst::Create(defaultBlock->getContext(), defaultBlock);
    // end default block

    const std::vector<VA> &jmpblocks = jmpptr->getJumpTable();

    // create a switch inst
    SwitchInst *theSwitch = SwitchInst::Create(
            real_index, 
            defaultBlock,
            jmpblocks.size(),
            block);

    // populate switch
    int myindex = 0;
    for(std::vector<VA>::const_iterator itr = jmpblocks.begin();
        itr != jmpblocks.end();
        itr++) 
    {
        std::string  bbname = "block_0x"+to_string<VA>(*itr, std::hex);
        BasicBlock *toBlock = bbFromStrName(bbname, F);
        TASSERT(toBlock != NULL, "Could not find block: "+bbname);
        theSwitch->addCase(CONST_V<32>(block, myindex), toBlock);
        ++myindex;
    }

}
开发者ID:IDA-RE-things,项目名称:mcsema,代码行数:59,代码来源:JumpTables.cpp

示例8: assert

void cgs_sisd::switch_to( multi_value const& cond, std::vector< std::pair<multi_value, insert_point_t> > const& cases, insert_point_t const& default_branch )
{
	assert(parallel_factor_ == 1);
	Value* v = cond.load()[0];
	SwitchInst* inst = builder().CreateSwitch( v, default_branch.block, static_cast<unsigned>(cases.size()) );
	for( size_t i_case = 0; i_case < cases.size(); ++i_case ){
		inst->addCase( llvm::cast<ConstantInt>( cases[i_case].first.load()[0] ), cases[i_case].second.block );
	}
}
开发者ID:,项目名称:,代码行数:9,代码来源:

示例9: LLVM_General_GetSwitchCases

void LLVM_General_GetSwitchCases(
	LLVMValueRef v,
	LLVMValueRef *values,
	LLVMBasicBlockRef *dests
) {
	SwitchInst *s = unwrap<SwitchInst>(v);
	for(SwitchInst::CaseIt i = s->case_begin(); i != s->case_end(); ++i, ++values, ++dests) {
		*values = wrap(i.getCaseValue());
		*dests = wrap(i.getCaseSuccessor());
	}
}
开发者ID:B-Rich,项目名称:llvm-general,代码行数:11,代码来源:InstructionC.cpp

示例10: LoadInst

Function* PrepareCSI::switchIndirect(Function* F, GlobalVariable* switcher,
                                     vector<Function*>& replicas){
  F->dropAllReferences();
  
  BasicBlock* newEntry = BasicBlock::Create(*Context, "newEntry", F);
  vector<Value*> callArgs;
  for(Function::arg_iterator k = F->arg_begin(), ke = F->arg_end(); k != ke; ++k)
    callArgs.push_back(k);
  
  // set up the switch
  LoadInst* whichCall = new LoadInst(switcher, "chooseCall", true, newEntry);
  SwitchInst* callSwitch = NULL;
  
  // stuff we need
  IntegerType* tInt = Type::getInt32Ty(*Context);

  // create one bb for each possible call (instrumentation scheme)
  bool aZero = false;
  for(unsigned int i = 0; i < replicas.size(); ++i){
    Function* newF = replicas[i];
    BasicBlock* bb = BasicBlock::Create(*Context, "call", F);
    if(callSwitch == NULL){
      callSwitch = SwitchInst::Create(whichCall, bb, replicas.size(),
                                      newEntry);
    }
    string funcName = newF->getName().str();

    if(funcName.length() > 5 &&
       funcName.substr(funcName.length()-5, 5) == "$none"){
      callSwitch->addCase(ConstantInt::get(tInt, 0), bb);
      if(aZero)
        report_fatal_error("multiple defaults for function '" +
                           F->getName() + "'");
      aZero = true;
    }
    else
      callSwitch->addCase(ConstantInt::get(tInt, i+1), bb);

    CallInst* oneCall = CallInst::Create(newF, callArgs,
       (F->getReturnType()->isVoidTy()) ? "" : "theCall", bb);
    oneCall->setTailCall(true);
    if(F->getReturnType()->isVoidTy())
      ReturnInst::Create(*Context, bb);
    else
      ReturnInst::Create(*Context, oneCall, bb);
  }
  // note that we intentionally started numbering the cases from 1 so that the
  // zero case is reserved for the uninstrumented variant (if there is one)
  if(!aZero)
    switcher->setInitializer(ConstantInt::get(tInt, 1));

  return(F);
}
开发者ID:chubbymaggie,项目名称:csi-cc,代码行数:53,代码来源:PrepareCSI.cpp

示例11: expandCaseRange

/// expandCaseRange - Expand case range into explicit case values within the
/// range
bool WriteBitcodePass::expandCaseRange(Function &F) {
  bool Changed = false;

  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
    SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator());
    if (SI == NULL) {
      continue;
    }

    for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
         i != e; ++i) {
      IntegersSubset& CaseRanges = i.getCaseValueEx();

      // All case ranges are already in single case values
      if (CaseRanges.isSingleNumbersOnly()) {
        continue;
      }

      // Create a new case
      Type *IntTy = SI->getCondition()->getType();
      IntegersSubsetToBB CaseBuilder;
      Changed = true;

      for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) {
        IntegersSubset::Range r = CaseRanges.getItem(ri);
        bool IsSingleNumber = CaseRanges.isSingleNumber(ri);

        if (IsSingleNumber) {
          CaseBuilder.add(r);
        } else {
          const APInt &Low = r.getLow();
          const APInt &High = r.getHigh();

          for (APInt V = Low; V != High; V++) {
            assert(r.isInRange(V) && "Unexpected out-of-range case value!");
            CaseBuilder.add(IntItem::fromType(IntTy, V));
          }
        }

        IntegersSubset Case = CaseBuilder.getCase();
        i.setValueEx(Case);
      }
    }
  }
  return Changed;
}
开发者ID:Proshivalskiy,项目名称:MT6582_kernel_source,代码行数:48,代码来源:BitcodeWriterPass.cpp

示例12: fread

void TestInstVisitor::visitSwitchInst(SwitchInst &I){
    if (except){
        return;
    }

    DynValEntry entry;
    size_t n = fread(&entry, sizeof(DynValEntry), 1, dlog);
    if (entry.entrytype == EXCEPTIONENTRY){
        except = true;
        return;
    }
    assert(entry.entrytype == SWITCHENTRY);
    //printf("switch %d\n", entry.entry.switchstmt.cond);
    IntegerType *intType = IntegerType::get(getGlobalContext(), sizeof(int)*8);
    ConstantInt *caseVal =
        ConstantInt::get(intType, entry.entry.switchstmt.cond);
    SwitchInst::CaseIt caseIndex = I.findCaseValue(caseVal);
    TFP->setNextBB(I.getSuccessor(caseIndex.getSuccessorIndex()));
}
开发者ID:3a9LL,项目名称:panda,代码行数:19,代码来源:llvm_trace_test.cpp

示例13: doJumpTableViaSwitchReg

void doJumpTableViaSwitchReg(
        BasicBlock *& block, 
        InstPtr ip, 
        Value *regVal,
        BasicBlock *&default_block)
{

    llvm::dbgs() << __FUNCTION__ << ": Doing jumpt table via switch(reg)\n";
    Function *F = block->getParent();
    Module *M = F->getParent();
    

    MCSJumpTablePtr jmpptr = ip->get_jump_table();

    // create a default block that just traps
    default_block = 
        BasicBlock::Create(block->getContext(), "", block->getParent(), 0);
    // end default block

    const std::vector<VA> &jmpblocks = jmpptr->getJumpTable();
    std::unordered_set<VA> uniq_blocks(jmpblocks.begin(), jmpblocks.end());

    // create a switch inst
    SwitchInst *theSwitch = SwitchInst::Create(
            regVal, 
            default_block,
            uniq_blocks.size(),
            block);

    // populate switch
    for(auto blockVA : uniq_blocks) 
    {
        std::string  bbname = "block_0x"+to_string<VA>(blockVA, std::hex);
        BasicBlock *toBlock = bbFromStrName(bbname, F);
        llvm::dbgs() << __FUNCTION__ << ": Mapping from " << to_string<VA>(blockVA, std::hex) << " => " << bbname << "\n";
        TASSERT(toBlock != NULL, "Could not find block: "+bbname);
        theSwitch->addCase(CONST_V<32>(block, blockVA), toBlock);
    }

}
开发者ID:IDA-RE-things,项目名称:mcsema,代码行数:40,代码来源:JumpTables.cpp

示例14: visitSwitchInst

void Interpreter::visitSwitchInst(SwitchInst &I) {
  ExecutionContext &SF = ECStack.back();
  GenericValue CondVal = getOperandValue(I.getOperand(0), SF);
  const Type *ElTy = I.getOperand(0)->getType();

  // Check to see if any of the cases match...
  BasicBlock *Dest = 0;
  for (unsigned i = 2, e = I.getNumOperands(); i != e; i += 2)
    if (executeSetEQInst(CondVal,
                         getOperandValue(I.getOperand(i), SF), ElTy).BoolVal) {
      Dest = cast<BasicBlock>(I.getOperand(i+1));
      break;
    }
  
  if (!Dest) Dest = I.getDefaultDest();   // No cases matched: use default
  SwitchToNewBasicBlock(Dest, SF);
}
开发者ID:chris-wood,项目名称:llvm-pgopre,代码行数:17,代码来源:Execution.cpp

示例15: Assert

Value* LoopTripCount::insertTripCount(Loop* L, Instruction* InsertPos)
{
	// inspired from Loop::getCanonicalInductionVariable
	BasicBlock *H = L->getHeader();
	BasicBlock* LoopPred = L->getLoopPredecessor();
	BasicBlock* startBB = NULL;//which basicblock stores start value
	int OneStep = 0;// the extra add or plus step for calc

   Assert(LoopPred, "Require Loop has a Pred");
	DEBUG(errs()<<"loop  depth:"<<L->getLoopDepth()<<"\n");
	/** whats difference on use of predecessor and preheader??*/
	//RET_ON_FAIL(self->getLoopLatch()&&self->getLoopPreheader());
	//assert(self->getLoopLatch() && self->getLoopPreheader() && "need loop simplify form" );
	ret_null_fail(L->getLoopLatch(), "need loop simplify form");

	BasicBlock* TE = NULL;//True Exit
	SmallVector<BasicBlock*,4> Exits;
	L->getExitingBlocks(Exits);

	if(Exits.size()==1) TE = Exits.front();
	else{
		if(std::find(Exits.begin(),Exits.end(),L->getLoopLatch())!=Exits.end()) TE = L->getLoopLatch();
		else{
			SmallVector<llvm::Loop::Edge,4> ExitEdges;
			L->getExitEdges(ExitEdges);
			//stl 用法,先把所有满足条件的元素(出口的结束符是不可到达)移动到数组的末尾,再统一删除
			ExitEdges.erase(std::remove_if(ExitEdges.begin(), ExitEdges.end(), 
						[](llvm::Loop::Edge& I){
						return isa<UnreachableInst>(I.second->getTerminator());
						}), ExitEdges.end());
			if(ExitEdges.size()==1) TE = const_cast<BasicBlock*>(ExitEdges.front().first);
		}
	}

	//process true exit
	ret_null_fail(TE, "need have a true exit");

	Instruction* IndOrNext = NULL;
	Value* END = NULL;
   //终止块的终止指令:分情况讨论branchinst,switchinst;
   //跳转指令br bool a1,a2;condition<-->bool
	if(isa<BranchInst>(TE->getTerminator())){
		const BranchInst* EBR = cast<BranchInst>(TE->getTerminator());
		Assert(EBR->isConditional(), "end branch is not conditional");
		ICmpInst* EC = dyn_cast<ICmpInst>(EBR->getCondition());
		if(EC->getPredicate() == EC->ICMP_SGT){
         Assert(!L->contains(EBR->getSuccessor(0)), *EBR<<":abnormal exit with great than");//终止块的终止指令---->跳出执行循环外的指令
         OneStep += 1;
      } else if(EC->getPredicate() == EC->ICMP_EQ)
         Assert(!L->contains(EBR->getSuccessor(0)), *EBR<<":abnormal exit with great than");
      else if(EC->getPredicate() == EC->ICMP_SLT) {
         ret_null_fail(!L->contains(EBR->getSuccessor(1)), *EBR<<":abnormal exit with less than");
      } else {
         ret_null_fail(0, *EC<<" unknow combination of end condition");
      }
		IndOrNext = dyn_cast<Instruction>(castoff(EC->getOperand(0)));//去掉类型转化
		END = EC->getOperand(1);
		DEBUG(errs()<<"end   value:"<<*EC<<"\n");
	}else if(isa<SwitchInst>(TE->getTerminator())){
		SwitchInst* ESW = const_cast<SwitchInst*>(cast<SwitchInst>(TE->getTerminator()));
		IndOrNext = dyn_cast<Instruction>(castoff(ESW->getCondition()));
		for(auto I = ESW->case_begin(),E = ESW->case_end();I!=E;++I){
			if(!L->contains(I.getCaseSuccessor())){
				ret_null_fail(!END,"");
				assert(!END && "shouldn't have two ends");
				END = I.getCaseValue();
			}
		}
		DEBUG(errs()<<"end   value:"<<*ESW<<"\n");
	}else{
		assert(0 && "unknow terminator type");
	}

	ret_null_fail(L->isLoopInvariant(END), "end value should be loop invariant");//至此得END值

	Value* start = NULL;
	Value* ind = NULL;
	Instruction* next = NULL;
	bool addfirst = false;//add before icmp ed

	DISABLE(errs()<<*IndOrNext<<"\n");
	if(isa<LoadInst>(IndOrNext)){
		//memory depend analysis
		Value* PSi = IndOrNext->getOperand(0);//point type Step.i

		int SICount[2] = {0};//store in predecessor count,store in loop body count
		for( auto I = PSi->use_begin(),E = PSi->use_end();I!=E;++I){
			DISABLE(errs()<<**I<<"\n");
			StoreInst* SI = dyn_cast<StoreInst>(*I);
			if(!SI || SI->getOperand(1) != PSi) continue;
			if(!start&&L->isLoopInvariant(SI->getOperand(0))) {
				if(SI->getParent() != LoopPred)
					if(std::find(pred_begin(LoopPred),pred_end(LoopPred),SI->getParent()) == pred_end(LoopPred)) continue;
				start = SI->getOperand(0);
				startBB = SI->getParent();
				++SICount[0];
			}
			Instruction* SI0 = dyn_cast<Instruction>(SI->getOperand(0));
			if(L->contains(SI) && SI0 && SI0->getOpcode() == Instruction::Add){
				next = SI0;
//.........这里部分代码省略.........
开发者ID:royqin,项目名称:llvm-pred,代码行数:101,代码来源:LoopTripCount.cpp


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