mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 05:08:14 +00:00
Add metadata to packed structs field accesses to state it is packed
This commit is contained in:
@@ -581,6 +581,10 @@ gb_internal LLVMTypeRef llvm_array_type(LLVMTypeRef ElementType, uint64_t Elemen
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gb_internal void lb_set_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name, u64 value);
|
||||||
|
gb_internal u64 lb_get_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name);
|
||||||
|
|
||||||
#define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
|
#define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
|
||||||
#define LB_CLEANUP_RUNTIME_PROC_NAME "__$cleanup_runtime"
|
#define LB_CLEANUP_RUNTIME_PROC_NAME "__$cleanup_runtime"
|
||||||
#define LB_TYPE_INFO_DATA_NAME "__$type_info_data"
|
#define LB_TYPE_INFO_DATA_NAME "__$type_info_data"
|
||||||
@@ -719,4 +723,4 @@ gb_global char const *llvm_linkage_strings[] = {
|
|||||||
"linker private weak linkage"
|
"linker private weak linkage"
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ODIN_METADATA_REQUIRE "odin-metadata-require", 21
|
#define ODIN_METADATA_IS_PACKED str_lit("odin-is-packed")
|
||||||
@@ -1107,6 +1107,12 @@ gb_internal lbValue lb_emit_load(lbProcedure *p, lbValue value) {
|
|||||||
GB_ASSERT(is_type_pointer(value.type));
|
GB_ASSERT(is_type_pointer(value.type));
|
||||||
Type *t = type_deref(value.type);
|
Type *t = type_deref(value.type);
|
||||||
LLVMValueRef v = LLVMBuildLoad2(p->builder, lb_type(p->module, t), value.value, "");
|
LLVMValueRef v = LLVMBuildLoad2(p->builder, lb_type(p->module, t), value.value, "");
|
||||||
|
|
||||||
|
u64 is_packed = lb_get_metadata_custom_u64(p->module, v, ODIN_METADATA_IS_PACKED);
|
||||||
|
if (is_packed != 0) {
|
||||||
|
LLVMSetAlignment(v, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return lbValue{v, t};
|
return lbValue{v, t};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,29 @@ gb_internal lbValue lb_correct_endianness(lbProcedure *p, lbValue value) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gb_internal void lb_set_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name, u64 value) {
|
||||||
|
unsigned md_id = LLVMGetMDKindIDInContext(m->ctx, cast(char const *)name.text, cast(unsigned)name.len);
|
||||||
|
LLVMMetadataRef md = LLVMValueAsMetadata(LLVMConstInt(lb_type(m, t_u64), value, false));
|
||||||
|
LLVMValueRef node = LLVMMetadataAsValue(m->ctx, LLVMMDNodeInContext2(m->ctx, &md, 1));
|
||||||
|
LLVMSetMetadata(v_ref, md_id, node);
|
||||||
|
}
|
||||||
|
gb_internal u64 lb_get_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name) {
|
||||||
|
unsigned md_id = LLVMGetMDKindIDInContext(m->ctx, cast(char const *)name.text, cast(unsigned)name.len);
|
||||||
|
LLVMValueRef v_md = LLVMGetMetadata(v_ref, md_id);
|
||||||
|
if (v_md == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
unsigned node_count = LLVMGetMDNodeNumOperands(v_md);
|
||||||
|
if (node_count == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
GB_ASSERT(node_count == 1);
|
||||||
|
LLVMValueRef value = nullptr;
|
||||||
|
LLVMGetMDNodeOperands(v_md, &value);
|
||||||
|
return LLVMConstIntGetZExtValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
gb_internal LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, usize len, unsigned alignment, bool is_volatile) {
|
gb_internal LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, usize len, unsigned alignment, bool is_volatile) {
|
||||||
return lb_mem_zero_ptr_internal(p, ptr, LLVMConstInt(lb_type(p->module, t_uint), len, false), alignment, is_volatile);
|
return lb_mem_zero_ptr_internal(p, ptr, LLVMConstInt(lb_type(p->module, t_uint), len, false), alignment, is_volatile);
|
||||||
}
|
}
|
||||||
@@ -1148,7 +1171,15 @@ gb_internal lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
|
|||||||
|
|
||||||
GB_ASSERT_MSG(result_type != nullptr, "%s %d", type_to_string(t), index);
|
GB_ASSERT_MSG(result_type != nullptr, "%s %d", type_to_string(t), index);
|
||||||
|
|
||||||
return lb_emit_struct_ep_internal(p, s, index, result_type);
|
lbValue gep = lb_emit_struct_ep_internal(p, s, index, result_type);
|
||||||
|
|
||||||
|
Type *bt = base_type(t);
|
||||||
|
if (bt->kind == Type_Struct && bt->Struct.is_packed) {
|
||||||
|
lb_set_metadata_custom_u64(p->module, gep.value, ODIN_METADATA_IS_PACKED, 1);
|
||||||
|
GB_ASSERT(lb_get_metadata_custom_u64(p->module, gep.value, ODIN_METADATA_IS_PACKED) == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gep;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index) {
|
gb_internal lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index) {
|
||||||
|
|||||||
Reference in New Issue
Block a user