Skip to content

Vector element access #3575

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion src/all_types.hpp
Original file line number Diff line number Diff line change
@@ -1183,13 +1183,22 @@ struct FnTypeId {
uint32_t fn_type_id_hash(FnTypeId*);
bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);

static const uint32_t VECTOR_INDEX_NONE = UINT32_MAX;
static const uint32_t VECTOR_INDEX_RUNTIME = UINT32_MAX - 1;

struct ZigTypePointer {
ZigType *child_type;
ZigType *slice_parent;

PtrLen ptr_len;
uint32_t explicit_alignment; // 0 means use ABI alignment

uint32_t bit_offset_in_host;
uint32_t host_int_bytes; // size of host integer. 0 means no host integer; this field is aligned
// size of host integer. 0 means no host integer; this field is aligned
// when vector_index != VECTOR_INDEX_NONE this is the len of the containing vector
uint32_t host_int_bytes;

uint32_t vector_index; // see the VECTOR_INDEX_* constants
bool is_const;
bool is_volatile;
bool allow_zero;
@@ -1732,8 +1741,11 @@ struct TypeId {
ZigType *child_type;
PtrLen ptr_len;
uint32_t alignment;

uint32_t bit_offset_in_host;
uint32_t host_int_bytes;

uint32_t vector_index;
bool is_const;
bool is_volatile;
bool allow_zero;
@@ -2414,6 +2426,7 @@ enum IrInstructionId {
IrInstructionIdLoadPtr,
IrInstructionIdLoadPtrGen,
IrInstructionIdStorePtr,
IrInstructionIdVectorStoreElem,
IrInstructionIdFieldPtr,
IrInstructionIdStructFieldPtr,
IrInstructionIdUnionFieldPtr,
@@ -2563,6 +2576,7 @@ enum IrInstructionId {
IrInstructionIdResume,
IrInstructionIdSpillBegin,
IrInstructionIdSpillEnd,
IrInstructionIdVectorExtractElem,
};

struct IrInstruction {
@@ -2757,6 +2771,14 @@ struct IrInstructionStorePtr {
IrInstruction *value;
};

struct IrInstructionVectorStoreElem {
IrInstruction base;

IrInstruction *vector_ptr;
IrInstruction *index;
IrInstruction *value;
};

struct IrInstructionFieldPtr {
IrInstruction base;

@@ -3890,6 +3912,13 @@ struct IrInstructionSpillEnd {
IrInstructionSpillBegin *begin;
};

struct IrInstructionVectorExtractElem {
IrInstruction base;

IrInstruction *vector;
IrInstruction *index;
};

enum ResultLocId {
ResultLocIdInvalid,
ResultLocIdNone,
71 changes: 57 additions & 14 deletions src/analyze.cpp
Original file line number Diff line number Diff line change
@@ -480,9 +480,10 @@ ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn) {
return entry;
}

ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_const,
bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero)
uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero,
uint32_t vector_index)
{
assert(ptr_len != PtrLenC || allow_zero);
assert(!type_is_invalid(child_type));
@@ -494,7 +495,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
byte_alignment = 0;
}

if (host_int_bytes != 0) {
if (host_int_bytes != 0 && vector_index == VECTOR_INDEX_NONE) {
uint32_t child_type_bits = type_size_bits(g, child_type);
if (host_int_bytes * 8 == child_type_bits) {
assert(bit_offset_in_host == 0);
@@ -504,7 +505,9 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons

TypeId type_id = {};
ZigType **parent_pointer = nullptr;
if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle || allow_zero) {
if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle ||
allow_zero || vector_index != VECTOR_INDEX_NONE)
{
type_id.id = ZigTypeIdPointer;
type_id.data.pointer.child_type = child_type;
type_id.data.pointer.is_const = is_const;
@@ -514,6 +517,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
type_id.data.pointer.host_int_bytes = host_int_bytes;
type_id.data.pointer.ptr_len = ptr_len;
type_id.data.pointer.allow_zero = allow_zero;
type_id.data.pointer.vector_index = vector_index;

auto existing_entry = g->type_table.maybe_get(type_id);
if (existing_entry)
@@ -540,19 +544,36 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
allow_zero_str = allow_zero ? "allowzero " : "";
}
buf_resize(&entry->name, 0);
if (host_int_bytes == 0 && byte_alignment == 0) {
if (host_int_bytes == 0 && byte_alignment == 0 && vector_index == VECTOR_INDEX_NONE) {
buf_appendf(&entry->name, "%s%s%s%s%s",
star_str, const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
} else if (host_int_bytes == 0) {
} else if (host_int_bytes == 0 && vector_index == VECTOR_INDEX_NONE) {
buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,
const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
} else if (byte_alignment == 0) {
buf_appendf(&entry->name, "%salign(:%" PRIu32 ":%" PRIu32 ") %s%s%s%s", star_str,
bit_offset_in_host, host_int_bytes, const_str, volatile_str, allow_zero_str,
assert(vector_index == VECTOR_INDEX_NONE);
buf_appendf(&entry->name, "%salign(:%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s%s",
star_str,
bit_offset_in_host, host_int_bytes, vector_index,
const_str, volatile_str, allow_zero_str,
buf_ptr(&child_type->name));
} else if (vector_index == VECTOR_INDEX_NONE) {
buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s%s",
star_str, byte_alignment,
bit_offset_in_host, host_int_bytes,
const_str, volatile_str, allow_zero_str,
buf_ptr(&child_type->name));
} else if (vector_index == VECTOR_INDEX_RUNTIME) {
buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":?) %s%s%s%s",
star_str, byte_alignment,
bit_offset_in_host, host_int_bytes,
const_str, volatile_str, allow_zero_str,
buf_ptr(&child_type->name));
} else {
buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,
bit_offset_in_host, host_int_bytes, const_str, volatile_str, allow_zero_str,
buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s%s",
star_str, byte_alignment,
bit_offset_in_host, host_int_bytes, vector_index,
const_str, volatile_str, allow_zero_str,
buf_ptr(&child_type->name));
}

@@ -581,6 +602,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
entry->data.pointer.bit_offset_in_host = bit_offset_in_host;
entry->data.pointer.host_int_bytes = host_int_bytes;
entry->data.pointer.allow_zero = allow_zero;
entry->data.pointer.vector_index = vector_index;

if (parent_pointer) {
*parent_pointer = entry;
@@ -590,8 +612,17 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
return entry;
}

ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero)
{
return get_pointer_to_type_extra2(g, child_type, is_const, is_volatile, ptr_len,
byte_alignment, bit_offset_in_host, host_int_bytes, allow_zero, VECTOR_INDEX_NONE);
}

ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const) {
return get_pointer_to_type_extra(g, child_type, is_const, false, PtrLenSingle, 0, 0, 0, false);
return get_pointer_to_type_extra2(g, child_type, is_const, false, PtrLenSingle, 0, 0, 0, false,
VECTOR_INDEX_NONE);
}

ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
@@ -6901,6 +6932,7 @@ uint32_t type_id_hash(TypeId x) {
(x.data.pointer.allow_zero ? (uint32_t)3324284834 : (uint32_t)3584904923) +
(((uint32_t)x.data.pointer.alignment) ^ (uint32_t)0x777fbe0e) +
(((uint32_t)x.data.pointer.bit_offset_in_host) ^ (uint32_t)2639019452) +
(((uint32_t)x.data.pointer.vector_index) ^ (uint32_t)0x19199716) +
(((uint32_t)x.data.pointer.host_int_bytes) ^ (uint32_t)529908881);
case ZigTypeIdArray:
return hash_ptr(x.data.array.child_type) +
@@ -6953,6 +6985,7 @@ bool type_id_eql(TypeId a, TypeId b) {
a.data.pointer.allow_zero == b.data.pointer.allow_zero &&
a.data.pointer.alignment == b.data.pointer.alignment &&
a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host &&
a.data.pointer.vector_index == b.data.pointer.vector_index &&
a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes;
case ZigTypeIdArray:
return a.data.array.child_type == b.data.array.child_type &&
@@ -8257,11 +8290,21 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus

if (type->data.pointer.is_const || type->data.pointer.is_volatile ||
type->data.pointer.explicit_alignment != 0 || type->data.pointer.ptr_len != PtrLenSingle ||
type->data.pointer.bit_offset_in_host != 0 || type->data.pointer.allow_zero)
type->data.pointer.bit_offset_in_host != 0 || type->data.pointer.allow_zero ||
type->data.pointer.vector_index != VECTOR_INDEX_NONE)
{
assertNoError(type_resolve(g, elem_type, ResolveStatusLLVMFwdDecl));
ZigType *peer_type = get_pointer_to_type_extra(g, elem_type, false, false,
PtrLenSingle, 0, 0, type->data.pointer.host_int_bytes, false);
ZigType *peer_type;
if (type->data.pointer.vector_index == VECTOR_INDEX_NONE) {
peer_type = get_pointer_to_type_extra2(g, elem_type, false, false,
PtrLenSingle, 0, 0, type->data.pointer.host_int_bytes, false,
VECTOR_INDEX_NONE);
} else {
uint32_t host_vec_len = type->data.pointer.host_int_bytes;
ZigType *host_vec_type = get_vector_type(g, host_vec_len, elem_type);
peer_type = get_pointer_to_type_extra2(g, host_vec_type, false, false,
PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE);
}
type->llvm_type = get_llvm_type(g, peer_type);
type->llvm_di_type = get_llvm_di_type(g, peer_type);
assertNoError(type_resolve(g, elem_type, wanted_resolve_status));
8 changes: 6 additions & 2 deletions src/analyze.hpp
Original file line number Diff line number Diff line change
@@ -17,10 +17,14 @@ ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node,
ZigType *new_type_table_entry(ZigTypeId id);
ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn);
ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const);
ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
bool is_volatile, PtrLen ptr_len,
ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type,
bool is_const, bool is_volatile, PtrLen ptr_len,
uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count,
bool allow_zero);
ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type,
bool is_const, bool is_volatile, PtrLen ptr_len,
uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count,
bool allow_zero, uint32_t vector_index);
uint64_t type_size(CodeGen *g, ZigType *type_entry);
uint64_t type_size_bits(CodeGen *g, ZigType *type_entry);
ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
Loading