From: Wilco Dijkstra Date: Wed, 3 Nov 2021 12:51:41 +0000 (+0000) Subject: AArch64: Improve GOT addressing X-Git-Tag: basepoints/gcc-13~3450 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a195c7270e4705a06a9aaade0d721d5f52ca2275;p=thirdparty%2Fgcc.git 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 * config/aarch64/aarch64.md (movsi): Add alternative for GOT accesses. (movdi): Likewise. (ldr_got_small_): 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. --- diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index fd9249c62b34..08f43aebe335 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 65ee6159d731..4035e0617067 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" @@ -6706,29 +6711,6 @@ [(set_attr "type" "alu_imm")] ) -(define_insn "ldr_got_small_" - [(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%0, [%1, #:got_lo12:%c2]" - [(set_attr "type" "load_")] -) - -(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_" [(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 18630815ffc1..87c0e5fe2a9c 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."