void Arith::ComputeFloat() { cs_.B_.SetInsertPoint(floatop_); auto floatt = cs_.rt_.GetType("lua_Number"); auto y_float = CreatePHI(floatt, y_float_inc_, "yfloat"); ra_.SetFloat(PerformFloatOp(x_float_, y_float)); cs_.B_.CreateBr(exit_); }
void TableGet::SaveResult() { cs_.B_.SetInsertPoint(saveresult_); auto ttvalue = cs_.rt_.GetType("TValue"); RTRegister result(cs_, CreatePHI(ttvalue, results_, "resultphi")); dest_.Assign(result); cs_.B_.CreateBr(exit_); }
void TableGet::FinishGet() { cs_.B_.SetInsertPoint(finishget_); auto ttvalue = cs_.rt_.GetType("TValue"); auto tmphi = CreatePHI(ttvalue, tms_, "tmphi"); auto args = { cs_.values_.state, table_.GetTValue(), key_.GetTValue(), dest_.GetTValue(), tmphi }; cs_.CreateCall("luaV_finishget", args); stack_.Update(); cs_.B_.CreateBr(exit_); }
void Arith::CheckYTag() { auto tonumber_y = cs_.CreateSubBlock("tonumber_y", check_y_); cs_.B_.SetInsertPoint(check_y_); auto floatt = cs_.rt_.GetType("lua_Number"); x_float_ = CreatePHI(floatt, x_float_inc_, "xfloat"); y_float_inc_.push_back({y_.GetFloat(), check_y_}); auto is_y_float = y_.HasTag(LUA_TNUMFLT); cs_.B_.CreateCondBr(is_y_float, floatop_, tonumber_y); cs_.B_.SetInsertPoint(tonumber_y); auto args = {y_.GetTValue(), cs_.values_.ynumber}; auto tonumberret = cs_.CreateCall("luaV_tonumber_", args); auto y_converted = cs_.B_.CreateLoad(cs_.values_.ynumber); y_float_inc_.push_back({y_converted, tonumber_y}); auto converted = cs_.ToBool(tonumberret); cs_.B_.CreateCondBr(converted, floatop_, tmop_); }
void GNUstep::IMPCacher::SpeculativelyInline(Instruction *call, Function *function) { BasicBlock *beforeCallBB = call->getParent(); BasicBlock *callBB = SplitBlock(beforeCallBB, call, Owner); BasicBlock *inlineBB = BasicBlock::Create(Context, "inline", callBB->getParent()); BasicBlock::iterator iter = call; iter++; BasicBlock *afterCallBB = SplitBlock(iter->getParent(), iter, Owner); removeTerminator(beforeCallBB); // Put a branch before the call, testing whether the callee really is the // function IRBuilder<> B = IRBuilder<>(beforeCallBB); Value *callee = isa<CallInst>(call) ? cast<CallInst>(call)->getCalledValue() : cast<InvokeInst>(call)->getCalledValue(); const FunctionType *FTy = function->getFunctionType(); const FunctionType *calleeTy = cast<FunctionType>( cast<PointerType>(callee->getType())->getElementType()); if (calleeTy != FTy) { callee = B.CreateBitCast(callee, function->getType()); } Value *isInlineValid = B.CreateICmpEQ(callee, function); B.CreateCondBr(isInlineValid, inlineBB, callBB); // In the inline BB, add a copy of the call, but this time calling the real // version. Instruction *inlineCall = call->clone(); Value *inlineResult= inlineCall; inlineBB->getInstList().push_back(inlineCall); B.SetInsertPoint(inlineBB); if (calleeTy != FTy) { for (unsigned i=0 ; i<FTy->getNumParams() ; i++) { LLVMType *callType = calleeTy->getParamType(i); LLVMType *argType = FTy->getParamType(i); if (callType != argType) { inlineCall->setOperand(i, new BitCastInst(inlineCall->getOperand(i), argType, "", inlineCall)); } } if (FTy->getReturnType() != calleeTy->getReturnType()) { if (FTy->getReturnType() == Type::getVoidTy(Context)) { inlineResult = Constant::getNullValue(calleeTy->getReturnType()); } else { inlineResult = new BitCastInst(inlineCall, calleeTy->getReturnType(), "", inlineBB); } } } B.CreateBr(afterCallBB); // Unify the return values if (call->getType() != Type::getVoidTy(Context)) { PHINode *phi = CreatePHI(call->getType(), 2, "", afterCallBB->begin()); call->replaceAllUsesWith(phi); phi->addIncoming(call, callBB); phi->addIncoming(inlineResult, inlineBB); } // Really do the real inlining InlineFunctionInfo IFI(0, 0); if (CallInst *c = dyn_cast<CallInst>(inlineCall)) { c->setCalledFunction(function); InlineFunction(c, IFI); } else if (InvokeInst *c = dyn_cast<InvokeInst>(inlineCall)) { c->setCalledFunction(function); InlineFunction(c, IFI); } }