Hexagon (target/hexagon) Analyze reads before writes
We divide gen_analyze_funcs.py into 3 phases Declare the operands Analyze the register reads Analyze the register writes We also create special versions of ctx_log_*_read for new operands Check that the operand is written before the read This is a precursor to improving the analysis for short-circuiting the packet semantics in a subsequent commit Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com> Reviewed-by: Brian Cain <bcain@quicinc.com> Message-Id: <20240201103340.119081-2-ltaylorsimpson@gmail.com> Signed-off-by: Brian Cain <bcain@quicinc.com>
This commit is contained in:
parent
248f6f62df
commit
76eaa97157
@ -183,10 +183,11 @@ when the override is present.
|
||||
}
|
||||
|
||||
We also generate an analyze_<tag> function for each instruction. Currently,
|
||||
these functions record the writes to registers by calling ctx_log_*. During
|
||||
gen_start_packet, we invoke the analyze_<tag> function for each instruction in
|
||||
the packet, and we mark the implicit writes. After the analysis is performed,
|
||||
we initialize the result register for each of the predicated assignments.
|
||||
these functions record the reads and writes to registers by calling ctx_log_*.
|
||||
During gen_start_packet, we invoke the analyze_<tag> function for each instruction in
|
||||
the packet, and we mark the implicit writes. The analysis determines if the packet
|
||||
semantics can be short-circuited. If not, we initialize the result register for each
|
||||
of the predicated assignments.
|
||||
|
||||
In addition to instruction semantics, we use a generator to create the decode
|
||||
tree. This generation is a four step process.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
##
|
||||
## Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||
## Copyright(c) 2022-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
@ -44,15 +44,25 @@ def gen_analyze_func(f, tag, regs, imms):
|
||||
|
||||
f.write(" Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
|
||||
|
||||
i = 0
|
||||
## Analyze all the registers
|
||||
for regtype, regid in regs:
|
||||
reg = hex_common.get_register(tag, regtype, regid)
|
||||
## Declare all the registers
|
||||
for regno, register in enumerate(regs):
|
||||
reg_type, reg_id = register
|
||||
reg = hex_common.get_register(tag, reg_type, reg_id)
|
||||
reg.decl_reg_num(f, regno)
|
||||
|
||||
## Analyze the register reads
|
||||
for regno, register in enumerate(regs):
|
||||
reg_type, reg_id = register
|
||||
reg = hex_common.get_register(tag, reg_type, reg_id)
|
||||
if reg.is_read():
|
||||
reg.analyze_read(f, regno)
|
||||
|
||||
## Analyze the register writes
|
||||
for regno, register in enumerate(regs):
|
||||
reg_type, reg_id = register
|
||||
reg = hex_common.get_register(tag, reg_type, reg_id)
|
||||
if reg.is_written():
|
||||
reg.analyze_write(f, tag, i)
|
||||
else:
|
||||
reg.analyze_read(f, i)
|
||||
i += 1
|
||||
reg.analyze_write(f, tag, regno)
|
||||
|
||||
has_generated_helper = not hex_common.skip_qemu_helper(
|
||||
tag
|
||||
@ -89,13 +99,13 @@ def main():
|
||||
tagimms = hex_common.get_tagimms()
|
||||
|
||||
with open(sys.argv[-1], "w") as f:
|
||||
f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
|
||||
f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
|
||||
f.write("#ifndef HEXAGON_ANALYZE_FUNCS_C_INC\n")
|
||||
f.write("#define HEXAGON_ANALYZE_FUNCS_C_INC\n\n")
|
||||
|
||||
for tag in hex_common.tags:
|
||||
gen_analyze_func(f, tag, tagregs[tag], tagimms[tag])
|
||||
|
||||
f.write("#endif /* HEXAGON_TCG_FUNCS_H */\n")
|
||||
f.write("#endif /* HEXAGON_ANALYZE_FUNCS_C_INC */\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
##
|
||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||
## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
@ -425,7 +425,6 @@ class GprDest(Register, Single, Dest):
|
||||
gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
|
||||
@ -438,7 +437,6 @@ class GprSource(Register, Single, OldSource):
|
||||
TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -449,9 +447,8 @@ class GprNewSource(Register, Single, NewSource):
|
||||
TCGv {self.reg_tcg()} = get_result_gpr(ctx, insn->regno[{regno}]);
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_read(ctx, {self.reg_num});
|
||||
ctx_log_reg_read_new(ctx, {self.reg_num});
|
||||
"""))
|
||||
|
||||
class GprReadWrite(Register, Single, ReadWrite):
|
||||
@ -471,8 +468,11 @@ class GprReadWrite(Register, Single, ReadWrite):
|
||||
f.write(code_fmt(f"""\
|
||||
gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
|
||||
@ -493,7 +493,6 @@ class ControlDest(Register, Single, Dest):
|
||||
gen_write_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
|
||||
@ -511,7 +510,6 @@ class ControlSource(Register, Single, OldSource):
|
||||
gen_read_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -532,7 +530,6 @@ class ModifierSource(Register, Single, OldSource):
|
||||
declared.append(self.reg_tcg())
|
||||
declared.append("CS")
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -548,7 +545,6 @@ class PredDest(Register, Single, Dest):
|
||||
gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_pred_write(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -560,7 +556,6 @@ class PredSource(Register, Single, OldSource):
|
||||
TCGv {self.reg_tcg()} = hex_pred[{self.reg_num}];
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_pred_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -571,9 +566,8 @@ class PredNewSource(Register, Single, NewSource):
|
||||
TCGv {self.reg_tcg()} = get_result_pred(ctx, insn->regno[{regno}]);
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_pred_read(ctx, {self.reg_num});
|
||||
ctx_log_pred_read_new(ctx, {self.reg_num});
|
||||
"""))
|
||||
|
||||
class PredReadWrite(Register, Single, ReadWrite):
|
||||
@ -587,8 +581,11 @@ class PredReadWrite(Register, Single, ReadWrite):
|
||||
f.write(code_fmt(f"""\
|
||||
gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_pred_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_pred_write(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -605,7 +602,6 @@ class PairDest(Register, Pair, Dest):
|
||||
gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
|
||||
@ -621,7 +617,6 @@ class PairSource(Register, Pair, OldSource):
|
||||
hex_gpr[{self.reg_num} + 1]);
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_read_pair(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -640,8 +635,11 @@ class PairReadWrite(Register, Pair, ReadWrite):
|
||||
f.write(code_fmt(f"""\
|
||||
gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_read_pair(ctx, {self.reg_num});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
|
||||
@ -663,7 +661,6 @@ class ControlPairDest(Register, Pair, Dest):
|
||||
gen_write_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
|
||||
@ -681,7 +678,6 @@ class ControlPairSource(Register, Pair, OldSource):
|
||||
gen_read_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_reg_read_pair(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -705,7 +701,6 @@ class VRegDest(Register, Hvx, Dest):
|
||||
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
newv = hvx_newv(tag)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
@ -728,7 +723,6 @@ class VRegSource(Register, Hvx, OldSource):
|
||||
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_vreg_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -746,9 +740,8 @@ class VRegNewSource(Register, Hvx, NewSource):
|
||||
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_vreg_read(ctx, {self.reg_num});
|
||||
ctx_log_vreg_read_new(ctx, {self.reg_num});
|
||||
"""))
|
||||
|
||||
class VRegReadWrite(Register, Hvx, ReadWrite):
|
||||
@ -772,8 +765,11 @@ class VRegReadWrite(Register, Hvx, ReadWrite):
|
||||
f.write(code_fmt(f"""\
|
||||
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_vreg_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
newv = hvx_newv(tag)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
@ -803,8 +799,11 @@ class VRegTmp(Register, Hvx, ReadWrite):
|
||||
f.write(code_fmt(f"""\
|
||||
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_vreg_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
newv = hvx_newv(tag)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
@ -830,7 +829,6 @@ class VRegPairDest(Register, Hvx, Dest):
|
||||
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
newv = hvx_newv(tag)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
@ -860,7 +858,6 @@ class VRegPairSource(Register, Hvx, OldSource):
|
||||
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_vreg_read_pair(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -892,8 +889,11 @@ class VRegPairReadWrite(Register, Hvx, ReadWrite):
|
||||
f.write(code_fmt(f"""\
|
||||
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_vreg_read_pair(ctx, {self.reg_num});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
newv = hvx_newv(tag)
|
||||
predicated = "true" if is_predicated(tag) else "false"
|
||||
f.write(code_fmt(f"""\
|
||||
@ -919,7 +919,6 @@ class QRegDest(Register, Hvx, Dest):
|
||||
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_qreg_write(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -941,7 +940,6 @@ class QRegSource(Register, Hvx, OldSource):
|
||||
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_qreg_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
@ -967,8 +965,11 @@ class QRegReadWrite(Register, Hvx, ReadWrite):
|
||||
f.write(code_fmt(f"""\
|
||||
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
|
||||
"""))
|
||||
def analyze_read(self, f, regno):
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_qreg_read(ctx, {self.reg_num});
|
||||
"""))
|
||||
def analyze_write(self, f, tag, regno):
|
||||
self.decl_reg_num(f, regno)
|
||||
f.write(code_fmt(f"""\
|
||||
ctx_log_qreg_write(ctx, {self.reg_num});
|
||||
"""))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||
* Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -75,6 +75,8 @@ typedef struct DisasContext {
|
||||
TCGv dczero_addr;
|
||||
} DisasContext;
|
||||
|
||||
bool is_gather_store_insn(DisasContext *ctx);
|
||||
|
||||
static inline void ctx_log_pred_write(DisasContext *ctx, int pnum)
|
||||
{
|
||||
if (!test_bit(pnum, ctx->pregs_written)) {
|
||||
@ -89,6 +91,12 @@ static inline void ctx_log_pred_read(DisasContext *ctx, int pnum)
|
||||
set_bit(pnum, ctx->pregs_read);
|
||||
}
|
||||
|
||||
static inline void ctx_log_pred_read_new(DisasContext *ctx, int pnum)
|
||||
{
|
||||
g_assert(test_bit(pnum, ctx->pregs_written));
|
||||
set_bit(pnum, ctx->pregs_read);
|
||||
}
|
||||
|
||||
static inline void ctx_log_reg_write(DisasContext *ctx, int rnum,
|
||||
bool is_predicated)
|
||||
{
|
||||
@ -120,6 +128,12 @@ static inline void ctx_log_reg_read(DisasContext *ctx, int rnum)
|
||||
set_bit(rnum, ctx->regs_read);
|
||||
}
|
||||
|
||||
static inline void ctx_log_reg_read_new(DisasContext *ctx, int rnum)
|
||||
{
|
||||
g_assert(test_bit(rnum, ctx->regs_written));
|
||||
set_bit(rnum, ctx->regs_read);
|
||||
}
|
||||
|
||||
static inline void ctx_log_reg_read_pair(DisasContext *ctx, int rnum)
|
||||
{
|
||||
ctx_log_reg_read(ctx, rnum);
|
||||
@ -171,6 +185,15 @@ static inline void ctx_log_vreg_read(DisasContext *ctx, int rnum)
|
||||
set_bit(rnum, ctx->vregs_read);
|
||||
}
|
||||
|
||||
static inline void ctx_log_vreg_read_new(DisasContext *ctx, int rnum)
|
||||
{
|
||||
g_assert(is_gather_store_insn(ctx) ||
|
||||
test_bit(rnum, ctx->vregs_updated) ||
|
||||
test_bit(rnum, ctx->vregs_select) ||
|
||||
test_bit(rnum, ctx->vregs_updated_tmp));
|
||||
set_bit(rnum, ctx->vregs_read);
|
||||
}
|
||||
|
||||
static inline void ctx_log_vreg_read_pair(DisasContext *ctx, int rnum)
|
||||
{
|
||||
ctx_log_vreg_read(ctx, rnum ^ 0);
|
||||
@ -205,7 +228,6 @@ extern TCGv hex_vstore_addr[VSTORES_MAX];
|
||||
extern TCGv hex_vstore_size[VSTORES_MAX];
|
||||
extern TCGv hex_vstore_pending[VSTORES_MAX];
|
||||
|
||||
bool is_gather_store_insn(DisasContext *ctx);
|
||||
void process_store(DisasContext *ctx, int slot_num);
|
||||
|
||||
FIELD(PROBE_PKT_SCALAR_STORE_S0, MMU_IDX, 0, 2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user