Message ID | 20240201103340.119081-2-ltaylorsimpson@gmail.com |
---|---|
State | New |
Headers | show |
Series | Hexagon (target/hexagon) Enable more short-circuit packets | expand |
> -----Original Message----- > From: Taylor Simpson <ltaylorsimpson@gmail.com> > Sent: Thursday, February 1, 2024 4:34 AM > To: qemu-devel@nongnu.org > Cc: Brian Cain <bcain@quicinc.com>; Matheus Bernardino (QUIC) > <quic_mathbern@quicinc.com>; Sid Manning <sidneym@quicinc.com>; > Marco Liebel (QUIC) <quic_mliebel@quicinc.com>; > richard.henderson@linaro.org; philmd@linaro.org; ale@rev.ng; anjo@rev.ng; > ltaylorsimpson@gmail.com > Subject: [PATCH v2 1/3] Hexagon (target/hexagon) Analyze reads before > writes > > WARNING: This email originated from outside of Qualcomm. Please be wary > of any links or attachments, and do not enable macros. > > 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> > --- > target/hexagon/translate.h | 26 +++++++++++- > target/hexagon/README | 9 +++-- > target/hexagon/gen_analyze_funcs.py | 34 ++++++++++------ > target/hexagon/hex_common.py | 63 +++++++++++++++-------------- > 4 files changed, 83 insertions(+), 49 deletions(-) > > diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h > index 4dd59c6726..f06d71fc53 100644 > --- a/target/hexagon/translate.h > +++ b/target/hexagon/translate.h > @@ -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) > diff --git a/target/hexagon/README b/target/hexagon/README > index 746ebec378..c1d8c8d0ab 100644 > --- a/target/hexagon/README > +++ b/target/hexagon/README > @@ -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. > diff --git a/target/hexagon/gen_analyze_funcs.py > b/target/hexagon/gen_analyze_funcs.py > index a9af666cef..890e6a3a95 100755 > --- a/target/hexagon/gen_analyze_funcs.py > +++ b/target/hexagon/gen_analyze_funcs.py > @@ -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__": > diff --git a/target/hexagon/hex_common.py > b/target/hexagon/hex_common.py > index 195620c7ec..33801e4bd7 100755 > --- a/target/hexagon/hex_common.py > +++ b/target/hexagon/hex_common.py > @@ -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 @@ def log_write(self, f, tag): > 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 @@ def decl_tcg(self, f, tag, regno): > 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 @@ def decl_tcg(self, f, tag, regno): > 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 @@ def log_write(self, f, tag): > 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 @@ def log_write(self, f, tag): > 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 @@ def decl_tcg(self, f, tag, regno): > 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 @@ def idef_arg(self, declared): > 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 @@ def log_write(self, f, tag): > 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 @@ def decl_tcg(self, f, tag, regno): > 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 @@ def decl_tcg(self, f, tag, regno): > 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 @@ def log_write(self, f, tag): > 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 @@ def log_write(self, f, tag): > 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 @@ def decl_tcg(self, f, tag, regno): > 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 @@ def log_write(self, f, tag): > 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 @@ def log_write(self, f, tag): > 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 @@ def decl_tcg(self, f, tag, regno): > 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 @@ def helper_hvx_desc(self, f): > /* {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 @@ def helper_hvx_desc(self, f): > /* {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 @@ def helper_hvx_desc(self, f): > /* {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 @@ def helper_hvx_desc(self, f): > 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 @@ def helper_hvx_desc(self, f): > 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 @@ def helper_hvx_desc(self, f): > /* {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 @@ def helper_hvx_desc(self, f): > /* {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 @@ def helper_hvx_desc(self, f): > 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 @@ def helper_hvx_desc(self, f): > /* {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 @@ def helper_hvx_desc(self, f): > /* {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 @@ def helper_hvx_desc(self, f): > 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}); > """)) > -- > 2.34.1 Reviewed-by: Brian Cain <bcain@quicinc.com>
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index 4dd59c6726..f06d71fc53 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -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) diff --git a/target/hexagon/README b/target/hexagon/README index 746ebec378..c1d8c8d0ab 100644 --- a/target/hexagon/README +++ b/target/hexagon/README @@ -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. diff --git a/target/hexagon/gen_analyze_funcs.py b/target/hexagon/gen_analyze_funcs.py index a9af666cef..890e6a3a95 100755 --- a/target/hexagon/gen_analyze_funcs.py +++ b/target/hexagon/gen_analyze_funcs.py @@ -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__": diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py index 195620c7ec..33801e4bd7 100755 --- a/target/hexagon/hex_common.py +++ b/target/hexagon/hex_common.py @@ -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 @@ def log_write(self, f, tag): 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 @@ def decl_tcg(self, f, tag, regno): 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 @@ def decl_tcg(self, f, tag, regno): 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 @@ def log_write(self, f, tag): 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 @@ def log_write(self, f, tag): 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 @@ def decl_tcg(self, f, tag, regno): 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 @@ def idef_arg(self, declared): 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 @@ def log_write(self, f, tag): 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 @@ def decl_tcg(self, f, tag, regno): 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 @@ def decl_tcg(self, f, tag, regno): 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 @@ def log_write(self, f, tag): 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 @@ def log_write(self, f, tag): 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 @@ def decl_tcg(self, f, tag, regno): 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 @@ def log_write(self, f, tag): 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 @@ def log_write(self, f, tag): 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 @@ def decl_tcg(self, f, tag, regno): 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 @@ def helper_hvx_desc(self, f): /* {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 @@ def helper_hvx_desc(self, f): /* {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 @@ def helper_hvx_desc(self, f): /* {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 @@ def helper_hvx_desc(self, f): 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 @@ def helper_hvx_desc(self, f): 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 @@ def helper_hvx_desc(self, f): /* {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 @@ def helper_hvx_desc(self, f): /* {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 @@ def helper_hvx_desc(self, f): 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 @@ def helper_hvx_desc(self, f): /* {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 @@ def helper_hvx_desc(self, f): /* {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 @@ def helper_hvx_desc(self, f): 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}); """))
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> --- target/hexagon/translate.h | 26 +++++++++++- target/hexagon/README | 9 +++-- target/hexagon/gen_analyze_funcs.py | 34 ++++++++++------ target/hexagon/hex_common.py | 63 +++++++++++++++-------------- 4 files changed, 83 insertions(+), 49 deletions(-)