Ejemplo n.º 1
0
llvm::Type * IrTypeSArray::sarray2llvm(Type * t)
{
    assert(t->ty == Tsarray && "not static array type");
    TypeSArray* tsa = static_cast<TypeSArray*>(t);
    uint64_t dim = static_cast<uint64_t>(tsa->dim->toUInteger());
    LLType* elemType = DtoMemType(t->nextOf());
    return llvm::ArrayType::get(elemType, dim);
}
Ejemplo n.º 2
0
llvm::Type* IrTypeVector::vector2llvm(Type* dt)
{
    assert(dt->ty == Tvector && "not vector type");
    TypeVector* tv = static_cast<TypeVector*>(dt);
    assert(tv->basetype->ty == Tsarray);
    TypeSArray* tsa = static_cast<TypeSArray*>(tv->basetype);
    uint64_t dim = static_cast<uint64_t>(tsa->dim->toUInteger());
    LLType* elemType = DtoMemType(tsa->next);
    return llvm::VectorType::get(elemType, dim);
}
Ejemplo n.º 3
0
IrTypeArray* IrTypeArray::get(Type* dt)
{
    assert(!dt->ctype);
    assert(dt->ty == Tarray && "not dynamic array type");

    LLType* elemType = DtoMemType(dt->nextOf());

    // Could have already built the type as part of a struct forward reference,
    // just as for pointers.
    if (!dt->ctype)
    {
        llvm::Type *types[] = { DtoSize_t(), llvm::PointerType::get(elemType, 0) };
        LLType* at = llvm::StructType::get(llvm::getGlobalContext(), types, false);
        dt->ctype = new IrTypeArray(dt, at);
    }

    return dt->ctype->isArray();
}
Ejemplo n.º 4
0
IrTypeStruct *IrTypeStruct::get(StructDeclaration *sd) {
  auto t = new IrTypeStruct(sd);
  sd->type->ctype = t;

  IF_LOG Logger::println("Building struct type %s @ %s", sd->toPrettyChars(),
                         sd->loc.toChars());
  LOG_SCOPE;

  // if it's a forward declaration, all bets are off, stick with the opaque
  if (sd->sizeok != SIZEOKdone) {
    return t;
  }

  t->packed = isPacked(sd);

  // For ldc.dcomptetypes.Pointer!(uint n,T),
  // emit { T addrspace(gIR->dcomputetarget->mapping[n])* }
    llvm::Optional<DcomputePointer> p;
  if (gIR->dcomputetarget && (p = toDcomputePointer(sd))) {
   
    // Translate the virtual dcompute address space into the real one for
    // the target
    int realAS = gIR->dcomputetarget->mapping[p->addrspace];

    llvm::SmallVector<LLType *, 1> body;
    body.push_back(DtoMemType(p->type)->getPointerTo(realAS));

    isaStruct(t->type)->setBody(body, t->packed);
    VarGEPIndices v;
    v[sd->fields[0]] = 0;
    t->varGEPIndices = v;
  } else {
    AggrTypeBuilder builder(t->packed);
    builder.addAggregate(sd);
    builder.addTailPadding(sd->structsize);
    isaStruct(t->type)->setBody(builder.defaultTypes(), t->packed);
    t->varGEPIndices = builder.varGEPIndices();
  }

  IF_LOG Logger::cout() << "final struct type: " << *t->type << std::endl;

  return t;
}
Ejemplo n.º 5
0
IrTypePointer* IrTypePointer::get(Type* dt)
{
    assert(!dt->ctype);
    assert((dt->ty == Tpointer || dt->ty == Tnull) && "not pointer/null type");

    LLType* elemType;
    if (dt->ty == Tnull)
    {
        elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
    }
    else
    {
        elemType = DtoMemType(dt->nextOf());

        // DtoType could have already created the same type, e.g. for
        // dt == Node* in struct Node { Node* n; }.
        if (dt->ctype)
            return dt->ctype->isPointer();
    }

    IrTypePointer* t = new IrTypePointer(dt, llvm::PointerType::get(elemType, 0));
    dt->ctype = t;
    return t;
}
Ejemplo n.º 6
0
LLPointerType *DtoPtrToType(Type *t) { return DtoMemType(t)->getPointerTo(); }
Ejemplo n.º 7
0
void AggrTypeBuilder::addAggregate(
    AggregateDeclaration *ad, const AggrTypeBuilder::VarInitMap *explicitInits,
    AggrTypeBuilder::Aliases aliases) {
  const size_t n = ad->fields.dim;
  if (n == 0)
    return;

  // prioritize overlapping fields
  LLSmallVector<FieldPriority, 16> priorities;
  priorities.reserve(n);
  for (auto f : ad->fields) {
    priorities.push_back(prioritize(f, explicitInits));
    IF_LOG Logger::println("Field priority for %s: %d", f->toChars(),
                           priorities.back());
  }

  // mirror the ad->fields array but only fill in contributors
  LLSmallVector<VarDeclaration *, 16> data(n, nullptr);

  // list of pairs: alias => actual field (same offset, same LL type)
  LLSmallVector<std::pair<VarDeclaration *, VarDeclaration *>, 16> aliasPairs;

  // one pass per priority in descending order
  const auto minMaxPriority =
      std::minmax_element(priorities.begin(), priorities.end());
  for (int p = *minMaxPriority.second; p >= *minMaxPriority.first; p--) {
    // iterate over fields of that priority, in declaration order
    for (size_t index = 0; index < n; ++index) {
      if (priorities[index] != p)
        continue;

      VarDeclaration *field = ad->fields[index];
      const size_t f_begin = field->offset;
      const size_t f_end = f_begin + field->type->size();

      // skip empty fields
      if (f_begin == f_end)
        continue;

      // check for overlapping existing fields
      bool overlaps = false;
      if (field->overlapped) {
        for (const auto vd : data) {
          if (!vd)
            continue;

          const size_t v_begin = vd->offset;
          const size_t v_end = v_begin + vd->type->size();

          if (v_begin < f_end && v_end > f_begin) {
            if (aliases == Aliases::AddToVarGEPIndices && v_begin == f_begin &&
                DtoMemType(vd->type) == DtoMemType(field->type)) {
              aliasPairs.push_back(std::make_pair(field, vd));
            }
            overlaps = true;
            break;
          }
        }
      }

      if (!overlaps)
        data[index] = field;
    }
  }

  // Now we can build a list of LLVM types for the actual LL fields.
  // Make sure to zero out any padding and set the GEP indices for the directly
  // indexable variables.

  // first we sort the list by offset
  std::sort(data.begin(), data.end(), var_offset_sort_cb);

  for (const auto vd : data) {
    if (!vd)
      continue;

    assert(vd->offset >= m_offset && "Variable overlaps previous field.");

    // Add an explicit field for any padding so we can zero it, as per TDPL
    // §7.1.1.
    if (m_offset < vd->offset) {
      m_fieldIndex += add_zeros(m_defaultTypes, m_offset, vd->offset);
      m_offset = vd->offset;
    }

    // add default type
    m_defaultTypes.push_back(DtoMemType(vd->type));

    // advance offset to right past this field
    m_offset += getMemberSize(vd->type);

    // set the field index
    m_varGEPIndices[vd] = m_fieldIndex;

    // let any aliases reuse this field/GEP index
    for (const auto &pair : aliasPairs) {
      if (pair.second == vd)
        m_varGEPIndices[pair.first] = m_fieldIndex;
    }

    ++m_fieldIndex;
  }
}