mirror of
https://github.com/danog/ir.git
synced 2025-01-22 05:31:32 +01:00
LSRA optimization
This commit is contained in:
parent
e5c01495da
commit
2a17b87219
17
ir_private.h
17
ir_private.h
@ -1043,6 +1043,8 @@ int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy);
|
||||
|
||||
#if defined(IR_REGSET_64BIT)
|
||||
|
||||
typedef enum _ir_reg ir_reg;
|
||||
|
||||
/*** Register Sets ***/
|
||||
#if IR_REGSET_64BIT
|
||||
typedef uint64_t ir_regset;
|
||||
@ -1100,13 +1102,21 @@ typedef uint32_t ir_regset;
|
||||
# define IR_REGSET_LAST(set) ((ir_reg)(ir_nlz(set)^31))
|
||||
#endif
|
||||
|
||||
IR_ALWAYS_INLINE ir_reg ir_regset_pop_first(ir_regset *set)
|
||||
{
|
||||
ir_reg reg;
|
||||
|
||||
IR_ASSERT(!IR_REGSET_IS_EMPTY(*set));
|
||||
reg = IR_REGSET_FIRST(*set);
|
||||
*set = (*set) & ((*set) - 1);
|
||||
return reg;
|
||||
}
|
||||
|
||||
#define IR_REGSET_FOREACH(set, reg) \
|
||||
do { \
|
||||
ir_regset _tmp = (set); \
|
||||
while (!IR_REGSET_IS_EMPTY(_tmp)) { \
|
||||
ir_reg _reg = IR_REGSET_FIRST(_tmp); \
|
||||
IR_REGSET_EXCL(_tmp, _reg); \
|
||||
reg = _reg; \
|
||||
reg = ir_regset_pop_first(&_tmp);
|
||||
|
||||
#define IR_REGSET_FOREACH_END() \
|
||||
} \
|
||||
@ -1152,7 +1162,6 @@ IR_ALWAYS_INLINE int8_t ir_get_alocated_reg(const ir_ctx *ctx, ir_ref ref, int o
|
||||
|
||||
#define IR_RULE_MASK 0xff
|
||||
|
||||
typedef enum _ir_reg ir_reg;
|
||||
typedef struct _ir_target_constraints ir_target_constraints;
|
||||
|
||||
#define IR_TMP_REG(_num, _type, _start, _end) \
|
||||
|
65
ir_ra.c
65
ir_ra.c
@ -2015,19 +2015,14 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, ir_live_interval *ival, ir_l
|
||||
reg = other->reg;
|
||||
IR_ASSERT(reg >= 0);
|
||||
if (reg >= IR_REG_SCRATCH) {
|
||||
ir_regset regset;
|
||||
|
||||
if (reg == IR_REG_SCRATCH) {
|
||||
regset = IR_REGSET_INTERSECTION(available, IR_REGSET_SCRATCH);
|
||||
available = IR_REGSET_DIFFERENCE(available, IR_REGSET_SCRATCH);
|
||||
} else {
|
||||
IR_ASSERT(reg == IR_REG_ALL);
|
||||
regset = available;
|
||||
available = IR_REGSET_EMPTY;
|
||||
}
|
||||
IR_REGSET_FOREACH(regset, reg) {
|
||||
freeUntilPos[reg] = 0;
|
||||
} IR_REGSET_FOREACH_END();
|
||||
} else if (IR_REGSET_IN(available, reg)) {
|
||||
freeUntilPos[reg] = 0;
|
||||
} else {
|
||||
IR_REGSET_EXCL(available, reg);
|
||||
}
|
||||
other = other->list_next;
|
||||
}
|
||||
@ -2038,13 +2033,15 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, ir_live_interval *ival, ir_l
|
||||
* but it is still necessary after coalescing and splitting
|
||||
*/
|
||||
other = inactive;
|
||||
pos = ival->end;
|
||||
while (other) {
|
||||
/* freeUntilPos[it.reg] = next intersection of it with current */
|
||||
if (other->current_range->start < pos) {
|
||||
next = ir_ivals_overlap(&ival->range, other->current_range);
|
||||
if (next) {
|
||||
reg = other->reg;
|
||||
IR_ASSERT(reg >= 0);
|
||||
if (reg >= IR_REG_SCRATCH) {
|
||||
next = ir_ivals_overlap(&ival->range, other->current_range);
|
||||
if (next) {
|
||||
ir_regset regset;
|
||||
|
||||
if (reg == IR_REG_SCRATCH) {
|
||||
@ -2058,13 +2055,13 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, ir_live_interval *ival, ir_l
|
||||
freeUntilPos[reg] = next;
|
||||
}
|
||||
} IR_REGSET_FOREACH_END();
|
||||
}
|
||||
} else if (IR_REGSET_IN(available, reg)) {
|
||||
next = ir_ivals_overlap(&ival->range, other->current_range);
|
||||
if (next && next < freeUntilPos[reg]) {
|
||||
if (next < freeUntilPos[reg]) {
|
||||
freeUntilPos[reg] = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
other = other->list_next;
|
||||
}
|
||||
|
||||
@ -2102,9 +2099,8 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, ir_live_interval *ival, ir_l
|
||||
pos = freeUntilPos[i];
|
||||
reg = i;
|
||||
} else if (freeUntilPos[i] == pos
|
||||
&& (reg == IR_REG_NONE
|
||||
|| (!IR_REGSET_IN(IR_REGSET_SCRATCH, reg)
|
||||
&& IR_REGSET_IN(IR_REGSET_SCRATCH, i)))) {
|
||||
&& !IR_REGSET_IN(IR_REGSET_SCRATCH, reg)
|
||||
&& IR_REGSET_IN(IR_REGSET_SCRATCH, i)) {
|
||||
/* prefer caller-saved registers to avoid save/restore in prologue/epilogue */
|
||||
pos = freeUntilPos[i];
|
||||
reg = i;
|
||||
@ -2699,21 +2695,24 @@ static int ir_linear_scan(ir_ctx *ctx)
|
||||
while (other) {
|
||||
ir_live_range *r = other->current_range;
|
||||
|
||||
if (r && r->end <= position) {
|
||||
IR_ASSERT(r);
|
||||
if (r->end <= position) {
|
||||
do {
|
||||
r = r->next;
|
||||
} while (r && r->end <= position);
|
||||
other->current_range = r;
|
||||
}
|
||||
/* if (ir_ival_end(other) <= position) {*/
|
||||
if (!r) {
|
||||
/* move i from active to handled */
|
||||
other = other->list_next;
|
||||
if (prev) {
|
||||
prev->list_next = other->list_next;
|
||||
prev->list_next = other;
|
||||
} else {
|
||||
active = other->list_next;
|
||||
active = other;
|
||||
}
|
||||
} else if (position < r->start) {
|
||||
continue;
|
||||
}
|
||||
other->current_range = r;
|
||||
}
|
||||
if (position < r->start) {
|
||||
/* move i from active to inactive */
|
||||
if (prev) {
|
||||
prev->list_next = other->list_next;
|
||||
@ -2734,22 +2733,24 @@ static int ir_linear_scan(ir_ctx *ctx)
|
||||
while (other) {
|
||||
ir_live_range *r = other->current_range;
|
||||
|
||||
if (r && r->end <= position) {
|
||||
IR_ASSERT(r);
|
||||
if (r->end <= position) {
|
||||
do {
|
||||
r = r->next;
|
||||
} while (r && r->end <= position);
|
||||
other->current_range = r;
|
||||
}
|
||||
/* if (ir_ival_end(other) <= position) {*/
|
||||
if (!r) {
|
||||
/* move i from inactive to handled */
|
||||
other = other->list_next;
|
||||
if (prev) {
|
||||
prev->list_next = other->list_next;
|
||||
prev->list_next = other;
|
||||
} else {
|
||||
inactive = other->list_next;
|
||||
inactive = other;
|
||||
}
|
||||
/* } else if (ir_ival_covers(other, position)) {*/
|
||||
} else if (position >= r->start) {
|
||||
continue;
|
||||
}
|
||||
other->current_range = r;
|
||||
}
|
||||
if (position >= r->start) {
|
||||
/* move i from active to inactive */
|
||||
if (prev) {
|
||||
prev->list_next = other->list_next;
|
||||
|
Loading…
x
Reference in New Issue
Block a user