Improve bounds checking to minimize its need

This commit is contained in:
gingerBill
2026-03-16 14:29:44 +00:00
parent 0bf2d01a04
commit fc41e44140
2 changed files with 35 additions and 11 deletions

View File

@@ -648,6 +648,11 @@ gb_internal LLVMTypeRef llvm_array_type(LLVMTypeRef ElementType, uint64_t Elemen
#endif
}
gb_internal lbValue lb_emit_struct_iv(lbProcedure *p, lbValue agg, lbValue field, i32 index);
gb_internal lbValue lb_build_struct_value(lbProcedure *p, Type *type, lbValue *fields, isize count);
gb_internal lbValue lb_make_slice_value(lbProcedure *p, Type *slice_type, lbValue elem, lbValue len);
gb_internal lbValue lb_make_string_value(lbProcedure *p, Type *string_type, lbValue elem, lbValue len);
gb_internal String lb_internal_gen_name_from_type(char const *prefix, Type *type);

View File

@@ -701,19 +701,19 @@ gb_internal void lb_set_file_line_col(lbProcedure *p, Array<lbValue> arr, TokenP
arr[2] = lb_const_int(p->module, t_i32, col);
}
gb_internal void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index, lbValue len) {
gb_internal bool lb_bounds_check_short_circuit(lbProcedure *p, lbValue index, lbValue len) {
if (build_context.no_bounds_check) {
return;
return true;
}
if ((p->state_flags & StateFlag_no_bounds_check) != 0) {
return;
return true;
}
if (LLVMIsConstant(index.value) && LLVMIsConstant(len.value)) {
i64 i = LLVMConstIntGetSExtValue(index.value);
i64 n = LLVMConstIntGetSExtValue(len.value);
if (0<= i && i < n) {
return;
if (0 <= i && i < n) {
return true;
}
}
@@ -722,7 +722,7 @@ gb_internal void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index
if (op == LLVMURem) {
LLVMValueRef divisor = LLVMGetOperand(index.value, 1);
if (divisor == len.value) {
return;
return true;
}
} else if (op == LLVMAnd) {
LLVMValueRef mask = LLVMGetOperand(index.value, 1);
@@ -730,11 +730,18 @@ gb_internal void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index
i64 m = LLVMConstIntGetSExtValue(mask);
i64 l = LLVMConstIntGetSExtValue(len.value);
if (l > 0 && (l & (l-1)) == 0 && m == l-1) {
return;
return true;
}
}
}
}
return false;
}
gb_internal void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index, lbValue len) {
if (lb_bounds_check_short_circuit(p, index, len)) {
return;
}
TEMPORARY_ALLOCATOR_GUARD();
@@ -783,6 +790,15 @@ gb_internal void lb_emit_multi_pointer_slice_bounds_check(lbProcedure *p, Token
return;
}
if (LLVMIsConstant(low.value) && LLVMIsConstant(high.value)) {
i64 i = LLVMConstIntGetSExtValue(low.value);
i64 n = LLVMConstIntGetSExtValue(high.value);
if (i < n) {
return;
}
}
low = lb_emit_conv(p, low, t_int);
high = lb_emit_conv(p, high, t_int);
@@ -795,12 +811,15 @@ gb_internal void lb_emit_multi_pointer_slice_bounds_check(lbProcedure *p, Token
}
gb_internal void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValue high, lbValue len, bool lower_value_used) {
if (build_context.no_bounds_check) {
return;
}
if ((p->state_flags & StateFlag_no_bounds_check) != 0) {
if (!lower_value_used && lb_bounds_check_short_circuit(p, high, len)) {
return;
}
// if (lower_value_used &&
// lb_bounds_check_short_circuit(p, low, high) &&
// lb_bounds_check_short_circuit(p, low, len) &&
// lb_bounds_check_short_circuit(p, high, len)) {
// return;
// }
high = lb_emit_conv(p, high, t_int);