diff mbox

RFA: cache enabled attribute by insn code

Message ID 87zji31fh7.fsf@sandifor-thinkpad.stglab.manchester.uk.ibm.com
State New
Headers show

Commit Message

Richard Sandiford May 27, 2014, 2:08 p.m. UTC
Christophe Lyon <christophe.lyon@linaro.org> writes:
> Hi,
>
> Commits 210964 and 210965 for this patch have broken GCC build on arm* targets.

Could you send me the .i?

> For instance on target arm-none-linux-gnueabi, when creating
> unwind-arm.o, I can see:
>         /tmp/5673443_3.tmpdir/aci-gcc-fsf/sources/gcc-fsf/trunk/gcc/lra.c:1362
> 0x8e3bcd process_insn_for_elimination
>         /tmp/5673443_3.tmpdir/aci-gcc-fsf/sources/gcc-fsf/trunk/gcc/lra-eliminations.c:1344
> 0x8e3bcd lra_eliminate(bool, bool)
>         /tmp/5673443_3.tmpdir/aci-gcc-fsf/sources/gcc-fsf/trunk/gcc/lra-eliminations.c:1408
> 0x8dd753 lra_constraints(bool)
>         /tmp/5673443_3.tmpdir/aci-gcc-fsf/sources/gcc-fsf/trunk/gcc/lra-constraints.c:4049
> 0x8cdc1a lra(_IO_FILE*)
>         /tmp/5673443_3.tmpdir/aci-gcc-fsf/sources/gcc-fsf/trunk/gcc/lra.c:2332
> 0x8911f8 do_reload
>         /tmp/5673443_3.tmpdir/aci-gcc-fsf/sources/gcc-fsf/trunk/gcc/ira.c:5444
> 0x891508 execute
>         /tmp/5673443_3.tmpdir/aci-gcc-fsf/sources/gcc-fsf/trunk/gcc/ira.c:5605
> Please submit a full bug report,

Hmm, is this because of "insn_enabled"?  If so, how did that work before
the patch?  LRA already assumed that the "enabled" attribute didn't depend
on the operands.

Does the following patch help?

Thanks,
Richard


gcc/
	* config/arm/iterators.md (shiftable_ops): New code iterator.
	(t2_binop0): New code attribute.
	* config/arm/arm.md (insn_enabled): Delete.
	(enabled): Remove insn_enabled test.
	(*arith_shiftsi): Split out...
	(*arith_multsi): ...this pattern and remove insn_enabled attribute.

Comments

Richard Sandiford May 27, 2014, 2:18 p.m. UTC | #1
Richard Sandiford <rsandifo@linux.vnet.ibm.com> writes:
> Does the following patch help?

Bah, it won't of course: %i1 needs to be the operator.

Richard
Richard Earnshaw May 27, 2014, 3:15 p.m. UTC | #2
On 27/05/14 15:08, Richard Sandiford wrote:
> Hmm, is this because of "insn_enabled"?  If so, how did that work before
> the patch?  LRA already assumed that the "enabled" attribute didn't depend
> on the operands.

Huh!  "enabled" can be applied to each alternative.  Alternatives are
selected based on the operands.  If LRA can't cope with that we have a
serious problem.  In fact, a pattern that matches but has no enabled
alternatives is meaningless and guaranteed to cause problems during
register allocation.

R.
Jakub Jelinek May 27, 2014, 3:27 p.m. UTC | #3
On Tue, May 27, 2014 at 04:15:47PM +0100, Richard Earnshaw wrote:
> On 27/05/14 15:08, Richard Sandiford wrote:
> > Hmm, is this because of "insn_enabled"?  If so, how did that work before
> > the patch?  LRA already assumed that the "enabled" attribute didn't depend
> > on the operands.
> 
> Huh!  "enabled" can be applied to each alternative.  Alternatives are
> selected based on the operands.  If LRA can't cope with that we have a
> serious problem.  In fact, a pattern that matches but has no enabled
> alternatives is meaningless and guaranteed to cause problems during
> register allocation.

This is not LRA fault, but the backend misusing the "enabled" attribute
for something it wasn't designed for, and IMHO against the documentation
of the attribute too.
Just look at the original submission why it has been added.

	Jakub
Richard Earnshaw May 27, 2014, 3:40 p.m. UTC | #4
On 27/05/14 16:27, Jakub Jelinek wrote:
> On Tue, May 27, 2014 at 04:15:47PM +0100, Richard Earnshaw wrote:
>> On 27/05/14 15:08, Richard Sandiford wrote:
>>> Hmm, is this because of "insn_enabled"?  If so, how did that work before
>>> the patch?  LRA already assumed that the "enabled" attribute didn't depend
>>> on the operands.
>>
>> Huh!  "enabled" can be applied to each alternative.  Alternatives are
>> selected based on the operands.  If LRA can't cope with that we have a
>> serious problem.  In fact, a pattern that matches but has no enabled
>> alternatives is meaningless and guaranteed to cause problems during
>> register allocation.
> 
> This is not LRA fault, but the backend misusing the "enabled" attribute
> for something it wasn't designed for, and IMHO against the documentation
> of the attribute too.
> Just look at the original submission why it has been added.
> 
> 	Jakub
> 

<quote>
The @code{enabled} insn attribute may be used to disable certain insn
alternatives for machine-specific reasons.
<quote>

The rest of the text just says what happens when this is done and then
gives an example usage.  It doesn't any time, either explicitly or
implicitly, say that this must be a static choice determined once-off at
run time.

That being said, I agree that this particular use case is pushing the
boundaries -- but that's always a risk when the boundaries aren't
clearly defined.

A better solution here would be to get rid of all those match_operator
patterns and replace them with iterators; but that's a lot of work,
particularly for all the conditinal operation patterns we have.  It
would probably also bloat the number of patterns quite alarmingly.
Jakub Jelinek May 27, 2014, 3:50 p.m. UTC | #5
On Tue, May 27, 2014 at 04:40:13PM +0100, Richard Earnshaw wrote:
> <quote>
> The @code{enabled} insn attribute may be used to disable certain insn
> alternatives for machine-specific reasons.
> <quote>
> 
> The rest of the text just says what happens when this is done and then
> gives an example usage.  It doesn't any time, either explicitly or
> implicitly, say that this must be a static choice determined once-off at
> run time.

It says:
"This definition should be based on other insn attributes and/or target flags."
where from what I understand Andreas originally meant was that the other
insn attributes would be again based on target flags or other such insn
attributes.  Yeah, it explicitly rules out just basing the enabled attribute on
the operands, arm uses just another attribute based on the operands there,
but it still goes against the intent of the attribute, and is definitely a
nightmare for the register allocator.
Decisions based on the operands should be through constraints.

From what I can see, arm uses it just on a single insn, so I'd say it
shouldn't be a big deal to rewrite it.

	Jakub
Richard Earnshaw May 27, 2014, 4:01 p.m. UTC | #6
On 27/05/14 16:50, Jakub Jelinek wrote:
> On Tue, May 27, 2014 at 04:40:13PM +0100, Richard Earnshaw wrote:
>> <quote>
>> The @code{enabled} insn attribute may be used to disable certain insn
>> alternatives for machine-specific reasons.
>> <quote>
>>
>> The rest of the text just says what happens when this is done and then
>> gives an example usage.  It doesn't any time, either explicitly or
>> implicitly, say that this must be a static choice determined once-off at
>> run time.
> 
> It says:
> "This definition should be based on other insn attributes and/or target flags."

<pedantry>
- It only says *should*, not *must*.  "Should" can imply a
recommendation, not a requirement.
- It only says *based on*, not *solely based on*.  Based on implies that
other information might be involved as well, without limitation.
</pedantary>

> where from what I understand Andreas originally meant was that the other
> insn attributes would be again based on target flags or other such insn
> attributes.  Yeah, it explicitly rules out just basing the enabled attribute on
> the operands, arm uses just another attribute based on the operands there,
> but it still goes against the intent of the attribute, and is definitely a
> nightmare for the register allocator.
> Decisions based on the operands should be through constraints.
> 
> From what I can see, arm uses it just on a single insn, so I'd say it
> shouldn't be a big deal to rewrite it.
> 

Pedantry aside, I'm not against making such a restriction; but it is a
new restriction that isn't explictly stated in the documentation today.

R.
diff mbox

Patch

Index: gcc/config/arm/arm.md
===================================================================
--- gcc/config/arm/arm.md	(revision 210972)
+++ gcc/config/arm/arm.md	(working copy)
@@ -200,17 +200,9 @@ 
 	  (const_string "yes")]
 	 (const_string "no")))
 
-; Allows an insn to disable certain alternatives for reasons other than
-; arch support.
-(define_attr "insn_enabled" "no,yes"
-  (const_string "yes"))
-
 ; Enable all alternatives that are both arch_enabled and insn_enabled.
  (define_attr "enabled" "no,yes"
-   (cond [(eq_attr "insn_enabled" "no")
-	  (const_string "no")
-
-	  (and (eq_attr "predicable_short_it" "no")
+   (cond [(and (eq_attr "predicable_short_it" "no")
 	       (and (eq_attr "predicated" "yes")
 	            (match_test "arm_restrict_it")))
 	  (const_string "no")
@@ -9876,39 +9868,38 @@ 
 
 ;; Patterns to allow combination of arithmetic, cond code and shifts
 
-(define_insn "*arith_shiftsi"
-  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
-        (match_operator:SI 1 "shiftable_operator"
-          [(match_operator:SI 3 "shift_operator"
-             [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
-              (match_operand:SI 5 "shift_amount_operand" "M,M,M,r")])
-           (match_operand:SI 2 "s_register_operand" "rk,rk,r,rk")]))]
+;; Separate out the (mult ...) case, since it doesn't allow register operands.
+(define_insn "*arith_multsi"
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+        (shiftable_ops:SI
+	  (match_operator:SI 2 "mult_operator"
+	    [(match_operand:SI 3 "s_register_operand" "r,r")
+	     (match_operand:SI 4 "power_of_two_operand")])
+	  (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
   "TARGET_32BIT"
-  "%i1%?\\t%0, %2, %4%S3"
+  "%i1%?\\t%0, %1, %3%S2"
   [(set_attr "predicable" "yes")
    (set_attr "predicable_short_it" "no")
    (set_attr "shift" "4")
-   (set_attr "arch" "a,t2,t2,a")
-   ;; Thumb2 doesn't allow the stack pointer to be used for 
-   ;; operand1 for all operations other than add and sub. In this case 
-   ;; the minus operation is a candidate for an rsub and hence needs
-   ;; to be disabled.
-   ;; We have to make sure to disable the fourth alternative if
-   ;; the shift_operator is MULT, since otherwise the insn will
-   ;; also match a multiply_accumulate pattern and validate_change
-   ;; will allow a replacement of the constant with a register
-   ;; despite the checks done in shift_operator.
-   (set_attr_alternative "insn_enabled"
-			 [(const_string "yes")
-			  (if_then_else
-			   (match_operand:SI 1 "add_operator" "")
-			   (const_string "yes") (const_string "no"))
-			  (const_string "yes")
-			  (if_then_else
-			   (match_operand:SI 3 "mult_operator" "")
-			   (const_string "no") (const_string "yes"))])
-   (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_imm,alu_shift_reg")])
+   (set_attr "arch" "a,t2")
+   (set_attr "type" "alu_shift_imm,alu_shift_imm")])
 
+;; Handles cases other than the above.
+(define_insn "*arith_shiftsi"
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+        (shiftable_ops:SI
+          (match_operator:SI 2 "shift_operator"
+            [(match_operand:SI 3 "s_register_operand" "r,r,r")
+             (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
+          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
+  "TARGET_32BIT && GET_CODE (operands[3]) != MULT"
+  "%i1%?\\t%0, %1, %3%S2"
+  [(set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")
+   (set_attr "shift" "4")
+   (set_attr "arch" "a,t2,a")
+   (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
+
 (define_split
   [(set (match_operand:SI 0 "s_register_operand" "")
 	(match_operator:SI 1 "shiftable_operator"
Index: gcc/config/arm/iterators.md
===================================================================
--- gcc/config/arm/iterators.md	(revision 210972)
+++ gcc/config/arm/iterators.md	(working copy)
@@ -194,6 +194,15 @@ 
 ;; Right shifts
 (define_code_iterator rshifts [ashiftrt lshiftrt])
 
+;; Binary operators whose second operand can be shifted.
+(define_code_iterator shiftable_ops [plus minus ior xor and])
+
+;; plus and minus are the only shiftable_ops for which Thumb2 allows
+;; a stack pointer opoerand.  The minus operation is a candidate for an rsub
+;; and hence only plus is supported.
+(define_code_attr t2_binop0
+  [(plus "rk") (minus "r") (ior "r") (xor "r") (and "r")])
+
 ;;----------------------------------------------------------------------------
 ;; Int iterators
 ;;----------------------------------------------------------------------------