diff mbox

[3/5] Pass an alternative_mask to constrain_operands

Message ID 87vbniagwq.fsf@e105548-lin.cambridge.arm.com
State New
Headers show

Commit Message

Richard Sandiford Oct. 17, 2014, 2:51 p.m. UTC
After the previous patch there are cases where we want to constrain
operands to any enabled alternative and cases where we want to also take
size/speed preferences into account.  The former applies when
constraining an existing instruction (which might originally have been
in a block with a different size/speed choice) or when making global
decisions.  The latter applies when evaluating a potential optimisation.

This patch therefore passes the mask of allowable alternatives as a
parameter to constrain_operands.

Richard


gcc/
	* recog.h (constrain_operands): Add an alternative_mask parameter.
	(constrain_operands_cached): Likewise.
	(get_preferred_alternatives): Declare new form.
	* recog.c (get_preferred_alternatives): New bb-taking instance.
	(constrain_operands): Take the set of available alternatives as
	a parameter.
	(check_asm_operands, insn_invalid_p, extract_constrain_insn)
	(extract_constrain_insn_cached): Update calls to constrain_operands.
	* caller-save.c (reg_save_code): Likewise.
	* ira.c (setup_prohibited_mode_move_regs): Likewise.
	* postreload-gcse.c (eliminate_partially_redundant_load): Likewise.
	* ree.c (combine_reaching_defs): Likewise.
	* reload.c (can_reload_into): Likewise.
	* reload1.c (reload, reload_as_needed, inc_for_reload): Likewise.
	(gen_reload_chain_without_interm_reg_p, emit_input_reload_insns)
	(emit_insn_if_valid_for_reload): Likewise.
	* reorg.c (fill_slots_from_thread): Likewise.
	* config/i386/i386.c (ix86_attr_length_address_default): Likewise.
	* config/pa/pa.c (pa_can_combine_p): Likewise.
	* config/rl78/rl78.c (insn_ok_now): Likewise.
	* config/sh/sh.md (define_peephole2): Likewise.
	* final.c (final_scan_insn): Update call to constrain_operands_cached.

Comments

Vladimir Makarov Oct. 21, 2014, 2:57 p.m. UTC | #1
On 10/17/2014 10:51 AM, Richard Sandiford wrote:
> After the previous patch there are cases where we want to constrain
> operands to any enabled alternative and cases where we want to also take
> size/speed preferences into account.  The former applies when
> constraining an existing instruction (which might originally have been
> in a block with a different size/speed choice) or when making global
> decisions.  The latter applies when evaluating a potential optimisation.
>
> This patch therefore passes the mask of allowable alternatives as a
> parameter to constrain_operands.
>
> Richard
>
RA parts look good for me too.
> gcc/
> 	* recog.h (constrain_operands): Add an alternative_mask parameter.
> 	(constrain_operands_cached): Likewise.
> 	(get_preferred_alternatives): Declare new form.
> 	* recog.c (get_preferred_alternatives): New bb-taking instance.
> 	(constrain_operands): Take the set of available alternatives as
> 	a parameter.
> 	(check_asm_operands, insn_invalid_p, extract_constrain_insn)
> 	(extract_constrain_insn_cached): Update calls to constrain_operands.
> 	* caller-save.c (reg_save_code): Likewise.
> 	* ira.c (setup_prohibited_mode_move_regs): Likewise.
> 	* postreload-gcse.c (eliminate_partially_redundant_load): Likewise.
> 	* ree.c (combine_reaching_defs): Likewise.
> 	* reload.c (can_reload_into): Likewise.
> 	* reload1.c (reload, reload_as_needed, inc_for_reload): Likewise.
> 	(gen_reload_chain_without_interm_reg_p, emit_input_reload_insns)
> 	(emit_insn_if_valid_for_reload): Likewise.
> 	* reorg.c (fill_slots_from_thread): Likewise.
> 	* config/i386/i386.c (ix86_attr_length_address_default): Likewise.
> 	* config/pa/pa.c (pa_can_combine_p): Likewise.
> 	* config/rl78/rl78.c (insn_ok_now): Likewise.
> 	* config/sh/sh.md (define_peephole2): Likewise.
> 	* final.c (final_scan_insn): Update call to constrain_operands_cached.
>
Jeff Law Oct. 21, 2014, 5:34 p.m. UTC | #2
On 10/17/14 14:51, Richard Sandiford wrote:
> After the previous patch there are cases where we want to constrain
> operands to any enabled alternative and cases where we want to also take
> size/speed preferences into account.  The former applies when
> constraining an existing instruction (which might originally have been
> in a block with a different size/speed choice) or when making global
> decisions.  The latter applies when evaluating a potential optimisation.
>
> This patch therefore passes the mask of allowable alternatives as a
> parameter to constrain_operands.
>
> Richard
>
>
> gcc/
> 	* recog.h (constrain_operands): Add an alternative_mask parameter.
> 	(constrain_operands_cached): Likewise.
> 	(get_preferred_alternatives): Declare new form.
> 	* recog.c (get_preferred_alternatives): New bb-taking instance.
> 	(constrain_operands): Take the set of available alternatives as
> 	a parameter.
> 	(check_asm_operands, insn_invalid_p, extract_constrain_insn)
> 	(extract_constrain_insn_cached): Update calls to constrain_operands.
> 	* caller-save.c (reg_save_code): Likewise.
> 	* ira.c (setup_prohibited_mode_move_regs): Likewise.
> 	* postreload-gcse.c (eliminate_partially_redundant_load): Likewise.
> 	* ree.c (combine_reaching_defs): Likewise.
> 	* reload.c (can_reload_into): Likewise.
> 	* reload1.c (reload, reload_as_needed, inc_for_reload): Likewise.
> 	(gen_reload_chain_without_interm_reg_p, emit_input_reload_insns)
> 	(emit_insn_if_valid_for_reload): Likewise.
> 	* reorg.c (fill_slots_from_thread): Likewise.
> 	* config/i386/i386.c (ix86_attr_length_address_default): Likewise.
> 	* config/pa/pa.c (pa_can_combine_p): Likewise.
> 	* config/rl78/rl78.c (insn_ok_now): Likewise.
> 	* config/sh/sh.md (define_peephole2): Likewise.
> 	* final.c (final_scan_insn): Update call to constrain_operands_cached.
>
OK.  Thanks for taking care of this.

Jeff
diff mbox

Patch

Index: gcc/recog.h
===================================================================
--- gcc/recog.h	2014-10-17 15:50:02.000000000 +0100
+++ gcc/recog.h	2014-10-17 15:50:02.627695847 +0100
@@ -95,8 +95,8 @@  extern void confirm_change_group (void);
 extern int apply_change_group (void);
 extern int num_validated_changes (void);
 extern void cancel_changes (int);
-extern int constrain_operands (int);
-extern int constrain_operands_cached (int);
+extern int constrain_operands (int, alternative_mask);
+extern int constrain_operands_cached (rtx_insn *, int);
 extern int memory_address_addr_space_p (enum machine_mode, rtx, addr_space_t);
 #define memory_address_p(mode,addr) \
 	memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
@@ -414,6 +414,7 @@  #define this_target_recog (&default_targ
 
 alternative_mask get_enabled_alternatives (rtx_insn *);
 alternative_mask get_preferred_alternatives (rtx_insn *);
+alternative_mask get_preferred_alternatives (rtx_insn *, basic_block);
 bool check_bool_attrs (rtx_insn *);
 
 void recog_init ();
Index: gcc/recog.c
===================================================================
--- gcc/recog.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/recog.c	2014-10-17 15:50:02.627695847 +0100
@@ -155,8 +155,9 @@  check_asm_operands (rtx x)
   if (reload_completed)
     {
       /* ??? Doh!  We've not got the wrapping insn.  Cook one up.  */
-      extract_insn (make_insn_raw (x));
-      constrain_operands (1);
+      rtx_insn *insn = make_insn_raw (x);
+      extract_insn (insn);
+      constrain_operands (1, get_enabled_alternatives (insn));
       return which_alternative >= 0;
     }
 
@@ -360,7 +361,7 @@  insn_invalid_p (rtx_insn *insn, bool in_
     {
       extract_insn (insn);
 
-      if (! constrain_operands (1))
+      if (! constrain_operands (1, get_preferred_alternatives (insn)))
 	return 1;
     }
 
@@ -2159,6 +2160,21 @@  get_preferred_alternatives (rtx_insn *in
     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
 }
 
+/* Return the set of alternatives of INSN that are allowed by the current
+   target and are preferred for the size/speed optimization choice
+   associated with BB.  Passing a separate BB is useful if INSN has not
+   been emitted yet or if we are considering moving it to a different
+   block.  */
+
+alternative_mask
+get_preferred_alternatives (rtx_insn *insn, basic_block bb)
+{
+  if (optimize_bb_for_speed_p (bb))
+    return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
+  else
+    return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
+}
+
 /* Assert that the cached boolean attributes for INSN are still accurate.
    The backend is required to define these attributes in a way that only
    depends on the current target (rather than operands, compiler phase,
@@ -2199,7 +2215,7 @@  extract_insn_cached (rtx_insn *insn)
 extract_constrain_insn (rtx_insn *insn)
 {
   extract_insn (insn);
-  if (!constrain_operands (reload_completed))
+  if (!constrain_operands (reload_completed, get_enabled_alternatives (insn)))
     fatal_insn_not_found (insn);
 }
 
@@ -2210,16 +2226,17 @@  extract_constrain_insn_cached (rtx_insn
 {
   extract_insn_cached (insn);
   if (which_alternative == -1
-      && !constrain_operands (reload_completed))
+      && !constrain_operands (reload_completed,
+			      get_enabled_alternatives (insn)))
     fatal_insn_not_found (insn);
 }
 
-/* Do cached constrain_operands and complain about failures.  */
+/* Do cached constrain_operands on INSN and complain about failures.  */
 int
-constrain_operands_cached (int strict)
+constrain_operands_cached (rtx_insn *insn, int strict)
 {
   if (which_alternative == -1)
-    return constrain_operands (strict);
+    return constrain_operands (strict, get_enabled_alternatives (insn));
   else
     return 1;
 }
@@ -2495,7 +2512,8 @@  preprocess_constraints (rtx insn)
 }
 
 /* Check the operands of an insn against the insn's operand constraints
-   and return 1 if they are valid.
+   and return 1 if they match any of the alternatives in ALTERNATIVES.
+
    The information about the insn's operands, constraints, operand modes
    etc. is obtained from the global variables set up by extract_insn.
 
@@ -2527,7 +2545,7 @@  struct funny_match
 };
 
 int
-constrain_operands (int strict)
+constrain_operands (int strict, alternative_mask alternatives)
 {
   const char *constraints[MAX_RECOG_OPERANDS];
   int matching_operands[MAX_RECOG_OPERANDS];
@@ -2554,7 +2572,7 @@  constrain_operands (int strict)
       int lose = 0;
       funny_match_index = 0;
 
-      if (!TEST_BIT (recog_data.enabled_alternatives, which_alternative))
+      if (!TEST_BIT (alternatives, which_alternative))
 	{
 	  int i;
 
@@ -2836,7 +2854,7 @@  constrain_operands (int strict)
   /* If we are about to reject this, but we are not to test strictly,
      try a very loose test.  Only return failure if it fails also.  */
   if (strict == 0)
-    return constrain_operands (-1);
+    return constrain_operands (-1, alternatives);
   else
     return 0;
 }
Index: gcc/caller-save.c
===================================================================
--- gcc/caller-save.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/caller-save.c	2014-10-17 15:50:02.611696037 +0100
@@ -138,15 +138,17 @@  reg_save_code (int reg, enum machine_mod
   cached_reg_restore_code[reg][mode] = recog_memoized (restinsn);
 
   /* Now extract both insns and see if we can meet their
-     constraints.  */
+     constraints.  We don't know here whether the save and restore will
+     be in size- or speed-tuned code, so just use the set of enabled
+     alternatives.  */
   ok = (cached_reg_save_code[reg][mode] != -1
 	&& cached_reg_restore_code[reg][mode] != -1);
   if (ok)
     {
       extract_insn (saveinsn);
-      ok = constrain_operands (1);
+      ok = constrain_operands (1, get_enabled_alternatives (saveinsn));
       extract_insn (restinsn);
-      ok &= constrain_operands (1);
+      ok &= constrain_operands (1, get_enabled_alternatives (restinsn));
     }
 
   if (! ok)
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/ira.c	2014-10-17 15:50:02.623695895 +0100
@@ -1760,7 +1760,9 @@  setup_prohibited_mode_move_regs (void)
 	  if (INSN_CODE (move_insn) < 0)
 	    continue;
 	  extract_insn (move_insn);
-	  if (! constrain_operands (1))
+	  /* We don't know whether the move will be in code that is optimized
+	     for size or speed, so consider all enabled alternatives.  */
+	  if (! constrain_operands (1, get_enabled_alternatives (move_insn)))
 	    continue;
 	  CLEAR_HARD_REG_BIT (ira_prohibited_mode_move_regs[i], j);
 	}
Index: gcc/postreload-gcse.c
===================================================================
--- gcc/postreload-gcse.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/postreload-gcse.c	2014-10-17 15:50:02.627695847 +0100
@@ -1003,10 +1003,11 @@  eliminate_partially_redundant_load (basi
 
 	  /* Make sure we can generate a move from register avail_reg to
 	     dest.  */
-	  extract_insn (as_a <rtx_insn *> (
-			  gen_move_insn (copy_rtx (dest),
-					 copy_rtx (avail_reg))));
-	  if (! constrain_operands (1)
+	  rtx_insn *move = as_a <rtx_insn *>
+	    (gen_move_insn (copy_rtx (dest), copy_rtx (avail_reg)));
+	  extract_insn (move);
+	  if (! constrain_operands (1, get_preferred_alternatives (insn,
+								   pred_bb))
 	      || reg_killed_on_edge (avail_reg, pred)
 	      || reg_used_on_edge (dest, pred))
 	    {
Index: gcc/ree.c
===================================================================
--- gcc/ree.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/ree.c	2014-10-17 15:50:02.627695847 +0100
@@ -762,7 +762,8 @@  combine_reaching_defs (ext_cand *cand, c
 	 This is merely to keep the test for safety and updating the insn
 	 stream simple.  Also ensure that within the block the candidate
 	 follows the defining insn.  */
-      if (BLOCK_FOR_INSN (cand->insn) != BLOCK_FOR_INSN (def_insn)
+      basic_block bb = BLOCK_FOR_INSN (cand->insn);
+      if (bb != BLOCK_FOR_INSN (def_insn)
 	  || DF_INSN_LUID (def_insn) > DF_INSN_LUID (cand->insn))
 	return false;
 
@@ -812,7 +813,7 @@  combine_reaching_defs (ext_cand *cand, c
       if (recog_memoized (insn) == -1)
 	return false;
       extract_insn (insn);
-      if (!constrain_operands (1))
+      if (!constrain_operands (1, get_preferred_alternatives (insn, bb)))
 	return false;
     }
 
Index: gcc/reload.c
===================================================================
--- gcc/reload.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/reload.c	2014-10-17 15:50:02.627695847 +0100
@@ -913,7 +913,7 @@  can_reload_into (rtx in, int regno, enum
   if (recog_memoized (test_insn) >= 0)
     {
       extract_insn (test_insn);
-      r = constrain_operands (1);
+      r = constrain_operands (1, get_enabled_alternatives (test_insn));
     }
   recog_data = save_recog_data;
   return r;
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/reload1.c	2014-10-17 15:50:02.627695847 +0100
@@ -1257,7 +1257,7 @@  reload (rtx_insn *first, int global)
 	if (asm_noperands (PATTERN (insn)) >= 0)
 	  {
 	    extract_insn (insn);
-	    if (!constrain_operands (1))
+	    if (!constrain_operands (1, get_enabled_alternatives (insn)))
 	      {
 		error_for_asm (insn,
 			       "%<asm%> operand has impossible constraints");
@@ -4709,7 +4709,9 @@  reload_as_needed (int live_known)
 		  if (p != insn && INSN_P (p)
 		      && GET_CODE (PATTERN (p)) != USE
 		      && (recog_memoized (p) < 0
-			  || (extract_insn (p), ! constrain_operands (1))))
+			  || (extract_insn (p),
+			      !(constrain_operands (1,
+				  get_enabled_alternatives (p))))))
 		    {
 		      error_for_asm (insn,
 				     "%<asm%> operand requires "
@@ -4792,7 +4794,8 @@  reload_as_needed (int live_known)
 			      if (n)
 				{
 				  extract_insn (p);
-				  n = constrain_operands (1);
+				  n = constrain_operands (1,
+				    get_enabled_alternatives (p));
 				}
 
 			      /* If the constraints were not met, then
@@ -5719,7 +5722,7 @@  gen_reload_chain_without_interm_reg_p (i
 	  /* We want constrain operands to treat this insn strictly in
 	     its validity determination, i.e., the way it would after
 	     reload has completed.  */
-	  result = constrain_operands (1);
+	  result = constrain_operands (1, get_enabled_alternatives (insn));
 	}
 
       delete_insns_since (last);
@@ -7389,7 +7392,7 @@  emit_input_reload_insns (struct insn_cha
 	     autoincrement addressing mode, then the resulting insn
 	     is ill-formed and we must reject this optimization.  */
 	  extract_insn (temp);
-	  if (constrain_operands (1)
+	  if (constrain_operands (1, get_enabled_alternatives (temp))
 #ifdef AUTO_INC_DEC
 	      && ! find_reg_note (temp, REG_INC, reloadreg)
 #endif
@@ -8576,7 +8579,7 @@  emit_insn_if_valid_for_reload (rtx pat)
       /* We want constrain operands to treat this insn strictly in its
 	 validity determination, i.e., the way it would after reload has
 	 completed.  */
-      if (constrain_operands (1))
+      if (constrain_operands (1, get_enabled_alternatives (insn)))
 	return insn;
     }
 
@@ -9213,7 +9216,7 @@  inc_for_reload (rtx reloadreg, rtx in, r
       if (code >= 0)
 	{
 	  extract_insn (add_insn);
-	  if (constrain_operands (1))
+	  if (constrain_operands (1, get_enabled_alternatives (add_insn)))
 	    {
 	      /* If this is a pre-increment and we have incremented the value
 		 where it lives, copy the incremented value to RELOADREG to
Index: gcc/reorg.c
===================================================================
--- gcc/reorg.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/reorg.c	2014-10-17 15:50:02.627695847 +0100
@@ -2764,7 +2764,8 @@  fill_slots_from_thread (rtx_insn *insn,
 				   insn);
 
 	  if (recog_memoized (ninsn) < 0
-	      || (extract_insn (ninsn), ! constrain_operands (1)))
+	      || (extract_insn (ninsn),
+		  !constrain_operands (1, get_preferred_alternatives (ninsn))))
 	    {
 	      delete_related_insns (ninsn);
 	      return 0;
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/config/i386/i386.c	2014-10-17 15:50:02.619695944 +0100
@@ -25300,7 +25300,7 @@  ix86_attr_length_address_default (rtx_in
   for (i = recog_data.n_operands - 1; i >= 0; --i)
     if (MEM_P (recog_data.operand[i]))
       {
-        constrain_operands_cached (reload_completed);
+        constrain_operands_cached (insn, reload_completed);
         if (which_alternative != -1)
 	  {
 	    const char *constraints = recog_data.constraints[i];
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/config/pa/pa.c	2014-10-17 15:50:02.623695895 +0100
@@ -9199,8 +9199,10 @@  pa_can_combine_p (rtx_insn *new_rtx, rtx
   XVECEXP (PATTERN (new_rtx), 0, 1) = PATTERN (floater);
   INSN_CODE (new_rtx) = -1;
   insn_code_number = recog_memoized (new_rtx);
+  basic_block bb = BLOCK_FOR_INSN (anchor);
   if (insn_code_number < 0
-      || (extract_insn (new_rtx), ! constrain_operands (1)))
+      || (extract_insn (new_rtx),
+	  !constrain_operands (1, get_preferred_alternatives (new_rtx, bb)))
     return 0;
 
   if (reversed)
Index: gcc/config/rl78/rl78.c
===================================================================
--- gcc/config/rl78/rl78.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/config/rl78/rl78.c	2014-10-17 15:50:02.623695895 +0100
@@ -2165,7 +2165,7 @@  insn_ok_now (rtx_insn *insn)
   if (recog (pattern, insn, 0) > -1)
     {
       extract_insn (insn);
-      if (constrain_operands (1))
+      if (constrain_operands (1, get_preferred_alternatives (insn)))
 	{
 #if DEBUG_ALLOC
 	  fprintf (stderr, "\033[32m");
@@ -2194,7 +2194,7 @@  insn_ok_now (rtx_insn *insn)
       if (recog (pattern, insn, 0) > -1)
 	{
 	  extract_insn (insn);
-	  if (constrain_operands (0))
+	  if (constrain_operands (0, get_preferred_alternatives (insn)))
 	    {
 	      cfun->machine->virt_insns_ok = 0;
 	      return false;
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	2014-10-17 15:50:02.000000000 +0100
+++ gcc/config/sh/sh.md	2014-10-17 15:50:02.623695895 +0100
@@ -1567,7 +1567,7 @@  (define_peephole2
    (set (match_dup 4) (match_dup 5))]
 {
   rtx set1, set2;
-  rtx_insn *insn2;
+  rtx_insn *insn1, *insn2;
   rtx replacements[4];
 
   /* We want to replace occurrences of operands[0] with operands[1] and
@@ -1594,14 +1594,16 @@  (define_peephole2
   /* ??? The last insn might be a jump insn, but the generic peephole2 code
      always uses emit_insn.  */
   /* Check that we don't violate matching constraints or earlyclobbers.  */
-  extract_insn (emit_insn (set1));
-  if (! constrain_operands (1))
+  basic_block bb = BLOCK_FOR_INSN (peep2_next_insn (2));
+  insn1 = emit_insn (set1);
+  extract_insn (insn1);
+  if (! constrain_operands (1, get_preferred_alternatives (insn1, bb)))
     goto failure;
   insn2 = emit (set2);
   if (GET_CODE (insn2) == BARRIER)
     goto failure;
   extract_insn (insn2);
-  if (! constrain_operands (1))
+  if (! constrain_operands (1, get_preferred_alternatives (insn2, bb)))
     {
       rtx tmp;
     failure:
Index: gcc/final.c
===================================================================
--- gcc/final.c	2014-10-17 15:50:02.000000000 +0100
+++ gcc/final.c	2014-10-17 15:50:02.623695895 +0100
@@ -2929,7 +2929,7 @@  final_scan_insn (rtx_insn *insn, FILE *f
 	    print_rtx_head = "";
 	  }
 
-	if (! constrain_operands_cached (1))
+	if (! constrain_operands_cached (insn, 1))
 	  fatal_insn_not_found (insn);
 
 	/* Some target machines need to prescan each insn before