public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-1575] rs6000: genfusion: Rewrite load/compare code
@ 2023-06-06 13:45 Segher Boessenkool
  0 siblings, 0 replies; only message in thread
From: Segher Boessenkool @ 2023-06-06 13:45 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:19e5bf1d5fac00da0b8cd4144d5651b2979d8308

commit r14-1575-g19e5bf1d5fac00da0b8cd4144d5651b2979d8308
Author: Segher Boessenkool <segher@kernel.crashing.org>
Date:   Fri Jun 2 15:32:41 2023 +0000

    rs6000: genfusion: Rewrite load/compare code
    
    This makes the code more readable, more digestible, more maintainable,
    more extensible.  That kind of thing.  It does that by pulling things
    apart a bit, but also making what stays together more cohesive lumps.
    
    The original function was a bunch of loops and early-outs, and then
    quite a bit of stuff done per iteration, with the iterations essentially
    independent of each other.  This patch moves the stuff done for one
    iteration to a new _one function.
    
    The second big thing is the stuff printed to the .md file is done in
    "here documents" now, which is a lot more readable than having to quote
    and escape and double-escape pieces of text.  Whitespace inside the
    here-document is significant (will be printed as-is), which is a bit
    awkward sometimes, or might take some getting used to, but it is also
    one of the benefits of using them.
    
    Local variables are declared at first use (or close to first use).
    There also shouldn't be many at all, often you can write easier to
    read and manage code by omitting to name something that is hard to name
    in the first place.
    
    Finally some things are done in more typical, more modern, and tighter
    Perl style, for example REs in "if"s or "qw" for lists of constants.
    
    2023-06-06  Segher Boessenkool  <segher@kernel.crashing.org>
    
            * config/rs6000/genfusion.pl (gen_ld_cmpi_p10_one): New, rewritten and
            split out from...
            (gen_ld_cmpi_p10): ... this.

Diff:
---
 gcc/config/rs6000/genfusion.pl | 185 +++++++++++++++++++++++------------------
 1 file changed, 103 insertions(+), 82 deletions(-)

diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index e4db352e0ce..2851bb73e85 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -53,92 +53,113 @@ sub mode_to_ldst_char
     return '?';
 }
 
+sub gen_ld_cmpi_p10_one
+{
+  my ($lmode, $result, $ccmode) = @_;
+
+  my $np = "NON_PREFIXED_D";
+  my $mempred = "non_update_memory_operand";
+  my $extend;
+
+  if ($ccmode eq "CC") {
+    # ld and lwa are both DS-FORM.
+    ($lmode =~ /^[SD]I$/) and $np = "NON_PREFIXED_DS";
+    ($lmode =~ /^[SD]I$/) and $mempred = "ds_form_mem_operand";
+  } else {
+    if ($lmode eq "DI") {
+      # ld is DS-form, but lwz is not.
+      $np = "NON_PREFIXED_DS";
+      $mempred = "ds_form_mem_operand";
+    }
+  }
+
+  my $cmpl = ($ccmode eq "CC") ? "" : "l";
+  my $echr = ($ccmode eq "CC") ? "a" : "z";
+  if ($lmode eq "DI") { $echr = ""; }
+  my $constpred = ($ccmode eq "CC") ? "const_m1_to_1_operand"
+  				    : "const_0_to_1_operand";
+
+  # For clobber, we need a SI/DI reg in case we
+  # split because we have to sign/zero extend.
+  my $clobbermode = ($lmode =~ /^[QH]I$/) ? "GPR" : $lmode;
+  if ($result =~ /^EXT/ || $result eq "GPR" || $clobbermode eq "GPR") {
+    # We always need extension if result > lmode.
+    $extend = ($ccmode eq "CC") ? "sign" : "zero";
+  } else {
+    # Result of SI/DI does not need sign extension.
+    $extend = "none";
+  }
+
+  my $ldst = mode_to_ldst_char($lmode);
+  print <<HERE;
+;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
+;; load mode is $lmode result mode is $result compare mode is $ccmode extend is $extend
+(define_insn_and_split "*l${ldst}${echr}_cmp${cmpl}di_cr0_${lmode}_${result}_${ccmode}_${extend}"
+  [(set (match_operand:${ccmode} 2 "cc_reg_operand" "=x")
+        (compare:${ccmode} (match_operand:${lmode} 1 "${mempred}" "m")
+HERE
+  print "   " if $ccmode eq "CCUNS";
+print <<HERE;
+                    (match_operand:${lmode} 3 "${constpred}" "n")))
+HERE
+
+  if ($result eq "clobber") {
+    print <<HERE;
+   (clobber (match_scratch:${clobbermode} 0 "=r"))]
+HERE
+  } elsif ($result eq $lmode) {
+    print <<HERE;
+   (set (match_operand:${result} 0 "gpc_reg_operand" "=r") (match_dup 1))]
+HERE
+  } else {
+    print <<HERE;
+   (set (match_operand:${result} 0 "gpc_reg_operand" "=r") (${extend}_extend:${result} (match_dup 1)))]
+HERE
+  }
+
+  print <<HERE;
+  "(TARGET_P10_FUSION)"
+  "l${ldst}${echr}%X1 %0,%1\\;cmp${cmpl}di %2,%0,%3"
+  "&& reload_completed
+   && (cc_reg_not_cr0_operand (operands[2], CCmode)
+       || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),
+                                      ${lmode}mode, ${np}))"
+HERE
+
+  if ($extend eq "none") {
+    print "  [(set (match_dup 0) (match_dup 1))\n";
+  } elsif ($result eq "clobber") {
+    print "  [(set (match_dup 0) (${extend}_extend:${clobbermode} (match_dup 1)))\n";
+  } else {
+    print "  [(set (match_dup 0) (${extend}_extend:${result} (match_dup 1)))\n";
+  }
+
+  print <<HERE;
+   (set (match_dup 2)
+        (compare:${ccmode} (match_dup 0) (match_dup 3)))]
+  ""
+  [(set_attr "type" "fused_load_cmpi")
+   (set_attr "cost" "8")
+   (set_attr "length" "8")])
+
+HERE
+}
+
 sub gen_ld_cmpi_p10
 {
-    my ($lmode, $ldst, $clobbermode, $result, $cmpl, $echr, $constpred,
-	$mempred, $ccmode, $np, $extend, $resultmode);
-  LMODE: foreach $lmode ('DI','SI','HI','QI') {
-      $ldst = mode_to_ldst_char($lmode);
-      $clobbermode = $lmode;
-      # For clobber, we need a SI/DI reg in case we
-      # split because we have to sign/zero extend.
-      if ($lmode eq 'HI' || $lmode eq 'QI') { $clobbermode = "GPR"; }
-    RESULT: foreach $result ('clobber', $lmode,  "EXT".$lmode) {
-	# EXTDI does not exist, and we cannot directly produce HI/QI results.
-	next RESULT if $result eq "EXTDI" || $result eq "HI" || $result eq "QI";
-	# Don't allow EXTQI because that would allow HI result which we can't do.
-	$result = "GPR" if $result eq "EXTQI";
-      CCMODE: foreach $ccmode ('CC','CCUNS') {
-	  $np = "NON_PREFIXED_D";
-	  $mempred = "non_update_memory_operand";
-	  if ( $ccmode eq 'CC' ) {
-	      next CCMODE if $lmode eq 'QI';
-	      if ( $lmode eq 'DI' || $lmode eq 'SI' ) {
-		  # ld and lwa are both DS-FORM.
-		  $np = "NON_PREFIXED_DS";
-		  $mempred = "ds_form_mem_operand";
-	      }
-	      $cmpl = "";
-	      $echr = "a";
-	      $constpred = "const_m1_to_1_operand";
-	  } else {
-	      if ( $lmode eq 'DI' ) {
-		  # ld is DS-form, but lwz is not.
-		  $np = "NON_PREFIXED_DS";
-		  $mempred = "ds_form_mem_operand";
-	      }
-	      $cmpl = "l";
-	      $echr = "z";
-	      $constpred = "const_0_to_1_operand";
-	  }
-	  if ($lmode eq 'DI') { $echr = ""; }
-	  if ($result =~ m/^EXT/ || $result eq 'GPR' || $clobbermode eq 'GPR') {
-	      # We always need extension if result > lmode.
-	      if ( $ccmode eq 'CC' ) {
-		  $extend = "sign";
-	      } else {
-		  $extend = "zero";
-	      }
-	  } else {
-	      # Result of SI/DI does not need sign extension.
-	      $extend = "none";
-	  }
-	  print ";; load-cmpi fusion pattern generated by gen_ld_cmpi_p10\n";
-	  print ";; load mode is $lmode result mode is $result compare mode is $ccmode extend is $extend\n";
+  foreach my $lmode (qw/DI SI HI QI/) {
+    foreach my $result ("clobber", $lmode,  "EXT$lmode") {
+      # EXTDI does not exist, and we cannot directly produce HI/QI results.
+      next if $result =~ /^(QI|HI|EXTDI)$/;
 
-	  print "(define_insn_and_split \"*l${ldst}${echr}_cmp${cmpl}di_cr0_${lmode}_${result}_${ccmode}_${extend}\"\n";
-	  print "  [(set (match_operand:${ccmode} 2 \"cc_reg_operand\" \"=x\")\n";
-	  print "        (compare:${ccmode} (match_operand:${lmode} 1 \"${mempred}\" \"m\")\n";
-	  if ($ccmode eq 'CCUNS') { print "   "; }
-	  print "                    (match_operand:${lmode} 3 \"${constpred}\" \"n\")))\n";
-	  if ($result eq 'clobber') {
-	      print "   (clobber (match_scratch:${clobbermode} 0 \"=r\"))]\n";
-	  } elsif ($result eq $lmode) {
-	      print "   (set (match_operand:${result} 0 \"gpc_reg_operand\" \"=r\") (match_dup 1))]\n";
-	  } else {
-	      print "   (set (match_operand:${result} 0 \"gpc_reg_operand\" \"=r\") (${extend}_extend:${result} (match_dup 1)))]\n";
-	  }
-	  print "  \"(TARGET_P10_FUSION)\"\n";
-	  print "  \"l${ldst}${echr}%X1 %0,%1\\;cmp${cmpl}di %2,%0,%3\"\n";
-	  print "  \"&& reload_completed\n";
-	  print "   && (cc_reg_not_cr0_operand (operands[2], CCmode)\n";
-	  print "       || !address_is_non_pfx_d_or_x (XEXP (operands[1], 0),\n";
-	  print "                                      ${lmode}mode, ${np}))\"\n";
+      # Don't allow EXTQI because that would allow HI result which we can't do.
+      $result = "GPR" if $result eq "EXTQI";
 
-	  if ($extend eq "none") {
-	      print "  [(set (match_dup 0) (match_dup 1))\n";
-	  } else {
-	      $resultmode = $result;
-	      if ( $result eq 'clobber' ) { $resultmode = $clobbermode }
-	      print "  [(set (match_dup 0) (${extend}_extend:${resultmode} (match_dup 1)))\n";
-	  }
-	  print "   (set (match_dup 2)\n";
-	  print "        (compare:${ccmode} (match_dup 0) (match_dup 3)))]\n";
-	  print "  \"\"\n";
-	  print "  [(set_attr \"type\" \"fused_load_cmpi\")\n";
-	  print "   (set_attr \"cost\" \"8\")\n";
-	  print "   (set_attr \"length\" \"8\")])\n";
-	  print "\n";
+      foreach my $ccmode (qw/CC CCUNS/) {
+	# We do not have signed single-byte loads.
+	next if ($lmode eq "QI" and $ccmode eq "CC");
+
+	gen_ld_cmpi_p10_one($lmode, $result, $ccmode);
       }
     }
   }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-06 13:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-06 13:45 [gcc r14-1575] rs6000: genfusion: Rewrite load/compare code Segher Boessenkool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).