Ejemplo n.º 1
0
LLConstant *DtoGEPi(LLConstant *ptr, unsigned i0, unsigned i1) {
  LLPointerType *p = isaPointer(ptr);
  (void)p;
  assert(p && "GEP expects a pointer type");
  LLValue *indices[] = {DtoConstUint(i0), DtoConstUint(i1)};
  return llvm::ConstantExpr::getGetElementPtr(
      p->getElementType(), ptr, indices, /* InBounds = */ true);
}
Ejemplo n.º 2
0
LLValue* DtoGEPi1(LLValue* ptr, unsigned i, const char* var, llvm::BasicBlock* bb)
{
    LLPointerType* p = isaPointer(ptr);
    assert(p && "GEP expects a pointer type");
    return llvm::GetElementPtrInst::Create(
#if LDC_LLVM_VER >= 307
        p->getElementType(),
#endif
        ptr, DtoConstUint(i), var, bb ? bb : gIR->scopebb());
}
Ejemplo n.º 3
0
LLConstant* DtoGEPi(LLConstant* ptr, unsigned i0, unsigned i1)
{
    LLPointerType* p = isaPointer(ptr);
    assert(p && "GEP expects a pointer type");
    LLValue* v[] = { DtoConstUint(i0), DtoConstUint(i1) };
    return llvm::ConstantExpr::getGetElementPtr(
#if LDC_LLVM_VER >= 307
        p->getElementType(),
#endif
        ptr, v, true);
}
Ejemplo n.º 4
0
LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var, llvm::BasicBlock* bb)
{
    LLPointerType* p = isaPointer(ptr);
    assert(p && "GEP expects a pointer type");
    LLValue* v[] = { i0, i1 };
    return llvm::GetElementPtrInst::Create(
#if LDC_LLVM_VER >= 307
        p->getElementType(),
#endif
        ptr, v, var, bb ? bb : gIR->scopebb());
}
Ejemplo n.º 5
0
LLFunctionType *DtoExtractFunctionType(LLType *type) {
  if (LLFunctionType *fty = isaFunction(type)) {
    return fty;
  }
  if (LLPointerType *pty = isaPointer(type)) {
    if (LLFunctionType *fty = isaFunction(pty->getElementType())) {
      return fty;
    }
  }
  return nullptr;
}
Ejemplo n.º 6
0
Archivo: nested.cpp Proyecto: torje/ldc
void DtoNestedInit(VarDeclaration* vd)
{
    Logger::println("DtoNestedInit for %s", vd->toChars());
    LOG_SCOPE

    IrFunction* irfunc = gIR->func()->decl->ir.irFunc;
    LLValue* nestedVar = irfunc->nestedVar;

    if (nestedCtx == NCArray) {
        // alloca as usual if no value already
        if (!vd->ir.irLocal->value)
            vd->ir.irLocal->value = DtoAlloca(vd->type, vd->toChars());

        // store the address into the nested vars array
        assert(vd->ir.irLocal->nestedIndex >= 0);
        LLValue* gep = DtoGEPi(nestedVar, 0, vd->ir.irLocal->nestedIndex);

        assert(isaPointer(vd->ir.irLocal->value));
        LLValue* val = DtoBitCast(vd->ir.irLocal->value, getVoidPtrType());

        DtoAlignedStore(val, gep);
    }
    else if (nestedCtx == NCHybrid) {
        assert(vd->ir.irLocal->value && "Nested variable without storage?");

        if (!vd->isParameter() && (vd->isRef() || vd->isOut())) {
            unsigned vardepth = vd->ir.irLocal->nestedDepth;

            LLValue* val = NULL;
            // Retrieve frame pointer
            if (vardepth == irfunc->depth) {
                val = nestedVar;
            } else {
                FuncDeclaration *parentfunc = getParentFunc(vd, true);
                assert(parentfunc && "No parent function for nested variable?");

                val = DtoGEPi(nestedVar, 0, vardepth);
                val = DtoAlignedLoad(val, (std::string(".frame.") + parentfunc->toChars()).c_str());
            }
            val = DtoGEPi(val, 0, vd->ir.irLocal->nestedIndex, vd->toChars());
            storeVariable(vd, val);
        } else {
            // Already initialized in DtoCreateNestedContext
        }
    }
    else {
        assert(0 && "Not implemented yet");
    }
}
Ejemplo n.º 7
0
static void storeVariable(VarDeclaration *vd, LLValue *dst)
{
    LLValue *value = vd->ir.irLocal->value;
    int ty = vd->type->ty;
    FuncDeclaration *fd = getParentFunc(vd, true);
    assert(fd && "No parent function for nested variable?");
    if (fd->needsClosure() && !vd->isRef() && (ty == Tstruct || ty == Tsarray) && isaPointer(value->getType())) {
        // Copy structs and static arrays
        LLValue *mem = DtoGcMalloc(vd->loc, DtoType(vd->type), ".gc_mem");
        DtoAggrCopy(mem, value);
        DtoAlignedStore(mem, dst);
    } else
    // Store the address into the frame
    DtoAlignedStore(value, dst);
}
Ejemplo n.º 8
0
static void addExplicitArguments(std::vector<LLValue *> &args, AttrSet &attrs,
                                 IrFuncTy &irFty, LLFunctionType *callableTy,
                                 const std::vector<DValue *> &argvals,
                                 int numFormalParams) {
  // Number of arguments added to the LLVM type that are implicit on the
  // frontend side of things (this, context pointers, etc.)
  const size_t implicitLLArgCount = args.size();

  // Number of formal arguments in the LLVM type (i.e. excluding varargs).
  const size_t formalLLArgCount = irFty.args.size();

  // The number of explicit arguments in the D call expression (including
  // varargs), not all of which necessarily generate a LLVM argument.
  const size_t explicitDArgCount = argvals.size();

  // construct and initialize an IrFuncTyArg object for each vararg
  std::vector<IrFuncTyArg *> optionalIrArgs;
  for (size_t i = numFormalParams; i < explicitDArgCount; i++) {
    Type *argType = argvals[i]->getType();
    bool passByVal = gABI->passByVal(argType);

    AttrBuilder initialAttrs;
    if (passByVal) {
      initialAttrs.add(LLAttribute::ByVal);
    } else {
      initialAttrs.add(DtoShouldExtend(argType));
    }

    optionalIrArgs.push_back(new IrFuncTyArg(argType, passByVal, initialAttrs));
    optionalIrArgs.back()->parametersIdx = i;
  }

  // let the ABI rewrite the IrFuncTyArg objects
  gABI->rewriteVarargs(irFty, optionalIrArgs);

  const size_t explicitLLArgCount = formalLLArgCount + optionalIrArgs.size();
  args.resize(implicitLLArgCount + explicitLLArgCount,
              static_cast<llvm::Value *>(nullptr));

  // Iterate the explicit arguments from left to right in the D source,
  // which is the reverse of the LLVM order if irFty.reverseParams is true.
  for (size_t i = 0; i < explicitLLArgCount; ++i) {
    const bool isVararg = (i >= irFty.args.size());
    IrFuncTyArg *irArg = nullptr;
    if (isVararg) {
      irArg = optionalIrArgs[i - numFormalParams];
    } else {
      irArg = irFty.args[i];
    }

    DValue *const argval = argvals[irArg->parametersIdx];
    Type *const argType = argval->getType();

    llvm::Value *llVal = nullptr;
    if (isVararg) {
      llVal = irFty.putParam(*irArg, argval);
    } else {
      llVal = irFty.putParam(i, argval);
    }

    const size_t llArgIdx =
        implicitLLArgCount +
        (irFty.reverseParams ? explicitLLArgCount - i - 1 : i);
    llvm::Type *const callableArgType =
        (isVararg ? nullptr : callableTy->getParamType(llArgIdx));

    // Hack around LDC assuming structs and static arrays are in memory:
    // If the function wants a struct, and the argument value is a
    // pointer to a struct, load from it before passing it in.
    if (isaPointer(llVal) && DtoIsPassedByRef(argType) &&
        ((!isVararg && !isaPointer(callableArgType)) ||
         (isVararg && !irArg->byref && !irArg->isByVal()))) {
      Logger::println("Loading struct type for function argument");
      llVal = DtoLoad(llVal);
    }

    // parameter type mismatch, this is hard to get rid of
    if (!isVararg && llVal->getType() != callableArgType) {
      IF_LOG {
        Logger::cout() << "arg:     " << *llVal << '\n';
        Logger::cout() << "expects: " << *callableArgType << '\n';
      }
      if (isaStruct(llVal)) {
        llVal = DtoAggrPaint(llVal, callableArgType);
      } else {
        llVal = DtoBitCast(llVal, callableArgType);
      }
    }

    args[llArgIdx] = llVal;
    // +1 as index 0 contains the function attributes.
    attrs.add(llArgIdx + 1, irArg->attrs);

    if (isVararg) {
      delete irArg;
    }
  }
Ejemplo n.º 9
0
DVarValue::DVarValue(Type* t, LLValue* llvmValue)
: DValue(t), var(0), val(llvmValue)
{
    assert(isaPointer(llvmValue));
}
Ejemplo n.º 10
0
DVarValue::DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue)
: DValue(t), var(vd), val(llvmValue)
{
    assert(isaPointer(llvmValue));
}