Merge remote-tracking branch 'origin/master' into llvm7
This commit is contained in:
@@ -2927,18 +2927,26 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
|
||||
return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, "");
|
||||
} else if (array_type->id == TypeTableEntryIdStruct) {
|
||||
assert(array_type->data.structure.is_slice);
|
||||
if (!type_has_bits(instruction->base.value.type)) {
|
||||
if (safety_check_on) {
|
||||
assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMIntegerTypeKind);
|
||||
add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, array_ptr);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
|
||||
assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
|
||||
|
||||
if (safety_check_on) {
|
||||
size_t len_index = array_type->data.structure.fields[1].gen_index;
|
||||
size_t len_index = array_type->data.structure.fields[slice_len_index].gen_index;
|
||||
assert(len_index != SIZE_MAX);
|
||||
LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");
|
||||
LLVMValueRef len = gen_load_untyped(g, len_ptr, 0, false, "");
|
||||
add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, len);
|
||||
}
|
||||
|
||||
size_t ptr_index = array_type->data.structure.fields[0].gen_index;
|
||||
size_t ptr_index = array_type->data.structure.fields[slice_ptr_index].gen_index;
|
||||
assert(ptr_index != SIZE_MAX);
|
||||
LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)ptr_index, "");
|
||||
LLVMValueRef ptr = gen_load_untyped(g, ptr_ptr, 0, false, "");
|
||||
@@ -3353,14 +3361,22 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
|
||||
static LLVMValueRef get_int_builtin_fn(CodeGen *g, TypeTableEntry *int_type, BuiltinFnId fn_id) {
|
||||
ZigLLVMFnKey key = {};
|
||||
const char *fn_name;
|
||||
uint32_t n_args;
|
||||
if (fn_id == BuiltinFnIdCtz) {
|
||||
fn_name = "cttz";
|
||||
n_args = 2;
|
||||
key.id = ZigLLVMFnIdCtz;
|
||||
key.data.ctz.bit_count = (uint32_t)int_type->data.integral.bit_count;
|
||||
} else if (fn_id == BuiltinFnIdClz) {
|
||||
fn_name = "ctlz";
|
||||
n_args = 2;
|
||||
key.id = ZigLLVMFnIdClz;
|
||||
key.data.clz.bit_count = (uint32_t)int_type->data.integral.bit_count;
|
||||
} else if (fn_id == BuiltinFnIdPopCount) {
|
||||
fn_name = "ctpop";
|
||||
n_args = 1;
|
||||
key.id = ZigLLVMFnIdPopCount;
|
||||
key.data.pop_count.bit_count = (uint32_t)int_type->data.integral.bit_count;
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
@@ -3375,7 +3391,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, TypeTableEntry *int_type, Bui
|
||||
int_type->type_ref,
|
||||
LLVMInt1Type(),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(int_type->type_ref, param_types, 2, false);
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(int_type->type_ref, param_types, n_args, false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, llvm_name, fn_type);
|
||||
assert(LLVMGetIntrinsicID(fn_val));
|
||||
|
||||
@@ -3408,6 +3424,14 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstru
|
||||
return gen_widen_or_shorten(g, false, int_type, instruction->base.value.type, wrong_size_int);
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) {
|
||||
TypeTableEntry *int_type = instruction->value->value.type;
|
||||
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount);
|
||||
LLVMValueRef operand = ir_llvm_value(g, instruction->value);
|
||||
LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, "");
|
||||
return gen_widen_or_shorten(g, false, int_type, instruction->base.value.type, wrong_size_int);
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutable *executable, IrInstructionSwitchBr *instruction) {
|
||||
LLVMValueRef target_value = ir_llvm_value(g, instruction->target_value);
|
||||
LLVMBasicBlockRef else_block = instruction->else_block->llvm_block;
|
||||
@@ -3894,11 +3918,15 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
|
||||
add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
|
||||
}
|
||||
|
||||
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_ptr_index, "");
|
||||
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
|
||||
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
|
||||
if (type_has_bits(array_type)) {
|
||||
size_t gen_ptr_index = instruction->base.value.type->data.structure.fields[slice_ptr_index].gen_index;
|
||||
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, "");
|
||||
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
|
||||
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
|
||||
}
|
||||
|
||||
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
|
||||
size_t gen_len_index = instruction->base.value.type->data.structure.fields[slice_len_index].gen_index;
|
||||
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_len_index, "");
|
||||
LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
|
||||
gen_store_untyped(g, len_value, len_field_ptr, 0, false);
|
||||
|
||||
@@ -4730,6 +4758,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
||||
return ir_render_clz(g, executable, (IrInstructionClz *)instruction);
|
||||
case IrInstructionIdCtz:
|
||||
return ir_render_ctz(g, executable, (IrInstructionCtz *)instruction);
|
||||
case IrInstructionIdPopCount:
|
||||
return ir_render_pop_count(g, executable, (IrInstructionPopCount *)instruction);
|
||||
case IrInstructionIdSwitchBr:
|
||||
return ir_render_switch_br(g, executable, (IrInstructionSwitchBr *)instruction);
|
||||
case IrInstructionIdPhi:
|
||||
@@ -6241,6 +6271,7 @@ static void define_builtin_fns(CodeGen *g) {
|
||||
create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdClz, "clz", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdPopCount, "popCount", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdImport, "import", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1);
|
||||
|
||||
Reference in New Issue
Block a user