Beispiel #1
0
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_);
}
Beispiel #2
0
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_);
}
Beispiel #3
0
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_);
}
Beispiel #4
0
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_);
}
Beispiel #5
0
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);
    }
}