2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
19 static bool attr_w clear_flag_cache(struct codegen_context *ctx)
21 memset(ctx->flag_cache, 0, function_n_variables(ctx->fn) * sizeof(int8_t));
25 /*#define clear_flag_cache(ctx) \
26 (debug("clearing flag cache @ %d", __LINE__), memset((ctx)->flag_cache, 0, function_n_variables(ctx->fn) * sizeof(int8_t)), true)*/
28 static inline void flag_set(struct codegen_context *ctx, frame_t slot, bool val)
30 if (val && !must_be_flat_chicken && da(ctx->fn,function)->local_variables_flags[slot].must_be_flat) {
31 internal(file_line, "flag_set: %s: setting slot %lu as not flat", da(ctx->fn,function)->function_name, (unsigned long)slot);
33 ctx->flag_cache[slot] = !val ? -1 : 1;
36 static inline void flag_set_unknown(struct codegen_context *ctx, frame_t slot)
38 ctx->flag_cache[slot] = 0;
41 static inline bool flag_must_be_flat(struct codegen_context *ctx, frame_t slot)
43 if (!must_be_flat_chicken && da(ctx->fn,function)->local_variables_flags[slot].must_be_flat) {
44 if (ctx->flag_cache[slot] == 1)
45 internal(file_line, "flag_must_be_flat: %s: must_be_flat slot %lu is not flat", da(ctx->fn,function)->function_name, (unsigned long)slot);
51 static inline bool flag_is_clear(struct codegen_context *ctx, frame_t slot)
53 if (!flag_cache_chicken && ctx->flag_cache[slot] == -1)
55 if (flag_must_be_flat(ctx, slot))
60 static inline bool flag_is_set(struct codegen_context *ctx, frame_t slot)
62 if (!flag_cache_chicken && ctx->flag_cache[slot] == 1)
67 static bool attr_w gen_test_1_cached(struct codegen_context *ctx, frame_t slot_1, uint32_t label)
69 if (flag_is_clear(ctx, slot_1))
71 return gen_test_1(ctx, R_FRAME, slot_1, 0, label, false, TEST);
74 static bool attr_w gen_test_2_cached(struct codegen_context *ctx, frame_t slot_1, frame_t slot_2, uint32_t label)
76 if (flag_is_clear(ctx, slot_1))
77 return gen_test_1_cached(ctx, slot_2, label);
78 if (flag_is_clear(ctx, slot_2))
79 return gen_test_1_cached(ctx, slot_1, label);
80 return gen_test_2(ctx, slot_1, slot_2, label);
83 static bool attr_w gen_test_1_jz_cached(struct codegen_context *ctx, frame_t slot_1, uint32_t label)
85 const struct type *type = get_type_of_local(ctx, slot_1);
86 if (!TYPE_IS_FLAT(type) && !da(ctx->fn,function)->local_variables_flags[slot_1].may_be_borrowed)
88 if (flag_is_set(ctx, slot_1))
90 return gen_test_1(ctx, R_FRAME, slot_1, 0, label, true, TEST);