Fix low reg issue in Thumb-2 movsi patterns
authorWilco Dijkstra <wdijkstr@arm.com>
Thu, 25 Jul 2019 14:24:41 +0000 (14:24 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Thu, 25 Jul 2019 14:24:41 +0000 (14:24 +0000)
The Thumb-2 movsi patterns try to prefer low registers for loads and stores.
However this is done incorrectly by using 2 separate variants with 'l' and 'h'
register classes.  The register allocator will only use low registers, and
as a result we end up with significantly more spills and moves to high
registers.  Fix this by merging the alternatives and use 'l*r' to indicate
preference for low registers.  This saves ~400 instructions from the pr77308
testcase.

    gcc/
* config/arm/thumb2.md (thumb2_movsi_insn): Fix load/store low reg.
* config/arm/vfp.md (thumb2_movsi_vfp): Likewise.

From-SVN: r273802

gcc/ChangeLog
gcc/config/arm/thumb2.md
gcc/config/arm/vfp.md

index 35fd8474919350bdcfc8f93dcc8f3a6dfcea82b9..1155e4eeb0c7b4b7c30f0a457c504ecea0247086 100644 (file)
@@ -1,3 +1,8 @@
+2019-07-25  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * config/arm/thumb2.md (thumb2_movsi_insn): Fix load/store low reg.
+       * config/arm/vfp.md (thumb2_movsi_vfp): Likewise.
+
 2019-07-23  Jan Hubicka  <hubicka@ucw.cz>
 
        * ipa-devirt.c (add_type_duplicate): Fix return value.
index b283a7b656526d3c4719860d10aa1c0550288ba3..a4e094f67c6950d67d09040fdc19d285bbd7475b 100644 (file)
 ;; regs.  The high register alternatives are not taken into account when
 ;; choosing register preferences in order to reflect their expense.
 (define_insn "*thumb2_movsi_insn"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,l ,*hk,m,*m")
-       (match_operand:SI 1 "general_operand"      "rk,I,Py,K,j,mi,*mi,l,*hk"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,lk*r,m")
+       (match_operand:SI 1 "general_operand"      "rk,I,Py,K,j,mi,lk*r"))]
   "TARGET_THUMB2 && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
    && (   register_operand (operands[0], SImode)
        || register_operand (operands[1], SImode))"
     case 3: return \"mvn%?\\t%0, #%B1\";
     case 4: return \"movw%?\\t%0, %1\";
     case 5:
-    case 6:
       /* Cannot load it directly, split to load it via MOV / MOVT.  */
       if (!MEM_P (operands[1]) && arm_disable_literal_pool)
        return \"#\";
       return \"ldr%?\\t%0, %1\";
-    case 7:
-    case 8: return \"str%?\\t%1, %0\";
+    case 6: return \"str%?\\t%1, %0\";
     default: gcc_unreachable ();
     }
 }
-  [(set_attr "type" "mov_reg,mov_imm,mov_imm,mvn_imm,mov_imm,load_4,load_4,store_4,store_4")
-   (set_attr "length" "2,4,2,4,4,4,4,4,4")
+  [(set_attr "type" "mov_reg,mov_imm,mov_imm,mvn_imm,mov_imm,load_4,store_4")
+   (set_attr "length" "2,4,2,4,4,4,4")
    (set_attr "predicable" "yes")
-   (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no")
-   (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*")
-   (set_attr "neg_pool_range" "*,*,*,*,*,0,0,*,*")]
+   (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no")
+   (set_attr "pool_range" "*,*,*,*,*,4094,*")
+   (set_attr "neg_pool_range" "*,*,*,*,*,0,*")]
 )
 
 (define_insn "tls_load_dot_plus_four"
index e0aaa7b00bb41c046da4531a293e123c94e8b9a4..9cc5946c79e027c0132d2b5e4fd6b97f13bca72e 100644 (file)
 ;; is chosen with length 2 when the instruction is predicated for
 ;; arm_restrict_it.
 (define_insn "*thumb2_movsi_vfp"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r, l,*hk,m, *m,*t, r,*t,*t,  *Uv")
-       (match_operand:SI 1 "general_operand"      "rk,I,Py,K,j,mi,*mi,l,*hk, r,*t,*t,*UvTu,*t"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,lk*r,m,*t, r,*t,*t,  *Uv")
+       (match_operand:SI 1 "general_operand"      "rk,I,Py,K,j,mi,lk*r, r,*t,*t,*UvTu,*t"))]
   "TARGET_THUMB2 && TARGET_HARD_FLOAT
    && (   s_register_operand (operands[0], SImode)
        || s_register_operand (operands[1], SImode))"
     case 4:
       return \"movw%?\\t%0, %1\";
     case 5:
-    case 6:
       /* Cannot load it directly, split to load it via MOV / MOVT.  */
       if (!MEM_P (operands[1]) && arm_disable_literal_pool)
        return \"#\";
       return \"ldr%?\\t%0, %1\";
-    case 7:
-    case 8:
+    case 6:
       return \"str%?\\t%1, %0\";
-    case 9:
+    case 7:
       return \"vmov%?\\t%0, %1\\t%@ int\";
-    case 10:
+    case 8:
       return \"vmov%?\\t%0, %1\\t%@ int\";
-    case 11:
+    case 9:
       return \"vmov%?.f32\\t%0, %1\\t%@ int\";
-    case 12: case 13:
+    case 10: case 11:
       return output_move_vfp (operands);
     default:
       gcc_unreachable ();
     }
   "
   [(set_attr "predicable" "yes")
-   (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no")
-   (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_imm,load_4,load_4,store_4,store_4,f_mcr,f_mrc,fmov,f_loads,f_stores")
-   (set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4,4,4")
-   (set_attr "pool_range"     "*,*,*,*,*,1018,4094,*,*,*,*,*,1018,*")
-   (set_attr "neg_pool_range" "*,*,*,*,*,   0,   0,*,*,*,*,*,1008,*")]
+   (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no")
+   (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_imm,load_4,store_4,f_mcr,f_mrc,fmov,f_loads,f_stores")
+   (set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4")
+   (set_attr "pool_range"     "*,*,*,*,*,4094,*,*,*,*,1018,*")
+   (set_attr "neg_pool_range" "*,*,*,*,*,   0,*,*,*,*,1008,*")]
 )