harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

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:
Minclude/expr.h | 2++
Msrc/check.c | 3+++
Msrc/gen.c | 4++--
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;