mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
More codegen cleanup.
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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, "");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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), "");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user