mirror of
https://github.com/danog/ir.git
synced 2024-11-26 20:34:53 +01:00
Add "must be in reg" constraint
This commit is contained in:
parent
ea46798aeb
commit
3e6f84eef4
2
TODO
2
TODO
@ -37,7 +37,7 @@
|
|||||||
- constraints
|
- constraints
|
||||||
- kill
|
- kill
|
||||||
- restricted regset
|
- restricted regset
|
||||||
- must be in register
|
+ must be in register
|
||||||
- temporary registers
|
- temporary registers
|
||||||
? spills
|
? spills
|
||||||
- spill slot allocation (packed/aligned according to SpillRange)
|
- spill slot allocation (packed/aligned according to SpillRange)
|
||||||
|
4
ir.h
4
ir.h
@ -517,9 +517,13 @@ typedef struct _ir_live_interval ir_live_interval;
|
|||||||
|
|
||||||
#define IR_LIVE_INTERVAL_COALESCED (1<<0)
|
#define IR_LIVE_INTERVAL_COALESCED (1<<0)
|
||||||
|
|
||||||
|
#define IR_USE_MUST_BE_IN_REG (1<<0)
|
||||||
|
#define IR_USE_SHOULD_BE_IN_REG (1<<1)
|
||||||
|
|
||||||
struct _ir_use_pos {
|
struct _ir_use_pos {
|
||||||
uint16_t op_num; /* 0 - means result */
|
uint16_t op_num; /* 0 - means result */
|
||||||
int8_t hint;
|
int8_t hint;
|
||||||
|
uint8_t flags;
|
||||||
ir_ref hint_ref;
|
ir_ref hint_ref;
|
||||||
ir_live_pos pos;
|
ir_live_pos pos;
|
||||||
ir_use_pos *next;
|
ir_use_pos *next;
|
||||||
|
10
ir_ra.c
10
ir_ra.c
@ -219,6 +219,7 @@ static void ir_add_use(ir_ctx *ctx, int v, int op_num, ir_live_pos pos, ir_reg h
|
|||||||
use_pos->hint = hint;
|
use_pos->hint = hint;
|
||||||
use_pos->hint_ref = hint_ref;
|
use_pos->hint_ref = hint_ref;
|
||||||
use_pos->pos = pos;
|
use_pos->pos = pos;
|
||||||
|
use_pos->flags = ctx->rules ? ir_get_use_flags(ctx, IR_LIVE_POS_TO_REF(pos), op_num) : 0;
|
||||||
|
|
||||||
ir_add_use_pos(ctx, v, use_pos);
|
ir_add_use_pos(ctx, v, use_pos);
|
||||||
}
|
}
|
||||||
@ -1284,6 +1285,9 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, int current, uint32_t len, ir
|
|||||||
// TODO: skip usages that don't require register
|
// TODO: skip usages that don't require register
|
||||||
use_pos = use_pos->next;
|
use_pos = use_pos->next;
|
||||||
}
|
}
|
||||||
|
while (use_pos && !(use_pos->flags & IR_USE_MUST_BE_IN_REG)) {
|
||||||
|
use_pos = use_pos->next;
|
||||||
|
}
|
||||||
if (!use_pos) {
|
if (!use_pos) {
|
||||||
/* spill */
|
/* spill */
|
||||||
return IR_REG_NONE;
|
return IR_REG_NONE;
|
||||||
@ -1328,6 +1332,9 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, int current, uint32_t len, ir
|
|||||||
while (use_pos && use_pos->pos <= ival->range.start) { // TODO: less or less-or-equal
|
while (use_pos && use_pos->pos <= ival->range.start) { // TODO: less or less-or-equal
|
||||||
use_pos = use_pos->next;
|
use_pos = use_pos->next;
|
||||||
}
|
}
|
||||||
|
while (use_pos && !(use_pos->flags & (IR_USE_MUST_BE_IN_REG|IR_USE_SHOULD_BE_IN_REG))) {
|
||||||
|
use_pos = use_pos->next;
|
||||||
|
}
|
||||||
if (use_pos && use_pos->pos < nextUsePos[reg]) {
|
if (use_pos && use_pos->pos < nextUsePos[reg]) {
|
||||||
nextUsePos[reg] = use_pos->pos;
|
nextUsePos[reg] = use_pos->pos;
|
||||||
}
|
}
|
||||||
@ -1357,6 +1364,9 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, int current, uint32_t len, ir
|
|||||||
while (use_pos && use_pos->pos < ival->range.start) {
|
while (use_pos && use_pos->pos < ival->range.start) {
|
||||||
use_pos = use_pos->next;
|
use_pos = use_pos->next;
|
||||||
}
|
}
|
||||||
|
while (use_pos && !(use_pos->flags & (IR_USE_MUST_BE_IN_REG|IR_USE_SHOULD_BE_IN_REG))) {
|
||||||
|
use_pos = use_pos->next;
|
||||||
|
}
|
||||||
if (use_pos && use_pos->pos < nextUsePos[reg]) {
|
if (use_pos && use_pos->pos < nextUsePos[reg]) {
|
||||||
nextUsePos[reg] = use_pos->pos;
|
nextUsePos[reg] = use_pos->pos;
|
||||||
}
|
}
|
||||||
|
18
ir_x86.dasc
18
ir_x86.dasc
@ -946,6 +946,24 @@ bool ir_result_reuses_op1_reg(ir_ctx *ctx, ir_ref ref)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t ir_get_use_flags(ir_ctx *ctx, ir_ref ref, int op_num)
|
||||||
|
{
|
||||||
|
ir_ref rule;
|
||||||
|
|
||||||
|
rule = ctx->rules[ref];
|
||||||
|
switch (rule) {
|
||||||
|
case IR_BINOP_INT:
|
||||||
|
case IR_BINOP_SSE2:
|
||||||
|
case IR_BINOP_AVX:
|
||||||
|
case IR_MUL_INT:
|
||||||
|
case IR_DIV_INT:
|
||||||
|
case IR_MOD_INT:
|
||||||
|
return (op_num == 2) ? IR_USE_SHOULD_BE_IN_REG : IR_USE_MUST_BE_IN_REG;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IR_USE_MUST_BE_IN_REG;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t ir_match_insn(ir_ctx *ctx, ir_ref ref, ir_block *bb)
|
static uint32_t ir_match_insn(ir_ctx *ctx, ir_ref ref, ir_block *bb)
|
||||||
{
|
{
|
||||||
ir_insn *op2_insn;
|
ir_insn *op2_insn;
|
||||||
|
1
ir_x86.h
1
ir_x86.h
@ -281,5 +281,6 @@ bool ir_needs_vreg(ir_ctx *ctx, ir_ref ref);
|
|||||||
ir_regset ir_get_scratch_regset(ir_ctx *ctx, ir_ref ref);
|
ir_regset ir_get_scratch_regset(ir_ctx *ctx, ir_ref ref);
|
||||||
ir_reg ir_uses_fixed_reg(ir_ctx *ctx, ir_ref ref, int op_num);
|
ir_reg ir_uses_fixed_reg(ir_ctx *ctx, ir_ref ref, int op_num);
|
||||||
bool ir_result_reuses_op1_reg(ir_ctx *ctx, ir_ref ref);
|
bool ir_result_reuses_op1_reg(ir_ctx *ctx, ir_ref ref);
|
||||||
|
uint8_t ir_get_use_flags(ir_ctx *ctx, ir_ref ref, int op_num);
|
||||||
|
|
||||||
#endif /* IR_X86_H */
|
#endif /* IR_X86_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user