Ejemplo n.º 1
0
bool OptimizeFastMemoryChecks::runOnFunction(Function &F) {
  ABA = &getAnalysis<ArrayBoundsAnalysis>();
  MSCI = &getAnalysis<MSCInfo>();

  // Visit all call instructions in the function to find the checks.
  visit(F);

  for (size_t i = 0, N = FastCheckCalls.size(); i < N; ++i) {
    CallInst *CI = FastCheckCalls[i];
    CheckInfoType *Info = MSCI->getCheckInfo(CI->getCalledFunction());
    assert(Info && Info->isFastMemoryCheck() && "expecting fast memory checks");

    Value *AccessPtr = CI->getArgOperand(Info->PtrArgNo);
    Value *AccessSize = CI->getArgOperand(Info->SizeArgNo);
    Value *ObjectPtr = CI->getArgOperand(Info->ObjArgNo);
    Value *ObjectSize = CI->getArgOperand(Info->ObjSizeArgNo);
    if (ABA->isAlwaysInBounds(AccessPtr, AccessSize, ObjectPtr, ObjectSize)) {
      CI->eraseFromParent();
      ++FastMemoryChecksRemoved;
    }
  }

  bool ChangedAnything = !FastCheckCalls.empty();
  FastCheckCalls.clear();
  return ChangedAnything;
}
Ejemplo n.º 2
0
bool LowerExpectIntrinsic::HandleSwitchExpect(SwitchInst *SI) {
  CallInst *CI = dyn_cast<CallInst>(SI->getCondition());
  if (!CI)
    return false;

  Function *Fn = CI->getCalledFunction();
  if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect)
    return false;

  Value *ArgValue = CI->getArgOperand(0);
  ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1));
  if (!ExpectedValue)
    return false;

  LLVMContext &Context = CI->getContext();
  const Type *Int32Ty = Type::getInt32Ty(Context);

  unsigned caseNo = SI->findCaseValue(ExpectedValue);
  std::vector<Value *> Vec;
  unsigned n = SI->getNumCases();
  Vec.resize(n + 1); // +1 for MDString

  Vec[0] = MDString::get(Context, "branch_weights");
  for (unsigned i = 0; i < n; ++i) {
    Vec[i + 1] = ConstantInt::get(Int32Ty, i == caseNo ? LikelyBranchWeight : UnlikelyBranchWeight);
  }

  MDNode *WeightsNode = llvm::MDNode::get(Context, Vec);
  SI->setMetadata(LLVMContext::MD_prof, WeightsNode);

  SI->setCondition(ArgValue);
  return true;
}
Ejemplo n.º 3
0
bool LowerExpectIntrinsic::HandleSwitchExpect(SwitchInst *SI) {
  CallInst *CI = dyn_cast<CallInst>(SI->getCondition());
  if (!CI)
    return false;

  Function *Fn = CI->getCalledFunction();
  if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect)
    return false;

  Value *ArgValue = CI->getArgOperand(0);
  ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1));
  if (!ExpectedValue)
    return false;

  SwitchInst::CaseIt Case = SI->findCaseValue(ExpectedValue);
  unsigned n = SI->getNumCases(); // +1 for default case.
  std::vector<uint32_t> Weights(n + 1);

  Weights[0] = Case == SI->case_default() ? LikelyBranchWeight
                                          : UnlikelyBranchWeight;
  for (unsigned i = 0; i != n; ++i)
    Weights[i + 1] = i == Case.getCaseIndex() ? LikelyBranchWeight
                                              : UnlikelyBranchWeight;

  SI->setMetadata(LLVMContext::MD_prof,
                  MDBuilder(CI->getContext()).createBranchWeights(Weights));

  SI->setCondition(ArgValue);
  return true;
}
Ejemplo n.º 4
0
/// \brief Check call has a unary float signature
/// It checks following:
/// a) call should have a single argument
/// b) argument type should be floating point type
/// c) call instruction type and argument type should be same
/// d) call should only reads memory.
/// If all these condition is met then return ValidIntrinsicID
/// else return not_intrinsic.
Intrinsic::ID
llvm::checkUnaryFloatSignature(const CallInst &I,
                               Intrinsic::ID ValidIntrinsicID) {
  if (I.getNumArgOperands() != 1 ||
      !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
      I.getType() != I.getArgOperand(0)->getType() || !I.onlyReadsMemory())
    return Intrinsic::not_intrinsic;

  return ValidIntrinsicID;
}
static bool ExpandOpForIntSize(Module *M, unsigned Bits, bool Mul) {
  IntegerType *IntTy = IntegerType::get(M->getContext(), Bits);
  SmallVector<Type *, 1> Types;
  Types.push_back(IntTy);
  Intrinsic::ID ID = (Mul ? Intrinsic::umul_with_overflow
                          : Intrinsic::uadd_with_overflow);
  std::string Name = Intrinsic::getName(ID, Types);
  Function *Intrinsic = M->getFunction(Name);
  if (!Intrinsic)
    return false;
  for (Value::use_iterator CallIter = Intrinsic->use_begin(),
         E = Intrinsic->use_end(); CallIter != E; ) {
    CallInst *Call = dyn_cast<CallInst>(*CallIter++);
    if (!Call) {
      report_fatal_error("ExpandArithWithOverflow: Taking the address of a "
                         "*.with.overflow intrinsic is not allowed");
    }
    Value *VariableArg;
    ConstantInt *ConstantArg;
    if (ConstantInt *C = dyn_cast<ConstantInt>(Call->getArgOperand(0))) {
      VariableArg = Call->getArgOperand(1);
      ConstantArg = C;
    } else if (ConstantInt *C = dyn_cast<ConstantInt>(Call->getArgOperand(1))) {
      VariableArg = Call->getArgOperand(0);
      ConstantArg = C;
    } else {
      errs() << "Use: " << *Call << "\n";
      report_fatal_error("ExpandArithWithOverflow: At least one argument of "
                         "*.with.overflow must be a constant");
    }

    Value *ArithResult = BinaryOperator::Create(
        (Mul ? Instruction::Mul : Instruction::Add), VariableArg, ConstantArg,
        Call->getName() + ".arith", Call);

    uint64_t ArgMax;
    if (Mul) {
      ArgMax = UintTypeMax(Bits) / ConstantArg->getZExtValue();
    } else {
      ArgMax = UintTypeMax(Bits) - ConstantArg->getZExtValue();
    }
    Value *OverflowResult = new ICmpInst(
        Call, CmpInst::ICMP_UGT, VariableArg, ConstantInt::get(IntTy, ArgMax),
        Call->getName() + ".overflow");

    // Construct the struct result.
    Value *NewStruct = UndefValue::get(Call->getType());
    NewStruct = CreateInsertValue(NewStruct, 0, ArithResult, Call);
    NewStruct = CreateInsertValue(NewStruct, 1, OverflowResult, Call);
    Call->replaceAllUsesWith(NewStruct);
    Call->eraseFromParent();
  }
  Intrinsic->eraseFromParent();
  return true;
}
Ejemplo n.º 6
0
bool LowerExpectIntrinsic::HandleIfExpect(BranchInst *BI) {
  if (BI->isUnconditional())
    return false;

  // Handle non-optimized IR code like:
  //   %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1)
  //   %tobool = icmp ne i64 %expval, 0
  //   br i1 %tobool, label %if.then, label %if.end
  //
  // Or the following simpler case:
  //   %expval = call i1 @llvm.expect.i1(i1 %cmp, i1 1)
  //   br i1 %expval, label %if.then, label %if.end

  CallInst *CI;

  ICmpInst *CmpI = dyn_cast<ICmpInst>(BI->getCondition());
  if (!CmpI) {
    CI = dyn_cast<CallInst>(BI->getCondition());
  } else {
    if (CmpI->getPredicate() != CmpInst::ICMP_NE)
      return false;
    CI = dyn_cast<CallInst>(CmpI->getOperand(0));
  }

  if (!CI)
    return false;

  Function *Fn = CI->getCalledFunction();
  if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect)
    return false;

  Value *ArgValue = CI->getArgOperand(0);
  ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1));
  if (!ExpectedValue)
    return false;

  MDBuilder MDB(CI->getContext());
  MDNode *Node;

  // If expect value is equal to 1 it means that we are more likely to take
  // branch 0, in other case more likely is branch 1.
  if (ExpectedValue->isOne())
    Node = MDB.createBranchWeights(LikelyBranchWeight, UnlikelyBranchWeight);
  else
    Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight);

  BI->setMetadata(LLVMContext::MD_prof, Node);

  if (CmpI)
    CmpI->setOperand(0, ArgValue);
  else
    BI->setCondition(ArgValue);
  return true;
}
Ejemplo n.º 7
0
// llvm.ptx.memcpy.const and llvm.ptx.memmove.const need to be modeled as
// TgtMemIntrinsic
// because we need the information that is only available in the "Value" type
// of destination
// pointer. In particular, the address space information.
bool
NVPTXTargetLowering::getTgtMemIntrinsic(IntrinsicInfo& Info, const CallInst &I,
                                        unsigned Intrinsic) const {
  switch (Intrinsic) {
  default:
    return false;

  case Intrinsic::nvvm_atomic_load_add_f32:
    Info.opc = ISD::INTRINSIC_W_CHAIN;
    Info.memVT = MVT::f32;
    Info.ptrVal = I.getArgOperand(0);
    Info.offset = 0;
    Info.vol = 0;
    Info.readMem = true;
    Info.writeMem = true;
    Info.align = 0;
    return true;

  case Intrinsic::nvvm_atomic_load_inc_32:
  case Intrinsic::nvvm_atomic_load_dec_32:
    Info.opc = ISD::INTRINSIC_W_CHAIN;
    Info.memVT = MVT::i32;
    Info.ptrVal = I.getArgOperand(0);
    Info.offset = 0;
    Info.vol = 0;
    Info.readMem = true;
    Info.writeMem = true;
    Info.align = 0;
    return true;

  case Intrinsic::nvvm_ldu_global_i:
  case Intrinsic::nvvm_ldu_global_f:
  case Intrinsic::nvvm_ldu_global_p:

    Info.opc = ISD::INTRINSIC_W_CHAIN;
    if (Intrinsic == Intrinsic::nvvm_ldu_global_i)
      Info.memVT = MVT::i32;
    else if (Intrinsic == Intrinsic::nvvm_ldu_global_p)
      Info.memVT = getPointerTy();
    else
      Info.memVT = MVT::f32;
    Info.ptrVal = I.getArgOperand(0);
    Info.offset = 0;
    Info.vol = 0;
    Info.readMem = true;
    Info.writeMem = false;
    Info.align = 0;
    return true;

  }
  return false;
}
Ejemplo n.º 8
0
/// AddCatchInfo - Extract the personality and type infos from an eh.selector
/// call, and add them to the specified machine basic block.
void llvm::AddCatchInfo(const CallInst &I, MachineModuleInfo *MMI,
                        MachineBasicBlock *MBB) {
    // Inform the MachineModuleInfo of the personality for this landing pad.
    const ConstantExpr *CE = cast<ConstantExpr>(I.getArgOperand(1));
    assert(CE->getOpcode() == Instruction::BitCast &&
           isa<Function>(CE->getOperand(0)) &&
           "Personality should be a function");
    MMI->addPersonality(MBB, cast<Function>(CE->getOperand(0)));

    // Gather all the type infos for this landing pad and pass them along to
    // MachineModuleInfo.
    std::vector<const GlobalVariable *> TyInfo;
    unsigned N = I.getNumArgOperands();

    for (unsigned i = N - 1; i > 1; --i) {
        if (const ConstantInt *CI = dyn_cast<ConstantInt>(I.getArgOperand(i))) {
            unsigned FilterLength = CI->getZExtValue();
            unsigned FirstCatch = i + FilterLength + !FilterLength;
            assert(FirstCatch <= N && "Invalid filter length");

            if (FirstCatch < N) {
                TyInfo.reserve(N - FirstCatch);
                for (unsigned j = FirstCatch; j < N; ++j)
                    TyInfo.push_back(ExtractTypeInfo(I.getArgOperand(j)));
                MMI->addCatchTypeInfo(MBB, TyInfo);
                TyInfo.clear();
            }

            if (!FilterLength) {
                // Cleanup.
                MMI->addCleanup(MBB);
            } else {
                // Filter.
                TyInfo.reserve(FilterLength - 1);
                for (unsigned j = i + 1; j < FirstCatch; ++j)
                    TyInfo.push_back(ExtractTypeInfo(I.getArgOperand(j)));
                MMI->addFilterTypeInfo(MBB, TyInfo);
                TyInfo.clear();
            }

            N = i;
        }
    }

    if (N > 2) {
        TyInfo.reserve(N - 2);
        for (unsigned j = 2; j < N; ++j)
            TyInfo.push_back(ExtractTypeInfo(I.getArgOperand(j)));
        MMI->addCatchTypeInfo(MBB, TyInfo);
    }
}
static bool expandIntrinsic(Module *M, Intrinsic::ID ID) {
  SmallVector<Type *, 3> Types;
  Types.push_back(Type::getInt8PtrTy(M->getContext()));
  if (ID != Intrinsic::memset)
    Types.push_back(Type::getInt8PtrTy(M->getContext()));
  unsigned LengthTypePos = Types.size();
  Types.push_back(Type::getInt64Ty(M->getContext()));

  std::string OldName = Intrinsic::getName(ID, Types);
  Function *OldIntrinsic = M->getFunction(OldName);
  if (!OldIntrinsic)
    return false;

  Types[LengthTypePos] = Type::getInt32Ty(M->getContext());
  Function *NewIntrinsic = Intrinsic::getDeclaration(M, ID, Types);

  for (Value::use_iterator CallIter = OldIntrinsic->use_begin(),
         E = OldIntrinsic->use_end(); CallIter != E; ) {
    CallInst *Call = dyn_cast<CallInst>(*CallIter++);
    if (!Call) {
      report_fatal_error("CanonicalizeMemIntrinsics: Taking the address of an "
                         "intrinsic is not allowed: " + OldName);
    }
    // This temporarily leaves Call non-well-typed.
    Call->setCalledFunction(NewIntrinsic);
    // Truncate the "len" argument.  No overflow check.
    IRBuilder<> Builder(Call);
    Value *Length = Builder.CreateTrunc(Call->getArgOperand(2),
                                        Type::getInt32Ty(M->getContext()),
                                        "mem_len_truncate");
    Call->setArgOperand(2, Length);
  }
  OldIntrinsic->eraseFromParent();
  return true;
}
Ejemplo n.º 10
0
    virtual bool runOnFunction(Function& F) {
        int num_changed = 0;
        StatCounter sc_num_unnescessary_boxes("opt_unnescessary_boxes");

        std::unordered_map<CallInst*, CallInst*> dead_boxing_call;
        for (inst_iterator inst_it = inst_begin(F), _inst_end = inst_end(F); inst_it != _inst_end; ++inst_it) {
            CallInst* CI = dyn_cast<CallInst>(&*inst_it);
            if (!CI)
                continue;

            // We are only interested in boxInt, boxFloat and boxBool calls
            void* func = getCalledFuncAddr(CI);
            if (func != boxInt && func != boxFloat && func != boxBool)
                continue;

            CallInst* CI2 = dyn_cast<CallInst>(CI->getArgOperand(0));
            if (!CI2)
                continue;

            // Check if the value passed as argument to the boxing call is coming from the corresponding unbox call
            void* func2 = getCalledFuncAddr(CI2);
            if ((func == boxInt && func2 == unboxInt) || (func == boxFloat && func2 == unboxFloat)
                || (func == boxBool && func2 == unboxBool))
                dead_boxing_call[CI] = CI2;
        }

        for (auto&& I : dead_boxing_call) {
            I.first->replaceAllUsesWith(new BitCastInst(I.second->getArgOperand(0), I.first->getType(), "", I.first));
            I.first->eraseFromParent();
            ++num_changed;
            sc_num_unnescessary_boxes.log();
        }

        return num_changed > 0;
    }
Ejemplo n.º 11
0
bool LowerExpectIntrinsic::runOnFunction(Function &F) {
  for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
    BasicBlock *BB = I++;

    // Create "block_weights" metadata.
    if (BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator())) {
      if (HandleIfExpect(BI))
        IfHandled++;
    } else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator())) {
      if (HandleSwitchExpect(SI))
        IfHandled++;
    }

    // remove llvm.expect intrinsics.
    for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
         BI != BE; ) {
      CallInst *CI = dyn_cast<CallInst>(BI++);
      if (!CI)
        continue;

      Function *Fn = CI->getCalledFunction();
      if (Fn && Fn->getIntrinsicID() == Intrinsic::expect) {
        Value *Exp = CI->getArgOperand(0);
        CI->replaceAllUsesWith(Exp);
        CI->eraseFromParent();
      }
    }
  }

  return false;
}
Ejemplo n.º 12
0
void Executor::executeAtomicDec(ExecutionState &state, 
                                KInstruction *target, 
                                std::vector< ref<Expr> > &arguments, 
                                unsigned seqNum) {
  // Load the value from addr
  ref<Expr> base = arguments[0];
  CallInst *ci = static_cast<CallInst*>(target->inst);     

  updateCType(state, ci->getArgOperand(0), base, state.tinfo.is_GPU_mode);
  executeMemoryOperation(state, false, base, 0, 
                         target, seqNum, true);     

  // (old == 0) | (old > val) 
  ref<Expr> zeroExpr = klee::ConstantExpr::create(0, arguments[1]->getWidth());
  ref<Expr> oneExpr = klee::ConstantExpr::create(1, arguments[1]->getWidth());
  ref<Expr> compCond = OrExpr::create(EqExpr::create(atomicRes, zeroExpr),
                                      UgtExpr::create(atomicRes, arguments[1]));

  Executor::StatePair branches = fork(state, compCond, true); 
  if (branches.first) {
    executeMemoryOperation(*branches.first, true, base, arguments[1], 
                           target, seqNum, true);
    bindLocal(target, *branches.first, atomicRes);
  } 
  if (branches.second) {
    executeMemoryOperation(*branches.second, true, base, 
                           SubExpr::create(atomicRes, oneExpr), 
                           target, seqNum, true);
    bindLocal(target, *branches.second, atomicRes);
  } 
}
Ejemplo n.º 13
0
void Executor::executeAtomicCAS(ExecutionState &state, KInstruction *target, 
                                std::vector< ref<Expr> > &arguments, 
                                unsigned seqNum) {
  // Load the value from addr
  ref<Expr> base = arguments[0];
  CallInst *ci = static_cast<CallInst*>(target->inst);     

  updateCType(state, ci->getArgOperand(0), base, state.tinfo.is_GPU_mode);
  executeMemoryOperation(state, false, base, 0, 
                         target, seqNum, true);     
   
  // old == compare 
  ref<Expr> compCond = EqExpr::create(atomicRes, arguments[1]);

  state.tinfo.is_Atomic_op = 1;
  Executor::StatePair branches = fork(state, compCond, true); 
  if (branches.first) {
    executeMemoryOperation(*branches.first, true, base, arguments[2], 
                           target, seqNum, true);
    bindLocal(target, *branches.first, atomicRes);
  }
  if (branches.second) {
    //executeMemoryOperation(*branches.second, true, base, atomicRes, 
    //                       target, seqNum, true, true);
    bindLocal(target, *branches.second, atomicRes);
  }
  state.tinfo.is_Atomic_op = 0;
}
Ejemplo n.º 14
0
void Aa::LowerConstantExpr::process(Instruction *inst)
{

  if(isa<llvm::CallInst>(inst))
    {
      CallInst* ci = dyn_cast<CallInst>(inst);
      for(int idx = 0; idx < ci->getNumArgOperands(); idx++) 
	{
	  llvm::Value *opnd = ci->getArgOperand(idx);
	  if (ConstantExpr *ce = dyn_cast<ConstantExpr>(opnd)) {
	    lower(ce, inst);
	  }
	}
    }
  else
    {
      for (unsigned oi = 0, oe = inst->getNumOperands();
	   oi != oe; oi++) {
	llvm::Value *opnd = inst->getOperand(oi);
	
	if (ConstantExpr *ce = dyn_cast<ConstantExpr>(opnd)) {
	  lower(ce, inst);
	}
      }
    }
}
Ejemplo n.º 15
0
static unsigned get_datatype_index(StringRef Name, const CallInst& I)
{
   GlobalVariable* datatype;
   unsigned C = lle::get_mpi_count_idx(&I);
   if(C==0){
      errs()<<"WARNNING: doesn't consider "<<Name<<" mpi call\n";
      return 0;
   }
   datatype = dyn_cast<GlobalVariable>(I.getArgOperand(C+1)); // this is p2p communication
   auto CI = dyn_cast<ConstantInt>(datatype->getInitializer());
   if(CI == NULL){
      errs()<<"WARNNING: not a constant number "<<*I.getArgOperand(C+1)<<"\n";
      return 0;
   }
   return CI->getZExtValue(); // datatype -> sizeof
}
Ejemplo n.º 16
0
void SelectionDAGBuilder::visitGCResult(const CallInst &CI) {
  // The result value of the gc_result is simply the result of the actual
  // call.  We've already emitted this, so just grab the value.
  Instruction *I = cast<Instruction>(CI.getArgOperand(0));
  assert(isStatepoint(I) && "first argument must be a statepoint token");

  if (I->getParent() != CI.getParent()) {
    // Statepoint is in different basic block so we should have stored call
    // result in a virtual register.
    // We can not use default getValue() functionality to copy value from this
    // register because statepoint and actuall call return types can be
    // different, and getValue() will use CopyFromReg of the wrong type,
    // which is always i32 in our case.
    PointerType *CalleeType = cast<PointerType>(
        ImmutableStatepoint(I).getCalledValue()->getType());
    Type *RetTy =
        cast<FunctionType>(CalleeType->getElementType())->getReturnType();
    SDValue CopyFromReg = getCopyFromRegs(I, RetTy);

    assert(CopyFromReg.getNode());
    setValue(&CI, CopyFromReg);
  } else {
    setValue(&CI, getValue(I));
  }
}
Ejemplo n.º 17
0
    void RuntimeHelperFixupPass::FixArrayInit(Function *F)
    {
        Module *M = F->getParent();
        LLVMContext &ctx = F->getContext();
        
        for (auto it = F->use_begin(), end = F->use_end(); it != end; ++it)
        {
            CallInst *CI = dyn_cast<CallInst>(*it);
            assert (CI && "Unknown usage for array init helper");
            
            Instruction *field_runtime_handle = dyn_cast<Instruction>(CI->getArgOperand(1));
            assert (field_runtime_handle);
            
            MDNode *md = field_runtime_handle->getMetadata("silk_runtime_field_handle");
            assert (md);
            
            ConstantInt *handle = dyn_cast<ConstantInt>(md->getOperand(0));
            assert(handle);
            
            auto vm_field = reinterpret_cast<VMField*>(handle->getValue().getLimitedValue());
            auto field_map = vm_field->field_mapping();
            
            auto vm_named_class = dynamic_cast<VMNamedClass*>(vm_field->type());
            auto size = vm_named_class->type_def()->class_size();

            raw_istream is(field_map.start(), size);

            std::vector<uint8_t> buf;
            buf.resize(size);
            is.read((char*)buf.data(), size);
            
            Constant *predefined_value = ConstantDataArray::get(ctx, buf);
            auto GV = new GlobalVariable(*M, predefined_value->getType(),
                                         true, GlobalValue::InternalLinkage,
                                         predefined_value, ".initdata");
            
            Value *array_ptr = CI->getArgOperand(0);
            IRBuilder<> builder(CI);
            
            auto intrinsic_array_base = intrinsic_->array_base_pointer();
            auto array_ptr_casted = builder.CreateBitCast(array_ptr, builder.getInt8PtrTy());
            auto array_base_ptr = builder.CreateCall(intrinsic_array_base, array_ptr_casted);
            builder.CreateMemCpy(array_base_ptr, GV, ConstantInt::get(Type::getInt64Ty(ctx), size), 0);
            CI->eraseFromParent();
        }
    }
Ejemplo n.º 18
0
bool LowerExpectIntrinsic::HandleIfExpect(BranchInst *BI) {
  if (BI->isUnconditional())
    return false;

  // Handle non-optimized IR code like:
  //   %expval = call i64 @llvm.expect.i64.i64(i64 %conv1, i64 1)
  //   %tobool = icmp ne i64 %expval, 0
  //   br i1 %tobool, label %if.then, label %if.end

  ICmpInst *CmpI = dyn_cast<ICmpInst>(BI->getCondition());
  if (!CmpI || CmpI->getPredicate() != CmpInst::ICMP_NE)
    return false;

  CallInst *CI = dyn_cast<CallInst>(CmpI->getOperand(0));
  if (!CI)
    return false;

  Function *Fn = CI->getCalledFunction();
  if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect)
    return false;

  Value *ArgValue = CI->getArgOperand(0);
  ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1));
  if (!ExpectedValue)
    return false;

  LLVMContext &Context = CI->getContext();
  const Type *Int32Ty = Type::getInt32Ty(Context);
  bool Likely = ExpectedValue->isOne();

  // If expect value is equal to 1 it means that we are more likely to take
  // branch 0, in other case more likely is branch 1.
  Value *Ops[] = {
    MDString::get(Context, "branch_weights"),
    ConstantInt::get(Int32Ty, Likely ? LikelyBranchWeight : UnlikelyBranchWeight),
    ConstantInt::get(Int32Ty, Likely ? UnlikelyBranchWeight : LikelyBranchWeight)
  };

  MDNode *WeightsNode = MDNode::get(Context, Ops);
  BI->setMetadata(LLVMContext::MD_prof, WeightsNode);

  CmpI->setOperand(0, ArgValue);
  return true;
}
/// \brief Recursively handle the condition leading to a loop
Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken) {
  if (PHINode *Phi = dyn_cast<PHINode>(Cond)) {
    BasicBlock *Parent = Phi->getParent();
    PHINode *NewPhi = PHINode::Create(Int64, 0, "", &Parent->front());
    Value *Ret = NewPhi;

    // Handle all non-constant incoming values first
    for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
      Value *Incoming = Phi->getIncomingValue(i);
      BasicBlock *From = Phi->getIncomingBlock(i);
      if (isa<ConstantInt>(Incoming)) {
        NewPhi->addIncoming(Broken, From);
        continue;
      }

      Phi->setIncomingValue(i, BoolFalse);
      Value *PhiArg = handleLoopCondition(Incoming, Broken);
      NewPhi->addIncoming(PhiArg, From);
    }

    BasicBlock *IDom = DT->getNode(Parent)->getIDom()->getBlock();

    for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {

      Value *Incoming = Phi->getIncomingValue(i);
      if (Incoming != BoolTrue)
        continue;

      BasicBlock *From = Phi->getIncomingBlock(i);
      if (From == IDom) {
        CallInst *OldEnd = dyn_cast<CallInst>(Parent->getFirstInsertionPt());
        if (OldEnd && OldEnd->getCalledFunction() == EndCf) {
          Value *Args[] = { OldEnd->getArgOperand(0), NewPhi };
          Ret = CallInst::Create(ElseBreak, Args, "", OldEnd);
          continue;
        }
      }
      TerminatorInst *Insert = From->getTerminator();
      Value *PhiArg = CallInst::Create(Break, Broken, "", Insert);
      NewPhi->setIncomingValue(i, PhiArg);
    }
    eraseIfUnused(Phi);
    return Ret;

  } else if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
    BasicBlock *Parent = Inst->getParent();
    TerminatorInst *Insert = Parent->getTerminator();
    Value *Args[] = { Cond, Broken };
    return CallInst::Create(IfBreak, Args, "", Insert);

  } else {
    llvm_unreachable("Unhandled loop condition!");
  }
  return 0;
}
Ejemplo n.º 20
0
bool IRTranslator::translateMemcpy(const CallInst &CI) {
  LLT SizeTy{*CI.getArgOperand(2)->getType(), *DL};
  if (cast<PointerType>(CI.getArgOperand(0)->getType())->getAddressSpace() !=
          0 ||
      cast<PointerType>(CI.getArgOperand(1)->getType())->getAddressSpace() !=
          0 ||
      SizeTy.getSizeInBits() != DL->getPointerSizeInBits(0))
    return false;

  SmallVector<CallLowering::ArgInfo, 8> Args;
  for (int i = 0; i < 3; ++i) {
    const auto &Arg = CI.getArgOperand(i);
    Args.emplace_back(getOrCreateVReg(*Arg), Arg->getType());
  }

  MachineOperand Callee = MachineOperand::CreateES("memcpy");

  return CLI->lowerCall(MIRBuilder, Callee,
                        CallLowering::ArgInfo(0, CI.getType()), Args);
}
Ejemplo n.º 21
0
/// \brief Recursively handle the condition leading to a loop
void SIAnnotateControlFlow::handleLoopCondition(Value *Cond) {
  if (PHINode *Phi = dyn_cast<PHINode>(Cond)) {

    // Handle all non-constant incoming values first
    for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
      Value *Incoming = Phi->getIncomingValue(i);
      if (isa<ConstantInt>(Incoming))
        continue;

      Phi->setIncomingValue(i, BoolFalse);
      handleLoopCondition(Incoming);
    }

    BasicBlock *Parent = Phi->getParent();
    BasicBlock *IDom = DT->getNode(Parent)->getIDom()->getBlock();

    for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {

      Value *Incoming = Phi->getIncomingValue(i);
      if (Incoming != BoolTrue)
        continue;

      BasicBlock *From = Phi->getIncomingBlock(i);
      if (From == IDom) {
        CallInst *OldEnd = dyn_cast<CallInst>(Parent->getFirstInsertionPt());
        if (OldEnd && OldEnd->getCalledFunction() == EndCf) {
          Value *Args[] = {
            OldEnd->getArgOperand(0),
            PhiInserter.GetValueAtEndOfBlock(Parent)
          };
          Value *Ret = CallInst::Create(ElseBreak, Args, "", OldEnd);
          PhiInserter.AddAvailableValue(Parent, Ret);
          continue;
        }
      }

      TerminatorInst *Insert = From->getTerminator();
      Value *Arg = PhiInserter.GetValueAtEndOfBlock(From);
      Value *Ret = CallInst::Create(Break, Arg, "", Insert);
      PhiInserter.AddAvailableValue(From, Ret);
    }
    eraseIfUnused(Phi);

  } else if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
    BasicBlock *Parent = Inst->getParent();
    TerminatorInst *Insert = Parent->getTerminator();
    Value *Args[] = { Cond, PhiInserter.GetValueAtEndOfBlock(Parent) };
    Value *Ret = CallInst::Create(IfBreak, Args, "", Insert);
    PhiInserter.AddAvailableValue(Parent, Ret);

  } else {
    llvm_unreachable("Unhandled loop condition!");
  }
}
Ejemplo n.º 22
0
void OptimizeGEPChecks::visitCallInst(CallInst &CI) {
  CheckInfoType *Info = MSCI->getCheckInfo(CI.getCalledFunction());
  if (!Info || !Info->isGEPCheck())
    return;

  // Check whether it is a GEP instruction just in case it has been converted
  // to a constant already.
  Value *GEPArg = CI.getArgOperand(Info->DestPtrArgNo);
  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(GEPArg)) {
    if (ABC->isGEPSafe(GEP))
      ToRemove.push_back(&CI);
  }
}
Ejemplo n.º 23
0
void ExtractContracts::visitCallInst(CallInst &I) {
  if (auto F = I.getCalledFunction()) {
    auto name = F->getName();
    if (name == Naming::CONTRACT_REQUIRES ||
        name == Naming::CONTRACT_ENSURES ||
        name == Naming::CONTRACT_INVARIANT) {

      validateAnnotation(I);

      if (auto J = dyn_cast<CallInst>(I.getArgOperand(0)))
        if (auto G = J->getCalledFunction())
          if (G->getName().find(Naming::CONTRACT_EXPR) != std::string::npos)
            return;

      Function* EF;
      std::vector<Value*> Args;
      tie(EF, Args) = extractExpression(I.getArgOperand(0), I.getParent());
      I.setArgOperand(0, CallInst::Create(EF, Args, "", &I));
      modified = true;

      // TODO can we somehow force LLVM to consider calls to the obsoleted
      // forall, exists, etc., to be dead code?

    } else if (name == Naming::CONTRACT_FORALL ||
               name == Naming::CONTRACT_EXISTS) {

      if (auto J = dyn_cast<CallInst>(I.getArgOperand(1)))
        if (auto G = J->getCalledFunction())
          if (G->getName().find(Naming::CONTRACT_EXPR) != std::string::npos)
            return;

      Function* EF;
      std::vector<Value*> Args;
      tie(EF, Args) = extractExpression(I.getArgOperand(1), I.getParent());
      I.setArgOperand(1, CallInst::Create(EF, Args, "", &I));
      modified = true;
    }
  }
}
Ejemplo n.º 24
0
void Executor::executeAtomicMax(ExecutionState &state, 
                                KInstruction *target, std::string fName, 
                                std::vector< ref<Expr> > &arguments, 
                                unsigned seqNum) {
  // Load the value from addr
  ref<Expr> base = arguments[0];
  CallInst *ci = static_cast<CallInst*>(target->inst);     

  updateCType(state, ci->getArgOperand(0), base, state.tinfo.is_GPU_mode);
  executeMemoryOperation(state, false, base, 0, 
                         target, seqNum, true);     
  // compare and store the value
  compareValue(state, target, fName, arguments, seqNum, base, false);
}
Ejemplo n.º 25
0
 void RuntimeHelperFixupPass::FixStringConstructor(Function *old_construct, Function *new_construct)
 {
     for (auto it = old_construct->use_begin(), end = old_construct->use_end(); it != end; ++it)
     {
         CallInst *CI = dyn_cast<CallInst>(*it);
         assert (CI);
         
         auto num_ops = CI->getNumArgOperands();
         SmallVector<Value*, 4> ops;
         for (size_t i = 1; i < num_ops; ++i)
             ops.push_back(CI->getArgOperand(i));
         
         IRBuilder<> builder(CI);
         auto new_call = builder.CreateCall(new_construct, ops);
         
         BitCastInst *this_ptr = cast<BitCastInst>(CI->getArgOperand(0));
         auto alloc = cast<Instruction>(this_ptr->llvm::User::getOperand(0));
         this_ptr->replaceAllUsesWith(new_call);
         CI->eraseFromParent();
         this_ptr->eraseFromParent();
         alloc->eraseFromParent();
     }
 }
Ejemplo n.º 26
0
void llvm::computeUsesVAFloatArgument(const CallInst &I,
                                      MachineModuleInfo &MMI) {
  FunctionType *FT =
      cast<FunctionType>(I.getCalledValue()->getType()->getContainedType(0));
  if (FT->isVarArg() && !MMI.usesVAFloatArgument()) {
    for (unsigned i = 0, e = I.getNumArgOperands(); i != e; ++i) {
      Type *T = I.getArgOperand(i)->getType();
      for (auto i : post_order(T)) {
        if (i->isFloatingPointTy()) {
          MMI.setUsesVAFloatArgument(true);
          return;
        }
      }
    }
  }
}
Ejemplo n.º 27
0
void LLSTDebuggingPass::insertSelfInSendMessageCheck(Function& F)
{
    Value* BrokenSelfMessage = m_builder->CreateGlobalStringPtr("\nself is broken\n");

    InstructionVector Calls;
    for (Function::iterator BB = F.begin(); BB != F.end(); ++BB)
    {
        for(BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II)
        {
            if (CallInst* Call = dyn_cast<CallInst>(II)) {
                if (Call->getCalledFunction()->getName() == "sendMessage")
                    Calls.push_back(Call);
            }
        }
    }

    for(std::size_t i = 0; i < Calls.size(); i++)
    {
        CallInst* Call = dyn_cast<CallInst>(Calls[i]);

        BasicBlock* PointerIsOkBB = Call->getParent()->splitBasicBlock( static_cast<BasicBlock::iterator>(Call) );
        BasicBlock* PointerIsBrokenBB = BasicBlock::Create(m_module->getContext(), "", &F, PointerIsOkBB);
        BasicBlock* PointerIsNotSmallIntBB = BasicBlock::Create(m_module->getContext(), "", &F, PointerIsBrokenBB);

        Instruction* branchToPointerIsOkBB = & PointerIsOkBB->getSinglePredecessor()->back();
        m_builder->SetInsertPoint(branchToPointerIsOkBB);


        Value* argsPtr = m_builder->CreateBitCast( Call->getArgOperand(2), m_baseTypes.object->getPointerTo());
        Value* self = m_builder->CreateCall2(getObjectField, argsPtr, m_builder->getInt32(0));

        Value* isSmallInt = m_builder->CreateCall(isSmallInteger, self);
        m_builder->CreateCondBr(isSmallInt, PointerIsOkBB, PointerIsNotSmallIntBB);


        m_builder->SetInsertPoint(PointerIsNotSmallIntBB);
        Value* klassPtr = m_builder->CreateCall(getObjectClass, self);
        Value* pointerIsNull = m_builder->CreateICmpEQ(klassPtr, ConstantPointerNull::get(m_baseTypes.klass->getPointerTo()) );
        m_builder->CreateCondBr(pointerIsNull, PointerIsBrokenBB, PointerIsOkBB);
        branchToPointerIsOkBB->eraseFromParent();

        m_builder->SetInsertPoint(PointerIsBrokenBB);
        m_builder->CreateCall(_printf, BrokenSelfMessage);
        m_builder->CreateBr(PointerIsOkBB);
    }
}
Ejemplo n.º 28
0
void Executor::executeAtomicExch(ExecutionState &state, KInstruction *target, 
                                 std::vector< ref<Expr> > &arguments, 
                                 unsigned seqNum) {
  // Load the value from addr
  ref<Expr> base = arguments[0];
  CallInst *ci = static_cast<CallInst*>(target->inst);     

  updateCType(state, ci->getArgOperand(0), base, state.tinfo.is_GPU_mode);
  executeMemoryOperation(state, false, base, 0, 
                         target, seqNum, true);     

  // Store back to original place 
  executeMemoryOperation(state, true, base, arguments[1], 
                         target, seqNum, true);

  bindLocal(target, state, atomicRes);
  return;
}
Ejemplo n.º 29
0
/// ComputeUsesVAFloatArgument - Determine if any floating-point values are
/// being passed to this variadic function, and set the MachineModuleInfo's
/// usesVAFloatArgument flag if so. This flag is used to emit an undefined
/// reference to _fltused on Windows, which will link in MSVCRT's
/// floating-point support.
void llvm::ComputeUsesVAFloatArgument(const CallInst &I,
                                      MachineModuleInfo *MMI)
{
    FunctionType *FT = cast<FunctionType>(
                           I.getCalledValue()->getType()->getContainedType(0));
    if (FT->isVarArg() && !MMI->usesVAFloatArgument()) {
        for (unsigned i = 0, e = I.getNumArgOperands(); i != e; ++i) {
            Type* T = I.getArgOperand(i)->getType();
            for (po_iterator<Type*> i = po_begin(T), e = po_end(T);
                    i != e; ++i) {
                if (i->isFloatingPointTy()) {
                    MMI->setUsesVAFloatArgument(true);
                    return;
                }
            }
        }
    }
}
Ejemplo n.º 30
0
bool OptimizeGEPChecks::runOnFunction(Function &F) {
  ABC = &getAnalysis<ArrayBoundsCheckLocal>();
  MSCI = &getAnalysis<MSCInfo>();

  // Visit all call instructions in the function.
  visit(F);

  for (size_t i = 0, N = ToRemove.size(); i < N; ++i) {
    CallInst *CI = ToRemove[i];
    CheckInfoType *Info = MSCI->getCheckInfo(CI->getCalledFunction());
    CI->replaceAllUsesWith(CI->getArgOperand(Info->DestPtrArgNo));
    CI->eraseFromParent();
    ++SafeGEPs;
  }

  bool ChangedAnything = !ToRemove.empty();
  ToRemove.clear();
  return ChangedAnything;
}