1 /*
2 * Copyright (C) 2009 Nicolai Haehnle.
3 * Copyright 2011 Tom Stellard <tstellar@gmail.com>
4 * Copyright 2012 Advanced Micro Devices, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * on the rights to use, copy, modify, merge, publish, distribute, sub
10 * license, and/or sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Author: Tom Stellard <thomas.stellard@amd.com>
26 */
27
28 #ifndef RADEON_REGALLOC_H
29 #define RADEON_REGALLOC_H
30
31 #include "util/register_allocate.h"
32 #include "util/u_memory.h"
33 #include "util/ralloc.h"
34
35 #include "radeon_variable.h"
36
37 struct ra_regs;
38
39 enum rc_reg_class {
40 RC_REG_CLASS_FP_SINGLE,
41 RC_REG_CLASS_FP_DOUBLE,
42 RC_REG_CLASS_FP_TRIPLE,
43 RC_REG_CLASS_FP_ALPHA,
44 RC_REG_CLASS_FP_SINGLE_PLUS_ALPHA,
45 RC_REG_CLASS_FP_DOUBLE_PLUS_ALPHA,
46 RC_REG_CLASS_FP_TRIPLE_PLUS_ALPHA,
47 RC_REG_CLASS_FP_X,
48 RC_REG_CLASS_FP_Y,
49 RC_REG_CLASS_FP_Z,
50 RC_REG_CLASS_FP_XY,
51 RC_REG_CLASS_FP_YZ,
52 RC_REG_CLASS_FP_XZ,
53 RC_REG_CLASS_FP_XW,
54 RC_REG_CLASS_FP_YW,
55 RC_REG_CLASS_FP_ZW,
56 RC_REG_CLASS_FP_XYW,
57 RC_REG_CLASS_FP_YZW,
58 RC_REG_CLASS_FP_XZW,
59 RC_REG_CLASS_FP_COUNT
60 };
61
62 enum rc_reg_class_vp {
63 RC_REG_CLASS_VP_SINGLE,
64 RC_REG_CLASS_VP_DOUBLE,
65 RC_REG_CLASS_VP_TRIPLE,
66 RC_REG_CLASS_VP_QUADRUPLE,
67 RC_REG_CLASS_VP_COUNT
68 };
69
70 struct rc_regalloc_state {
71 struct ra_regs *regs;
72 struct ra_class *classes[RC_REG_CLASS_FP_COUNT];
73 const struct rc_class *class_list;
74 };
75
76 struct register_info {
77 struct live_intervals Live[4];
78
79 unsigned int Used:1;
80 unsigned int Allocated:1;
81 unsigned int File:3;
82 unsigned int Index:RC_REGISTER_INDEX_BITS;
83 unsigned int Writemask;
84 };
85
86 struct regalloc_state {
87 struct radeon_compiler * C;
88
89 struct register_info * Input;
90 unsigned int NumInputs;
91
92 struct register_info * Temporary;
93 unsigned int NumTemporaries;
94
95 unsigned int Simple;
96 int LoopEnd;
97 };
98
99 struct rc_class {
100 enum rc_reg_class ID;
101
102 unsigned int WritemaskCount;
103
104 /** List of writemasks that belong to this class */
105 unsigned int Writemasks[6];
106 };
107
108 int rc_find_class(
109 const struct rc_class * classes,
110 unsigned int writemask,
111 unsigned int max_writemask_count);
112
113 unsigned int rc_overlap_live_intervals_array(
114 struct live_intervals * a,
115 struct live_intervals * b);
116
reg_get_index(int reg)117 static inline unsigned int reg_get_index(int reg)
118 {
119 return reg / RC_MASK_XYZW;
120 };
121
reg_get_writemask(int reg)122 static inline unsigned int reg_get_writemask(int reg)
123 {
124 return (reg % RC_MASK_XYZW) + 1;
125 };
126
get_reg_id(unsigned int index,unsigned int writemask)127 static inline int get_reg_id(unsigned int index, unsigned int writemask)
128 {
129 assert(writemask);
130 if (writemask == 0) {
131 return 0;
132 }
133 return (index * RC_MASK_XYZW) + (writemask - 1);
134 }
135
136 void rc_build_interference_graph(
137 struct ra_graph * graph,
138 struct rc_list * variables);
139
140 void rc_init_regalloc_state(struct rc_regalloc_state *s, enum rc_program_type prog);
141 void rc_destroy_regalloc_state(struct rc_regalloc_state *s);
142
143 #endif /* RADEON_REGALLOC_H */
144