projects
/
libfirm
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
2a26867
)
First try to add aliasing support in ilp coalescer
author
Quentin Colombet
<quentin.colombet@ens-lyon.fr>
Fri, 9 Dec 2011 11:46:01 +0000
(12:46 +0100)
committer
Matthias Braun
<matthias.braun@kit.edu>
Thu, 1 Mar 2012 15:02:00 +0000
(16:02 +0100)
ir/be/becopyilp2.c
patch
|
blob
|
history
diff --git
a/ir/be/becopyilp2.c
b/ir/be/becopyilp2.c
index
8b51a31
..
8527319
100644
(file)
--- a/
ir/be/becopyilp2.c
+++ b/
ir/be/becopyilp2.c
@@
-64,6
+64,17
@@
typedef struct local_env_t {
const unsigned *allocatable_colors;
} local_env_t;
const unsigned *allocatable_colors;
} local_env_t;
+static unsigned check_alignment_constraints(ir_node *node)
+{
+ const arch_register_req_t *req = arch_get_irn_register_req(node);
+ // For larger than 1 variables, support only aligned constraints
+ assert(((!(req->type & arch_register_req_type_aligned)
+ && req->width == 1)
+ || (req->type & arch_register_req_type_aligned))
+ && "Unaligned large (width > 1) variables not supported");
+ return (req->type & arch_register_req_type_aligned) && req->width > 1;
+}
+
static void make_color_var_name(char *buf, size_t buf_size,
const ir_node *node, unsigned color)
{
static void make_color_var_name(char *buf, size_t buf_size,
const ir_node *node, unsigned color)
{
@@
-89,10
+100,13
@@
static void build_coloring_cstr(ilp_env_t *ienv)
unsigned col;
int cst_idx;
unsigned curr_node_color;
unsigned col;
int cst_idx;
unsigned curr_node_color;
+ unsigned has_alignment_cstr;
if (sr_is_removed(ienv->sr, irn))
continue;
if (sr_is_removed(ienv->sr, irn))
continue;
+ has_alignment_cstr = check_alignment_constraints(irn);
+
req = arch_get_irn_register_req(irn);
/* get assignable colors */
req = arch_get_irn_register_req(irn);
/* get assignable colors */
@@
-109,7
+123,8
@@
static void build_coloring_cstr(ilp_env_t *ienv)
for (col = 0; col < n_regs; ++col) {
int var_idx;
double val;
for (col = 0; col < n_regs; ++col) {
int var_idx;
double val;
- if (!rbitset_is_set(colors, col))
+ if (!rbitset_is_set(colors, col)
+ || (has_alignment_cstr && ((col % req->width) != 0)))
continue;
make_color_var_name(buf, sizeof(buf), irn, col);
continue;
make_color_var_name(buf, sizeof(buf), irn, col);
@@
-128,9
+143,20
@@
static void build_coloring_cstr(ilp_env_t *ienv)
for (col = 0; col < n_regs; ++col) {
int cst_idx;
int var_idx;
for (col = 0; col < n_regs; ++col) {
int cst_idx;
int var_idx;
- if (rbitset_is_set(colors, col))
+ if (rbitset_is_set(colors, col)
+ // for aligned variable, we set the unaligned part to 0
+ && (!has_alignment_cstr || ((col % req->width) == 0)))
continue;
continue;
+ // If it is possible to have only a part of a large variable that
+ // cannot be used, we should invalidate the whole piece.
+ // Since we do not think this can happen, we did implemented the
+ // support for that.
+ assert((!has_alignment_cstr
+ || rbitset_is_set(colors, col)
+ || !rbitset_is_set(colors, col - (col % req->width)))
+ && "Register constraints that invalidate just a part of "
+ "a large variable is not yet supported");
make_color_var_name(buf, sizeof(buf), irn, col);
cst_idx = lpp_add_cst(ienv->lp, NULL, lpp_equal, 0.0);
var_idx = lpp_add_var(ienv->lp, buf, lpp_binary, 0.0);
make_color_var_name(buf, sizeof(buf), irn, col);
cst_idx = lpp_add_cst(ienv->lp, NULL, lpp_equal, 0.0);
var_idx = lpp_add_var(ienv->lp, buf, lpp_binary, 0.0);
@@
-180,11
+206,21
@@
static void build_interference_cstr(ilp_env_t *ienv)
ir_node *irn = clique[i];
char buf[32];
int var_idx;
ir_node *irn = clique[i];
char buf[32];
int var_idx;
+ unsigned aligment_offset = 0;
if (sr_is_removed(ienv->sr, irn))
continue;
if (sr_is_removed(ienv->sr, irn))
continue;
- make_color_var_name(buf, sizeof(buf), irn, col);
+ // Use the first part of the large registers for all
+ // interference, since it is the only colorable one.
+ if (check_alignment_constraints(irn)) {
+ const arch_register_req_t *req
+ = arch_get_irn_register_req(irn);
+ aligment_offset = col % req->width;
+ }
+
+ make_color_var_name(buf, sizeof(buf), irn,
+ col - aligment_offset);
var_idx = lpp_get_var_idx(lpp, buf);
lpp_set_factor_fast(lpp, cst_idx, var_idx, 1);
}
var_idx = lpp_get_var_idx(lpp, buf);
lpp_set_factor_fast(lpp, cst_idx, var_idx, 1);
}