From: Alyssa Rosenzweig Date: Thu, 12 Mar 2020 00:08:03 +0000 (-0400) Subject: panfrost: Move lcra to panfrost/util X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f06db4d54c1a83005e4e0e00a9d2fdeb5bface29;p=mesa.git panfrost: Move lcra to panfrost/util We'll want to use it for the Bifrost RA as well. Signed-off-by: Alyssa Rosenzweig Part-of: --- diff --git a/src/panfrost/Makefile.sources b/src/panfrost/Makefile.sources index fd58252345a..212a1d7e540 100644 --- a/src/panfrost/Makefile.sources +++ b/src/panfrost/Makefile.sources @@ -54,7 +54,6 @@ midgard_FILES := \ midgard/mir_promote_uniforms.c \ midgard/mir_squeeze.c \ midgard/nir_undef_to_zero.c \ - midgard/lcra.c shared_FILES := \ shared/pan_minmax_cache.c \ diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h index 6614439fbfb..bc43309c7a1 100644 --- a/src/panfrost/midgard/compiler.h +++ b/src/panfrost/midgard/compiler.h @@ -28,7 +28,6 @@ #include "helpers.h" #include "midgard_compile.h" #include "midgard_ops.h" -#include "lcra.h" #include "util/hash_table.h" #include "util/u_dynarray.h" @@ -39,6 +38,7 @@ #include "compiler/nir_types.h" #include "compiler/nir/nir.h" #include "panfrost/util/pan_ir.h" +#include "panfrost/util/lcra.h" /* Forward declare */ struct midgard_block; diff --git a/src/panfrost/midgard/lcra.c b/src/panfrost/midgard/lcra.c deleted file mode 100644 index 28f9a735a44..00000000000 --- a/src/panfrost/midgard/lcra.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (C) 2019 Collabora, Ltd. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors (Collabora): - * Alyssa Rosenzweig - */ - -#include -#include -#include -#include -#include -#include "util/macros.h" -#include "util/u_math.h" -#include "lcra.h" - -/* This module is the reference implementation of "Linearly Constrained - * Register Allocation". The paper is available in PDF form - * (https://people.collabora.com/~alyssa/LCRA.pdf) as well as Markdown+LaTeX - * (https://gitlab.freedesktop.org/alyssa/lcra/blob/master/LCRA.md) - */ - -struct lcra_state * -lcra_alloc_equations( - unsigned node_count, - unsigned min_alignment, unsigned max_alignment, - unsigned bound, unsigned class_count) -{ - struct lcra_state *l = calloc(1, sizeof(*l)); - - l->node_count = node_count; - l->class_count = class_count; - l->bound = bound; - - l->alignment = calloc(sizeof(l->alignment[0]), node_count); - l->linear = calloc(sizeof(l->linear[0]), node_count * node_count); - l->modulus = calloc(sizeof(l->modulus[0]), node_count); - l->class = calloc(sizeof(l->class[0]), node_count); - l->class_start = calloc(sizeof(l->class_start[0]), class_count); - l->class_disjoint = calloc(sizeof(l->class_disjoint[0]), class_count * class_count); - l->class_size = calloc(sizeof(l->class_size[0]), class_count); - l->spill_cost = calloc(sizeof(l->spill_cost[0]), node_count); - l->solutions = calloc(sizeof(l->solutions[0]), node_count); - - memset(l->solutions, ~0, sizeof(l->solutions[0]) * node_count); - - return l; -} - -void -lcra_free(struct lcra_state *l) -{ - if (!l) - return; - - free(l->alignment); - free(l->linear); - free(l->modulus); - free(l->class); - free(l->class_start); - free(l->class_disjoint); - free(l->class_size); - free(l->spill_cost); - free(l->solutions); - - free(l); -} - -void -lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2) -{ - l->alignment[node] = align_log2 + 1; -} - -void -lcra_set_disjoint_class(struct lcra_state *l, unsigned c1, unsigned c2) -{ - l->class_disjoint[(c1 * l->class_count) + c2] = true; - l->class_disjoint[(c2 * l->class_count) + c1] = true; -} - -void -lcra_restrict_range(struct lcra_state *l, unsigned node, unsigned len) -{ - if (node < l->node_count && l->alignment[node]) - l->modulus[node] = DIV_ROUND_UP(l->bound - len + 1, 1 << (l->alignment[node] - 1)); -} - -void -lcra_add_node_interference(struct lcra_state *l, unsigned i, unsigned cmask_i, unsigned j, unsigned cmask_j) -{ - if (i == j) - return; - - if (l->class_disjoint[(l->class[i] * l->class_count) + l->class[j]]) - return; - - uint32_t constraint_fw = 0; - uint32_t constraint_bw = 0; - - for (unsigned D = 0; D < 16; ++D) { - if (cmask_i & (cmask_j << D)) { - constraint_bw |= (1 << (15 + D)); - constraint_fw |= (1 << (15 - D)); - } - - if (cmask_i & (cmask_j >> D)) { - constraint_fw |= (1 << (15 + D)); - constraint_bw |= (1 << (15 - D)); - } - } - - l->linear[j * l->node_count + i] |= constraint_fw; - l->linear[i * l->node_count + j] |= constraint_bw; -} - -static bool -lcra_test_linear(struct lcra_state *l, unsigned *solutions, unsigned i) -{ - unsigned *row = &l->linear[i * l->node_count]; - signed constant = solutions[i]; - - for (unsigned j = 0; j < l->node_count; ++j) { - if (solutions[j] == ~0) continue; - - signed lhs = solutions[j] - constant; - - if (lhs < -15 || lhs > 15) - continue; - - if (row[j] & (1 << (lhs + 15))) - return false; - } - - return true; -} - -bool -lcra_solve(struct lcra_state *l) -{ - for (unsigned step = 0; step < l->node_count; ++step) { - if (l->solutions[step] != ~0) continue; - if (l->alignment[step] == 0) continue; - - unsigned _class = l->class[step]; - unsigned class_start = l->class_start[_class]; - - unsigned shift = l->alignment[step] - 1; - - unsigned P = l->bound >> shift; - unsigned Q = l->modulus[step]; - unsigned r_max = l->class_size[_class]; - unsigned k_max = r_max >> shift; - unsigned m_max = k_max / P; - bool succ = false; - - for (unsigned m = 0; m < m_max; ++m) { - for (unsigned n = 0; n < Q; ++n) { - l->solutions[step] = ((m * P + n) << shift) + class_start; - succ = lcra_test_linear(l, l->solutions, step); - - if (succ) break; - } - - if (succ) break; - } - - /* Out of registers - prepare to spill */ - if (!succ) { - l->spill_class = l->class[step]; - return false; - } - } - - return true; -} - -/* Register spilling is implemented with a cost-benefit system. Costs are set - * by the user. Benefits are calculated from the constraints. */ - -void -lcra_set_node_spill_cost(struct lcra_state *l, unsigned node, signed cost) -{ - if (node < l->node_count) - l->spill_cost[node] = cost; -} - -/* Count along the lower triangle */ - -static unsigned -lcra_count_constraints(struct lcra_state *l, unsigned i) -{ - unsigned count = 0; - unsigned *constraints = &l->linear[i * l->node_count]; - - for (unsigned j = 0; j < i; ++j) - count += util_bitcount(constraints[j]); - - return count; -} - -signed -lcra_get_best_spill_node(struct lcra_state *l) -{ - float best_benefit = -1.0; - signed best_node = -1; - - for (unsigned i = 0; i < l->node_count; ++i) { - /* Find spillable nodes */ - if (l->class[i] != l->spill_class) continue; - if (l->spill_cost[i] < 0) continue; - - /* Adapted from Chaitin's heuristic */ - float constraints = lcra_count_constraints(l, i); - float cost = (l->spill_cost[i] + 1); - float benefit = constraints / cost; - - if (benefit > best_benefit) { - best_benefit = benefit; - best_node = i; - } - } - - return best_node; -} diff --git a/src/panfrost/midgard/lcra.h b/src/panfrost/midgard/lcra.h deleted file mode 100644 index 68afc4a848e..00000000000 --- a/src/panfrost/midgard/lcra.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2019 Collabora, Ltd. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors (Collabora): - * Alyssa Rosenzweig - */ - -#ifndef __LCRA_H -#define __LCRA_H - -#include -#include - -struct lcra_state { - unsigned node_count; - - /* Word boundary where vectors can't cross */ - unsigned bound; - - /* Alignment for node in log2(bytes)+1. Since alignment must be - * non-negative power-of-two, the elements are strictly positive - * integers. Zero is the sentinel for a missing node */ - unsigned *alignment; - - /* Linear constraints imposed. Nested array sized upfront, organized as - * linear[node_left][node_right]. That is, calculate indices as: - * - * Each element is itself a bit field denoting whether (c_j - c_i) bias - * is present or not, including negative biases. - * - * Note for Midgard, there are 16 components so the bias is in range - * [-15, 15] so encoded by 32-bit field. */ - - uint32_t *linear; - - /* Per node max modulus constraints */ - uint8_t *modulus; - - /* Classes allow nodes to be partitioned with a starting register. - * Classes cannot interfere; that is, they are true partitions in the - * usual sense of the word. class_count is the number of classes. - * class[] is indexed by a node to get the mapped class. class_start is - * biased to all solutions in the class. */ - - unsigned class_count; - unsigned *class; - unsigned *class_start; - unsigned *class_size; - bool *class_disjoint; - - /* Before solving, forced registers; after solving, solutions. */ - unsigned *solutions; - - /* For register spilling, the costs to spill nodes (as set by the user) - * are in spill_cost[], negative if a node is unspillable. Internally, - * spill_class specifies which class to spill (whichever class failed - * to allocate) */ - - signed *spill_cost; - unsigned spill_class; -}; - -struct lcra_state * -lcra_alloc_equations( - unsigned node_count, - unsigned min_alignment, unsigned max_alignment, - unsigned bound, unsigned class_count); - -void -lcra_free(struct lcra_state *l); - -void -lcra_set_disjoint_class(struct lcra_state *l, unsigned c1, unsigned c2); - -void -lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2); - -void -lcra_restrict_range(struct lcra_state *l, unsigned node, unsigned len); - -void -lcra_add_node_interference(struct lcra_state *l, unsigned i, unsigned cmask_i, unsigned j, unsigned cmask_j); - -bool -lcra_solve(struct lcra_state *l); - -void -lcra_set_node_spill_cost(struct lcra_state *l, unsigned node, signed cost); - -signed -lcra_get_best_spill_node(struct lcra_state *l); - -#endif diff --git a/src/panfrost/midgard/meson.build b/src/panfrost/midgard/meson.build index ba69b3fe55a..8b93b4fa128 100644 --- a/src/panfrost/midgard/meson.build +++ b/src/panfrost/midgard/meson.build @@ -41,7 +41,6 @@ libpanfrost_midgard_files = files( 'midgard_errata_lod.c', 'nir_undef_to_zero.c', 'disassemble.c', - 'lcra.c' ) midgard_nir_algebraic_c = custom_target( diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c index ae6d0efc6d2..48122c4967a 100644 --- a/src/panfrost/midgard/midgard_ra.c +++ b/src/panfrost/midgard/midgard_ra.c @@ -26,7 +26,6 @@ #include "midgard_ops.h" #include "util/u_math.h" #include "util/u_memory.h" -#include "lcra.h" #include "midgard_quirks.h" struct phys_reg { diff --git a/src/panfrost/util/lcra.c b/src/panfrost/util/lcra.c new file mode 100644 index 00000000000..28f9a735a44 --- /dev/null +++ b/src/panfrost/util/lcra.c @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2019 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors (Collabora): + * Alyssa Rosenzweig + */ + +#include +#include +#include +#include +#include +#include "util/macros.h" +#include "util/u_math.h" +#include "lcra.h" + +/* This module is the reference implementation of "Linearly Constrained + * Register Allocation". The paper is available in PDF form + * (https://people.collabora.com/~alyssa/LCRA.pdf) as well as Markdown+LaTeX + * (https://gitlab.freedesktop.org/alyssa/lcra/blob/master/LCRA.md) + */ + +struct lcra_state * +lcra_alloc_equations( + unsigned node_count, + unsigned min_alignment, unsigned max_alignment, + unsigned bound, unsigned class_count) +{ + struct lcra_state *l = calloc(1, sizeof(*l)); + + l->node_count = node_count; + l->class_count = class_count; + l->bound = bound; + + l->alignment = calloc(sizeof(l->alignment[0]), node_count); + l->linear = calloc(sizeof(l->linear[0]), node_count * node_count); + l->modulus = calloc(sizeof(l->modulus[0]), node_count); + l->class = calloc(sizeof(l->class[0]), node_count); + l->class_start = calloc(sizeof(l->class_start[0]), class_count); + l->class_disjoint = calloc(sizeof(l->class_disjoint[0]), class_count * class_count); + l->class_size = calloc(sizeof(l->class_size[0]), class_count); + l->spill_cost = calloc(sizeof(l->spill_cost[0]), node_count); + l->solutions = calloc(sizeof(l->solutions[0]), node_count); + + memset(l->solutions, ~0, sizeof(l->solutions[0]) * node_count); + + return l; +} + +void +lcra_free(struct lcra_state *l) +{ + if (!l) + return; + + free(l->alignment); + free(l->linear); + free(l->modulus); + free(l->class); + free(l->class_start); + free(l->class_disjoint); + free(l->class_size); + free(l->spill_cost); + free(l->solutions); + + free(l); +} + +void +lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2) +{ + l->alignment[node] = align_log2 + 1; +} + +void +lcra_set_disjoint_class(struct lcra_state *l, unsigned c1, unsigned c2) +{ + l->class_disjoint[(c1 * l->class_count) + c2] = true; + l->class_disjoint[(c2 * l->class_count) + c1] = true; +} + +void +lcra_restrict_range(struct lcra_state *l, unsigned node, unsigned len) +{ + if (node < l->node_count && l->alignment[node]) + l->modulus[node] = DIV_ROUND_UP(l->bound - len + 1, 1 << (l->alignment[node] - 1)); +} + +void +lcra_add_node_interference(struct lcra_state *l, unsigned i, unsigned cmask_i, unsigned j, unsigned cmask_j) +{ + if (i == j) + return; + + if (l->class_disjoint[(l->class[i] * l->class_count) + l->class[j]]) + return; + + uint32_t constraint_fw = 0; + uint32_t constraint_bw = 0; + + for (unsigned D = 0; D < 16; ++D) { + if (cmask_i & (cmask_j << D)) { + constraint_bw |= (1 << (15 + D)); + constraint_fw |= (1 << (15 - D)); + } + + if (cmask_i & (cmask_j >> D)) { + constraint_fw |= (1 << (15 + D)); + constraint_bw |= (1 << (15 - D)); + } + } + + l->linear[j * l->node_count + i] |= constraint_fw; + l->linear[i * l->node_count + j] |= constraint_bw; +} + +static bool +lcra_test_linear(struct lcra_state *l, unsigned *solutions, unsigned i) +{ + unsigned *row = &l->linear[i * l->node_count]; + signed constant = solutions[i]; + + for (unsigned j = 0; j < l->node_count; ++j) { + if (solutions[j] == ~0) continue; + + signed lhs = solutions[j] - constant; + + if (lhs < -15 || lhs > 15) + continue; + + if (row[j] & (1 << (lhs + 15))) + return false; + } + + return true; +} + +bool +lcra_solve(struct lcra_state *l) +{ + for (unsigned step = 0; step < l->node_count; ++step) { + if (l->solutions[step] != ~0) continue; + if (l->alignment[step] == 0) continue; + + unsigned _class = l->class[step]; + unsigned class_start = l->class_start[_class]; + + unsigned shift = l->alignment[step] - 1; + + unsigned P = l->bound >> shift; + unsigned Q = l->modulus[step]; + unsigned r_max = l->class_size[_class]; + unsigned k_max = r_max >> shift; + unsigned m_max = k_max / P; + bool succ = false; + + for (unsigned m = 0; m < m_max; ++m) { + for (unsigned n = 0; n < Q; ++n) { + l->solutions[step] = ((m * P + n) << shift) + class_start; + succ = lcra_test_linear(l, l->solutions, step); + + if (succ) break; + } + + if (succ) break; + } + + /* Out of registers - prepare to spill */ + if (!succ) { + l->spill_class = l->class[step]; + return false; + } + } + + return true; +} + +/* Register spilling is implemented with a cost-benefit system. Costs are set + * by the user. Benefits are calculated from the constraints. */ + +void +lcra_set_node_spill_cost(struct lcra_state *l, unsigned node, signed cost) +{ + if (node < l->node_count) + l->spill_cost[node] = cost; +} + +/* Count along the lower triangle */ + +static unsigned +lcra_count_constraints(struct lcra_state *l, unsigned i) +{ + unsigned count = 0; + unsigned *constraints = &l->linear[i * l->node_count]; + + for (unsigned j = 0; j < i; ++j) + count += util_bitcount(constraints[j]); + + return count; +} + +signed +lcra_get_best_spill_node(struct lcra_state *l) +{ + float best_benefit = -1.0; + signed best_node = -1; + + for (unsigned i = 0; i < l->node_count; ++i) { + /* Find spillable nodes */ + if (l->class[i] != l->spill_class) continue; + if (l->spill_cost[i] < 0) continue; + + /* Adapted from Chaitin's heuristic */ + float constraints = lcra_count_constraints(l, i); + float cost = (l->spill_cost[i] + 1); + float benefit = constraints / cost; + + if (benefit > best_benefit) { + best_benefit = benefit; + best_node = i; + } + } + + return best_node; +} diff --git a/src/panfrost/util/lcra.h b/src/panfrost/util/lcra.h new file mode 100644 index 00000000000..68afc4a848e --- /dev/null +++ b/src/panfrost/util/lcra.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2019 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors (Collabora): + * Alyssa Rosenzweig + */ + +#ifndef __LCRA_H +#define __LCRA_H + +#include +#include + +struct lcra_state { + unsigned node_count; + + /* Word boundary where vectors can't cross */ + unsigned bound; + + /* Alignment for node in log2(bytes)+1. Since alignment must be + * non-negative power-of-two, the elements are strictly positive + * integers. Zero is the sentinel for a missing node */ + unsigned *alignment; + + /* Linear constraints imposed. Nested array sized upfront, organized as + * linear[node_left][node_right]. That is, calculate indices as: + * + * Each element is itself a bit field denoting whether (c_j - c_i) bias + * is present or not, including negative biases. + * + * Note for Midgard, there are 16 components so the bias is in range + * [-15, 15] so encoded by 32-bit field. */ + + uint32_t *linear; + + /* Per node max modulus constraints */ + uint8_t *modulus; + + /* Classes allow nodes to be partitioned with a starting register. + * Classes cannot interfere; that is, they are true partitions in the + * usual sense of the word. class_count is the number of classes. + * class[] is indexed by a node to get the mapped class. class_start is + * biased to all solutions in the class. */ + + unsigned class_count; + unsigned *class; + unsigned *class_start; + unsigned *class_size; + bool *class_disjoint; + + /* Before solving, forced registers; after solving, solutions. */ + unsigned *solutions; + + /* For register spilling, the costs to spill nodes (as set by the user) + * are in spill_cost[], negative if a node is unspillable. Internally, + * spill_class specifies which class to spill (whichever class failed + * to allocate) */ + + signed *spill_cost; + unsigned spill_class; +}; + +struct lcra_state * +lcra_alloc_equations( + unsigned node_count, + unsigned min_alignment, unsigned max_alignment, + unsigned bound, unsigned class_count); + +void +lcra_free(struct lcra_state *l); + +void +lcra_set_disjoint_class(struct lcra_state *l, unsigned c1, unsigned c2); + +void +lcra_set_alignment(struct lcra_state *l, unsigned node, unsigned align_log2); + +void +lcra_restrict_range(struct lcra_state *l, unsigned node, unsigned len); + +void +lcra_add_node_interference(struct lcra_state *l, unsigned i, unsigned cmask_i, unsigned j, unsigned cmask_j); + +bool +lcra_solve(struct lcra_state *l); + +void +lcra_set_node_spill_cost(struct lcra_state *l, unsigned node, signed cost); + +signed +lcra_get_best_spill_node(struct lcra_state *l); + +#endif diff --git a/src/panfrost/util/meson.build b/src/panfrost/util/meson.build index 76e2249b60e..a39ad5130bb 100644 --- a/src/panfrost/util/meson.build +++ b/src/panfrost/util/meson.build @@ -20,6 +20,8 @@ # SOFTWARE. libpanfrost_util_files = files( + 'lcra.c', + 'lcra.h', 'pan_ir.c', 'pan_ir.h', 'pan_liveness.c',