More codegen cleanup.

This commit is contained in:
Christoffer Lerno
2022-08-13 00:19:09 +02:00
parent d93c7090f6
commit 7805fb8d1c
7 changed files with 129 additions and 70 deletions

View File

@@ -112,9 +112,9 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_
}
if (was_modified)
{
return LLVMConstStructInContext(c->context, parts, vec_size(parts), true);
return llvm_get_unnamed_struct(c, parts, true);
}
return LLVMConstArray(element_type_llvm, parts, vec_size(parts));
return llvm_get_array(element_type_llvm, parts, vec_size(parts));
}
case CONST_INIT_ARRAY:
@@ -160,9 +160,9 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_
}
if (was_modified)
{
return LLVMConstStructInContext(c->context, parts, vec_size(parts), pack);
return llvm_get_unnamed_struct(c, parts, pack);
}
return LLVMConstArray(element_type_llvm, parts, vec_size(parts));
return llvm_get_array(element_type_llvm, parts, vec_size(parts));
}
case CONST_INIT_UNION:
{
@@ -197,10 +197,10 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_
if (first_type != result_type)
{
// Yes, so the type needs to be modified.
return LLVMConstStructInContext(c->context, values, value_count, false);
return llvm_get_struct(c, values, value_count);
}
return LLVMConstNamedStruct(union_type_llvm, values, value_count);
return llvm_get_struct_named(union_type_llvm, values, value_count);
}
case CONST_INIT_STRUCT:
{
@@ -241,10 +241,9 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_
}
if (was_modified)
{
LLVMValueRef value = LLVMConstStructInContext(c->context, entries, vec_size(entries), decl->is_packed);
return value;
return llvm_get_unnamed_struct(c, entries, decl->is_packed);
}
return LLVMConstNamedStruct(llvm_get_type(c, const_init->type), entries, vec_size(entries));
return llvm_get_struct_of_type(c, const_init->type, entries, vec_size(entries));
}
case CONST_INIT_VALUE:
{
@@ -341,10 +340,7 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
BEValue value;
if (init_expr->expr_kind == EXPR_CONST && init_expr->const_expr.const_kind == CONST_BYTES)
{
init_value = LLVMConstStringInContext(c->context,
init_expr->const_expr.bytes.ptr,
init_expr->const_expr.bytes.len,
1);
init_value = llvm_get_bytes(c, init_expr->const_expr.bytes.ptr, init_expr->const_expr.bytes.len);
}
else
{

View File

@@ -170,11 +170,11 @@ LLVMValueRef llvm_emit_coerce_alignment(GenContext *c, BEValue *be_value, LLVMTy
LLVMValueRef llvm_emit_aggregate_two(GenContext *c, Type *type, LLVMValueRef value1, LLVMValueRef value2)
{
bool is_constant = LLVMIsConstant(value1) && LLVMIsConstant(value2);
bool is_constant = llvm_is_const(value1) && llvm_is_const(value2);
if (is_constant)
{
LLVMValueRef two[2] = { value1, value2 };
return LLVMConstNamedStruct(llvm_get_type(c, type), two, 2);
return llvm_get_struct_of_type(c, type, two, 2);
}
LLVMValueRef result = llvm_get_undef(c, type);
result = llvm_emit_insert_value(c, result, value1, 0);
@@ -189,15 +189,15 @@ void llvm_value_aggregate_two(GenContext *c, BEValue *value, Type *type, LLVMVal
static inline LLVMValueRef llvm_const_low_bitmask(GenContext *c, LLVMTypeRef type, int type_bits, int low_bits)
{
if (low_bits < 1) return llvm_get_zero_raw(type);
if (type_bits <= low_bits) return LLVMConstAllOnes(type);
return llvm_emit_lshr_fixed(c, LLVMConstAllOnes(type), (type_bits - low_bits));
if (type_bits <= low_bits) return llvm_get_ones_raw(type);
return llvm_emit_lshr_fixed(c, llvm_get_ones_raw(type), (type_bits - low_bits));
}
static inline LLVMValueRef llvm_const_high_bitmask(GenContext *c, LLVMTypeRef type, int type_bits, int high_bits)
{
if (high_bits < 1) return llvm_get_zero_raw(type);
if (type_bits <= high_bits) return LLVMConstAllOnes(type);
return LLVMBuildNot(c->builder, llvm_emit_lshr_fixed(c, LLVMConstAllOnes(type), high_bits), "");
if (type_bits <= high_bits) return llvm_get_ones_raw(type);
return LLVMBuildNot(c->builder, llvm_emit_lshr_fixed(c, llvm_get_ones_raw(type), high_bits), "");
}
LLVMValueRef llvm_mask_low_bits(GenContext *c, LLVMValueRef value, unsigned low_bits)
@@ -206,7 +206,7 @@ LLVMValueRef llvm_mask_low_bits(GenContext *c, LLVMValueRef value, unsigned low_
if (low_bits < 1) return llvm_get_zero_raw(type);
BitSize type_bits = llvm_bitsize(c, type);
if (type_bits <= low_bits) return value;
LLVMValueRef mask = llvm_emit_lshr_fixed(c, LLVMConstAllOnes(type), type_bits - low_bits);
LLVMValueRef mask = llvm_emit_lshr_fixed(c, llvm_get_ones_raw(type), type_bits - low_bits);
return LLVMBuildAnd(c->builder, mask, value, "");
}
@@ -693,7 +693,7 @@ static void llvm_emit_bitstruct_member(GenContext *c, BEValue *value, Decl *pare
static LLVMValueRef llvm_emit_bswap(GenContext *c, LLVMValueRef value)
{
if (LLVMIsConstant(value))
if (llvm_is_const(value))
{
return LLVMConstBswap(value);
}
@@ -780,7 +780,7 @@ static inline void llvm_extract_bitvalue_from_array(GenContext *c, BEValue *be_v
continue;
}
if (!LLVMIsNull(element)) res = LLVMBuildOr(c->builder, element, res, "");
if (!llvm_is_const_null(element)) res = LLVMBuildOr(c->builder, element, res, "");
}
if (big_endian)
{
@@ -883,7 +883,7 @@ static inline void llvm_emit_bitassign_array(GenContext *c, BEValue *result, BEV
LLVMValueRef current = llvm_load(c, c->byte_type, byte_ptr, alignment, "");
LLVMValueRef bit = llvm_emit_shl_fixed(c, LLVMConstInt(c->byte_type, 1, 0), start_bit % 8);
current = LLVMBuildAnd(c->builder, current, LLVMBuildNot(c->builder, bit, ""), "");
if (!LLVMIsNull(value)) current = LLVMBuildOr(c->builder, current, value, "");
if (!llvm_is_const_null(value)) current = LLVMBuildOr(c->builder, current, value, "");
llvm_store_to_ptr_raw_aligned(c, byte_ptr, current, alignment);
return;
}
@@ -932,7 +932,7 @@ static inline void llvm_emit_bitassign_array(GenContext *c, BEValue *result, BEV
// Empty the top bits.
current = LLVMBuildAnd(c->builder, current, mask, "");
// Use *or* with the top bits from "res":
if (!LLVMIsNull(res)) current = LLVMBuildOr(c->builder, current, res, "");
if (!llvm_is_const_null(res)) current = LLVMBuildOr(c->builder, current, res, "");
// And store it back.
llvm_store_to_ptr_raw_aligned(c, byte_ptr, current, alignment);
// We now shift the value by the number of bits we used.
@@ -952,7 +952,7 @@ static inline void llvm_emit_bitassign_array(GenContext *c, BEValue *result, BEV
// Clear the lower bits.
current = LLVMBuildAnd(c->builder, current, LLVMBuildNot(c->builder, mask, ""), "");
// Use *or* with the bottom bits from "value":
if (!LLVMIsNull(value)) current = LLVMBuildOr(c->builder, current, value, "");
if (!llvm_is_const_null(value)) current = LLVMBuildOr(c->builder, current, value, "");
// And store it back.
llvm_store_to_ptr_raw_aligned(c, byte_ptr, current, alignment);
continue;
@@ -1002,7 +1002,7 @@ static inline void llvm_emit_bitassign_expr(GenContext *c, BEValue *be_value, Ex
LLVMTypeRef struct_type = LLVMTypeOf(current_value);
// We now need to create a mask, a very naive algorithm:
LLVMValueRef mask = LLVMConstAllOnes(struct_type);
LLVMValueRef mask = llvm_get_ones_raw(struct_type);
TypeSize bits = type_size(parent.type) * 8;
int start_bit = (int)member->var.start_bit;
int end_bit = (int)member->var.end_bit;
@@ -1024,7 +1024,7 @@ static inline void llvm_emit_bitassign_expr(GenContext *c, BEValue *be_value, Ex
value = LLVMBuildAnd(c->builder, value, mask, "");
current_value = LLVMBuildAnd(c->builder, current_value, LLVMBuildNot(c->builder, mask, ""), "");
// Skip this op for LLVM14 if zero.
if (!LLVMIsNull(value)) current_value = LLVMBuildOr(c->builder, current_value, value, "");
if (!llvm_is_const_null(value)) current_value = LLVMBuildOr(c->builder, current_value, value, "");
llvm_store_raw(c, &parent, current_value);
}
static inline void llvm_emit_bitaccess(GenContext *c, BEValue *be_value, Expr *expr)
@@ -1095,7 +1095,6 @@ void llvm_emit_vector_to_array_cast(GenContext *c, BEValue *value, Type *to_type
{
llvm_value_rvalue(c, value);
LLVMValueRef array = llvm_get_undef(c, to_type);
bool is_const = LLVMIsConstant(value->value);
for (unsigned i = 0; i < to_type->array.len; i++)
{
LLVMValueRef element = llvm_emit_extract_value(c, value->value, i);
@@ -1769,7 +1768,7 @@ LLVMValueRef llvm_emit_const_bitstruct_array(GenContext *c, ConstInitializer *in
slots[(unsigned)j] = LLVMBuildOr(c->builder, to_or, current_value, "");
}
}
return LLVMConstArray(c->byte_type, slots, elements);
return llvm_get_array(c->byte_type, slots, elements);
}
LLVMValueRef llvm_emit_const_bitstruct(GenContext *c, ConstInitializer *initializer)
@@ -1811,7 +1810,7 @@ LLVMValueRef llvm_emit_const_bitstruct(GenContext *c, ConstInitializer *initiali
value = llvm_zext_trunc(c, value, llvm_base_type);
if (bit_size < base_type_bitsize)
{
LLVMValueRef mask = llvm_emit_lshr_fixed(c, LLVMConstAllOnes(llvm_base_type), base_type_bitsize - bit_size);
LLVMValueRef mask = llvm_emit_lshr_fixed(c, llvm_get_ones_raw(llvm_base_type), base_type_bitsize - bit_size);
value = LLVMBuildAnd(c->builder, mask, value, "");
}
if (start_bit > 0)
@@ -2459,7 +2458,7 @@ static void llvm_emit_slice_assign(GenContext *c, BEValue *be_value, Expr *expr)
llvm_value_rvalue(c, &start);
llvm_value_rvalue(c, &end);
if (LLVMIsConstant(start.value) && LLVMIsConstant(end.value))
if (llvm_is_const(start.value) && llvm_is_const(end.value))
{
assert(type_is_integer(start.type) && type_is_integer(end.type));
bool signed_start = type_is_signed(start.type);
@@ -2656,7 +2655,7 @@ void llvm_emit_int_comp_raw(GenContext *c, BEValue *result, Type *lhs_type, Type
}
}
}
if (lhs_signed && !rhs_signed && !vector_type && LLVMIsConstant(lhs_value) && type_size(lhs_type) <= 64)
if (lhs_signed && !rhs_signed && !vector_type && llvm_is_const(lhs_value) && type_size(lhs_type) <= 64)
{
long long val = LLVMConstIntGetSExtValue(lhs_value);
if (val < 0)
@@ -3780,10 +3779,7 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr)
llvm_set_private_linkage(global_name);
LLVMSetGlobalConstant(global_name, 1);
LLVMSetInitializer(global_name, LLVMConstStringInContext(c->context,
expr->const_expr.bytes.ptr,
expr->const_expr.bytes.len,
1));
LLVMSetInitializer(global_name, llvm_get_bytes(c, expr->const_expr.bytes.ptr, expr->const_expr.bytes.len));
global_name = llvm_emit_bitcast_ptr(c, global_name, type_char);
llvm_value_set_address_abi_aligned(be_value, global_name, type);
return;
@@ -3843,15 +3839,12 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr)
llvm_set_private_linkage(global_name);
LLVMSetUnnamedAddress(global_name, LLVMGlobalUnnamedAddr);
LLVMSetGlobalConstant(global_name, 1);
LLVMValueRef string = LLVMConstStringInContext(c->context,
expr->const_expr.string.chars,
expr->const_expr.string.len,
0);
LLVMValueRef string = llvm_get_zstring(c, expr->const_expr.string.chars, expr->const_expr.string.len);
if (size > strlen + 1)
{
LLVMValueRef trailing_zeros = llvm_get_zero_raw(LLVMArrayType(c->byte_type, size - strlen - 1));
LLVMValueRef values[2] = { string, trailing_zeros };
string = LLVMConstStructInContext(c->context, values, 2, true);
string = llvm_get_packed_struct(c, values, 2);
}
LLVMSetInitializer(global_name, string);
if (is_array)
@@ -3872,17 +3865,20 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr)
LLVMValueRef string;
if (array_len <= size)
{
string = LLVMConstStringInContext(c->context,
expr->const_expr.string.chars,
array_len, array_len < size);
if (zero_terminate)
{
string = llvm_get_zstring(c, expr->const_expr.string.chars, expr->const_expr.string.len);
}
else
{
string = llvm_get_bytes(c, expr->const_expr.string.chars, array_len);
}
}
else
{
char *buffer = ccalloc(1, array_len);
memcpy(buffer, expr->const_expr.string.chars, expr->const_expr.string.len);
string = LLVMConstStringInContext(c->context,
buffer,
array_len, true);
string = llvm_get_bytes(c, buffer, array_len);
}
llvm_value_set(be_value, string, type);
return;
@@ -4008,7 +4004,7 @@ LLVMValueRef llvm_emit_struct_gep_raw(GenContext *context, LLVMValueRef ptr, LLV
unsigned struct_alignment, AlignSize *alignment)
{
*alignment = type_min_alignment((AlignSize)LLVMOffsetOfElement(context->target_data, struct_type, index), struct_alignment);
if (LLVMIsConstant(ptr))
if (llvm_is_const(ptr))
{
LLVMValueRef idx[2] = { llvm_get_zero(context, type_int), llvm_const_int(context, type_int, index) };
return LLVMBuildInBoundsGEP2(context->builder, struct_type, ptr, idx, 2, "");

View File

@@ -312,12 +312,21 @@ INLINE LLVMValueRef llvm_get_zero(GenContext *c, Type *type);
INLINE LLVMValueRef llvm_get_zero_raw(LLVMTypeRef type);
INLINE LLVMValueRef llvm_get_undef(GenContext *c, Type *type);
INLINE LLVMValueRef llvm_get_undef_raw(LLVMTypeRef type);
INLINE LLVMValueRef llvm_get_ones_raw(LLVMTypeRef type);
INLINE LLVMValueRef llvm_get_zstring(GenContext *c, const char *str, size_t len);
INLINE LLVMValueRef llvm_get_bytes(GenContext *c, const char *str, size_t len);
INLINE LLVMValueRef llvm_get_struct(GenContext *c, LLVMValueRef *vals, size_t len);
INLINE LLVMValueRef llvm_get_packed_struct(GenContext *c, LLVMValueRef *vals, size_t len);
INLINE LLVMValueRef llvm_get_unnamed_struct(GenContext *c, LLVMValueRef *vals, bool is_packed);
INLINE LLVMValueRef llvm_get_array(LLVMTypeRef type, LLVMValueRef *vals, unsigned count);
INLINE LLVMValueRef llvm_get_struct_named(LLVMTypeRef type, LLVMValueRef *vals, unsigned count);
INLINE LLVMValueRef llvm_get_struct_of_type(GenContext *c, Type *type, LLVMValueRef *vals, unsigned count);
// -- Jumps --
void llvm_emit_cond_br(GenContext *context, BEValue *value, LLVMBasicBlockRef then_block, LLVMBasicBlockRef else_block);
void llvm_emit_cond_br_raw(GenContext *context, LLVMValueRef b, LLVMBasicBlockRef then_block, LLVMBasicBlockRef else_block);
void llvm_emit_br(GenContext *c, LLVMBasicBlockRef next_block);
void llvm_emit_jump_to_optional_exit(GenContext *c, LLVMValueRef err_value);
void llvm_emit_jump_to_optional_exit(GenContext *c, LLVMValueRef opt_value);
void llvm_emit_return_abi(GenContext *c, BEValue *return_value, BEValue *failable);
void llvm_emit_return_implicit(GenContext *c);
@@ -333,6 +342,8 @@ void llvm_emit_comp(GenContext *c, BEValue *result, BEValue *lhs, BEValue *rhs,
void llvm_emit_int_comp(GenContext *c, BEValue *result, BEValue *lhs, BEValue *rhs, BinaryOp binary_op);
void llvm_emit_int_comp_zero(GenContext *c, BEValue *result, BEValue *lhs, BinaryOp binary_op);
void llvm_emit_int_comp_raw(GenContext *c, BEValue *result, Type *lhs_type, Type *rhs_type, LLVMValueRef lhs_value, LLVMValueRef rhs_value, BinaryOp binary_op);
INLINE bool llvm_is_const_null(LLVMValueRef value);
INLINE bool llvm_is_const(LLVMValueRef value);
// -- Load ---
LLVMValueRef llvm_load(GenContext *c, LLVMTypeRef type, LLVMValueRef pointer, AlignSize alignment, const char *name);

View File

@@ -197,6 +197,65 @@ INLINE LLVMValueRef llvm_get_undef_raw(LLVMTypeRef type)
return LLVMGetUndef(type);
}
INLINE LLVMValueRef llvm_get_ones_raw(LLVMTypeRef type)
{
return LLVMConstAllOnes(type);
}
INLINE bool llvm_is_const_null(LLVMValueRef value)
{
return LLVMIsNull(value);
}
INLINE bool llvm_is_const(LLVMValueRef value)
{
return LLVMIsConstant(value);
}
INLINE LLVMValueRef llvm_get_zstring(GenContext *c, const char *str, size_t len)
{
assert(len == (unsigned)len);
return LLVMConstStringInContext(c->context, str, (unsigned)len, 0);
}
INLINE LLVMValueRef llvm_get_bytes(GenContext *c, const char *str, size_t len)
{
assert(len == (unsigned)len);
return LLVMConstStringInContext(c->context, str, (unsigned)len, 1);
}
INLINE LLVMValueRef llvm_get_struct(GenContext *c, LLVMValueRef *vals, size_t len)
{
assert(len == (unsigned)len);
return LLVMConstStructInContext(c->context, vals, (unsigned)len, false);
}
INLINE LLVMValueRef llvm_get_packed_struct(GenContext *c, LLVMValueRef *vals, size_t len)
{
assert(len == (unsigned)len);
return LLVMConstStructInContext(c->context, vals, (unsigned)len, true);
}
INLINE LLVMValueRef llvm_get_unnamed_struct(GenContext *c, LLVMValueRef *vals, bool is_packed)
{
return LLVMConstStructInContext(c->context, vals, vec_size(vals), is_packed);
}
INLINE LLVMValueRef llvm_get_array(LLVMTypeRef type, LLVMValueRef *vals, unsigned count)
{
return LLVMConstArray(type, vals, count);
}
INLINE LLVMValueRef llvm_get_struct_named(LLVMTypeRef type, LLVMValueRef *vals, unsigned count)
{
return LLVMConstNamedStruct(type, vals, count);
}
INLINE LLVMValueRef llvm_get_struct_of_type(GenContext *c, Type *type, LLVMValueRef *vals, unsigned count)
{
return LLVMConstNamedStruct(llvm_get_type(c, type), vals, count);
}
INLINE LLVMValueRef llvm_const_int(GenContext *c, Type *type, uint64_t val)
{
type = type_lowering(type);

View File

@@ -1080,11 +1080,9 @@ LLVMValueRef llvm_emit_zstring_named(GenContext *c, const char *str, const char
LLVMValueRef global_string = llvm_add_global_raw(c, extname, char_array_type, 0);
llvm_set_internal_linkage(global_string);
LLVMSetGlobalConstant(global_string, 1);
LLVMSetInitializer(global_string, LLVMConstStringInContext(c->context, str, len, 0));
LLVMSetInitializer(global_string, llvm_get_zstring(c, str, len));
AlignSize alignment;
// TODO alignment
LLVMValueRef string = llvm_emit_array_gep_raw(c, global_string, char_array_type, 0,
1, &alignment);
LLVMValueRef string = llvm_emit_array_gep_raw(c, global_string, char_array_type, 0, 1, &alignment);
return llvm_emit_bitcast_ptr(c, string, type_char);
}

View File

@@ -522,7 +522,7 @@ static inline LLVMValueRef llvm_generate_introspection_global(GenContext *c, LLV
[INTROSPECT_INDEX_SIZEOF] = llvm_const_int(c, type_usize, type_size(type)),
[INTROSPECT_INDEX_INNER] = inner ? llvm_get_typeid(c, inner) : llvm_get_zero(c, type_typeid),
[INTROSPECT_INDEX_LEN] = llvm_const_int(c, type_usize, len),
[INTROSPECT_INDEX_ADDITIONAL] = additional ? additional : LLVMConstArray(llvm_get_type(c, type_typeid), NULL, 0)
[INTROSPECT_INDEX_ADDITIONAL] = additional ? additional : llvm_get_array(llvm_get_type(c, type_typeid), NULL, 0)
};
LLVMValueRef global_name;
scratch_buffer_clear();
@@ -530,13 +530,13 @@ static inline LLVMValueRef llvm_generate_introspection_global(GenContext *c, LLV
type_mangle_introspect_name_to_buffer(type);
if (additional)
{
LLVMValueRef constant = LLVMConstStructInContext(c->context, values, INTROSPECT_INDEX_TOTAL, false);
LLVMValueRef constant = llvm_get_struct(c, values, INTROSPECT_INDEX_TOTAL);
global_name = LLVMAddGlobal(c->module, LLVMTypeOf(constant), scratch_buffer_to_string());
LLVMSetInitializer(global_name, constant);
}
else
{
LLVMValueRef strukt = LLVMConstNamedStruct(c->introspect_type, values, INTROSPECT_INDEX_TOTAL);
LLVMValueRef strukt = llvm_get_struct_named(c->introspect_type, values, INTROSPECT_INDEX_TOTAL);
global_name = LLVMAddGlobal(c->module, c->introspect_type, scratch_buffer_to_string());
LLVMSetInitializer(global_name, strukt);
}
@@ -603,9 +603,9 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type)
}
LLVMValueRef name_ref = llvm_emit_zstring_named(c, name, scratch_buffer_to_string());
LLVMValueRef data[2] = { name_ref, llvm_const_int(c, type_usize, len) };
values[i] = LLVMConstNamedStruct(subarray, data, 2);
values[i] = llvm_get_struct_named(subarray, data, 2);
}
LLVMValueRef names = LLVMConstArray(subarray, values, elements);
LLVMValueRef names = llvm_get_array(subarray, values, elements);
LLVMValueRef val = llvm_generate_introspection_global(c, NULL, type, INTROSPECT_TYPE_ENUM, type_flatten(type), elements, names, is_external);
LLVMTypeRef val_type;
@@ -631,9 +631,8 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type)
if (val_type != LLVMTypeOf(llvm_value)) mixed = true;
}
Decl *associated_value = associated_values[ai];
LLVMValueRef associated_value_arr = mixed ? LLVMConstStruct(values, elements, true) : LLVMConstArray(val_type,
values,
elements);
LLVMValueRef associated_value_arr = mixed ? llvm_get_packed_struct(c, values, elements)
: llvm_get_array(val_type, values, elements);
scratch_buffer_clear();
scratch_buffer_append(decl->extname);
scratch_buffer_append("$");
@@ -698,7 +697,7 @@ static LLVMValueRef llvm_get_introspection_for_fault(GenContext *c, Type *type)
llvm_emit_aggregate_two(c, type_chars, llvm_emit_zstring_named(c, val->name, ".fault"),
llvm_const_int(c, type_usize, strlen(val->name))) };
LLVMSetInitializer(global_name, LLVMConstNamedStruct(c->fault_type, vals, 2));
LLVMSetInitializer(global_name, llvm_get_struct_named(c->fault_type, vals, 2));
llvm_set_linkonce(c, global_name);
val->backend_ref = LLVMBuildPointerCast(c->builder, global_name, llvm_get_type(c, type_typeid), "");
}

View File

@@ -70,41 +70,41 @@ void llvm_value_rvalue(GenContext *c, BEValue *value)
value->kind = BE_VALUE;
}
void llvm_emit_jump_to_optional_exit(GenContext *c, LLVMValueRef err_value)
void llvm_emit_jump_to_optional_exit(GenContext *c, LLVMValueRef opt_value)
{
assert(c->catch_block && "unexpected emit");
bool is_constant_err = LLVMIsConstant(err_value);
bool is_constant_opt = llvm_is_const(opt_value);
// Maybe we don't need to emit anything?
if (is_constant_err && LLVMIsNull(err_value)) return;
if (is_constant_opt && llvm_is_const_null(opt_value)) return;
LLVMBasicBlockRef after_block = llvm_basic_block_new(c, "after_check");
// No error variable
if (!c->opt_var)
{
// No error var and a constant error means jumping to the "catch" block
if (is_constant_err)
if (is_constant_opt)
{
llvm_emit_br(c, c->catch_block);
}
else
{
llvm_emit_cond_br_raw(c, llvm_emit_is_no_opt(c, err_value), after_block, c->catch_block);
llvm_emit_cond_br_raw(c, llvm_emit_is_no_opt(c, opt_value), after_block, c->catch_block);
}
llvm_emit_block(c, after_block);
return;
}
// If it's not a constant, then jump conditionally
if (!is_constant_err)
if (!is_constant_opt)
{
LLVMValueRef was_ok = llvm_emit_is_no_opt(c, err_value);
LLVMValueRef was_ok = llvm_emit_is_no_opt(c, opt_value);
LLVMBasicBlockRef error_block = llvm_basic_block_new(c, "assign_optional");
llvm_emit_cond_br_raw(c, was_ok, after_block, error_block);
llvm_emit_block(c, error_block);
}
llvm_store_to_ptr_raw(c, c->opt_var, err_value, type_anyerr);
llvm_store_to_ptr_raw(c, c->opt_var, opt_value, type_anyerr);
llvm_emit_br(c, c->catch_block);
llvm_emit_block(c, after_block);
}