Re: [PATCH, AArch64] Allow symbol+offset as symbolic constant expression

2012-07-23 Thread Marcus Shawcroft

On 06/07/12 16:31, Ian Bolton wrote:

Hi,

This patch reduces codesize for cases such as this one:

  int arr[100];
  int foo () { return arr[10]; }

Before the patch, the code looked like this:

  adrp x0, arr
  add x0, x0, :lo12:arr
  ldr w0, [x0,40]

Now, it looks like this:

  adrp x0, arr+40
  ldr w0, [x0,#:lo12:arr+40]

Some workloads have seen up to 1K reduction in code size.

OK to commit?

Cheers,
Ian



2012-07-06  Ian Bolton

* gcc/config/aarch64/aarch64.c (aarch64_print_operand): Use
aarch64_classify_symbolic_expression for classifying operands.

* gcc/config/aarch64/aarch64.c
(aarch64_classify_symbolic_expression): New function.

* gcc/config/aarch64/aarch64.c (aarch64_symbolic_constant_p):
New function.

* gcc/config/aarch64/predicates.md (aarch64_valid_symref):
Symbol with constant offset is a valid symbol reference.


OK



[PATCH, AArch64] Allow symbol+offset as symbolic constant expression

2012-07-06 Thread Ian Bolton
Hi,

This patch reduces codesize for cases such as this one:

 int arr[100];
 int foo () { return arr[10]; }

Before the patch, the code looked like this:

 adrp x0, arr
 add x0, x0, :lo12:arr
 ldr w0, [x0,40]

Now, it looks like this:
 
 adrp x0, arr+40
 ldr w0, [x0,#:lo12:arr+40]

Some workloads have seen up to 1K reduction in code size.

OK to commit?

Cheers,
Ian



2012-07-06  Ian Bolton  

* gcc/config/aarch64/aarch64.c (aarch64_print_operand): Use
aarch64_classify_symbolic_expression for classifying operands.

* gcc/config/aarch64/aarch64.c
(aarch64_classify_symbolic_expression): New function.

* gcc/config/aarch64/aarch64.c (aarch64_symbolic_constant_p):
New function.

* gcc/config/aarch64/predicates.md (aarch64_valid_symref):
Symbol with constant offset is a valid symbol reference.diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 542c1e0..53c238a 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2820,6 +2820,17 @@ aarch64_symbolic_address_p (rtx x)
   return GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF;
 }
 
+/* Classify the base of symbolic expression X, given that X appears in
+   context CONTEXT.  */
+static enum aarch64_symbol_type
+aarch64_classify_symbolic_expression (rtx x, enum aarch64_symbol_context 
context)
+{
+  rtx offset;
+  split_const (x, &x, &offset);
+  return aarch64_classify_symbol (x, context);
+}
+
+
 /* Return TRUE if X is a legitimate address for accessing memory in
mode MODE.  */
 static bool
@@ -3227,7 +3238,7 @@ aarch64_print_operand (FILE *f, rtx x, char code)
   if (GET_CODE (x) == HIGH)
x = XEXP (x, 0);
 
-  switch (aarch64_classify_symbol (x, SYMBOL_CONTEXT_ADR))
+  switch (aarch64_classify_symbolic_expression (x, SYMBOL_CONTEXT_ADR))
{
case SYMBOL_SMALL_GOT:
  asm_fprintf (asm_out_file, ":got:");
@@ -3256,7 +3267,7 @@ aarch64_print_operand (FILE *f, rtx x, char code)
   break;
 
 case 'L':
-  switch (aarch64_classify_symbol (x, SYMBOL_CONTEXT_ADR))
+  switch (aarch64_classify_symbolic_expression (x, SYMBOL_CONTEXT_ADR))
{
case SYMBOL_SMALL_GOT:
  asm_fprintf (asm_out_file, ":lo12:");
@@ -3285,7 +3296,8 @@ aarch64_print_operand (FILE *f, rtx x, char code)
   break;
 
 case 'G':
-  switch (aarch64_classify_symbol (x, SYMBOL_CONTEXT_ADR))
+
+  switch (aarch64_classify_symbolic_expression (x, SYMBOL_CONTEXT_ADR))
{
case SYMBOL_SMALL_TPREL:
  asm_fprintf (asm_out_file, ":tprel_hi12:");
@@ -4746,6 +4758,8 @@ aarch64_classify_tls_symbol (rtx x)
 }
 }
 
+/* Return the method that should be used to access SYMBOL_REF or
+   LABEL_REF X in context CONTEXT.  */
 enum aarch64_symbol_type
 aarch64_classify_symbol (rtx x,
 enum aarch64_symbol_context context ATTRIBUTE_UNUSED)
@@ -4817,7 +4831,23 @@ aarch64_classify_symbol (rtx x,
   return SYMBOL_FORCE_TO_MEM;
 }
 
+/* Return true if X is a symbolic constant that can be used in context
+   CONTEXT.  If it is, store the type of the symbol in *SYMBOL_TYPE.  */
+
+bool
+aarch64_symbolic_constant_p (rtx x, enum aarch64_symbol_context context,
+enum aarch64_symbol_type *symbol_type)
+{
+  rtx offset;
+  split_const (x, &x, &offset);
+  if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
+*symbol_type = aarch64_classify_symbol (x, context);
+  else
+return false;
 
+  /* No checking of offset at this point.  */
+  return true;
+}
 
 bool
 aarch64_constant_address_p (rtx x)
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 7089e8b..328e5cf 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -114,8 +114,12 @@
(match_test "mode == DImode && CONSTANT_ADDRESS_P (op)")))
 
 (define_predicate "aarch64_valid_symref"
-  (and (match_code "symbol_ref, label_ref")
-   (match_test "aarch64_classify_symbol (op, SYMBOL_CONTEXT_ADR) != 
SYMBOL_FORCE_TO_MEM")))
+  (match_code "const, symbol_ref, label_ref")
+{
+  enum aarch64_symbol_type symbol_type;
+  return (aarch64_symbolic_constant_p (op, SYMBOL_CONTEXT_ADR, &symbol_type)
+&& symbol_type != SYMBOL_FORCE_TO_MEM);
+})
 
 (define_predicate "aarch64_tls_ie_symref"
   (match_code "symbol_ref, label_ref")