From: Matthew Fortune <matthew.fort...@imgtec.com> This option redirects the destination of a load to $0 if it is volatile and the result is not used.
gcc/ChangeLog: * config/mips/loongson-mmi.md: Add the additional argument. * config/mips/mips-msa.md: Likewise. * config/mips/mips-protos.h (mips_output_move): Add the additional parameter. * config/mips/mips.c (mips_output_move): Perform the redirection. * config/mips/mips.md: Same as the other .md files. * config/mips/mips.opt: Add the option -mdead-loads. * doc/invoke.texi: Document the option -mdead-loads. Cherry-picked a9a9df621143d9cac0e898f2a0bedd98b4db8ae4 from https://github.com/MIPS/gcc Signed-off-by: Matthew Fortune <matthew.fort...@imgtec.com> Signed-off-by: Faraz Shahbazker <fshahbaz...@wavecomp.com> Signed-off-by: Aleksandar Rakic <aleksandar.ra...@htecgroup.com> --- gcc/config/mips/loongson-mmi.md | 2 +- gcc/config/mips/mips-msa.md | 2 +- gcc/config/mips/mips-protos.h | 2 +- gcc/config/mips/mips.cc | 33 ++++++++++++++------ gcc/config/mips/mips.md | 54 ++++++++++++++++----------------- gcc/config/mips/mips.opt | 4 +++ gcc/doc/invoke.texi | 13 ++++++++ 7 files changed, 71 insertions(+), 39 deletions(-) diff --git a/gcc/config/mips/loongson-mmi.md b/gcc/config/mips/loongson-mmi.md index 4d958730139..39682eeaeb6 100644 --- a/gcc/config/mips/loongson-mmi.md +++ b/gcc/config/mips/loongson-mmi.md @@ -112,7 +112,7 @@ [(set (match_operand:VWHB 0 "nonimmediate_operand" "=m,f,d,f, d, m, d") (match_operand:VWHB 1 "move_operand" "f,m,f,dYG,dYG,dYG,m"))] "TARGET_HARD_FLOAT && TARGET_LOONGSON_MMI" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "fpstore,fpload,mfc,mtc,move,store,load") (set_attr "mode" "DI")]) diff --git a/gcc/config/mips/mips-msa.md b/gcc/config/mips/mips-msa.md index 976f296402e..f6edd5897a4 100644 --- a/gcc/config/mips/mips-msa.md +++ b/gcc/config/mips/mips-msa.md @@ -680,7 +680,7 @@ [(set (match_operand:MSA 0 "nonimmediate_operand" "=f,f,R,*d,*f") (match_operand:MSA 1 "move_operand" "fYGYI,R,f,*f,*d"))] "ISA_HAS_MSA" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "type" "simd_move,simd_load,simd_store,simd_copy,simd_insert") (set_attr "mode" "<MODE>")]) diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 96e084e6e64..c514c0711de 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -222,7 +222,7 @@ extern bool mips_split_128bit_move_p (rtx, rtx); extern void mips_split_msa_copy_d (rtx, rtx, rtx, rtx (*)(rtx, rtx, rtx)); extern void mips_split_msa_insert_d (rtx, rtx, rtx, rtx); extern void mips_split_msa_fill_d (rtx, rtx); -extern const char *mips_output_move (rtx, rtx); +extern const char *mips_output_move (rtx, rtx, rtx); extern bool mips_cfun_has_cprestore_slot_p (void); extern bool mips_cprestore_address_p (rtx, bool); extern void mips_save_gp_to_cprestore_slot (rtx, rtx, rtx, rtx); diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc index 069c7ef6a42..4c719fbaed5 100644 --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc @@ -5374,7 +5374,7 @@ mips_split_move_insn (rtx dest, rtx src, rtx insn) that SRC is operand 1 and DEST is operand 0. */ const char * -mips_output_move (rtx dest, rtx src) +mips_output_move (rtx insn, rtx dest, rtx src) { enum rtx_code dest_code = GET_CODE (dest); enum rtx_code src_code = GET_CODE (src); @@ -5502,14 +5502,29 @@ mips_output_move (rtx dest, rtx src) } if (src_code == MEM) - switch (GET_MODE_SIZE (mode)) - { - case 1: return "lbu\t%0,%1"; - case 2: return "lhu\t%0,%1"; - case 4: return "lw\t%0,%1"; - case 8: return "ld\t%0,%1"; - default: gcc_unreachable (); - } + { + if (TARGET_DEAD_LOADS + && MEM_VOLATILE_P (src) + && find_regno_note (insn, REG_UNUSED, REGNO (dest)) + && !TARGET_MIPS16) + switch (GET_MODE_SIZE (mode)) + { + case 1: return "lbu\t$0,%1"; + case 2: return "lhu\t$0,%1"; + case 4: return "lw\t$0,%1"; + case 8: return "ld\t$0,%1"; + default: gcc_unreachable (); + } + else + switch (GET_MODE_SIZE (mode)) + { + case 1: return "lbu\t%0,%1"; + case 2: return "lhu\t%0,%1"; + case 4: return "lw\t%0,%1"; + case 8: return "ld\t%0,%1"; + default: gcc_unreachable (); + } + } if (src_code == CONST_INT) { diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index bf8a1217ee9..b1e55428682 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -4882,7 +4882,7 @@ "!TARGET_64BIT && !TARGET_MIPS16 && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore") (set (attr "mode") (if_then_else (eq_attr "move_type" "imul") @@ -4895,7 +4895,7 @@ "!TARGET_64BIT && TARGET_MIPS16 && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo") (set_attr "mode" "DI")]) @@ -4905,7 +4905,7 @@ "TARGET_64BIT && !TARGET_MIPS16 && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mtlo,mflo,mtc,fpload,mfc,fpstore") (set_attr "mode" "DI")]) @@ -4915,7 +4915,7 @@ "TARGET_64BIT && TARGET_MIPS16 && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo") (set_attr "mode" "DI")]) @@ -4983,7 +4983,7 @@ "!TARGET_MIPS16 && (register_operand (operands[0], <MODE>mode) || reg_or_0_operand (operands[1], <MODE>mode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,move,const,const,const,load,load,load,store,store,store,mtc,fpload,mfc,fpstore,mfc,mtc,mtlo,mflo,mtc,fpload,mfc,fpstore") (set_attr "compression" "all,micromips,micromips,*,*,micromips,micromips,*,micromips,micromips,*,*,*,*,*,*,*,*,*,*,*,*,*") (set_attr "mode" "SI")]) @@ -4994,7 +4994,7 @@ "TARGET_MIPS16 && (register_operand (operands[0], <MODE>mode) || register_operand (operands[1], <MODE>mode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo") (set_attr "mode" "SI")]) @@ -5124,7 +5124,7 @@ "!TARGET_MIPS16 && (register_operand (operands[0], HImode) || reg_or_0_operand (operands[1], HImode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,const,const,load,load,store,store,mtlo,mflo") (set_attr "compression" "all,micromips,*,micromips,*,micromips,*,*,*") (set_attr "mode" "HI")]) @@ -5135,7 +5135,7 @@ "TARGET_MIPS16 && (register_operand (operands[0], HImode) || register_operand (operands[1], HImode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo") (set_attr "mode" "HI")]) @@ -5200,7 +5200,7 @@ "!TARGET_MIPS16 && (register_operand (operands[0], QImode) || reg_or_0_operand (operands[1], QImode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,const,const,load,load,store,store,mtlo,mflo") (set_attr "compression" "all,micromips,*,micromips,*,micromips,*,*,*") (set_attr "mode" "QI")]) @@ -5211,7 +5211,7 @@ "TARGET_MIPS16 && (register_operand (operands[0], QImode) || register_operand (operands[1], QImode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo") (set_attr "mode" "QI")]) @@ -5257,7 +5257,7 @@ [(set (match_operand:CCF 0 "nonimmediate_operand" "=f,f,m") (match_operand:CCF 1 "nonimmediate_operand" "f,m,f"))] "ISA_HAS_CCF" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "fmove,fpload,fpstore")]) (define_insn "*movsf_hardfloat" @@ -5266,7 +5266,7 @@ "TARGET_HARD_FLOAT && (register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "SF")]) @@ -5276,7 +5276,7 @@ "TARGET_SOFT_FLOAT && !TARGET_MIPS16 && (register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,load,store") (set_attr "mode" "SF")]) @@ -5286,7 +5286,7 @@ "TARGET_MIPS16 && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,move,move,load,store") (set_attr "mode" "SF")]) @@ -5307,7 +5307,7 @@ "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && (register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "DF")]) @@ -5317,7 +5317,7 @@ "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16 && (register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,load,store") (set_attr "mode" "DF")]) @@ -5327,7 +5327,7 @@ "TARGET_MIPS16 && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,move,move,load,store") (set_attr "mode" "DF")]) @@ -5349,7 +5349,7 @@ && !TARGET_MIPS16 && (register_operand (operands[0], TImode) || reg_or_0_operand (operands[1], TImode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo") (set (attr "mode") (if_then_else (eq_attr "move_type" "imul") @@ -5454,7 +5454,7 @@ && TARGET_PAIRED_SINGLE_FLOAT && (register_operand (operands[0], V2SFmode) || reg_or_0_operand (operands[1], V2SFmode))" - { return mips_output_move (operands[0], operands[1]); } + { return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") (set_attr "mode" "DF")]) @@ -5535,7 +5535,7 @@ "TARGET_HARD_FLOAT" { operands[0] = mips_subword (operands[0], 0); - return mips_output_move (operands[0], operands[1]); + return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "mtc,fpload") (set_attr "mode" "<HALFMODE>")]) @@ -5550,7 +5550,7 @@ "TARGET_HARD_FLOAT" { operands[0] = mips_subword (operands[0], 1); - return mips_output_move (operands[0], operands[1]); + return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "mtc,fpload") (set_attr "mode" "<HALFMODE>")]) @@ -5565,7 +5565,7 @@ "TARGET_HARD_FLOAT" { operands[1] = mips_subword (operands[1], INTVAL (operands[2])); - return mips_output_move (operands[0], operands[1]); + return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "move_type" "mfc,fpstore") (set_attr "mode" "<HALFMODE>")]) @@ -6947,7 +6947,7 @@ (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d,B")] UNSPEC_COP0))] "" -{ return mips_output_move (operands[0], operands[1]); } +{ return mips_output_move (insn, operands[0], operands[1]); } [(set_attr "type" "mtc,mfc") (set_attr "mode" "SI")]) @@ -7954,16 +7954,16 @@ However, order of the loads need to be checked for correctness. */ if (!load_p || !reg_overlap_mentioned_p (operands[0], operands[1])) { - output_asm_insn (mips_output_move (operands[0], operands[1]), + output_asm_insn (mips_output_move (insn, operands[0], operands[1]), operands); - output_asm_insn (mips_output_move (operands[2], operands[3]), + output_asm_insn (mips_output_move (insn, operands[2], operands[3]), &operands[2]); } else { - output_asm_insn (mips_output_move (operands[2], operands[3]), + output_asm_insn (mips_output_move (insn, operands[2], operands[3]), &operands[2]); - output_asm_insn (mips_output_move (operands[0], operands[1]), + output_asm_insn (mips_output_move (insn, operands[0], operands[1]), operands); } return ""; diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index 64c3dca4cc2..28b8de216fe 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -536,3 +536,7 @@ Enum(mips_lib_setting) String(tiny) Value(MIPS_LIB_TINY) mforbidden-slots Target Undocumented Var(TARGET_FORBIDDEN_SLOTS) Init(1) + +mdead-loads +Target Var(TARGET_DEAD_LOADS) Init(0) +Redirect dead loads to $0 to avoid spurious output dependencies. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index aac7a0b75cd..636aea39e53 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1153,6 +1153,7 @@ Objective-C and Objective-C++ Dialects}. -membedded-data -mno-embedded-data -muninit-const-in-rodata -mno-uninit-const-in-rodata -mcode-readable=@var{setting} +-mdead-loads -mno-dead-loads -msplit-addresses -mno-split-addresses -mexplicit-relocs -mno-explicit-relocs -mexplicit-relocs=@var{release} @@ -28837,6 +28838,18 @@ SRAM interface but that (unlike the M4K) do not automatically redirect PC-relative loads to the instruction RAM. @end table +@opindex mdead-loads +@opindex mno-dead-loads +@item -mdead-loads +@itemx -mno-dead-loads +Apply (do not apply) special handling to avoid output dependency stalls +for volatile loads where the result is unused. Volatile loads tend +to be high latency as they represent access to special data or hardware. +When the result of such a load is unused then there may be an output +dependency stall if the result register is reused soon after the load. +For MIPS32 a dead load will be redirected to @code{$0} to avoid the output +dependency. + @opindex msplit-addresses @opindex mno-split-addresses @item -msplit-addresses -- 2.34.1