Patchwork [AArch64] Relax CANNOT_CHANGE_MODE_CLASS.

login
register
mail settings
Submitter Tejas Belagod
Date Jan. 16, 2014, 6:22 p.m.
Message ID <52D82357.1030303@arm.com>
Download mbox | patch
Permalink /patch/311816/
State New
Headers show

Comments

Tejas Belagod - Jan. 16, 2014, 6:22 p.m.
Tejas Belagod wrote:
> Tejas Belagod wrote:
>> Hi,
>>
>> Currently, CANNOT_CHANGE_MODE_CLASS is too restrictive wrt the mode-changes it 
>> allows on FPREGs - it allows none at the moment. In fact, there are many mode 
>> changes that are safe and can be allowed. For example, in a pattern like:
>>
>>      (subreg:SF (reg:V4SF v0) 0)
>>
>> it is legal to reduce this to
>>
>>       (reg:SF v0)
>>
>> The attached patch helps parts of rtlanal.c make such decisions(eg. 
>> simplify_subreg_regno).
>>
>> Tested on aarch64-none-elf and aarch64_be-none-elf. OK for trunk?
>>
>> Thanks,
>> Tejas Belagod
>> ARM.
>>
>> Changelog:
>>
>> 2013-11-28  Tejas Belagod  <tejas.belagod@arm.com>
>>
>> gcc/
>> 	* config/aarch64/aarch64-protos.h (aarch64_cannot_change_mode_class):
>> 	Declare.
>> 	* config/aarch64/aarch64.c (aarch64_cannot_change_mode_class): New.
>> 	* config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Change to call
>> 	backend function aarch64_cannot_change_mode_class.
>>
> 
> Hi,
> 
> I'm testing a patch that is more general than the change presented here for 
> CANNOT_CHANGE_MODE_CLASS. This patch is now defunct.

Ideally CANNOT_CHANGE_MODE_CLASS should be undefined, but that exposed a bug in 
LRA and subregs in general.

Until http://gcc.gnu.org/ml/gcc/2013-12/msg00086.html  and 
http://gcc.gnu.org/ml/gcc/2014-01/msg00087.html are resolved, we have to run 
with the attached patch. It is a slightly modified version of the initial patch.

Tested on aarch64-none-elf and aarch64_be-none-elf. OK for trunk?

Thanks,
Tejas.

2014-01-16  Tejas Belagod  <tejas.belagod@arm.com>

gcc/
	* config/aarch64/aarch64-protos.h
	(aarch64_cannot_change_mode_class_ptr): Declare.
	* config/aarch64/aarch64.c (aarch64_cannot_change_mode_class,
	aarch64_cannot_change_mode_class_ptr): New.
	* config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Change to call
	backend hook aarch64_cannot_change_mode_class.
Richard Earnshaw - Jan. 17, 2014, 4:01 p.m.
On 16/01/14 18:22, Tejas Belagod wrote:
> Tejas Belagod wrote:
>> Tejas Belagod wrote:
>>> Hi,
>>>
>>> Currently, CANNOT_CHANGE_MODE_CLASS is too restrictive wrt the mode-changes it 
>>> allows on FPREGs - it allows none at the moment. In fact, there are many mode 
>>> changes that are safe and can be allowed. For example, in a pattern like:
>>>
>>>      (subreg:SF (reg:V4SF v0) 0)
>>>
>>> it is legal to reduce this to
>>>
>>>       (reg:SF v0)
>>>
>>> The attached patch helps parts of rtlanal.c make such decisions(eg. 
>>> simplify_subreg_regno).
>>>
>>> Tested on aarch64-none-elf and aarch64_be-none-elf. OK for trunk?
>>>
>>> Thanks,
>>> Tejas Belagod
>>> ARM.
>>>
>>> Changelog:
>>>
>>> 2013-11-28  Tejas Belagod  <tejas.belagod@arm.com>
>>>
>>> gcc/
>>> 	* config/aarch64/aarch64-protos.h (aarch64_cannot_change_mode_class):
>>> 	Declare.
>>> 	* config/aarch64/aarch64.c (aarch64_cannot_change_mode_class): New.
>>> 	* config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Change to call
>>> 	backend function aarch64_cannot_change_mode_class.
>>>
>>
>> Hi,
>>
>> I'm testing a patch that is more general than the change presented here for 
>> CANNOT_CHANGE_MODE_CLASS. This patch is now defunct.
> 
> Ideally CANNOT_CHANGE_MODE_CLASS should be undefined, but that exposed a bug in 
> LRA and subregs in general.
> 
> Until http://gcc.gnu.org/ml/gcc/2013-12/msg00086.html  and 
> http://gcc.gnu.org/ml/gcc/2014-01/msg00087.html are resolved, we have to run 
> with the attached patch. It is a slightly modified version of the initial patch.
> 
> Tested on aarch64-none-elf and aarch64_be-none-elf. OK for trunk?
> 
> Thanks,
> Tejas.
> 
> 2014-01-16  Tejas Belagod  <tejas.belagod@arm.com>
> 
> gcc/
> 	* config/aarch64/aarch64-protos.h
> 	(aarch64_cannot_change_mode_class_ptr): Declare.
> 	* config/aarch64/aarch64.c (aarch64_cannot_change_mode_class,
> 	aarch64_cannot_change_mode_class_ptr): New.
> 	* config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Change to call
> 	backend hook aarch64_cannot_change_mode_class.
> 
> 

OK.

R.

Patch

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 489fd1c..3dcc7c3 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -160,6 +160,9 @@  struct tune_params
 
 HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
 bool aarch64_bitmask_imm (HOST_WIDE_INT val, enum machine_mode);
+bool aarch64_cannot_change_mode_class (enum machine_mode,
+				       enum machine_mode,
+				       enum reg_class);
 enum aarch64_symbol_type
 aarch64_classify_symbolic_expression (rtx, enum aarch64_symbol_context);
 bool aarch64_constant_address_p (rtx);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b1b4eef..6567a1b 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -8209,6 +8209,42 @@  aarch64_vectorize_vec_perm_const_ok (enum machine_mode vmode,
   return ret;
 }
 
+/* Implement target hook CANNOT_CHANGE_MODE_CLASS.  */
+bool
+aarch64_cannot_change_mode_class (enum machine_mode from,
+				  enum machine_mode to,
+				  enum reg_class rclass)
+{
+  /* Full-reg subregs are allowed on general regs or any class if they are
+     the same size.  */
+  if (GET_MODE_SIZE (from) == GET_MODE_SIZE (to)
+      || !reg_classes_intersect_p (FP_REGS, rclass))
+    return false;
+
+  /* Limited combinations of subregs are safe on FPREGs.  Particularly,
+     1. Vector Mode to Scalar mode where 1 unit of the vector is accessed.
+     2. Scalar to Scalar for integer modes or same size float modes.
+     3. Vector to Vector modes.  */
+  if (GET_MODE_SIZE (from) > GET_MODE_SIZE (to))
+    {
+      if (aarch64_vector_mode_supported_p (from)
+	  && GET_MODE_SIZE (GET_MODE_INNER (from)) == GET_MODE_SIZE (to))
+	return false;
+
+      if (GET_MODE_NUNITS (from) == 1
+	  && GET_MODE_NUNITS (to) == 1
+	  && (GET_MODE_CLASS (from) == MODE_INT
+	      || from == to))
+	return false;
+
+      if (aarch64_vector_mode_supported_p (from)
+	  && aarch64_vector_mode_supported_p (to))
+	return false;
+    }
+
+  return true;
+}
+
 #undef TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST aarch64_address_cost
 
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index cead022..b58fe04 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -818,13 +818,8 @@  do {									     \
   extern void  __aarch64_sync_cache_range (void *, void *);	\
   __aarch64_sync_cache_range (beg, end)
 
-/*  VFP registers may only be accessed in the mode they
-   were set.  */
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)	\
-  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)		\
-   ? reg_classes_intersect_p (FP_REGS, (CLASS))		\
-   : 0)
-
+  aarch64_cannot_change_mode_class (FROM, TO, CLASS)
 
 #define SHIFT_COUNT_TRUNCATED !TARGET_SIMD