[committed] More useless code elimination on the H8

Jeff Law jeffreyalaw@gmail.com
Fri Jun 18 22:06:05 GMT 2021


Two minor improvements on the H8 today.

First, the source operand of a SET could be a SYMBOL_REF.  That's valid 
for setting condition codes.  I'm guessing its primarily valuable when 
testing for weak symbols.  Either way, adding support for that in 
select_cc_mode allows the compiler to remove a few more comparisons.

Second, the H8 does not expose DImode operations, so generic parts of 
the compiler will arrange to synthesize DImode operations from SImode 
operations.  This is fine and good.  However, doing so does tend to 
generate some useless code.  For example (and:DI (reg:DI) (const_int 
0xffffffff00000000) when synthesized via SImode operations generates an 
AND against -1 for the upper word which should simplify into a trivial copy.

But on the H8 we do not have SImode and DImode tieable.  So the costing 
model falls apart a bit and CSE thinks it's better to just leave things 
alone.  This patch adds a bit of smarts to the logical expander to avoid 
creating the obviously useless logical ops.  Note we don't have to 
handle everything here.  If the RHS would simplify to a constant, CSE 
would do the right thing.   So we just want to handle cases where the 
RHS is going to simplify into a simple register operand.  And in 
practice I've only seen this fire for AND.  Anyway, the twiddle to the 
expander eliminates a few more instructions, particularly in libgcc.

Anyway, these have both run through my tester and I'm committing this to 
the trunk.

Jeff
-------------- next part --------------
commit 629cbc682a773e64c4bcb800ea98fb3051cd810c
Author: Jeff Law <jeffreyalaw@gmail.com>
Date:   Fri Jun 18 18:02:16 2021 -0400

    [committed] More useless code elimination on the H8
    
    gcc/
            * config/h8300/h8300.c (h8300_select_cc_mode): Handle SYMBOL_REF.
            * config/h8300/logical.md (<code><mode>3 logcial expander): Generate
            more efficient code when the source can be trivially simplified.

diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 1077a2b6ae0..2b88325d2f7 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -1950,7 +1950,7 @@ h8300_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1)
           || GET_CODE (op0) == NEG || GET_CODE (op0) == AND
           || GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
           || GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT
-	  || GET_CODE (op0) == MULT
+	  || GET_CODE (op0) == MULT || GET_CODE (op0) == SYMBOL_REF
 	  || GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND
 	  || REG_P (op0) || MEM_P (op0)))
     return CCZNmode;
diff --git a/gcc/config/h8300/logical.md b/gcc/config/h8300/logical.md
index cb4c6384bdf..07d36cf0ef4 100644
--- a/gcc/config/h8300/logical.md
+++ b/gcc/config/h8300/logical.md
@@ -4,7 +4,27 @@
 	(logicals:QHSI (match_operand:QHSI 1 "register_operand" "")
 		       (match_operand:QHSI 2 "h8300_src_operand" "")))]
   ""
-  "")
+  "
+  {
+    enum machine_mode mode = GET_MODE (operands[0]);
+    /* DImodes are not considered tieable, as a result operations involving
+       subregs of DImode objects are considered expensive which can prevent
+       CSE from doing obvious simplifications.
+
+       We may ultimately change what is tieable, but this is an immediate
+       workaround while we evaluate changes to tieable modes.
+
+       The key in terms of what we want to handle is then the result of
+       the operation is not a constant.  */
+    if ((<CODE> == AND && operands[2] == CONSTM1_RTX (mode))
+	|| (<CODE> == IOR && operands[2] == CONST0_RTX (mode))
+	|| (<CODE> == XOR && operands[2] == CONST0_RTX (mode))
+	|| ((<CODE> == AND || <CODE> == IOR) && operands[1] == operands[2]))
+      {
+	emit_move_insn (operands[0], operands[1]);
+	DONE;
+      }
+  }")
 
 ;; There's a ton of cleanup to do from here below.
 ;; ----------------------------------------------------------------------


More information about the Gcc-patches mailing list