Ejemplo n.º 1
0
/// 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;
  }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
/*
 * 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));
    }
}
Ejemplo n.º 4
0
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()));
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
    }

}
Ejemplo n.º 8
0
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 );
	}
}
Ejemplo n.º 9
0
void CfgCodeSelector::genSwitchEdges(U_32 tailNodeId, U_32 numTargets, 
                                        U_32 *targets, double *probs, 
                                        U_32 defaultTarget) 
{
    // 
    //  Switch structure:
    //                              
    //      origBlock                                       switchBlock
    //     ===========                  Fallthrough        =============          
    //        ....                       =======>            .......
    //      if (switchVar >= numTargets)                    swTarget= jmp [switchVar + swTableBase]  
    //         jmp defaultTarget                            
    //  
    Node * origBlock = nodes[tailNodeId];
    const Edges& outEdges=origBlock->getOutEdges();
    assert(outEdges.size() == 1);
    Node * switchBlock= outEdges.front()->getTargetNode();
    assert(switchBlock->isBlockNode());
    assert(((Inst*)switchBlock->getLastInst())->hasKind(Inst::Kind_SwitchInst));
    SwitchInst * swInst = (SwitchInst *)switchBlock->getLastInst();

    double    defaultEdgeProb = 1.0;
    defaultEdgeProb = 1.0;
    for (U_32 i = 0; i < numTargets; i++) {
        U_32 targetId = targets[i];
        if ( targetId == defaultTarget) {
            defaultEdgeProb = probs[i];
            break;
        }
        if (std::find(targets, targets+i, targetId)!=targets+i) {
            continue; //repeated target
        }
        if (probs[i] < 0) {
            defaultEdgeProb = 0;
            break;
        } 
        defaultEdgeProb -= 1.0/(numTargets+1);
    }

    genTrueEdge(tailNodeId, defaultTarget, defaultEdgeProb);

    //  Fix probability of fallthrough edge
    if (defaultEdgeProb!=0) {
        origBlock->getOutEdges().front()->setEdgeProb(1.0 - defaultEdgeProb);
    }
    //  Generate edges from switchBlock to switch targets
    for (U_32 i = 0; i < numTargets; i++) {
        Node * targetNode = nodes[targets[i]];
        // Avoid generating duplicate edges. Jump table however needs all entries
        if (! switchBlock->isConnectedTo(true, targetNode)) {
            irManager.getFlowGraph()->addEdge(switchBlock, targetNode, probs[i]);
        }
        swInst->setTarget(i, targetNode);
    }
}
Ejemplo n.º 10
0
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());
	}
}
Ejemplo n.º 11
0
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);
}
/// 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;
}
Ejemplo n.º 13
0
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()));
}
Ejemplo n.º 14
0
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);
    }

}
Ejemplo n.º 15
0
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);
}
Ejemplo n.º 16
0
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;
				++SICount[1];
			}

		}
		Assert(SICount[0]==1 && SICount[1]==1, "");
		ind = IndOrNext;
	}else{
		if(isa<PHINode>(IndOrNext)){
			PHINode* PHI = cast<PHINode>(IndOrNext);
			ind = IndOrNext;
			if(castoff(PHI->getIncomingValue(0)) == castoff(PHI->getIncomingValue(1)) && PHI->getParent() != H)
				ind = castoff(PHI->getIncomingValue(0));
			addfirst = false;
		}else if(IndOrNext->getOpcode() == Instruction::Add){
			next = IndOrNext;
			addfirst = true;
		}else{
			Assert(0 ,"unknow how to analysis");
		}

		for(auto I = H->begin();isa<PHINode>(I);++I){
			PHINode* P = cast<PHINode>(I);
			if(ind && P == ind){
				//start = P->getIncomingValueForBlock(L->getLoopPredecessor());
				start = tryFindStart(P, L, startBB);
				next = dyn_cast<Instruction>(P->getIncomingValueForBlock(L->getLoopLatch()));
			}else if(next && P->getIncomingValueForBlock(L->getLoopLatch()) == next){
				//start = P->getIncomingValueForBlock(L->getLoopPredecessor());
				start = tryFindStart(P, L, startBB);
				ind = P;
			}
		}
	}


	Assert(start ,"couldn't find a start value");
	//process complex loops later
	//DEBUG(if(L->getLoopDepth()>1 || !L->getSubLoops().empty()) return NULL);
	DEBUG(errs()<<"start value:"<<*start<<"\n");
	DEBUG(errs()<<"ind   value:"<<*ind<<"\n");
	DEBUG(errs()<<"next  value:"<<*next<<"\n");


	//process non add later
	unsigned next_phi_idx = 0;
	ConstantInt* Step = NULL,*PrevStep = NULL;/*only used if next is phi node*/
   ret_null_fail(next, "");
	PHINode* next_phi = dyn_cast<PHINode>(next);
	do{
		if(next_phi) {
			next = dyn_cast<Instruction>(next_phi->getIncomingValue(next_phi_idx));
			ret_null_fail(next, "");
			DEBUG(errs()<<"next phi "<<next_phi_idx<<":"<<*next<<"\n");
			if(Step&&PrevStep){
				Assert(Step->getSExtValue() == PrevStep->getSExtValue(),"");
			}
			PrevStep = Step;
		}
		Assert(next->getOpcode() == Instruction::Add , "why induction increment is not Add");
		Assert(next->getOperand(0) == ind ,"why induction increment is not add it self");
		Step = dyn_cast<ConstantInt>(next->getOperand(1));
		Assert(Step,"");
	}while(next_phi && ++next_phi_idx<next_phi->getNumIncomingValues());
	//RET_ON_FAIL(Step->equalsInt(1));
	//assert(VERBOSE(Step->equalsInt(1),Step) && "why induction increment number is not 1");


	Value* RES = NULL;
	//if there are no predecessor, we can insert code into start value basicblock
	IRBuilder<> Builder(InsertPos);
	Assert(start->getType()->isIntegerTy() && END->getType()->isIntegerTy() , " why increment is not integer type");
	if(start->getType() != END->getType()){
		start = Builder.CreateCast(CastInst::getCastOpcode(start, false,
					END->getType(), false),start,END->getType());
	}
   if(Step->getType() != END->getType()){
      //Because Step is a Constant, so it casted is constant
		Step = dyn_cast<ConstantInt>(Builder.CreateCast(CastInst::getCastOpcode(Step, false,
					END->getType(), false),Step,END->getType()));
      AssertRuntime(Step);
   }
	if(Step->isMinusOne())
		RES = Builder.CreateSub(start,END);
	else//Step Couldn't be zero
		RES = Builder.CreateSub(END, start);
	if(addfirst) OneStep -= 1;
	if(Step->isMinusOne()) OneStep*=-1;
	assert(OneStep<=1 && OneStep>=-1);
	RES = (OneStep==1)?Builder.CreateAdd(RES,Step):(OneStep==-1)?Builder.CreateSub(RES, Step):RES;
	if(!Step->isMinusOne()&&!Step->isOne())
		RES = Builder.CreateSDiv(RES, Step);
	RES->setName(H->getName()+".tc");

	return RES;
}
Ejemplo n.º 17
0
/// buildCFICheck - emits __cfi_check for the current module.
void CrossDSOCFI::buildCFICheck(Module &M) {
  // FIXME: verify that __cfi_check ends up near the end of the code section,
  // but before the jump slots created in LowerTypeTests.
  llvm::DenseSet<uint64_t> TypeIds;
  SmallVector<MDNode *, 2> Types;
  for (GlobalObject &GO : M.global_objects()) {
    Types.clear();
    GO.getMetadata(LLVMContext::MD_type, Types);
    for (MDNode *Type : Types) {
      // Sanity check. GO must not be a function declaration.
      assert(!isa<Function>(&GO) || !cast<Function>(&GO)->isDeclaration());

      if (ConstantInt *TypeId = extractNumericTypeId(Type))
        TypeIds.insert(TypeId->getZExtValue());
    }
  }

  LLVMContext &Ctx = M.getContext();
  Constant *C = M.getOrInsertFunction(
      "__cfi_check", Type::getVoidTy(Ctx), Type::getInt64Ty(Ctx),
      Type::getInt8PtrTy(Ctx), Type::getInt8PtrTy(Ctx), nullptr);
  Function *F = dyn_cast<Function>(C);
  F->setAlignment(4096);
  auto args = F->arg_begin();
  Value &CallSiteTypeId = *(args++);
  CallSiteTypeId.setName("CallSiteTypeId");
  Value &Addr = *(args++);
  Addr.setName("Addr");
  Value &CFICheckFailData = *(args++);
  CFICheckFailData.setName("CFICheckFailData");
  assert(args == F->arg_end());

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

  BasicBlock *TrapBB = BasicBlock::Create(Ctx, "fail", F);
  IRBuilder<> IRBFail(TrapBB);
  Constant *CFICheckFailFn = M.getOrInsertFunction(
      "__cfi_check_fail", Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx),
      Type::getInt8PtrTy(Ctx), nullptr);
  IRBFail.CreateCall(CFICheckFailFn, {&CFICheckFailData, &Addr});
  IRBFail.CreateBr(ExitBB);

  IRBuilder<> IRBExit(ExitBB);
  IRBExit.CreateRetVoid();

  IRBuilder<> IRB(BB);
  SwitchInst *SI = IRB.CreateSwitch(&CallSiteTypeId, TrapBB, TypeIds.size());
  for (uint64_t TypeId : TypeIds) {
    ConstantInt *CaseTypeId = ConstantInt::get(Type::getInt64Ty(Ctx), TypeId);
    BasicBlock *TestBB = BasicBlock::Create(Ctx, "test", F);
    IRBuilder<> IRBTest(TestBB);
    Function *BitsetTestFn = Intrinsic::getDeclaration(&M, Intrinsic::type_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);
    ++NumTypeIds;
  }
}
Ejemplo n.º 18
0
void vSSA::createSigmasIfNeeded(BasicBlock *BB)
{
	TerminatorInst *ti = BB->getTerminator();
	// If the condition used in the terminator instruction is a Comparison instruction:
	//for each operand of the CmpInst, create sigmas, depending on some conditions
	/*
	if(isa<BranchInst>(ti)){
		BranchInst * bc = cast<BranchInst>(ti);
		if(bc->isConditional()){
			Value * cond = bc->getCondition();
			CmpInst *comparison = dyn_cast<CmpInst>(cond);
			for (User::const_op_iterator it = comparison->op_begin(), e = comparison->op_end(); it != e; ++it) {
				Value *operand = *it;
				if (isa<Instruction>(operand) || isa<Argument>(operand)) {
					insertSigmas(ti, operand);
				}
			}
		}
	}
	*/
	
	// CASE 1: Branch Instruction
	BranchInst *bi = NULL;
	SwitchInst *si = NULL;
	if ((bi = dyn_cast<BranchInst>(ti))) {
		if (bi->isConditional()) {
			Value *condition = bi->getCondition();
			
			ICmpInst *comparison = dyn_cast<ICmpInst>(condition);
			
			if (comparison) {
				// Create sigmas for ICmp operands
				for (User::const_op_iterator opit = comparison->op_begin(), opend = comparison->op_end(); opit != opend; ++opit) {
					Value *operand = *opit;
					
					if (isa<Instruction>(operand) || isa<Argument>(operand)) {
						insertSigmas(ti, operand);
						
						// If the operand is a result of a indirect instruction (e.g. ZExt, SExt, Trunc),
						// Create sigmas for the operands of the operands too
						CastInst *cinst = NULL;
						if ((cinst = dyn_cast<CastInst>(operand))) {
							insertSigmas(ti, cinst->getOperand(0));
						}
					}
				}
			}
		}
	}
	// CASE 2: Switch Instruction
	
	else if ((si = dyn_cast<SwitchInst>(ti))) {
		Value *condition = si->getCondition();
		
		if (isa<Instruction>(condition) || isa<Argument>(condition)) {
			insertSigmas(ti, condition);
			
			// If the operand is a result of a indirect instruction (e.g. ZExt, SExt, Trunc),
			// Create sigmas for the operands of the operands too
			CastInst *cinst = NULL;
			if ((cinst = dyn_cast<CastInst>(condition))) {
				insertSigmas(ti, cinst->getOperand(0));
			}
		}
	}
	
}
Ejemplo n.º 19
0
Node * JavaFlowGraphBuilder::edgesForBlock(Node* block) {
    //
    // find if this block has any region that could catch the exception
    //
    Node *dispatch = NULL;
    ExceptionInfo *exceptionInfo = (CatchBlock*)((LabelInst*)block->getFirstInst())->getState();
    if (exceptionInfo != NULL) {
        dispatch = exceptionInfo->getLabelInst()->getNode();
    }else{
        dispatch = fg->getUnwindNode();
    }
    assert(dispatch->isDispatchNode());

    //
    // split the block so that 
    //      each potentially-exceptional instruction ends a block
    //
    Inst* first = (Inst*)block->getFirstInst();
    Inst* last = (Inst*)block->getLastInst();
    Inst* lastExceptionalInstSeen = NULL;
    for (Inst* inst = first->getNextInst(); inst != NULL; inst = inst->getNextInst()) {
        if (lastExceptionalInstSeen != NULL) {
            // start a new basic block
            LabelInst* label = irBuilder.getInstFactory()->makeLabel();
            Node *newblock = createBlockNodeAfter(block, label); 
            uint16 bcOffset = ILLEGAL_BC_MAPPING_VALUE;
            for (Inst *ins = lastExceptionalInstSeen->getNextInst(), *nextIns = NULL; ins!=NULL; ins = nextIns) {
                nextIns = ins->getNextInst();
                ins->unlink();
                newblock->appendInst(ins);
                if (bcOffset == ILLEGAL_BC_MAPPING_VALUE) {
                    bcOffset = ins->getBCOffset();
                }
            }
            label->setBCOffset(bcOffset);

            // now fix up the CFG, duplicating edges
            if (!lastExceptionalInstSeen->isThrow())
                fg->addEdge(block,newblock);
            //
            // add an edge to handler entry node
            //
            assert(!block->findTargetEdge(dispatch));
            fg->addEdge(block,dispatch);
            block = newblock;
            lastExceptionalInstSeen = NULL;
        } 
        if (inst->getOperation().canThrow()) {
            lastExceptionalInstSeen = inst;
        }
    }

    // 
    // examine the last instruction and create appropriate CFG edges
    //
    switch(last->getOpcode()) {
    case Op_Jump:
        {
        fg->addEdge(block,((BranchInst*)last)->getTargetLabel()->getNode());
        last->unlink();
        }
        break;
    case Op_Branch:
    case Op_JSR:
        addEdge(block, ((BranchInst*)last)->getTargetLabel()->getNode());
        edgeForFallthrough(block);
        break;
    case Op_Throw:
    case Op_ThrowSystemException:
    case Op_ThrowLinkingException:
        // throw/rethrow creates an edge to a handler that catches the exception
        assert(dispatch != NULL);
        assert(lastExceptionalInstSeen == last);
        break;
    case Op_Return:
        addEdge(block, fg->getReturnNode());
        break;
    case Op_Ret:
        break; // do  not do anything
    case Op_Switch:
        {
            SwitchInst *sw = (SwitchInst*)last;
            U_32 num = sw->getNumTargets();
            for (U_32 i = 0; i < num; i++) {
                Node* target = sw->getTarget(i)->getNode();
                // two switch values may go to the same block
                if (!block->findTargetEdge(target)) {
                    fg->addEdge(block,target);
                }
            }
            Node* target = sw->getDefaultTarget()->getNode();
            if (!block->findTargetEdge(target)) {
                fg->addEdge(block,target);
            }
        }
        break;
    default:;
        if (block != fg->getReturnNode()) { // a fallthrough edge is needed
           // if the basic block does not have any outgoing edge, add one fall through edge
           if (block->getOutEdges().empty())
               edgeForFallthrough(block);
        }
    }
    //
    // add an edge to handler entry node
    //
    if (lastExceptionalInstSeen != NULL)
        addEdge(block,dispatch);
    return block;
}
Ejemplo n.º 20
0
static BasicBlock *doCmpsV(BasicBlock *pred) {
    Value   *lhsRegVal = R_READ<32>(pred, X86::ESI);
    Value   *lhsFromMem = M_READ_0<width>(pred, lhsRegVal);

    Value   *rhsRegVal = R_READ<32>(pred, X86::EDI);
    Value   *rhsFromMem = M_READ_0<width>(pred, rhsRegVal);

    //perform a subtraction
    Value   *res = BinaryOperator::CreateSub(lhsFromMem, rhsFromMem, "", pred);

    //set flags according to this result
    WritePF<width>(pred, res);
    WriteZF<width>(pred, res);
    WriteSF<width>(pred, res);
    WriteCFSub(pred, lhsFromMem, rhsFromMem);
    WriteAFAddSub<width>(pred, res, lhsFromMem, rhsFromMem);
    WriteOFSub<width>(pred, res, lhsFromMem, rhsFromMem);

    //now, either increment or decrement EDI based on the DF flag
    CREATE_BLOCK(df_zero, pred);
    CREATE_BLOCK(df_one, pred);

    CREATE_BLOCK(post_write, pred);

    Value *df = F_READ(pred, DF);
    SwitchInst *dfSwitch = SwitchInst::Create(df, block_df_zero, 2, pred);
    dfSwitch->addCase(CONST_V<1>(pred, 0), block_df_zero);
    dfSwitch->addCase(CONST_V<1>(pred, 1), block_df_one);

    uint32_t    disp;
    switch(width) {
        case 8:
            disp = 1;
            break;
        case 16:
            disp = 2;
            break;
        case 32:
            disp = 4;
            break;
        case 64:
            disp = 8;
            break;
        default:
            throw TErr(__LINE__, __FILE__, "Invalid width");
    }

    //if zero, then add to src and dst registers
    Value   *add_lhs = 
        BinaryOperator::CreateAdd(  lhsRegVal,
                                    CONST_V<32>(block_df_zero, disp), 
                                    "", 
                                    block_df_zero);

    Value   *add_rhs = 
        BinaryOperator::CreateAdd(  rhsRegVal,
                                    CONST_V<32>(block_df_zero, disp), 
                                    "", 
                                    block_df_zero);

    R_WRITE<32>(block_df_zero, X86::ESI, add_lhs);
    R_WRITE<32>(block_df_zero, X86::EDI, add_rhs);
    // return to a single block, to which we will add new instructions
    BranchInst::Create(block_post_write, block_df_zero);

    //if one, then sub to src and dst registers
    Value   *sub_lhs = 
        BinaryOperator::CreateSub(  lhsRegVal,
                                    CONST_V<32>(block_df_one, disp), 
                                    "", 
                                    block_df_one);

    Value   *sub_rhs = 
        BinaryOperator::CreateSub(  rhsRegVal,
                                    CONST_V<32>(block_df_one, disp), 
                                    "", 
                                    block_df_one);

    R_WRITE<32>(block_df_one, X86::ESI, sub_lhs);
    R_WRITE<32>(block_df_one, X86::EDI, sub_rhs);
    // return to a single block, to which we will add new instructions
    BranchInst::Create(block_post_write, block_df_one);

    return block_post_write;
}
Ejemplo n.º 21
0
// Set outgoing edges alive dependent on the terminator instruction SI.
// If the terminator is an Invoke instruction, the call has already been run.
// Return true if anything changed.
bool IntegrationAttempt::checkBlockOutgoingEdges(ShadowInstruction* SI) {

  // TOCHECK: I think this only returns false if the block ends with an Unreachable inst?
  switch(SI->invar->I->getOpcode()) {
  case Instruction::Br:
  case Instruction::Switch:
  case Instruction::Invoke:
  case Instruction::Resume:
    break;
  default:
    return false;
  }

  if(inst_is<InvokeInst>(SI)) {

    InlineAttempt* IA = getInlineAttempt(SI);

    bool changed = false;

    // !localStore indicates the invoke instruction doesn't return normally
    if(SI->parent->localStore) {

      changed |= !SI->parent->succsAlive[0];
      SI->parent->succsAlive[0] = true;

    }      

    // I mark the exceptional edge reachable here if the call is disabled, even though
    // we might have proved it isn't feasible. This could be improved by converting the
    // invoke into a call in the final program.
    if((!IA) || (!IA->isEnabled()) || IA->mayUnwind) {

      changed |= !SI->parent->succsAlive[1];
      SI->parent->succsAlive[1] = true;

    }

    return changed;
    
  }
  else if(inst_is<ResumeInst>(SI)) {

    bool changed = !mayUnwind;
    mayUnwind = true;
    return changed;

  }
  else if(BranchInst* BI = dyn_cast_inst<BranchInst>(SI)) {

    if(BI->isUnconditional()) {
      bool changed = !SI->parent->succsAlive[0];
      SI->parent->succsAlive[0] = true;
      return changed;
    }

  }

  // Both switches and conditional branches use operand 0 for the condition.
  ShadowValue Condition = SI->getOperand(0);
      
  bool changed = false;
  
  ConstantInt* ConstCondition = dyn_cast_or_null<ConstantInt>(getConstReplacement(Condition));
  if(!ConstCondition) {

    if(Condition.t == SHADOWVAL_INST || Condition.t == SHADOWVAL_ARG) {

      // Switch statements can operate on a ptrtoint operand, of which only ptrtoint(null) is useful:
      if(ImprovedValSetSingle* IVS = dyn_cast_or_null<ImprovedValSetSingle>(getIVSRef(Condition))) {
	
	if(IVS->onlyContainsNulls()) {
	  
	  ConstCondition = cast<ConstantInt>(Constant::getNullValue(SI->invar->I->getOperand(0)->getType()));
	  
	}

      }

    }

  }

  if(!ConstCondition) {
    
    std::pair<ValSetType, ImprovedVal> PathVal;

    if(tryGetPathValue(Condition, SI->parent, PathVal))
      ConstCondition = dyn_cast_val<ConstantInt>(PathVal.second.V);

  }

  TerminatorInst* TI = cast_inst<TerminatorInst>(SI);
  const unsigned NumSucc = TI->getNumSuccessors();

  if(ConstCondition) {

    BasicBlock* takenTarget = 0;

    if(BranchInst* BI = dyn_cast_inst<BranchInst>(SI)) {
      // This ought to be a boolean.
      if(ConstCondition->isZero())
	takenTarget = BI->getSuccessor(1);
      else
	takenTarget = BI->getSuccessor(0);
    }
    else {
      SwitchInst* SwI = cast_inst<SwitchInst>(SI);
      SwitchInst::CaseIt targetidx = SwI->findCaseValue(ConstCondition);
      takenTarget = targetidx.getCaseSuccessor();
    }
    if(takenTarget) {
      // We know where the instruction is going -- remove this block as a predecessor for its other targets.
      LPDEBUG("Branch or switch instruction given known target: " << takenTarget->getName() << "\n");

      return setEdgeAlive(TI, SI->parent, takenTarget);

    }
    
    // Else fall through to set all alive.

  }

  SwitchInst* Switch;
  ImprovedValSetSingle* IVS;

  if((Switch = dyn_cast_inst<SwitchInst>(SI)) && 
     (IVS = dyn_cast<ImprovedValSetSingle>(getIVSRef(Condition))) && 
     IVS->SetType == ValSetTypeScalar && 
     !IVS->Values.empty()) {

    // A set of values feeding a switch. Set each corresponding edge alive.

    bool changed = false;

    for (unsigned i = 0, ilim = IVS->Values.size(); i != ilim; ++i) {
      
      SwitchInst::CaseIt targetit = Switch->findCaseValue(cast<ConstantInt>(getConstReplacement(IVS->Values[i].V)));
      BasicBlock* target = targetit.getCaseSuccessor();
      changed |= setEdgeAlive(TI, SI->parent, target);

    }

    return changed;

  }

  // Condition unknown -- set all successors alive.
  for (unsigned I = 0; I != NumSucc; ++I) {
    
    // Mark outgoing edge alive
    if(!SI->parent->succsAlive[I])
      changed = true;
    SI->parent->succsAlive[I] = true;
    
  }

  return changed;

}
Ejemplo n.º 22
0
    llvm::Function* compile(PyCodeObject* co, int inlineopcodes = 1) {
        using namespace llvm;
    
        std::string fname = make_function_name(co);
        // XXX check if function already exists
        Function* func = Function::Create(ty_jitted_function, Function::ExternalLinkage, fname.c_str(), the_module);
        Function::arg_iterator func_args = func->arg_begin();
        Value* func_f = func_args++;
        func_f->setName("f");
        Value* func_tstate = func_args++;
        func_tstate->setName("tstate");
        Value* func_throwflag = func_args++; // XXX
        func_throwflag->setName("throwflag");

        std::vector<CallInst*> to_inline;

        const uint8_t* bytecode = (const uint8_t*) PyString_AS_STRING(co->co_code);
        Py_ssize_t codelen = PyString_Size(co->co_code);
        
        BasicBlock* entry = BasicBlock::Create("entry", func);
        BasicBlock* gen_throw_block = BasicBlock::Create("gen_throw", func);

        IRBuilder<> builder(entry);
  
        Value* st_var = builder.CreateAlloca(the_module->getTypeByName("struct.interpreter_state"), 0, "st"); 
        CallInst* init_st = builder.CreateCall3(the_module->getFunction("init_interpreter_state"), st_var, func_f, func_tstate);
        to_inline.push_back(init_st);

        Value* dispatch_var = builder.CreateAlloca(Type::Int32Ty, 0, "dispatch_to_instr"); 
        
        BasicBlock* end_block = BasicBlock::Create("end", func);
        {
            builder.SetInsertPoint(end_block);
            CallInst* retvalval = builder.CreateCall(the_module->getFunction("get_retval"), st_var);
            to_inline.push_back(retvalval);
            builder.CreateRet(retvalval);
        }
        // create the opcode blocks

        BasicBlock* dispatch_block = BasicBlock::Create("dispatch", func);
        builder.SetInsertPoint(dispatch_block);
        Value* dispatch_val = builder.CreateLoad(dispatch_var);
        SwitchInst* dispatch_switch = builder.CreateSwitch(dispatch_val, end_block);

        std::vector<BasicBlock*> opblocks(codelen);
        for (const uint8_t* cur_instr = bytecode; *cur_instr; ++cur_instr) {
            int line = cur_instr - bytecode;
            unsigned int opcode = *cur_instr;
            if (HAS_ARG(opcode)) cur_instr += 2;
            
            char opblockname[20];
            sprintf(opblockname, "__op_%d", line);
            BasicBlock* opblock = BasicBlock::Create(std::string(opblockname), func);
            
            opblocks[line] = opblock; 
            dispatch_switch->addCase(constant(line), opblock);
        }
        
        BasicBlock* block_end_block = BasicBlock::Create("block_end", func);

        // if throwflag goto block_end else dispatch to opblocks[f_lasti+1]
        builder.SetInsertPoint(entry);
        CallInst* gli = builder.CreateCall(the_module->getFunction("get_lasti"),
                                           func_f);
        to_inline.push_back(gli);
        Value* lastipp = builder.CreateAdd(gli, constant(1));
        builder.CreateStore(lastipp, dispatch_var);
        builder.CreateCondBr(is_zero(builder, func_throwflag), dispatch_block, gen_throw_block);

        builder.SetInsertPoint(gen_throw_block);
        to_inline.push_back(builder.CreateCall2(the_module->getFunction("set_why"), st_var, constant(WHY_EXCEPTION)));
        builder.CreateBr(block_end_block);
        
        // fill in the opcode blocks
        for (const uint8_t* cur_instr = bytecode; *cur_instr; ++cur_instr) {
            int line = cur_instr - bytecode;
            unsigned int opcode = *cur_instr;
            unsigned int oparg = 0;
            if (HAS_ARG(opcode)) {
                unsigned int arg1 = *++cur_instr;
                unsigned int arg2 = *++cur_instr;
                oparg = (arg2 << 8) + arg1;
            }

            builder.SetInsertPoint(opblocks[line]);

            std::vector<Value*> opcode_args = vector_of
                (st_var)
                (constant(line))
                (constant(opcode))
                (constant(oparg))
                .move();

            Function* ophandler;
            CallInst* opret;
#           define DEFAULT_HANDLER                                      \
            if (opcode_funcs.count(opcode)) ophandler = opcode_funcs[opcode]; \
            else ophandler = opcode_unimplemented;                      \
            assert(ophandler);                                          \
            opret = builder.CreateCall(ophandler, opcode_args.begin(), opcode_args.end()); \
            opret->setCallingConv(CallingConv::Fast);                   \
            if (!fat_opcode[opcode]) to_inline.push_back(opret);        \
            /**/
      
            switch(opcode) {
            case YIELD_VALUE: // XXX this will have to change (trace?)
            case RETURN_VALUE:
                DEFAULT_HANDLER;
                builder.CreateBr(block_end_block);
                break;
            case JUMP_FORWARD: {
                int next_line = line + 3 + oparg; // 3 is JUMP_FORWARD + oparg
                assert(next_line < codelen);
                builder.CreateBr(opblocks[next_line]);
                break;
            }
            case JUMP_ABSOLUTE: {
                builder.CreateBr(opblocks[oparg]);
                break;
            }
            case JUMP_IF_TRUE:
            case JUMP_IF_FALSE: {
                int true_line = line + 3;
                int false_line = line + 3 + oparg;
                if (opcode == JUMP_IF_TRUE) std::swap(true_line, false_line);
                CallInst* cond = builder.CreateCall(is_top_true, st_var);
                cond->setCallingConv(CallingConv::Fast);
                to_inline.push_back(cond);
                builder.CreateCondBr(is_zero(builder, cond), opblocks[false_line], opblocks[true_line]);
                break;
            }

            case FOR_ITER: {
                opret = builder.CreateCall(opcode_funcs[opcode], opcode_args.begin(), opcode_args.end());
                opret->setCallingConv(CallingConv::Fast);       
                to_inline.push_back(opret);
                SwitchInst* sw = builder.CreateSwitch(opret, block_end_block);
                sw->addCase(constant(1), block_end_block); // error
                sw->addCase(constant(0), opblocks[line + 3]); // continue loop
                sw->addCase(constant(2), opblocks[line + 3 + oparg]); // end loop
                break;
            }
                
            default: {
                DEFAULT_HANDLER;
                int next_line = line + (HAS_ARG(opcode) ? 3 : 1);
                if (next_line < codelen)
                    builder.CreateCondBr(is_zero(builder, opret), opblocks[next_line], block_end_block);
                else
                    builder.CreateBr(block_end_block);
                break;
            }
            }
        }
        
        builder.SetInsertPoint(block_end_block);
        
        CallInst* do_jump = builder.CreateCall2(unwind_stack, st_var, dispatch_var);
        do_jump->setCallingConv(CallingConv::Fast);
        //to_inline.push_back(do_jump);
        builder.CreateCondBr(is_zero(builder, do_jump), dispatch_block, end_block);

        //verify_function(func);

        if (inlineopcodes) {
            for (size_t i = 0; i < to_inline.size(); ++i)  {
                InlineFunction(to_inline[i]);
            }
        }
        FPM->run(*func);
        return func;
    }
bool LowerEmSetjmp::runOnModule(Module &M) {
  TheModule = &M;

  Function *Setjmp = TheModule->getFunction("setjmp");
  Function *Longjmp = TheModule->getFunction("longjmp");
  if (!Setjmp && !Longjmp) return false;

  Type *i32 = Type::getInt32Ty(M.getContext());
  Type *Void = Type::getVoidTy(M.getContext());

  // Add functions

  Function *EmSetjmp = NULL;

  if (Setjmp) {
    SmallVector<Type*, 2> EmSetjmpTypes;
    EmSetjmpTypes.push_back(Setjmp->getFunctionType()->getParamType(0));
    EmSetjmpTypes.push_back(i32); // extra param that says which setjmp in the function it is
    FunctionType *EmSetjmpFunc = FunctionType::get(i32, EmSetjmpTypes, false);
    EmSetjmp = Function::Create(EmSetjmpFunc, GlobalValue::ExternalLinkage, "emscripten_setjmp", TheModule);
  }

  Function *EmLongjmp = Longjmp ? Function::Create(Longjmp->getFunctionType(), GlobalValue::ExternalLinkage, "emscripten_longjmp", TheModule) : NULL;

  SmallVector<Type*, 1> IntArgTypes;
  IntArgTypes.push_back(i32);
  FunctionType *IntIntFunc = FunctionType::get(i32, IntArgTypes, false);

  Function *CheckLongjmp = Function::Create(IntIntFunc, GlobalValue::ExternalLinkage, "emscripten_check_longjmp", TheModule); // gets control flow

  Function *GetLongjmpResult = Function::Create(IntIntFunc, GlobalValue::ExternalLinkage, "emscripten_get_longjmp_result", TheModule); // gets int value longjmp'd

  FunctionType *VoidFunc = FunctionType::get(Void, false);
  Function *PrepSetjmp = Function::Create(VoidFunc, GlobalValue::ExternalLinkage, "emscripten_prep_setjmp", TheModule);

  Function *CleanupSetjmp = Function::Create(VoidFunc, GlobalValue::ExternalLinkage, "emscripten_cleanup_setjmp", TheModule);

  Function *PreInvoke = TheModule->getFunction("emscripten_preinvoke");
  if (!PreInvoke) PreInvoke = Function::Create(VoidFunc, GlobalValue::ExternalLinkage, "emscripten_preinvoke", TheModule);

  FunctionType *IntFunc = FunctionType::get(i32, false);
  Function *PostInvoke = TheModule->getFunction("emscripten_postinvoke");
  if (!PostInvoke) PostInvoke = Function::Create(IntFunc, GlobalValue::ExternalLinkage, "emscripten_postinvoke", TheModule);

  // Process all callers of setjmp and longjmp. Start with setjmp.

  typedef std::vector<PHINode*> Phis;
  typedef std::map<Function*, Phis> FunctionPhisMap;
  FunctionPhisMap SetjmpOutputPhis;
  std::vector<Instruction*> ToErase;

  if (Setjmp) {
    for (Instruction::user_iterator UI = Setjmp->user_begin(), UE = Setjmp->user_end(); UI != UE; ++UI) {
      User *U = *UI;
      if (CallInst *CI = dyn_cast<CallInst>(U)) {
        BasicBlock *SJBB = CI->getParent();
        // The tail is everything right after the call, and will be reached once when setjmp is
        // called, and later when longjmp returns to the setjmp
        BasicBlock *Tail = SplitBlock(SJBB, CI->getNextNode());
        // Add a phi to the tail, which will be the output of setjmp, which indicates if this is the
        // first call or a longjmp back. The phi directly uses the right value based on where we
        // arrive from
        PHINode *SetjmpOutput = PHINode::Create(i32, 2, "", Tail->getFirstNonPHI());
        SetjmpOutput->addIncoming(ConstantInt::get(i32, 0), SJBB); // setjmp initial call returns 0
        CI->replaceAllUsesWith(SetjmpOutput); // The proper output is now this, not the setjmp call itself
        // longjmp returns to the setjmp will add themselves to this phi
        Phis& P = SetjmpOutputPhis[SJBB->getParent()];
        P.push_back(SetjmpOutput);
        // fix call target
        SmallVector<Value *, 2> Args;
        Args.push_back(CI->getArgOperand(0));
        Args.push_back(ConstantInt::get(i32, P.size())); // our index in the function is our place in the array + 1
        CallInst::Create(EmSetjmp, Args, "", CI);
        ToErase.push_back(CI);
      } else {
        errs() << **UI << "\n";
        report_fatal_error("bad use of setjmp, should only call it");
      }
    }
  }

  // Update longjmp FIXME: we could avoid throwing in longjmp as an optimization when longjmping back into the current function perhaps?

  if (Longjmp) Longjmp->replaceAllUsesWith(EmLongjmp);

  // Update all setjmping functions

  for (FunctionPhisMap::iterator I = SetjmpOutputPhis.begin(); I != SetjmpOutputPhis.end(); I++) {
    Function *F = I->first;
    Phis& P = I->second;

    CallInst::Create(PrepSetjmp, "", F->begin()->begin());

    // Update each call that can longjmp so it can return to a setjmp where relevant

    for (Function::iterator BBI = F->begin(), E = F->end(); BBI != E; ) {
      BasicBlock *BB = BBI++;
      for (BasicBlock::iterator Iter = BB->begin(), E = BB->end(); Iter != E; ) {
        Instruction *I = Iter++;
        CallInst *CI;
        if ((CI = dyn_cast<CallInst>(I))) {
          Value *V = CI->getCalledValue();
          if (V == PrepSetjmp || V == EmSetjmp || V == CheckLongjmp || V == GetLongjmpResult || V == PreInvoke || V == PostInvoke) continue;
          if (Function *CF = dyn_cast<Function>(V)) if (CF->isIntrinsic()) continue;
          // TODO: proper analysis of what can actually longjmp. Currently we assume anything but setjmp can.
          // This may longjmp, so we need to check if it did. Split at that point, and
          // envelop the call in pre/post invoke, if we need to
          CallInst *After;
          Instruction *Check = NULL;
          if (Iter != E && (After = dyn_cast<CallInst>(Iter)) && After->getCalledValue() == PostInvoke) {
            // use the pre|postinvoke that exceptions lowering already made
            Check = Iter++;
          }
          BasicBlock *Tail = SplitBlock(BB, Iter); // Iter already points to the next instruction, as we need
          TerminatorInst *TI = BB->getTerminator();
          if (!Check) {
            // no existing pre|postinvoke, create our own
            CallInst::Create(PreInvoke, "", CI);
            Check = CallInst::Create(PostInvoke, "", TI); // CI is at the end of the block

            // If we are calling a function that is noreturn, we must remove that attribute. The code we
            // insert here does expect it to return, after we catch the exception.
            if (CI->doesNotReturn()) {
              if (Function *F = dyn_cast<Function>(CI->getCalledValue())) {
                F->removeFnAttr(Attribute::NoReturn);
              }
              CI->setAttributes(CI->getAttributes().removeAttribute(TheModule->getContext(), AttributeSet::FunctionIndex, Attribute::NoReturn));
              assert(!CI->doesNotReturn());
            }
          }

          // We need to replace the terminator in Tail - SplitBlock makes BB go straight to Tail, we need to check if a longjmp occurred, and
          // go to the right setjmp-tail if so
          SmallVector<Value *, 1> Args;
          Args.push_back(Check);
          Instruction *LongjmpCheck = CallInst::Create(CheckLongjmp, Args, "", BB);
          Instruction *LongjmpResult = CallInst::Create(GetLongjmpResult, Args, "", BB);
          SwitchInst *SI = SwitchInst::Create(LongjmpCheck, Tail, 2, BB);
          // -1 means no longjmp happened, continue normally (will hit the default switch case). 0 means a longjmp that is not ours to handle, needs a rethrow. Otherwise
          // the index mean is the same as the index in P+1 (to avoid 0).
          for (unsigned i = 0; i < P.size(); i++) {
            SI->addCase(cast<ConstantInt>(ConstantInt::get(i32, i+1)), P[i]->getParent());
            P[i]->addIncoming(LongjmpResult, BB);
          }
          ToErase.push_back(TI); // new terminator is now the switch

          // we are splitting the block here, and must continue to find other calls in the block - which is now split. so continue
          // to traverse in the Tail
          BB = Tail;
          Iter = BB->begin();
          E = BB->end();
        } else if (InvokeInst *CI = dyn_cast<InvokeInst>(I)) { // XXX check if target is setjmp
          (void)CI;
          report_fatal_error("TODO: invoke inside setjmping functions");
        }
      }
    }

    // add a cleanup before each return
    for (Function::iterator BBI = F->begin(), E = F->end(); BBI != E; ) {
      BasicBlock *BB = BBI++;
      TerminatorInst *TI = BB->getTerminator();
      if (isa<ReturnInst>(TI)) {
        CallInst::Create(CleanupSetjmp, "", TI);
      }
    }
  }

  for (unsigned i = 0; i < ToErase.size(); i++) {
    ToErase[i]->eraseFromParent();
  }

  // Finally, our modifications to the cfg can break dominance of SSA variables. For example,
  //   if (x()) { .. setjmp() .. }
  //   if (y()) { .. longjmp() .. }
  // We must split the longjmp block, and it can jump into the setjmp one. But that means that when
  // we split the setjmp block, it's first part no longer dominates its second part - there is
  // a theoretically possible control flow path where x() is false, then y() is true and we
  // reach the second part of the setjmp block, without ever reaching the first part. So,
  // we recalculate regs vs. mem
  for (FunctionPhisMap::iterator I = SetjmpOutputPhis.begin(); I != SetjmpOutputPhis.end(); I++) {
    Function *F = I->first;
    doRegToMem(*F);
    doMemToReg(*F);
  }

  return true;
}
Ejemplo n.º 24
0
// RewriteLoopBodyWithConditionConstant - We know either that the value LIC has
// the value specified by Val in the specified loop, or we know it does NOT have
// that value.  Rewrite any uses of LIC or of properties correlated to it.
void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
                                                        Constant *Val,
                                                        bool IsEqual) {
  assert(!isa<Constant>(LIC) && "Why are we unswitching on a constant?");
  
  // FIXME: Support correlated properties, like:
  //  for (...)
  //    if (li1 < li2)
  //      ...
  //    if (li1 > li2)
  //      ...
  
  // FOLD boolean conditions (X|LIC), (X&LIC).  Fold conditional branches,
  // selects, switches.
  std::vector<User*> Users(LIC->use_begin(), LIC->use_end());
  std::vector<Instruction*> Worklist;
  LLVMContext &Context = Val->getContext();


  // If we know that LIC == Val, or that LIC == NotVal, just replace uses of LIC
  // in the loop with the appropriate one directly.
  if (IsEqual || (isa<ConstantInt>(Val) &&
      Val->getType()->isIntegerTy(1))) {
    Value *Replacement;
    if (IsEqual)
      Replacement = Val;
    else
      Replacement = ConstantInt::get(Type::getInt1Ty(Val->getContext()), 
                                     !cast<ConstantInt>(Val)->getZExtValue());
    
    for (unsigned i = 0, e = Users.size(); i != e; ++i)
      if (Instruction *U = cast<Instruction>(Users[i])) {
        if (!L->contains(U))
          continue;
        U->replaceUsesOfWith(LIC, Replacement);
        Worklist.push_back(U);
      }
    SimplifyCode(Worklist, L);
    return;
  }
  
  // Otherwise, we don't know the precise value of LIC, but we do know that it
  // is certainly NOT "Val".  As such, simplify any uses in the loop that we
  // can.  This case occurs when we unswitch switch statements.
  for (unsigned i = 0, e = Users.size(); i != e; ++i) {
    Instruction *U = cast<Instruction>(Users[i]);
    if (!L->contains(U))
      continue;

    Worklist.push_back(U);

    // TODO: We could do other simplifications, for example, turning 
    // 'icmp eq LIC, Val' -> false.

    // If we know that LIC is not Val, use this info to simplify code.
    SwitchInst *SI = dyn_cast<SwitchInst>(U);
    if (SI == 0 || !isa<ConstantInt>(Val)) continue;
    
    unsigned DeadCase = SI->findCaseValue(cast<ConstantInt>(Val));
    if (DeadCase == 0) continue;  // Default case is live for multiple values.
    
    // Found a dead case value.  Don't remove PHI nodes in the 
    // successor if they become single-entry, those PHI nodes may
    // be in the Users list.
        
    // FIXME: This is a hack.  We need to keep the successor around
    // and hooked up so as to preserve the loop structure, because
    // trying to update it is complicated.  So instead we preserve the
    // loop structure and put the block on a dead code path.
    BasicBlock *Switch = SI->getParent();
    SplitEdge(Switch, SI->getSuccessor(DeadCase), this);
    // Compute the successors instead of relying on the return value
    // of SplitEdge, since it may have split the switch successor
    // after PHI nodes.
    BasicBlock *NewSISucc = SI->getSuccessor(DeadCase);
    BasicBlock *OldSISucc = *succ_begin(NewSISucc);
    // Create an "unreachable" destination.
    BasicBlock *Abort = BasicBlock::Create(Context, "us-unreachable",
                                           Switch->getParent(),
                                           OldSISucc);
    new UnreachableInst(Context, Abort);
    // Force the new case destination to branch to the "unreachable"
    // block while maintaining a (dead) CFG edge to the old block.
    NewSISucc->getTerminator()->eraseFromParent();
    BranchInst::Create(Abort, OldSISucc,
                       ConstantInt::getTrue(Context), NewSISucc);
    // Release the PHI operands for this edge.
    for (BasicBlock::iterator II = NewSISucc->begin();
         PHINode *PN = dyn_cast<PHINode>(II); ++II)
      PN->setIncomingValue(PN->getBasicBlockIndex(Switch),
                           UndefValue::get(PN->getType()));
    // Tell the domtree about the new block. We don't fully update the
    // domtree here -- instead we force it to do a full recomputation
    // after the pass is complete -- but we do need to inform it of
    // new blocks.
    if (DT)
      DT->addNewBlock(Abort, NewSISucc);
  }
  
  SimplifyCode(Worklist, L);
}
Ejemplo n.º 25
0
BasicBlock *
cpu_translate_all(cpu_t *cpu, BasicBlock *bb_ret, BasicBlock *bb_trap)
{
	// find all instructions that need labels and create basic blocks for them
	int bbs = 0;
	addr_t pc;
	pc = cpu->code_start;
	while (pc < cpu->code_end) {
		// Do not create the basic block if it is already present in some other function.
		if (is_start_of_basicblock(cpu, pc) && !(get_tag(cpu, pc) & TAG_TRANSLATED)) {
			create_basicblock(cpu, pc, cpu->cur_func, BB_TYPE_NORMAL);
			bbs++;
		}
		pc++;
	}
	LOG("bbs: %d\n", bbs);

	// create dispatch basicblock
	BasicBlock* bb_dispatch = BasicBlock::Create(_CTX(), "dispatch", cpu->cur_func, 0);
	Value *v_pc = new LoadInst(cpu->ptr_PC, "", false, bb_dispatch);
	SwitchInst* sw = SwitchInst::Create(v_pc, bb_ret, bbs, bb_dispatch);

	// translate basic blocks
	bbaddr_map &bb_addr = cpu->func_bb[cpu->cur_func];
	bbaddr_map::const_iterator it;
	for (it = bb_addr.begin(); it != bb_addr.end(); it++) {
		pc = it->first;
		BasicBlock *cur_bb = it->second;

		tag_t tag;
		BasicBlock *bb_target = NULL, *bb_next = NULL, *bb_cont = NULL;

		// Tag the function as translated.
		or_tag(cpu, pc, TAG_TRANSLATED);

		LOG("basicblock: L%08llx\n", (unsigned long long)pc);

		// Add dispatch switch case for basic block.
		ConstantInt* c = ConstantInt::get(getIntegerType(cpu->info.address_size), pc);
		sw->addCase(c, cur_bb);

		do {
			tag_t dummy1;

			if (LOGGING)
				disasm_instr(cpu, pc);

			tag = get_tag(cpu, pc);

			/* get address of the following instruction */
			addr_t new_pc, next_pc;
			cpu->f.tag_instr(cpu, pc, &dummy1, &new_pc, &next_pc);

			/* get target basic block */
			if (tag & TAG_RET)
				bb_target = bb_dispatch;
			if (tag & (TAG_CALL|TAG_BRANCH)) {
				if (new_pc == NEW_PC_NONE) /* translate_instr() will set PC */
					bb_target = bb_dispatch;
				else
					bb_target = (BasicBlock*)lookup_basicblock(cpu, cpu->cur_func, new_pc, bb_ret, BB_TYPE_NORMAL);
			}
			/* get not-taken basic block */
			if (tag & TAG_CONDITIONAL)
 				bb_next = (BasicBlock*)lookup_basicblock(cpu, cpu->cur_func, next_pc, bb_ret, BB_TYPE_NORMAL);

			bb_cont = translate_instr(cpu, pc, tag, bb_target, bb_trap, bb_next, cur_bb);

			pc = next_pc;
			
		} while (
					/* new basic block starts here (and we haven't translated it yet)*/
					(!is_start_of_basicblock(cpu, pc)) &&
					/* end of code section */ //XXX no: this is whether it's TAG_CODE
					is_code(cpu, pc) &&
					/* last intruction jumped away */
					bb_cont
				);

		/* link with next basic block if there isn't a control flow instr. already */
		if (bb_cont) {
			BasicBlock *target = (BasicBlock*)lookup_basicblock(cpu, cpu->cur_func, pc, bb_ret, BB_TYPE_NORMAL);
			LOG("info: linking continue $%04llx!\n", (unsigned long long)pc);
			BranchInst::Create(target, bb_cont);
		}
    }

	return bb_dispatch;
}
static bool convertFunction(Function *Func) {
  bool Changed = false;
  IntegerType *I32 = Type::getInt32Ty(Func->getContext());

  // Skip zero in case programs treat a null pointer as special.
  uint32_t NextNum = 1;
  DenseMap<BasicBlock *, ConstantInt *> LabelNums;
  BasicBlock *DefaultBB = NULL;

  // Replace each indirectbr with a switch.
  //
  // If there are multiple indirectbr instructions in the function,
  // this could be expensive.  While an indirectbr is usually
  // converted to O(1) machine instructions, the switch we generate
  // here will be O(n) in the number of target labels.
  //
  // However, Clang usually generates just a single indirectbr per
  // function anyway when compiling C computed gotos.
  //
  // We could try to generate one switch to handle all the indirectbr
  // instructions in the function, but that would be complicated to
  // implement given that variables that are live at one indirectbr
  // might not be live at others.
  for (llvm::Function::iterator BB = Func->begin(), E = Func->end();
       BB != E; ++BB) {
    if (IndirectBrInst *Br = dyn_cast<IndirectBrInst>(BB->getTerminator())) {
      Changed = true;

      if (!DefaultBB) {
        DefaultBB = BasicBlock::Create(Func->getContext(),
                                       "indirectbr_default", Func);
        new UnreachableInst(Func->getContext(), DefaultBB);
      }

      // An indirectbr can list the same target block multiple times.
      // Keep track of the basic blocks we've handled to avoid adding
      // the same case multiple times.
      DenseSet<BasicBlock *> BlocksSeen;

      Value *Cast = new PtrToIntInst(Br->getAddress(), I32,
                                     "indirectbr_cast", Br);
      unsigned Count = Br->getNumSuccessors();
      SwitchInst *Switch = SwitchInst::Create(Cast, DefaultBB, Count, Br);
      for (unsigned I = 0; I < Count; ++I) {
        BasicBlock *Dest = Br->getSuccessor(I);
        if (!BlocksSeen.insert(Dest).second) {
          // Remove duplicated entries from phi nodes.
          for (BasicBlock::iterator Inst = Dest->begin(); ; ++Inst) {
            PHINode *Phi = dyn_cast<PHINode>(Inst);
            if (!Phi)
              break;
            Phi->removeIncomingValue(Br->getParent());
          }
          continue;
        }
        ConstantInt *Val;
        if (LabelNums.count(Dest) == 0) {
          Val = ConstantInt::get(I32, NextNum++);
          LabelNums[Dest] = Val;

          BlockAddress *BA = BlockAddress::get(Func, Dest);
          Value *ValAsPtr = ConstantExpr::getIntToPtr(Val, BA->getType());
          BA->replaceAllUsesWith(ValAsPtr);
          BA->destroyConstant();
        } else {
          Val = LabelNums[Dest];
        }
        Switch->addCase(Val, Br->getSuccessor(I));
      }
      Br->eraseFromParent();
    }
  }

  // If there are any blockaddresses that are never used by an
  // indirectbr, replace them with dummy values.
  SmallVector<Value *, 20> Users(Func->user_begin(), Func->user_end());
  for (auto U : Users) {
    if (BlockAddress *BA = dyn_cast<BlockAddress>(U)) {
      Changed = true;
      Value *DummyVal = ConstantExpr::getIntToPtr(ConstantInt::get(I32, ~0L),
                                                  BA->getType());
      BA->replaceAllUsesWith(DummyVal);
      BA->destroyConstant();
    }
  }
  return Changed;
}
bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
  Module &M = *F.getParent();
  LLVMContext &C = F.getContext();
  IRBuilder<> IRB(C);
  SmallVector<Instruction *, 64> ToErase;
  // Vector of %setjmpTable values
  std::vector<Instruction *> SetjmpTableInsts;
  // Vector of %setjmpTableSize values
  std::vector<Instruction *> SetjmpTableSizeInsts;

  // Setjmp preparation

  // This instruction effectively means %setjmpTableSize = 4.
  // We create this as an instruction intentionally, and we don't want to fold
  // this instruction to a constant 4, because this value will be used in
  // SSAUpdater.AddAvailableValue(...) later.
  BasicBlock &EntryBB = F.getEntryBlock();
  BinaryOperator *SetjmpTableSize = BinaryOperator::Create(
      Instruction::Add, IRB.getInt32(4), IRB.getInt32(0), "setjmpTableSize",
      &*EntryBB.getFirstInsertionPt());
  // setjmpTable = (int *) malloc(40);
  Instruction *SetjmpTable = CallInst::CreateMalloc(
      SetjmpTableSize, IRB.getInt32Ty(), IRB.getInt32Ty(), IRB.getInt32(40),
      nullptr, nullptr, "setjmpTable");
  // setjmpTable[0] = 0;
  IRB.SetInsertPoint(SetjmpTableSize);
  IRB.CreateStore(IRB.getInt32(0), SetjmpTable);
  SetjmpTableInsts.push_back(SetjmpTable);
  SetjmpTableSizeInsts.push_back(SetjmpTableSize);

  // Setjmp transformation
  std::vector<PHINode *> SetjmpRetPHIs;
  Function *SetjmpF = M.getFunction("setjmp");
  for (User *U : SetjmpF->users()) {
    auto *CI = dyn_cast<CallInst>(U);
    if (!CI)
      report_fatal_error("Does not support indirect calls to setjmp");

    BasicBlock *BB = CI->getParent();
    if (BB->getParent() != &F) // in other function
      continue;

    // The tail is everything right after the call, and will be reached once
    // when setjmp is called, and later when longjmp returns to the setjmp
    BasicBlock *Tail = SplitBlock(BB, CI->getNextNode());
    // Add a phi to the tail, which will be the output of setjmp, which
    // indicates if this is the first call or a longjmp back. The phi directly
    // uses the right value based on where we arrive from
    IRB.SetInsertPoint(Tail->getFirstNonPHI());
    PHINode *SetjmpRet = IRB.CreatePHI(IRB.getInt32Ty(), 2, "setjmp.ret");

    // setjmp initial call returns 0
    SetjmpRet->addIncoming(IRB.getInt32(0), BB);
    // The proper output is now this, not the setjmp call itself
    CI->replaceAllUsesWith(SetjmpRet);
    // longjmp returns to the setjmp will add themselves to this phi
    SetjmpRetPHIs.push_back(SetjmpRet);

    // Fix call target
    // Our index in the function is our place in the array + 1 to avoid index
    // 0, because index 0 means the longjmp is not ours to handle.
    IRB.SetInsertPoint(CI);
    Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()),
                     SetjmpTable, SetjmpTableSize};
    Instruction *NewSetjmpTable =
        IRB.CreateCall(SaveSetjmpF, Args, "setjmpTable");
    Instruction *NewSetjmpTableSize =
        IRB.CreateLoad(TempRet0GV, "setjmpTableSize");
    SetjmpTableInsts.push_back(NewSetjmpTable);
    SetjmpTableSizeInsts.push_back(NewSetjmpTableSize);
    ToErase.push_back(CI);
  }

  // Update each call that can longjmp so it can return to a setjmp where
  // relevant.

  // Because we are creating new BBs while processing and don't want to make
  // all these newly created BBs candidates again for longjmp processing, we
  // first make the vector of candidate BBs.
  std::vector<BasicBlock *> BBs;
  for (BasicBlock &BB : F)
    BBs.push_back(&BB);

  // BBs.size() will change within the loop, so we query it every time
  for (unsigned i = 0; i < BBs.size(); i++) {
    BasicBlock *BB = BBs[i];
    for (Instruction &I : *BB) {
      assert(!isa<InvokeInst>(&I));
      auto *CI = dyn_cast<CallInst>(&I);
      if (!CI)
        continue;

      const Value *Callee = CI->getCalledValue();
      if (!canLongjmp(M, Callee))
        continue;

      Value *Threw = nullptr;
      BasicBlock *Tail;
      if (Callee->getName().startswith(InvokePrefix)) {
        // If invoke wrapper has already been generated for this call in
        // previous EH phase, search for the load instruction
        // %__THREW__.val = __THREW__;
        // in postamble after the invoke wrapper call
        LoadInst *ThrewLI = nullptr;
        StoreInst *ThrewResetSI = nullptr;
        for (auto I = std::next(BasicBlock::iterator(CI)), IE = BB->end();
             I != IE; ++I) {
          if (auto *LI = dyn_cast<LoadInst>(I))
            if (auto *GV = dyn_cast<GlobalVariable>(LI->getPointerOperand()))
              if (GV == ThrewGV) {
                Threw = ThrewLI = LI;
                break;
              }
        }
        // Search for the store instruction after the load above
        // __THREW__ = 0;
        for (auto I = std::next(BasicBlock::iterator(ThrewLI)), IE = BB->end();
             I != IE; ++I) {
          if (auto *SI = dyn_cast<StoreInst>(I))
            if (auto *GV = dyn_cast<GlobalVariable>(SI->getPointerOperand()))
              if (GV == ThrewGV && SI->getValueOperand() == IRB.getInt32(0)) {
                ThrewResetSI = SI;
                break;
              }
        }
        assert(Threw && ThrewLI && "Cannot find __THREW__ load after invoke");
        assert(ThrewResetSI && "Cannot find __THREW__ store after invoke");
        Tail = SplitBlock(BB, ThrewResetSI->getNextNode());

      } else {
        // Wrap call with invoke wrapper and generate preamble/postamble
        Threw = wrapInvoke(CI);
        ToErase.push_back(CI);
        Tail = SplitBlock(BB, CI->getNextNode());
      }

      // We need to replace the terminator in Tail - SplitBlock makes BB go
      // straight to Tail, we need to check if a longjmp occurred, and go to the
      // right setjmp-tail if so
      ToErase.push_back(BB->getTerminator());

      // Generate a function call to testSetjmp function and preamble/postamble
      // code to figure out (1) whether longjmp occurred (2) if longjmp
      // occurred, which setjmp it corresponds to
      Value *Label = nullptr;
      Value *LongjmpResult = nullptr;
      BasicBlock *EndBB = nullptr;
      wrapTestSetjmp(BB, CI, Threw, SetjmpTable, SetjmpTableSize, Label,
                     LongjmpResult, EndBB);
      assert(Label && LongjmpResult && EndBB);

      // Create switch instruction
      IRB.SetInsertPoint(EndBB);
      SwitchInst *SI = IRB.CreateSwitch(Label, Tail, SetjmpRetPHIs.size());
      // -1 means no longjmp happened, continue normally (will hit the default
      // switch case). 0 means a longjmp that is not ours to handle, needs a
      // rethrow. Otherwise the index is the same as the index in P+1 (to avoid
      // 0).
      for (unsigned i = 0; i < SetjmpRetPHIs.size(); i++) {
        SI->addCase(IRB.getInt32(i + 1), SetjmpRetPHIs[i]->getParent());
        SetjmpRetPHIs[i]->addIncoming(LongjmpResult, EndBB);
      }

      // We are splitting the block here, and must continue to find other calls
      // in the block - which is now split. so continue to traverse in the Tail
      BBs.push_back(Tail);
    }
  }

  // Erase everything we no longer need in this function
  for (Instruction *I : ToErase)
    I->eraseFromParent();

  // Free setjmpTable buffer before each return instruction
  for (BasicBlock &BB : F) {
    TerminatorInst *TI = BB.getTerminator();
    if (isa<ReturnInst>(TI))
      CallInst::CreateFree(SetjmpTable, TI);
  }

  // Every call to saveSetjmp can change setjmpTable and setjmpTableSize
  // (when buffer reallocation occurs)
  // entry:
  //   setjmpTableSize = 4;
  //   setjmpTable = (int *) malloc(40);
  //   setjmpTable[0] = 0;
  // ...
  // somebb:
  //   setjmpTable = saveSetjmp(buf, label, setjmpTable, setjmpTableSize);
  //   setjmpTableSize = __tempRet0;
  // So we need to make sure the SSA for these variables is valid so that every
  // saveSetjmp and testSetjmp calls have the correct arguments.
  SSAUpdater SetjmpTableSSA;
  SSAUpdater SetjmpTableSizeSSA;
  SetjmpTableSSA.Initialize(Type::getInt32PtrTy(C), "setjmpTable");
  SetjmpTableSizeSSA.Initialize(Type::getInt32Ty(C), "setjmpTableSize");
  for (Instruction *I : SetjmpTableInsts)
    SetjmpTableSSA.AddAvailableValue(I->getParent(), I);
  for (Instruction *I : SetjmpTableSizeInsts)
    SetjmpTableSizeSSA.AddAvailableValue(I->getParent(), I);

  for (auto UI = SetjmpTable->use_begin(), UE = SetjmpTable->use_end();
       UI != UE;) {
    // Grab the use before incrementing the iterator.
    Use &U = *UI;
    // Increment the iterator before removing the use from the list.
    ++UI;
    if (Instruction *I = dyn_cast<Instruction>(U.getUser()))
      if (I->getParent() != &EntryBB)
        SetjmpTableSSA.RewriteUse(U);
  }
  for (auto UI = SetjmpTableSize->use_begin(), UE = SetjmpTableSize->use_end();
       UI != UE;) {
    Use &U = *UI;
    ++UI;
    if (Instruction *I = dyn_cast<Instruction>(U.getUser()))
      if (I->getParent() != &EntryBB)
        SetjmpTableSizeSSA.RewriteUse(U);
  }

  // Finally, our modifications to the cfg can break dominance of SSA variables.
  // For example, in this code,
  // if (x()) { .. setjmp() .. }
  // if (y()) { .. longjmp() .. }
  // We must split the longjmp block, and it can jump into the block splitted
  // from setjmp one. But that means that when we split the setjmp block, it's
  // first part no longer dominates its second part - there is a theoretically
  // possible control flow path where x() is false, then y() is true and we
  // reach the second part of the setjmp block, without ever reaching the first
  // part. So, we rebuild SSA form here.
  rebuildSSA(F);
  return true;
}
Ejemplo n.º 28
0
// This is the equivalent of return fpuregs[regslot];
// FPU registers are referenced as ST(i) where i [0-7], and references a
// register slot based on the value of the TOP flag. 
// So if TOP == 5, then ST(0) references register slot 5, and ST(3) references
// register slot 0.
static Value   *FPUR_READV(BasicBlock *&b, Value *regslot)
{
    // Check TAG register
    // If TAG(regslot) != 0, then we have a problem.
    Value *tagval = GetFPUTagV(b, regslot);
    Function *F = b->getParent();

    BasicBlock *read_normal_block =
        BasicBlock::Create(b->getContext(), "fpu_read_normal", F);
    //BasicBlock *read_zero_block =
    //    BasicBlock::Create(b->getContext(), "fpu_read_zero", F);
    //BasicBlock *read_special_block =
    //    BasicBlock::Create(b->getContext(), "fpu_read_special", F);
    BasicBlock *read_empty_block =
        BasicBlock::Create(b->getContext(), "fpu_read_empty", F);

    BasicBlock *fpu_read_continue =
        BasicBlock::Create(b->getContext(), "fpu_read_continue", F);

    // The default case should never be hit. Use LLVM Switch Node.
    SwitchInst *tagSwitch = SwitchInst::Create(tagval, read_empty_block, 4, b);
    tagSwitch->addCase(CONST_V<2>(b, FPU_TAG_VALID), read_normal_block);
    tagSwitch->addCase(CONST_V<2>(b, FPU_TAG_ZERO), read_normal_block);
    tagSwitch->addCase(CONST_V<2>(b, FPU_TAG_SPECIAL), read_normal_block);
    //tagSwitch->addCase(CONST_V<2>(b, 1), read_zero_block);
    //tagSwitch->addCase(CONST_V<2>(b, 2), read_special_block);
    //tagSwitch->addCase(CONST_V<2>(b, 3), read_empty_block);

    Value *streg = GetFPURegV(read_normal_block, regslot);
    Value *loadVal = new LoadInst(streg, "", read_normal_block);

    // C1 is set load needs to round up and cleared otherwise.
    FPUF_CLEAR(read_normal_block, "C1");
    BranchInst::Create(fpu_read_continue, read_normal_block);

    // Populate read zero block.
    // This is the zero block. Return zero.
    // But there are two zeros - negative and positive.
    // Check the sign of the number, then return +0 or -0.
    //Value *streg_z = GetFPURegV(read_zero_block, regslot);
    //Value *loadVal_z = new LoadInst(streg_z, "", read_zero_block);
    //Value *neg_zero = ConstantFP::getNegativeZero(Type::getX86_FP80Ty(read_zero_block->getContext()));
    // Is the value we loaded less than or equal to -0.0?
    //Value *fcmp_inst = new FCmpInst(*read_zero_block, FCmpInst::FCMP_OLE, loadVal_z, neg_zero, "");

    // if val <= -0.0, return -0.0. Otherwise, return +0.0.
    //Value *zval = SelectInst::Create(fcmp_inst, neg_zero,
    //    CONSTFP_V(read_zero_block, 0.0), "", read_zero_block);

    //BranchInst::Create(fpu_read_continue, read_zero_block);

    // Populate read special block.
    // TODO: Check if we need special NaN handling.
    //BranchInst::Create(fpu_read_continue, read_special_block);
    //Value *streg_s = GetFPURegV(read_special_block, regslot);
    //Value *loadVal_s = new LoadInst(streg_s, "", read_special_block);
    //BranchInst::Create(fpu_read_continue, read_special_block);

    // Populate read empty block.
    // For now, just branch to fpu_read_continue and clear C1 to indicate stack
    // underflow.
    // TODO: Throw an exception.
    FPUF_CLEAR(read_empty_block, "C1");
    Value *zval = CONSTFP_V(read_empty_block, 0.0);
    BranchInst::Create(fpu_read_continue, read_empty_block);


    // Populate continue block.
    // Use phi instruction to determine value that was loaded.
    PHINode *whichval = 
        PHINode::Create(Type::getX86_FP80Ty(F->getContext()),
                        2,
                        "fpu_switch_phinode",
                        fpu_read_continue);

    whichval->addIncoming(loadVal, read_normal_block);
    //whichval->addIncoming(zval, read_zero_block);
    //whichval->addIncoming(loadVal_s, read_special_block);

    // Would not get here, but throw exception?
    whichval->addIncoming(zval, read_empty_block);

    b = fpu_read_continue;

    // Read PC flag and adjust precision based on its value.
    Value *precision_adjusted = adjustFpuPrecision(b, whichval);
    return precision_adjusted;
}
Ejemplo n.º 29
0
static void convertInstruction(Instruction *Inst, ConversionState &State) {
  if (SExtInst *Sext = dyn_cast<SExtInst>(Inst)) {
    Value *Op = Sext->getOperand(0);
    Value *NewInst = NULL;
    // If the operand to be extended is illegal, we first need to fill its
    // upper bits (which are zero) with its sign bit.
    if (shouldConvert(Op)) {
      NewInst = getSignExtend(State.getConverted(Op), Op, Sext);
    }
    // If the converted type of the operand is the same as the converted
    // type of the result, we won't actually be changing the type of the
    // variable, just its value.
    if (getPromotedType(Op->getType()) !=
        getPromotedType(Sext->getType())) {
      NewInst = new SExtInst(
          NewInst ? NewInst : State.getConverted(Op),
          getPromotedType(cast<IntegerType>(Sext->getType())),
          Sext->getName() + ".sext", Sext);
    }
    // Now all the bits of the result are correct, but we need to restore
    // the bits above its type to zero.
    if (shouldConvert(Sext)) {
      NewInst = getClearUpper(NewInst, Sext->getType(), Sext);
    }
    assert(NewInst && "Failed to convert sign extension");
    State.recordConverted(Sext, NewInst);
  } else if (ZExtInst *Zext = dyn_cast<ZExtInst>(Inst)) {
    Value *Op = Zext->getOperand(0);
    Value *NewInst = NULL;
    // TODO(dschuff): Some of these zexts could be no-ops.
    if (shouldConvert(Op)) {
      NewInst = getClearUpper(State.getConverted(Op),
                              Op->getType(),
                              Zext);
    }
    // If the converted type of the operand is the same as the converted
    // type of the result, we won't actually be changing the type of the
    // variable, just its value.
    if (getPromotedType(Op->getType()) !=
        getPromotedType(Zext->getType())) {
      NewInst = CastInst::CreateZExtOrBitCast(
          NewInst ? NewInst : State.getConverted(Op),
          getPromotedType(cast<IntegerType>(Zext->getType())),
          "", Zext);
    }
    assert(NewInst);
    State.recordConverted(Zext, NewInst);
  } else if (TruncInst *Trunc = dyn_cast<TruncInst>(Inst)) {
    Value *Op = Trunc->getOperand(0);
    Value *NewInst = NULL;
    // If the converted type of the operand is the same as the converted
    // type of the result, we won't actually be changing the type of the
    // variable, just its value.
    if (getPromotedType(Op->getType()) !=
        getPromotedType(Trunc->getType())) {
      NewInst = new TruncInst(
          State.getConverted(Op),
          getPromotedType(cast<IntegerType>(Trunc->getType())),
          State.getConverted(Op)->getName() + ".trunc",
          Trunc);
    }
    // Restoring the upper-bits-are-zero invariant effectively truncates the
    // value.
    if (shouldConvert(Trunc)) {
      NewInst = getClearUpper(NewInst ? NewInst : Op,
                              Trunc->getType(),
                              Trunc);
    }
    assert(NewInst);
    State.recordConverted(Trunc, NewInst);
  } else if (AllocaInst *Alloc = dyn_cast<AllocaInst>(Inst)) {
    // Don't handle arrays of illegal types, but we could handle an array
    // with size specified as an illegal type, as unlikely as that seems.
    if (shouldConvert(Alloc) && Alloc->isArrayAllocation())
      report_fatal_error("Can't convert arrays of illegal type");
    AllocaInst *NewInst = new AllocaInst(
        getPromotedType(Alloc->getAllocatedType()),
        State.getConverted(Alloc->getArraySize()),
        "", Alloc);
    NewInst->setAlignment(Alloc->getAlignment());
    State.recordConverted(Alloc, NewInst);
  } else if (BitCastInst *BCInst = dyn_cast<BitCastInst>(Inst)) {
    // Only handle pointers. Ints can't be casted to/from other ints
    Type *DestType = shouldConvert(BCInst) ?
        getPromotedType(BCInst->getDestTy()) : BCInst->getDestTy();
    BitCastInst *NewInst = new BitCastInst(
        State.getConverted(BCInst->getOperand(0)),
        DestType,
        "", BCInst);
    State.recordConverted(BCInst, NewInst);
  } else if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
    if (shouldConvert(Load)) {
      splitLoad(Load, State);
    }
  } else if (StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
    if (shouldConvert(Store->getValueOperand())) {
      splitStore(Store, State);
    }
  } else if (isa<CallInst>(Inst)) {
    report_fatal_error("can't convert calls with illegal types");
  } else if (BinaryOperator *Binop = dyn_cast<BinaryOperator>(Inst)) {
    Value *NewInst = NULL;
    if (Binop->getOpcode() == Instruction::AShr) {
      // The AShr operand needs to be sign-extended to the promoted size
      // before shifting. Because the sign-extension is implemented with
      // with AShr, it can be combined with the original operation.
      Value *Op = Binop->getOperand(0);
      Value *ShiftAmount = NULL;
      APInt SignShiftAmt = APInt(
          getPromotedType(Op->getType())->getIntegerBitWidth(),
          getPromotedType(Op->getType())->getIntegerBitWidth() -
          Op->getType()->getIntegerBitWidth());
      NewInst = BinaryOperator::Create(
          Instruction::Shl,
          State.getConverted(Op),
          ConstantInt::get(getPromotedType(Op->getType()), SignShiftAmt),
          State.getConverted(Op)->getName() + ".getsign",
          Binop);
      if (ConstantInt *C = dyn_cast<ConstantInt>(
              State.getConverted(Binop->getOperand(1)))) {
        ShiftAmount = ConstantInt::get(getPromotedType(Op->getType()),
                                       SignShiftAmt + C->getValue());
      } else {
        ShiftAmount = BinaryOperator::Create(
            Instruction::Add,
            State.getConverted(Binop->getOperand(1)),
            ConstantInt::get(
                getPromotedType(Binop->getOperand(1)->getType()),
                SignShiftAmt),
            State.getConverted(Op)->getName() + ".shamt", Binop);
      }
      NewInst = BinaryOperator::Create(
          Instruction::AShr,
          NewInst,
          ShiftAmount,
          Binop->getName() + ".result", Binop);
    } else {
      // If the original operation is not AShr, just recreate it as usual.
      NewInst = BinaryOperator::Create(
          Binop->getOpcode(),
          State.getConverted(Binop->getOperand(0)),
          State.getConverted(Binop->getOperand(1)),
          Binop->getName() + ".result", Binop);
      if (isa<OverflowingBinaryOperator>(NewInst)) {
        cast<BinaryOperator>(NewInst)->setHasNoUnsignedWrap
            (Binop->hasNoUnsignedWrap());
        cast<BinaryOperator>(NewInst)->setHasNoSignedWrap(
            Binop->hasNoSignedWrap());
      }
    }

    // Now restore the invariant if necessary.
    // This switch also sanity-checks the operation.
    switch (Binop->getOpcode()) {
      case Instruction::And:
      case Instruction::Or:
      case Instruction::Xor:
      case Instruction::LShr:
        // These won't change the upper bits.
        break;
        // These can change the upper bits, unless we are sure they never
        // overflow. So clear them now.
      case Instruction::Add:
      case Instruction::Sub:
        if (!(Binop->hasNoUnsignedWrap() && Binop->hasNoSignedWrap()))
          NewInst = getClearUpper(NewInst, Binop->getType(), Binop);
        break;
      case Instruction::Shl:
        if (!Binop->hasNoUnsignedWrap())
          NewInst = getClearUpper(NewInst, Binop->getType(), Binop);
        break;
        // We modified the upper bits ourselves when implementing AShr
      case Instruction::AShr:
        NewInst = getClearUpper(NewInst, Binop->getType(), Binop);
        break;
        // We should not see FP operators here.
        // We don't handle mul/div.
      case Instruction::FAdd:
      case Instruction::FSub:
      case Instruction::Mul:
      case Instruction::FMul:
      case Instruction::UDiv:
      case Instruction::SDiv:
      case Instruction::FDiv:
      case Instruction::URem:
      case Instruction::SRem:
      case Instruction::FRem:
      case Instruction::BinaryOpsEnd:
        errs() << *Inst << "\n";
        llvm_unreachable("Cannot handle binary operator");
        break;
    }

    State.recordConverted(Binop, NewInst);
  } else if (ICmpInst *Cmp = dyn_cast<ICmpInst>(Inst)) {
    Value *Op0, *Op1;
    // For signed compares, operands are sign-extended to their
    // promoted type. For unsigned or equality compares, the comparison
    // is equivalent with the larger type because they are already
    // zero-extended.
    if (Cmp->isSigned()) {
      Op0 = getSignExtend(State.getConverted(Cmp->getOperand(0)),
                          Cmp->getOperand(0),
                          Cmp);
      Op1 = getSignExtend(State.getConverted(Cmp->getOperand(1)),
                          Cmp->getOperand(1),
                          Cmp);
    } else {
      Op0 = State.getConverted(Cmp->getOperand(0));
      Op1 = State.getConverted(Cmp->getOperand(1));
    }
    ICmpInst *NewInst = new ICmpInst(
        Cmp, Cmp->getPredicate(), Op0, Op1, "");
    State.recordConverted(Cmp, NewInst);
  } else if (SelectInst *Select = dyn_cast<SelectInst>(Inst)) {
    SelectInst *NewInst = SelectInst::Create(
        Select->getCondition(),
        State.getConverted(Select->getTrueValue()),
        State.getConverted(Select->getFalseValue()),
        "", Select);
    State.recordConverted(Select, NewInst);
  } else if (PHINode *Phi = dyn_cast<PHINode>(Inst)) {
    PHINode *NewPhi = PHINode::Create(
        getPromotedType(Phi->getType()),
        Phi->getNumIncomingValues(),
        "", Phi);
    for (unsigned I = 0, E = Phi->getNumIncomingValues(); I < E; ++I) {
      NewPhi->addIncoming(State.getConverted(Phi->getIncomingValue(I)),
                          Phi->getIncomingBlock(I));
    }
    State.recordConverted(Phi, NewPhi);
  } else if (SwitchInst *Switch = dyn_cast<SwitchInst>(Inst)) {
    SwitchInst *NewInst = SwitchInst::Create(
        State.getConverted(Switch->getCondition()),
        Switch->getDefaultDest(),
        Switch->getNumCases(),
        Switch);
    for (SwitchInst::CaseIt I = Switch->case_begin(),
             E = Switch->case_end();
         I != E; ++I) {
      // Build a new case from the ranges that map to the successor BB. Each
      // range consists of a high and low value which are typed, so the ranges
      // must be rebuilt and a new case constructed from them.
      IntegersSubset CaseRanges = I.getCaseValueEx();
      IntegersSubsetToBB CaseBuilder;
      for (unsigned RI = 0, RE = CaseRanges.getNumItems(); RI < RE; ++RI) {
        CaseBuilder.add(
            IntItem::fromConstantInt(cast<ConstantInt>(convertConstant(
                CaseRanges.getItem(RI).getLow().toConstantInt()))),
            IntItem::fromConstantInt(cast<ConstantInt>(convertConstant(
                CaseRanges.getItem(RI).getHigh().toConstantInt()))));
      }
      IntegersSubset Case = CaseBuilder.getCase();
      NewInst->addCase(Case, I.getCaseSuccessor());
    }
    Switch->eraseFromParent();
  } else {
    errs() << *Inst<<"\n";
    llvm_unreachable("unhandled instruction");
  }
}