aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorWilco Dijkstra <wdijkstr@arm.com>2021-11-03 12:51:41 +0000
committerWilco Dijkstra <wdijkstr@arm.com>2021-11-03 13:46:05 +0000
commita195c7270e4705a06a9aaade0d721d5f52ca2275 (patch)
treeabb0b6a8fb3ee012a7af5f3cdcb2cad0f044f30d /gcc
parent4096eb50d108a9ccef134f2e891c751b1cc9f6b2 (diff)
downloadgcc-a195c7270e4705a06a9aaade0d721d5f52ca2275.zip
gcc-a195c7270e4705a06a9aaade0d721d5f52ca2275.tar.gz
gcc-a195c7270e4705a06a9aaade0d721d5f52ca2275.tar.bz2
AArch64: Improve GOT addressing
Improve GOT addressing by treating the instructions as a pair. This reduces register pressure and improves code quality significantly. SPECINT2017 improves by 0.6% with -fPIC and codesize is 0.73% smaller. Perlbench has 0.9% smaller codesize, 1.5% fewer executed instructions and is 1.8% faster on Neoverse N1. ChangeLog: 2021-11-02 Wilco Dijkstra <wdijkstr@arm.com> * config/aarch64/aarch64.md (movsi): Add alternative for GOT accesses. (movdi): Likewise. (ldr_got_small_<mode>): Remove pattern. (ldr_got_small_sidi): Likewise. * config/aarch64/aarch64.c (aarch64_load_symref_appropriately): Keep GOT accesses as moves. (aarch64_print_operand): Correctly print got_lo12 in L specifier. (aarch64_mov_operand_p): Make GOT accesses valid move operands. * config/aarch64/constraints.md: Add new constraint Usw for GOT access.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/aarch64/aarch64.c50
-rw-r--r--gcc/config/aarch64/aarch64.md48
-rw-r--r--gcc/config/aarch64/constraints.md7
3 files changed, 30 insertions, 75 deletions
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index fd9249c..08f43ae 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3754,47 +3754,8 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
}
case SYMBOL_SMALL_GOT_4G:
- {
- /* In ILP32, the mode of dest can be either SImode or DImode,
- while the got entry is always of SImode size. The mode of
- dest depends on how dest is used: if dest is assigned to a
- pointer (e.g. in the memory), it has SImode; it may have
- DImode if dest is dereferenced to access the memeory.
- This is why we have to handle three different ldr_got_small
- patterns here (two patterns for ILP32). */
-
- rtx insn;
- rtx mem;
- rtx tmp_reg = dest;
- machine_mode mode = GET_MODE (dest);
-
- if (can_create_pseudo_p ())
- tmp_reg = gen_reg_rtx (mode);
-
- emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, imm));
- if (mode == ptr_mode)
- {
- if (mode == DImode)
- insn = gen_ldr_got_small_di (dest, tmp_reg, imm);
- else
- insn = gen_ldr_got_small_si (dest, tmp_reg, imm);
-
- mem = XVECEXP (SET_SRC (insn), 0, 0);
- }
- else
- {
- gcc_assert (mode == Pmode);
-
- insn = gen_ldr_got_small_sidi (dest, tmp_reg, imm);
- mem = XVECEXP (XEXP (SET_SRC (insn), 0), 0, 0);
- }
-
- gcc_assert (MEM_P (mem));
- MEM_READONLY_P (mem) = 1;
- MEM_NOTRAP_P (mem) = 1;
- emit_insn (insn);
- return;
- }
+ emit_insn (gen_rtx_SET (dest, imm));
+ return;
case SYMBOL_SMALL_TLSGD:
{
@@ -11156,7 +11117,7 @@ aarch64_print_operand (FILE *f, rtx x, int code)
switch (aarch64_classify_symbolic_expression (x))
{
case SYMBOL_SMALL_GOT_4G:
- asm_fprintf (asm_out_file, ":lo12:");
+ asm_fprintf (asm_out_file, ":got_lo12:");
break;
case SYMBOL_SMALL_TLSGD:
@@ -20264,6 +20225,11 @@ aarch64_mov_operand_p (rtx x, machine_mode mode)
return aarch64_simd_valid_immediate (x, NULL);
}
+ /* GOT accesses are valid moves. */
+ if (SYMBOL_REF_P (x)
+ && aarch64_classify_symbolic_expression (x) == SYMBOL_SMALL_GOT_4G)
+ return true;
+
x = strip_salt (x);
if (SYMBOL_REF_P (x) && mode == DImode && CONSTANT_ADDRESS_P (x))
return true;
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 65ee615..4035e06 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1262,8 +1262,8 @@
)
(define_insn_and_split "*movsi_aarch64"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r, r,w, m, m, r, r, w,r,w, w")
- (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,Usv,m,m,rZ,w,Usa,Ush,rZ,w,w,Ds"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r, r,w, m, m, r, r, r, w,r,w, w")
+ (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,Usv,m,m,rZ,w,Usw,Usa,Ush,rZ,w,w,Ds"))]
"(register_operand (operands[0], SImode)
|| aarch64_reg_or_zero (operands[1], SImode))"
"@
@@ -1277,6 +1277,7 @@
ldr\\t%s0, %1
str\\t%w1, %0
str\\t%s1, %0
+ adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1]
adr\\t%x0, %c1
adrp\\t%x0, %A1
fmov\\t%s0, %w1
@@ -1292,13 +1293,15 @@
}"
;; The "mov_imm" type for CNT is just a placeholder.
[(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,load_4,
- load_4,store_4,store_4,adr,adr,f_mcr,f_mrc,fmov,neon_move")
- (set_attr "arch" "*,*,*,*,*,sve,*,fp,*,fp,*,*,fp,fp,fp,simd")]
+ load_4,store_4,store_4,load_4,adr,adr,f_mcr,f_mrc,fmov,neon_move")
+ (set_attr "arch" "*,*,*,*,*,sve,*,fp,*,fp,*,*,*,fp,fp,fp,simd")
+ (set_attr "length" "4,4,4,4,*, 4,4, 4,4, 4,8,4,4, 4, 4, 4, 4")
+]
)
(define_insn_and_split "*movdi_aarch64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,r, r,w, m,m, r, r, w,r,w, w")
- (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,M,n,Usv,m,m,rZ,w,Usa,Ush,rZ,w,w,Dd"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,r, r,w, m,m, r, r, r, w,r,w, w")
+ (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,M,n,Usv,m,m,rZ,w,Usw,Usa,Ush,rZ,w,w,Dd"))]
"(register_operand (operands[0], DImode)
|| aarch64_reg_or_zero (operands[1], DImode))"
"@
@@ -1313,13 +1316,14 @@
ldr\\t%d0, %1
str\\t%x1, %0
str\\t%d1, %0
+ * return TARGET_ILP32 ? \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %L1]\" : \"adrp\\t%0, %A1\;ldr\\t%0, [%0, %L1]\";
adr\\t%x0, %c1
adrp\\t%x0, %A1
fmov\\t%d0, %x1
fmov\\t%x0, %d1
fmov\\t%d0, %d1
* return aarch64_output_scalar_simd_mov_immediate (operands[1], DImode);"
- "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))
+ "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode)
&& REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
[(const_int 0)]
"{
@@ -1328,9 +1332,10 @@
}"
;; The "mov_imm" type for CNTD is just a placeholder.
[(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,mov_imm,
- load_8,load_8,store_8,store_8,adr,adr,f_mcr,f_mrc,fmov,
- neon_move")
- (set_attr "arch" "*,*,*,*,*,*,sve,*,fp,*,fp,*,*,fp,fp,fp,simd")]
+ load_8,load_8,store_8,store_8,load_8,adr,adr,f_mcr,f_mrc,
+ fmov,neon_move")
+ (set_attr "arch" "*,*,*,*,*,*,sve,*,fp,*,fp,*,*,*,fp,fp,fp,simd")
+ (set_attr "length" "4,4,4,4,4,*, 4,4, 4,4, 4,8,4,4, 4, 4, 4, 4")]
)
(define_insn "insv_imm<mode>"
@@ -6706,29 +6711,6 @@
[(set_attr "type" "alu_imm")]
)
-(define_insn "ldr_got_small_<mode>"
- [(set (match_operand:PTR 0 "register_operand" "=r")
- (unspec:PTR [(mem:PTR (lo_sum:PTR
- (match_operand:PTR 1 "register_operand" "r")
- (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
- UNSPEC_GOTSMALLPIC))]
- ""
- "ldr\\t%<w>0, [%1, #:got_lo12:%c2]"
- [(set_attr "type" "load_<ldst_sz>")]
-)
-
-(define_insn "ldr_got_small_sidi"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (unspec:SI [(mem:SI (lo_sum:DI
- (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "aarch64_valid_symref" "S")))]
- UNSPEC_GOTSMALLPIC)))]
- "TARGET_ILP32"
- "ldr\\t%w0, [%1, #:got_lo12:%c2]"
- [(set_attr "type" "load_4")]
-)
-
(define_insn "ldr_got_small_28k_<mode>"
[(set (match_operand:PTR 0 "register_operand" "=r")
(unspec:PTR [(mem:PTR (lo_sum:PTR
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index 1863081..87c0e5f 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -152,6 +152,13 @@
(match_test "aarch64_symbolic_address_p (op)")
(match_test "aarch64_mov_operand_p (op, GET_MODE (op))")))
+(define_constraint "Usw"
+ "@internal
+ A constraint that matches a small GOT access."
+ (and (match_code "symbol_ref")
+ (match_test "aarch64_classify_symbolic_expression (op)
+ == SYMBOL_SMALL_GOT_4G")))
+
(define_constraint "Uss"
"@internal
A constraint that matches an immediate shift constant in SImode."