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)
31 if (val && !must_be_flat_chicken && da(ctx->fn,function)->local_variables_flags[slot].must_be_flat) {
32 internal(file_line, "flag_set: %s: setting slot %lu as not flat", da(ctx->fn,function)->function_name, (unsigned long)slot);
34 c = ctx->flag_cache[slot] & ~(FLAG_CACHE_IS_FLAT | FLAG_CACHE_IS_NOT_FLAT);
35 ctx->flag_cache[slot] = c | (!val ? FLAG_CACHE_IS_FLAT : FLAG_CACHE_IS_NOT_FLAT);
38 static inline void flag_set_unknown(struct codegen_context *ctx, frame_t slot)
40 ctx->flag_cache[slot] = 0;
43 static inline bool flag_must_be_flat(struct codegen_context *ctx, frame_t slot)
45 if (!must_be_flat_chicken && da(ctx->fn,function)->local_variables_flags[slot].must_be_flat) {
46 if (unlikely((ctx->flag_cache[slot] & FLAG_CACHE_IS_NOT_FLAT) != 0))
47 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);
53 static inline bool flag_is_clear(struct codegen_context *ctx, frame_t slot)
55 if (!flag_cache_chicken && ctx->flag_cache[slot] & FLAG_CACHE_IS_FLAT)
57 if (flag_must_be_flat(ctx, slot))
62 static inline bool flag_is_set(struct codegen_context *ctx, frame_t slot)
64 if (!flag_cache_chicken && ctx->flag_cache[slot] & FLAG_CACHE_IS_NOT_FLAT)
69 static bool attr_w gen_test_1_cached(struct codegen_context *ctx, frame_t slot_1, uint32_t label)
71 if (flag_is_clear(ctx, slot_1))
73 return gen_test_1(ctx, R_FRAME, slot_1, 0, label, false, TEST);
76 static bool attr_w gen_test_2_cached(struct codegen_context *ctx, frame_t slot_1, frame_t slot_2, uint32_t label)
78 if (flag_is_clear(ctx, slot_1))
79 return gen_test_1_cached(ctx, slot_2, label);
80 if (flag_is_clear(ctx, slot_2))
81 return gen_test_1_cached(ctx, slot_1, label);
82 return gen_test_2(ctx, slot_1, slot_2, label);
85 static bool attr_w gen_test_1_jz_cached(struct codegen_context *ctx, frame_t slot_1, uint32_t label)
87 const struct type *type = get_type_of_local(ctx, slot_1);
88 if (!TYPE_IS_FLAT(type) && !da(ctx->fn,function)->local_variables_flags[slot_1].may_be_borrowed)
90 if (flag_is_set(ctx, slot_1))
92 return gen_test_1(ctx, R_FRAME, slot_1, 0, label, true, TEST);