Hexagon (target/hexagon) Implicit writes to USR don't force packet commit

Implicit writes to USR are only to specific fields of USR to indicate
side effects (e.g., saturation overflow, floating point status).
In these cases, we don't force a packet commit. This will allow more
packets to be short-circuited (avoid writing the results to temporaries).

When there is a packet commit with an implicit write to USR, we initialize
new_value_usr during gen_start_packet and write to USR in gen_reg_writes.

Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
This commit is contained in:
Taylor Simpson authored and Brian Cain committed 2025-12-31 22:57:44 -06:00
1 parent c2f724cfb7
commit 3e98496691
2 files changed
+23 -13

No files matched your search

+22 -13
View File
@@ -272,12 +272,7 @@ static void mark_implicit_reg_write(DisasContext *ctx, int attrib, int rnum)
{
uint16_t opcode = ctx->insn->opcode;
if (GET_ATTRIB(opcode, attrib)) {
/*
* USR is used to set overflow and FP exceptions,
* so treat it as conditional
*/
bool is_predicated = GET_ATTRIB(opcode, A_CONDEXEC) ||
rnum == HEX_REG_USR;
bool is_predicated = GET_ATTRIB(opcode, A_CONDEXEC);
/* LC0/LC1 is conditionally written by endloop instructions */
if ((rnum == HEX_REG_LC0 || rnum == HEX_REG_LC1) &&
@@ -291,6 +286,14 @@ static void mark_implicit_reg_write(DisasContext *ctx, int attrib, int rnum)
}
}
static void mark_implicit_usr_write(DisasContext *ctx, int attrib)
{
uint16_t opcode = ctx->insn->opcode;
if (GET_ATTRIB(opcode, attrib)) {
ctx->implicit_usr_write = true;
}
}
static void mark_implicit_reg_writes(DisasContext *ctx)
{
mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_FP, HEX_REG_FP);
@@ -300,8 +303,9 @@ static void mark_implicit_reg_writes(DisasContext *ctx)
mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SA0, HEX_REG_SA0);
mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_LC1, HEX_REG_LC1);
mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SA1, HEX_REG_SA1);
mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_USR, HEX_REG_USR);
mark_implicit_reg_write(ctx, A_FPOP, HEX_REG_USR);
mark_implicit_usr_write(ctx, A_IMPLICIT_WRITES_USR);
mark_implicit_usr_write(ctx, A_FPOP);
}
static void mark_implicit_pred_write(DisasContext *ctx, int attrib, int pnum)
@@ -351,11 +355,6 @@ static bool need_commit(DisasContext *ctx)
}
}
/* Floating point instructions are hard-coded to use new_value */
if (check_for_attrib(pkt, A_FPOP)) {
return true;
}
if (ctx->read_after_write || ctx->has_hvx_overlap) {
return true;
}
@@ -467,6 +466,12 @@ static void gen_start_packet(DisasContext *ctx)
}
}
/* Preload usr to new_value_usr */
if (ctx->need_commit && ctx->implicit_usr_write &&
!test_bit(HEX_REG_USR, ctx->regs_written)) {
tcg_gen_mov_tl(hex_new_value_usr, hex_gpr[HEX_REG_USR]);
}
/*
* Preload the predicated pred registers into ctx->new_pred_value[pred_num]
* Only endloop instructions conditionally write to pred registers
@@ -587,6 +592,10 @@ static void gen_reg_writes(DisasContext *ctx)
ctx->is_tight_loop = false;
}
}
if (ctx->implicit_usr_write && !test_bit(HEX_REG_USR, ctx->regs_written)) {
tcg_gen_mov_tl(hex_gpr[HEX_REG_USR], hex_new_value_usr);
}
}
static void gen_pred_writes(DisasContext *ctx)
+1
View File
@@ -39,6 +39,7 @@ typedef struct DisasContext {
int reg_log_idx;
DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS);
DECLARE_BITMAP(predicated_regs, TOTAL_PER_THREAD_REGS);
bool implicit_usr_write;
int preg_log[PRED_WRITES_MAX];
int preg_log_idx;
DECLARE_BITMAP(pregs_written, NUM_PREGS);