commit ca6ac4e270a1902b6b0275e112bc0f549c0f9f66
parent 43c2ab14fd8ee84072f850936118795ab46342b6
Author: Sebastian <sebastian@sebsite.pw>
Date: Thu, 5 Jan 2023 18:00:41 -0500
gen: omit runtime bounds checks when done at compile-time
When bounds have been sufficiently checked at compile-time (for constant
indices and an array with a known defined length), they don't need to be
included at runtime. This doesn't effect bounds checks for operations on
a slice, since the length of the slice is only known at runtime.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/expr.h b/include/expr.h
@@ -62,6 +62,7 @@ struct expression_access {
struct {
struct expression *array;
struct expression *index;
+ bool bounds_checked;
};
struct {
struct expression *_struct;
@@ -291,6 +292,7 @@ struct expression_return {
struct expression_slice {
struct expression *object;
struct expression *start, *end;
+ bool bounds_checked;
};
struct case_option {
diff --git a/src/check.c b/src/check.c
@@ -241,6 +241,7 @@ check_expr_access(struct context *ctx,
free(evaled);
return;
}
+ expr->access.bounds_checked = true;
}
free(evaled);
}
@@ -2501,6 +2502,8 @@ slice_bounds_check(struct context *ctx, struct expression *expr)
if (end) free(end);
return;
}
+
+ expr->slice.bounds_checked = true;
}
if (end != NULL) {
diff --git a/src/gen.c b/src/gen.c
@@ -238,7 +238,7 @@ gen_access_index(struct gen_context *ctx, const struct expression *expr)
glval = gen_autoderef(ctx, glval);
struct qbe_value qlval = mkqval(ctx, &glval);
struct qbe_value qival = mkqtmp(ctx, ctx->arch.ptr, ".%d");
- bool checkbounds = true;
+ bool checkbounds = !expr->access.bounds_checked;
struct qbe_value length;
const struct type *ty = type_dealias(glval.type);
switch (ty->storage) {
@@ -2939,7 +2939,7 @@ gen_expr_slice_at(struct gen_context *ctx,
object = gen_autoderef(ctx, object);
const struct type *srctype = type_dealias(object.type);
- bool check_bounds = true;
+ bool check_bounds = !expr->slice.bounds_checked;
struct gen_value length;
struct qbe_value qlength;
struct qbe_value qbase;