From d0fa78c4c29a15964467276493280efa091fbd64 Mon Sep 17 00:00:00 2001
From: Evandro Menezes <e.menezes@samsung.com>
Date: Fri, 13 Nov 2015 15:55:45 -0600
Subject: [PATCH] [AArch64] Handle function literal pools according to function
size
gcc/
PR target/63304
* config/aarch64/aarch64-protos.h (aarch64_nopcrelative_literal_loads):
Move to module scope in "aarch64.c".
(aarch64_may_load_literal_pcrel) New function.
* config/aarch64/aarch64.c (aarch64_nopcrelative_literal_loads): Change
scope to module.
(aarch64_may_load_literal_pcrel): New function that replaces the global
variable "aarch64_nopcrelative_literal_loads" in most cases.
(+aarch64_current_func_size): New function.
* config/aarch64/aarch64.h (machine_function): Add new member "size".
* config/aarch64/aarch64.md (aarch64_reload_movcp<GPF_TF:mode><P:mode>):
Use "aarch64_may_load_literal_pcrel".
(aarch64_reload_movcp<VALL:mode><P:mode>): Likewise.
---
gcc/config/aarch64/aarch64-protos.h | 4 ++-
gcc/config/aarch64/aarch64.c | 49 ++++++++++++++++++++++++++++++++-----
gcc/config/aarch64/aarch64.h | 7 +++++-
gcc/config/aarch64/aarch64.md | 4 +--
4 files changed, 54 insertions(+), 10 deletions(-)
@@ -426,5 +426,7 @@ int aarch64_ccmp_mode_to_code (enum machine_mode mode);
bool extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset);
bool aarch64_operands_ok_for_ldpstp (rtx *, bool, enum machine_mode);
bool aarch64_operands_adjust_ok_for_ldpstp (rtx *, bool, enum machine_mode);
-extern bool aarch64_nopcrelative_literal_loads;
+
+extern bool aarch64_may_load_literal_pcrel (void);
+
#endif /* GCC_AARCH64_PROTOS_H */
@@ -139,6 +139,7 @@ static bool aarch64_vector_mode_supported_p (machine_mode);
static bool aarch64_vectorize_vec_perm_const_ok (machine_mode vmode,
const unsigned char *sel);
static int aarch64_address_cost (rtx, machine_mode, addr_space_t, bool);
+static unsigned long aarch64_current_func_size (void);
/* Major revision number of the ARM Architecture implemented by the target. */
unsigned aarch64_architecture_version;
@@ -150,7 +151,7 @@ enum aarch64_processor aarch64_tune = cortexa53;
unsigned long aarch64_tune_flags = 0;
/* Global flag for PC relative loads. */
-bool aarch64_nopcrelative_literal_loads;
+static bool aarch64_nopcrelative_literal_loads;
/* Support for command line parsing of boolean flags in the tuning
structures. */
@@ -1558,7 +1559,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
we need to expand the literal pool access carefully.
This is something that needs to be done in a number
of places, so could well live as a separate function. */
- if (aarch64_nopcrelative_literal_loads)
+ if (!aarch64_may_load_literal_pcrel ())
{
gcc_assert (can_create_pseudo_p ());
base = gen_reg_rtx (ptr_mode);
@@ -3698,7 +3699,7 @@ aarch64_classify_address (struct aarch64_address_info *info,
return ((GET_CODE (sym) == LABEL_REF
|| (GET_CODE (sym) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (sym)
- && !aarch64_nopcrelative_literal_loads)));
+ && aarch64_may_load_literal_pcrel ())));
}
return false;
@@ -4929,7 +4930,7 @@ aarch64_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x,
if (MEM_P (x) && GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x)
&& (SCALAR_FLOAT_MODE_P (GET_MODE (x))
|| targetm.vector_mode_supported_p (GET_MODE (x)))
- && aarch64_nopcrelative_literal_loads)
+ && !aarch64_may_load_literal_pcrel ())
{
sri->icode = aarch64_constant_pool_reload_icode (mode);
return NO_REGS;
@@ -5256,6 +5257,22 @@ aarch64_uxt_size (int shift, HOST_WIDE_INT mask)
return 0;
}
+/* Return true if PC-relative loads may be used to access the per function
+ literal pool. */
+
+bool
+aarch64_may_load_literal_pcrel (void)
+{
+ /* The range for PC-relative loads is +/-1MB. To stay on the safe side,
+ the function size limit is set lower to half of the range. */
+ const unsigned long max_func_size = 1048576UL / 2;
+
+ if (aarch64_nopcrelative_literal_loads)
+ return false;
+
+ return (aarch64_current_func_size () < max_func_size);
+}
+
/* Constant pools are per function only when PC relative
literal loads are true or we are in the large memory
model. */
@@ -5263,7 +5280,7 @@ aarch64_uxt_size (int shift, HOST_WIDE_INT mask)
static inline bool
aarch64_can_use_per_function_literal_pools_p (void)
{
- return (!aarch64_nopcrelative_literal_loads
+ return (aarch64_may_load_literal_pcrel ()
|| aarch64_cmodel == AARCH64_CMODEL_LARGE);
}
@@ -7181,6 +7198,26 @@ aarch64_sched_first_cycle_multipass_dfa_lookahead (void)
return issue_rate > 1 && !sched_fusion ? issue_rate : 0;
}
+/* Return the size of the current function in bytes. */
+
+unsigned long
+aarch64_current_func_size (void)
+{
+ unsigned long func_size;
+ rtx_insn *insn;
+
+ if (cfun->machine->size)
+ return cfun->machine->size;
+
+ if (reload_in_progress)
+ return 0;
+
+ for (func_size = 0, insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ func_size += get_attr_length (insn);
+
+ cfun->machine->size = func_size;
+ return func_size;
+}
/* Implement TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD as
autopref_multipass_dfa_lookahead_guard from haifa-sched.c. It only
@@ -8966,7 +9003,7 @@ aarch64_classify_symbol (rtx x, rtx offset)
/* This is alright even in PIC code as the constant
pool reference is always PC relative and within
the same translation unit. */
- if (nopcrelative_literal_loads
+ if (!aarch64_may_load_literal_pcrel ()
&& CONSTANT_POOL_ADDRESS_P (x))
return SYMBOL_SMALL_ABSOLUTE;
else
@@ -546,12 +546,17 @@ struct GTY (()) aarch64_frame
bool laid_out;
};
+#endif
typedef struct GTY (()) machine_function
{
+ /* Approximate size of the current function in bytes.
+ Only valid after reload and if non-zero. */
+ unsigned long size;
+#ifdef HOST_WIDE_INT
struct aarch64_frame frame;
-} machine_function;
#endif
+} machine_function;
/* Which ABI to use. */
enum aarch64_abi_type
@@ -4535,7 +4535,7 @@
[(set (match_operand:GPF_TF 0 "register_operand" "=w")
(mem:GPF_TF (match_operand 1 "aarch64_constant_pool_symref" "S")))
(clobber (match_operand:P 2 "register_operand" "=&r"))]
- "TARGET_FLOAT && aarch64_nopcrelative_literal_loads"
+ "TARGET_FLOAT && !aarch64_may_load_literal_pcrel ()"
{
aarch64_expand_mov_immediate (operands[2], XEXP (operands[1], 0));
emit_move_insn (operands[0], gen_rtx_MEM (<GPF_TF:MODE>mode, operands[2]));
@@ -4548,7 +4548,7 @@
[(set (match_operand:VALL 0 "register_operand" "=w")
(mem:VALL (match_operand 1 "aarch64_constant_pool_symref" "S")))
(clobber (match_operand:P 2 "register_operand" "=&r"))]
- "TARGET_FLOAT && aarch64_nopcrelative_literal_loads"
+ "TARGET_FLOAT && !aarch64_may_load_literal_pcrel ()"
{
aarch64_expand_mov_immediate (operands[2], XEXP (operands[1], 0));
emit_move_insn (operands[0], gen_rtx_MEM (<VALL:MODE>mode, operands[2]));
--
2.1.0.243.g30d45f7