Example #1
0
LLValue* DtoBinFloatsEquals(Loc loc, DValue* lhs, DValue* rhs, TOK op)
{
    LLValue* res = 0;
#if DMDV2
    if (op == TOKequal) {
        res = gIR->ir->CreateFCmpOEQ(lhs->getRVal(), rhs->getRVal(), "tmp");
    } else if (op == TOKnotequal) {
        res = gIR->ir->CreateFCmpUNE(lhs->getRVal(), rhs->getRVal(), "tmp");
    } else {
        llvm::ICmpInst::Predicate cmpop;
        if (op == TOKidentity)
            cmpop = llvm::ICmpInst::ICMP_EQ;
        else
            cmpop = llvm::ICmpInst::ICMP_NE;

        LLValue* sz = DtoConstSize_t(getTypeStoreSize(DtoType(lhs->getType())));
        LLValue* val = DtoMemCmp(makeLValue(loc, lhs), makeLValue(loc, rhs), sz);
        res = gIR->ir->CreateICmp(cmpop, val, LLConstantInt::get(val->getType(), 0, false), "tmp");
    }
#else
    LLValue* lv = lhs->getRVal();
    LLValue* rv = rhs->getRVal();
    res = (op == TOKidentity || op == TOKequal) ?
                gIR->ir->CreateFCmpOEQ(lv, rv, "tmp") :
                gIR->ir->CreateFCmpUNE(lv, rv, "tmp");

#endif
    assert(res);
    return res;
}
Example #2
0
DValue* DtoArgument(Parameter* fnarg, Expression* argexp)
{
    IF_LOG Logger::println("DtoArgument");
    LOG_SCOPE;

    DValue* arg = toElem(argexp);

    // ref/out arg
    if (fnarg && (fnarg->storageClass & (STCref | STCout)))
    {
        Loc loc;
        arg = new DImValue(argexp->type, makeLValue(loc, arg));
    }
    // lazy arg
    else if (fnarg && (fnarg->storageClass & STClazy))
    {
        assert(argexp->type->toBasetype()->ty == Tdelegate);
        assert(!arg->isLVal());
        return arg;
    }
    // byval arg, but expr has no storage yet
    else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isNull()))
    {
        LLValue* alloc = DtoAlloca(argexp->type, ".tmp_arg");
        DVarValue* vv = new DVarValue(argexp->type, alloc);
        DtoAssign(argexp->loc, vv, arg);
        arg = vv;
    }

    return arg;
}
Example #3
0
File: aa.cpp Project: alexrp/ldc
DValue *DtoAARemove(Loc& loc, DValue* aa, DValue* key)
{
    // D1:
    // call:
    // extern(C) void _aaDel(AA aa, TypeInfo keyti, void* pkey)

    // D2:
    // call:
    // extern(C) bool _aaDelX(AA aa, TypeInfo keyti, void* pkey)

    // first get the runtime function
#if DMDV2
    llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaDelX");
#else
    llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaDel");
#endif
    LLFunctionType* funcTy = func->getFunctionType();

    if (Logger::enabled())
        Logger::cout() << "_aaDel = " << *func << '\n';

    // aa param
    LLValue* aaval = aa->getRVal();
    if (Logger::enabled())
    {
        Logger::cout() << "aaval: " << *aaval << '\n';
        Logger::cout() << "totype: " << *funcTy->getParamType(0) << '\n';
    }
    aaval = DtoBitCast(aaval, funcTy->getParamType(0));

    // keyti param
#if DMDV2
    LLValue* keyti = to_keyti(aa);
#else
    LLValue* keyti = to_keyti(key);
#endif
    keyti = DtoBitCast(keyti, funcTy->getParamType(1));

    // pkey param
    LLValue* pkey = makeLValue(loc, key);
    pkey = DtoBitCast(pkey, funcTy->getParamType(2));

    // build arg vector
    LLSmallVector<LLValue*, 3> args;
    args.push_back(aaval);
    args.push_back(keyti);
    args.push_back(pkey);

    // call runtime
    LLCallSite call = gIR->CreateCallOrInvoke(func, args);

#if DMDV2
    return new DImValue(Type::tbool, call.getInstruction());
#else
    return NULL;
#endif
}
Example #4
0
LLValue *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op) {
  LLValue *res = nullptr;
  if (op == TOKequal || op == TOKnotequal) {
    LLValue *l = DtoRVal(lhs);
    LLValue *r = DtoRVal(rhs);
    res = (op == TOKequal ? gIR->ir->CreateFCmpOEQ(l, r)
                          : gIR->ir->CreateFCmpUNE(l, r));
    if (lhs->type->toBasetype()->ty == Tvector) {
      res = mergeVectorEquals(res, op);
    }
  } else {
    const auto cmpop =
        op == TOKidentity ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
    LLValue *sz = DtoConstSize_t(getTypeStoreSize(DtoType(lhs->type)));
    LLValue *val = DtoMemCmp(makeLValue(loc, lhs), makeLValue(loc, rhs), sz);
    res = gIR->ir->CreateICmp(cmpop, val,
                              LLConstantInt::get(val->getType(), 0, false));
  }
  assert(res);
  return res;
}
Example #5
0
File: aa.cpp Project: alexrp/ldc
DValue* DtoAAIn(Loc& loc, Type* type, DValue* aa, DValue* key)
{
    // D1:
    // call:
    // extern(C) void* _aaIn(AA aa*, TypeInfo keyti, void* pkey)

    // D2:
    // call:
    // extern(C) void* _aaInX(AA aa*, TypeInfo keyti, void* pkey)

    // first get the runtime function
#if DMDV2
    llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaInX");
#else
    llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaIn");
#endif
    LLFunctionType* funcTy = func->getFunctionType();

    if (Logger::enabled())
        Logger::cout() << "_aaIn = " << *func << '\n';

    // aa param
    LLValue* aaval = aa->getRVal();
    if (Logger::enabled())
    {
        Logger::cout() << "aaval: " << *aaval << '\n';
        Logger::cout() << "totype: " << *funcTy->getParamType(0) << '\n';
    }
    aaval = DtoBitCast(aaval, funcTy->getParamType(0));

    // keyti param
#if DMDV2
    LLValue* keyti = to_keyti(aa);
#else
    LLValue* keyti = to_keyti(key);
#endif
    keyti = DtoBitCast(keyti, funcTy->getParamType(1));

    // pkey param
    LLValue* pkey = makeLValue(loc, key);
    pkey = DtoBitCast(pkey, getVoidPtrType());

    // call runtime
    LLValue* ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.in").getInstruction();

    // cast return value
    LLType* targettype = DtoType(type);
    if (ret->getType() != targettype)
        ret = DtoBitCast(ret, targettype);

    return new DImValue(type, ret);
}
Example #6
0
DValue *DtoAARemove(Loc &loc, DValue *aa, DValue *key) {
  // D1:
  // call:
  // extern(C) void _aaDel(AA aa, TypeInfo keyti, void* pkey)

  // D2:
  // call:
  // extern(C) bool _aaDelX(AA aa, TypeInfo keyti, void* pkey)

  // first get the runtime function
  llvm::Function *func = getRuntimeFunction(loc, gIR->module, "_aaDelX");
  LLFunctionType *funcTy = func->getFunctionType();

  IF_LOG Logger::cout() << "_aaDel = " << *func << '\n';

  // aa param
  LLValue *aaval = aa->getRVal();
  IF_LOG {
    Logger::cout() << "aaval: " << *aaval << '\n';
    Logger::cout() << "totype: " << *funcTy->getParamType(0) << '\n';
  }
  aaval = DtoBitCast(aaval, funcTy->getParamType(0));

  // keyti param
  LLValue *keyti = to_keyti(aa);
  keyti = DtoBitCast(keyti, funcTy->getParamType(1));

  // pkey param
  LLValue *pkey = makeLValue(loc, key);
  pkey = DtoBitCast(pkey, funcTy->getParamType(2));

  // call runtime
  LLCallSite call = gIR->CreateCallOrInvoke(func, aaval, keyti, pkey);

  return new DImValue(Type::tbool, call.getInstruction());
}
Example #7
0
File: aa.cpp Project: glycerine/ldc
DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
{
    // D1:
    // call:
    // extern(C) void* _aaGet(AA* aa, TypeInfo keyti, size_t valuesize, void* pkey)
    // or
    // extern(C) void* _aaIn(AA aa*, TypeInfo keyti, void* pkey)

    // D2:
    // call:
    // extern(C) void* _aaGetX(AA* aa, TypeInfo keyti, size_t valuesize, void* pkey)
    // or
    // extern(C) void* _aaInX(AA aa*, TypeInfo keyti, void* pkey)

    // first get the runtime function
    llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGetX":"_aaInX");
    LLFunctionType* funcTy = func->getFunctionType();

    // aa param
    LLValue* aaval = lvalue ? aa->getLVal() : aa->getRVal();
    aaval = DtoBitCast(aaval, funcTy->getParamType(0));

    // keyti param
    LLValue* keyti = to_keyti(aa);
    keyti = DtoBitCast(keyti, funcTy->getParamType(1));

    // pkey param
    LLValue* pkey = makeLValue(loc, key);
    pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2));

    // call runtime
    LLValue* ret;
    if (lvalue) {
        // valuesize param
        LLValue* valsize = DtoConstSize_t(getTypePaddedSize(DtoType(type)));

        ret = gIR->CreateCallOrInvoke4(func, aaval, keyti, valsize, pkey, "aa.index").getInstruction();
    } else {
        ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.index").getInstruction();
    }

    // cast return value
    LLType* targettype = getPtrToType(DtoType(type));
    if (ret->getType() != targettype)
        ret = DtoBitCast(ret, targettype);

    // Only check bounds for rvalues ('aa[key]').
    // Lvalue use ('aa[key] = value') auto-adds an element.
    if (!lvalue && global.params.useArrayBounds) {
        llvm::BasicBlock* oldend = gIR->scopeend();
        llvm::BasicBlock* failbb = llvm::BasicBlock::Create(gIR->context(), "aaboundscheckfail", gIR->topfunc(), oldend);
        llvm::BasicBlock* okbb = llvm::BasicBlock::Create(gIR->context(), "aaboundsok", gIR->topfunc(), oldend);

        LLValue* nullaa = LLConstant::getNullValue(ret->getType());
        LLValue* cond = gIR->ir->CreateICmpNE(nullaa, ret, "aaboundscheck");
        gIR->ir->CreateCondBr(cond, okbb, failbb);

        // set up failbb to call the array bounds error runtime function

        gIR->scope() = IRScope(failbb, okbb);

        std::vector<LLValue*> args;

        // module param
        LLValue *moduleInfoSymbol = gIR->func()->decl->getModule()->moduleInfoSymbol();
        LLType *moduleInfoType = DtoType(Module::moduleinfo->type);
        args.push_back(DtoBitCast(moduleInfoSymbol, getPtrToType(moduleInfoType)));

        // line param
        LLConstant* c = DtoConstUint(loc.linnum);
        args.push_back(c);

        // call
        llvm::Function* errorfn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_bounds");
        gIR->CreateCallOrInvoke(errorfn, args);

        // the function does not return
        gIR->ir->CreateUnreachable();

        // if ok, proceed in okbb
        gIR->scope() = IRScope(okbb, oldend);
    }
    return new DVarValue(type, ret);
}
Example #8
0
DValue *DtoAAIndex(Loc &loc, Type *type, DValue *aa, DValue *key, bool lvalue) {
  // D2:
  // call:
  // extern(C) void* _aaGetY(AA* aa, TypeInfo aati, size_t valuesize, void*
  // pkey)
  // or
  // extern(C) void* _aaInX(AA aa*, TypeInfo keyti, void* pkey)

  // first get the runtime function
  llvm::Function *func = getRuntimeFunction(
      loc, gIR->module, lvalue ? "_aaGetY" : "_aaInX");
  LLFunctionType *funcTy = func->getFunctionType();

  // aa param
  LLValue *aaval = lvalue ? aa->getLVal() : aa->getRVal();
  aaval = DtoBitCast(aaval, funcTy->getParamType(0));

  // pkey param
  LLValue *pkey = makeLValue(loc, key);
  pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2));

  // call runtime
  LLValue *ret;
  if (lvalue) {
    LLValue *rawAATI =
        DtoTypeInfoOf(aa->type->unSharedOf()->mutableOf(), false);
    LLValue *castedAATI = DtoBitCast(rawAATI, funcTy->getParamType(1));
    LLValue *valsize = DtoConstSize_t(getTypePaddedSize(DtoType(type)));
    ret = gIR->CreateCallOrInvoke(func, aaval, castedAATI, valsize, pkey,
                                  "aa.index")
              .getInstruction();
  } else {
    LLValue *keyti = DtoBitCast(to_keyti(aa), funcTy->getParamType(1));
    ret = gIR->CreateCallOrInvoke(func, aaval, keyti, pkey, "aa.index")
              .getInstruction();
  }

  // cast return value
  LLType *targettype = DtoPtrToType(type);
  if (ret->getType() != targettype) {
    ret = DtoBitCast(ret, targettype);
  }

  // Only check bounds for rvalues ('aa[key]').
  // Lvalue use ('aa[key] = value') auto-adds an element.
  if (!lvalue && gIR->emitArrayBoundsChecks()) {
    llvm::BasicBlock *failbb = llvm::BasicBlock::Create(
        gIR->context(), "aaboundscheckfail", gIR->topfunc());
    llvm::BasicBlock *okbb =
        llvm::BasicBlock::Create(gIR->context(), "aaboundsok", gIR->topfunc());

    LLValue *nullaa = LLConstant::getNullValue(ret->getType());
    LLValue *cond = gIR->ir->CreateICmpNE(nullaa, ret, "aaboundscheck");
    gIR->ir->CreateCondBr(cond, okbb, failbb);

    // set up failbb to call the array bounds error runtime function

    gIR->scope() = IRScope(failbb);

    llvm::Function *errorfn =
        getRuntimeFunction(loc, gIR->module, "_d_arraybounds");
    gIR->CreateCallOrInvoke(
        errorfn, DtoModuleFileName(gIR->func()->decl->getModule(), loc),
        DtoConstUint(loc.linnum));

    // the function does not return
    gIR->ir->CreateUnreachable();

    // if ok, proceed in okbb
    gIR->scope() = IRScope(okbb);
  }
  return new DVarValue(type, ret);
}