* MIPS: the method of getting GOT address for PIC code
@ 2023-08-25 7:16 YunQiang Su
2024-01-15 6:04 ` YunQiang Su
0 siblings, 1 reply; 2+ messages in thread
From: YunQiang Su @ 2023-08-25 7:16 UTC (permalink / raw)
To: apinski--- via Gcc-patches
When working on LLVM, I found this problem
https://github.com/llvm/llvm-project/issues/64974.
Maybe it's time for us to reconsider the way of getting GOT address
for PIC code.
1.Background[1]:
All of the accessing of global variables and normal function calls
needs help from GOT.
So normally, the first 3 instructions of a function are to compute the
address of GOT.
Normally like:
lui $gp,%hi(_gp_disp)
addiu $gp,$gp,%lo(_gp_disp)
addu $gp,$gp,$t9
These 3 instructions load the value of _gp_disp, which is a link-time
constant value,
and add them with $t9, which normally contains the address of the
current function.
So, why $t9? The reason is that the pre-R6 MIPS lacks instructions to
get the PC value.
Thus, the ABI defines that, the caller should call functions with
jr/jarl $t9. So the callee
can get the address of itself by $t9.
2. What's my proposal?
2.1 For MIPSr6, its has instructions to get the current PC value, so
we can use them,
which can gain performance improvement.
2.2 For pre-R6, in fact, it can get the value of PC with NAL
instruction [2], while the performance will be some worse. For the
worst case, the decreasing of performance will be 20%-40%
My plan for pre-R6, is to add a non-default option to use NAL to get
the address of GOT.
Some software, like Linux kernel (for Kalsr support) will need it.
Any suggestions?
[1] https://refspecs.linuxfoundation.org/elf/mipsabi.pdf
[2] https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00087-2B-MIPS64BIS-AFP-6.06.pdf
Page 404
--
YunQiang Su
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: MIPS: the method of getting GOT address for PIC code
2023-08-25 7:16 MIPS: the method of getting GOT address for PIC code YunQiang Su
@ 2024-01-15 6:04 ` YunQiang Su
0 siblings, 0 replies; 2+ messages in thread
From: YunQiang Su @ 2024-01-15 6:04 UTC (permalink / raw)
To: apinski--- via Gcc-patches
[-- Attachment #1: Type: text/plain, Size: 438 bytes --]
YunQiang Su <wzssyqa@gmail.com> 于2023年8月25日周五 15:16写道:
>
> When working on LLVM, I found this problem
> https://github.com/llvm/llvm-project/issues/64974.
> Maybe it's time for us to reconsider the way of getting GOT address
> for PIC code.
>
I have my draft patch pushed to GitHub:
https://github.com/wzssyqa/gcc/tree/pcrel
And the patch is also attached.
Any comment is welcome.
--
YunQiang Su
[-- Attachment #2: 0001-MIPS-PCREL-support.patch --]
[-- Type: application/octet-stream, Size: 16678 bytes --]
From 0c2e26830edbcc60fff67e8c6d889755e39276f9 Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq@gcc.gnu.org>
Date: Thu, 11 Jan 2024 18:09:20 +0800
Subject: [PATCH] MIPS: PCREL support
1. Use auipc to get GOT instead of t9.
2. Use auipc to access non-preemptible variables/functions.
3. Add an option -mforce-pcrel: use BAL on r2.
4. -mno-shared for executable or kernel.
TODO:
1. Use ALUIPC/NO_GOT_BASE_REGISTER for R6.
Need R_MIPS_GOTPC_HI/LO support in binutils.
Use GOT_BASE_REGISTER, as it will caculate once only for
a single function; caculate GOT is expensive on R2.
2. 4+(a+4) instead of a+8.
---
gcc/config/mips/mips.cc | 148 +++++++++++++++++++++++++++++++++++++--
gcc/config/mips/mips.h | 17 ++++-
gcc/config/mips/mips.md | 49 ++++++++++++-
gcc/config/mips/mips.opt | 4 ++
gcc/rtl.h | 1 +
gcc/rtlanal.cc | 20 ++++--
6 files changed, 225 insertions(+), 14 deletions(-)
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 30e99811ff6..c31acc9f58a 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -2217,7 +2217,18 @@ mips_classify_symbol (const_rtx x, enum mips_symbol_context context)
access will work for any kind of symbol. However, there seems
little point in doing things differently. */
if (mips_global_symbol_p (x))
- return SYMBOL_GOT_DISP;
+ {
+ if (TARGET_PCREL_PIC
+ && SYMBOL_REF_LOCAL_P (x) && !SYMBOL_REF_EXTERNAL_P (x))
+ return SYMBOL_PC_RELATIVE;
+ else
+ return SYMBOL_GOT_DISP;
+ }
+
+ if (TARGET_PCREL_PIC && strcmp (XSTR (x, 0), "_gp_disp") == 0)
+ {
+ return ABI_HAS_64BIT_SYMBOLS ? SYMBOL_64_LOW : SYMBOL_ABSOLUTE;
+ }
return SYMBOL_GOT_PAGE_OFST;
}
@@ -5243,6 +5254,7 @@ mips_output_move (rtx dest, rtx src)
bool dbl_p = (GET_MODE_SIZE (mode) == 8);
bool msa_p = MSA_SUPPORTED_MODE_P (mode);
enum mips_symbol_type symbol_type;
+ rtx src0;
if (mips_split_move_p (dest, src, SPLIT_IF_NECESSARY))
return "#";
@@ -5385,7 +5397,43 @@ mips_output_move (rtx dest, rtx src)
}
if (src_code == HIGH)
- return (TARGET_MIPS16 && !ISA_HAS_MIPS16E2) ? "#" : "lui\t%0,%h1";
+ {
+ src0 = XEXP (src, 0);
+ enum mips_loadgp_style loadgp_style = mips_current_loadgp_style ();
+ const_rtx symbol_ref;
+ const char *label;
+ if (TARGET_PCREL_PIC
+ && (symbol_ref = get_first_code_subrtx (src0, SYMBOL_REF))
+ && mips_symbolic_constant_p (src0, SYMBOL_CONTEXT_LEA, &symbol_type)
+ && (symbol_type == SYMBOL_PC_RELATIVE
+ || (symbol_type == SYMBOL_ABSOLUTE
+ && loadgp_style == LOADGP_OLDABI
+ && strcmp (XSTR (src0, 0), "_gp_disp") == 0)
+ || (symbol_type == SYMBOL_GOTOFF_LOADGP
+ && loadgp_style == LOADGP_NEWABI)))
+ {
+ if (symbol_type == SYMBOL_GOTOFF_LOADGP)
+ {
+ label = XSTR (symbol_ref, 0);
+ if (TARGET_PCREL_INSN)
+ /* FIXME: Use ALUIPC when binutils is ready. */
+ return concat ("\n", label, ":\n\tauipc\t%0,%h1", NULL);
+ else if (TARGET_64BIT)
+ return concat ("bal\t. + 8\n\tlui\t%0,%h1\n", label, ":\n\tdaddu\t%0,%0,$ra", NULL);
+ else
+ return concat ("bal\t. + 8\n\tlui\t%0,%h1\n", label, ":\n\taddu\t%0,%0,$ra", NULL);
+ }
+ if (!TARGET_PCREL_INSN)
+ return TARGET_64BIT ? "bal\t. + 8\n\tlui\t%0,%h1\n\tdaddu\t%0,%0,$ra"
+ : "bal\t. + 8\n\tlui\t%0,%h1\n\taddu\t%0,%0,$ra";
+ else if (TARGET_PCREL_INSN)
+ /* FIXME: Use ALUIPC when binutils is ready. */
+ return "auipc\t%0,%h1";
+ else
+ gcc_unreachable ();
+ }
+ return (TARGET_MIPS16 && !ISA_HAS_MIPS16E2) ? "#" : "lui\t%0,%h1";
+ }
if (CONST_GP_P (src))
return "move\t%0,%1";
@@ -8908,6 +8956,10 @@ mips_init_relocs (void)
mips_split_p[SYMBOL_ABSOLUTE] = true;
mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
+
+ mips_split_p[SYMBOL_PC_RELATIVE] = true;
+ mips_hi_relocs[SYMBOL_PC_RELATIVE] = "%pcrel_hi(";
+ mips_lo_relocs[SYMBOL_PC_RELATIVE] = "(%pcrel_lo(";
}
}
else
@@ -8919,6 +8971,10 @@ mips_init_relocs (void)
mips_split_p[SYMBOL_ABSOLUTE] = true;
mips_hi_relocs[SYMBOL_ABSOLUTE] = "%hi(";
mips_lo_relocs[SYMBOL_ABSOLUTE] = "%lo(";
+
+ mips_split_p[SYMBOL_PC_RELATIVE] = true;
+ mips_hi_relocs[SYMBOL_PC_RELATIVE] = "%pcrel_hi(";
+ mips_lo_relocs[SYMBOL_PC_RELATIVE] = "(%pcrel_lo(";
}
}
}
@@ -9016,12 +9072,22 @@ mips_print_operand_reloc (FILE *file, rtx op, enum mips_symbol_context context,
{
enum mips_symbol_type symbol_type;
const char *p;
+ static int count_pcrel_lo;
symbol_type = mips_classify_symbolic_expression (op, context);
gcc_assert (relocs[symbol_type]);
fputs (relocs[symbol_type], file);
output_addr_const (file, mips_strip_unspec_address (op));
+ if (strcmp (relocs[symbol_type], "%pcrel_hi(") == 0)
+ count_pcrel_lo = 0;
+ if (strcmp (relocs[symbol_type], "(%pcrel_lo(") == 0)
+ {
+ count_pcrel_lo ++;
+ fprintf (file, ")+%d)", 4 * count_pcrel_lo);
+ return;
+ }
+
for (p = relocs[symbol_type]; *p != 0; p++)
if (*p == '(')
fputc (')', file);
@@ -11198,6 +11264,10 @@ mips_save_reg_p (unsigned int regno)
if (regno == RETURN_ADDR_REGNUM && crtl->calls_eh_return)
return true;
+ /* We need to use NAL to get PC. NAL will clobber $ra. */
+ if (TARGET_PCREL_PIC && !TARGET_PCREL_INSN && regno == RETURN_ADDR_REGNUM)
+ return true;
+
return false;
}
@@ -12140,7 +12210,8 @@ mips_output_function_prologue (FILE *file)
Also emit the ".set noreorder; .set nomacro" sequence for functions
that need it. */
if (mips_must_initialize_gp_p ()
- && mips_current_loadgp_style () == LOADGP_OLDABI)
+ && mips_current_loadgp_style () == LOADGP_OLDABI
+ && !TARGET_PCREL_PIC)
{
if (TARGET_MIPS16)
{
@@ -12225,6 +12296,10 @@ mips_frame_barrier (void)
static GTY(()) rtx mips_gnu_local_gp;
+/* The _gp_disp symbol. */
+
+static GTY(()) rtx mips_gp_disp;
+
/* If we're generating n32 or n64 abicalls, emit instructions
to set up the global pointer. */
@@ -12248,14 +12323,37 @@ mips_emit_loadgp (void)
case LOADGP_OLDABI:
/* Added by mips_output_function_prologue. */
+ if (!TARGET_PCREL_PIC)
+ break;
+ if (mips_gp_disp == NULL)
+ {
+ mips_gp_disp = gen_rtx_SYMBOL_REF (Pmode, "_gp_disp");
+ SYMBOL_REF_FLAGS (mips_gp_disp) |= SYMBOL_FLAG_LOCAL;
+ }
+ emit_insn (gen_rtx_SET (pic_reg, gen_rtx_HIGH (Pmode, mips_gp_disp)));
+ emit_insn (gen_rtx_SET (pic_reg, gen_rtx_LO_SUM (Pmode, pic_reg, mips_gp_disp)));
+ SCHED_GROUP_P (get_last_insn ()) = 1;
break;
case LOADGP_NEWABI:
+ if (TARGET_PCREL_PIC)
+ {
+ char *label_name = concat (".L_",
+ IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
+ "_gotcalc", NULL);
+ addr = gen_rtx_SYMBOL_REF (Pmode, label_name);
+ SYMBOL_REF_FLAGS (addr) |= SYMBOL_FLAG_LOCAL;
+ offset = mips_unspec_address (addr, SYMBOL_GOTOFF_LOADGP);
+ incoming_address = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
+ emit_insn (PMODE_INSN (gen_loadgp_newabi_pcrel,
+ (pic_reg, offset, incoming_address)));
+ break;
+ }
addr = XEXP (DECL_RTL (current_function_decl), 0);
offset = mips_unspec_address (addr, SYMBOL_GOTOFF_LOADGP);
incoming_address = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
emit_insn (PMODE_INSN (gen_loadgp_newabi,
- (pic_reg, offset, incoming_address)));
+ (pic_reg, offset, incoming_address)));
break;
case LOADGP_RTP:
@@ -15451,6 +15549,43 @@ mips_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
return cached_can_issue_more;
}
+/* Implement TARGET_SCHED_MACRO_FUSION_PAIR_P. Return true if PREV and CURR
+ should be kept together during scheduling.
+ TARGET_SCHED_MACRO_FUSION_P is set to always true. */
+
+static bool
+mips_macro_fusion_pair_p (rtx_insn *prev ATTRIBUTE_UNUSED, rtx_insn *curr)
+{
+ rtx curr_set = single_set (curr);
+ rtx csrc = SET_SRC (curr_set);
+
+ /* If TARGET_PCREL_PIC,
+ (set (reg/i:SI 2 $2)
+ (mem/c:SI (lo_sum:SI (reg/f:SI 2 $2 [196])
+ (symbol_ref:SI ("g") [flags 0x2])) [1 g+0 S4 A32]))
+ (set (reg/f:SI 201)
+ (lo_sum:SI (reg/f:SI 202)
+ (symbol_ref:SI ("f") [flags 0x3])))
+ (set (reg:SI 3 $3 [ g+4 ])
+ (mem/c:SI (lo_sum:SI (reg/f:SI 2 $2 [196])
+ (const:SI (plus:SI (symbol_ref:SI ("g") [flags 0x2])
+ (const_int 4 [0x4])))) [1 g+4 S4 A32]))
+ will be convert to %pcrel_lo. */
+ if (TARGET_PCREL_PIC)
+ {
+ const_rtx symbol_ref = NULL_RTX;
+ const_rtx lo_sum = get_first_code_subrtx (csrc, LO_SUM);
+ if (lo_sum)
+ symbol_ref = get_first_code_subrtx (lo_sum, SYMBOL_REF);
+
+ if (symbol_ref && SYMBOL_REF_P (symbol_ref)
+ && SYMBOL_REF_LOCAL_P (symbol_ref) && !SYMBOL_REF_EXTERNAL_P (symbol_ref))
+ return true;
+ }
+
+ return false;
+}
+
/* Update round-robin counters for ALU1/2 and FALU1/2. */
static void
@@ -23076,6 +23211,11 @@ mips_bit_clear_p (enum machine_mode mode, unsigned HOST_WIDE_INT m)
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
mips_multipass_dfa_lookahead
+#undef TARGET_SCHED_MACRO_FUSION_P
+#define TARGET_SCHED_MACRO_FUSION_P hook_bool_void_true
+#undef TARGET_SCHED_MACRO_FUSION_PAIR_P
+#define TARGET_SCHED_MACRO_FUSION_PAIR_P mips_macro_fusion_pair_p
+
#undef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
mips_small_register_classes_for_mode_p
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 8768933ba37..ac283669a25 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -154,6 +154,16 @@ struct mips_cpu_info {
#define TARGET_ABICALLS_PIC2 \
(TARGET_ABICALLS && !TARGET_ABICALLS_PIC0)
+/* True if there are instructions that can get value of PC without side effects.
+ Otherwise, we will need to use NAL, which clobbers $31. */
+#define TARGET_PCREL_INSN (mips_isa_rev >= 6)
+
+/* True if the output file is shared but not abicall, aka pcrel.
+ FIXME: enable it for MIPS16 and microMIPS? */
+#define TARGET_PCREL_PIC (flag_pic && TARGET_EXPLICIT_RELOCS \
+ && !TARGET_MIPS16 && !TARGET_MICROMIPS \
+ && (TARGET_PCREL_INSN || TARGET_FORCE_PCREL))
+
/* True if the call patterns should be split into a jalr followed by
an instruction to restore $gp. It is only safe to split the load
from the call when every use of $gp is explicit.
@@ -175,7 +185,8 @@ struct mips_cpu_info {
(TARGET_ABICALLS \
&& !TARGET_SHARED \
&& TARGET_EXPLICIT_RELOCS \
- && !ABI_HAS_64BIT_SYMBOLS)
+ && !ABI_HAS_64BIT_SYMBOLS \
+ && !TARGET_PCREL_PIC)
/* True if we can optimize sibling calls. For simplicity, we only
handle cases in which call_insn_operand will reject invalid
@@ -192,7 +203,9 @@ struct mips_cpu_info {
(!TARGET_MIPS16 && (!TARGET_USE_GOT || TARGET_EXPLICIT_RELOCS))
/* True if we need to use a global offset table to access some symbols. */
-#define TARGET_USE_GOT (TARGET_ABICALLS || TARGET_RTP_PIC)
+#define TARGET_USE_GOT ((TARGET_ABICALLS \
+ && !(TARGET_PCREL_PIC && !TARGET_SHARED)) \
+ || TARGET_RTP_PIC)
/* True if TARGET_USE_GOT and if $gp is a call-clobbered register. */
#define TARGET_CALL_CLOBBERED_GP (TARGET_ABICALLS && TARGET_OLDABI)
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 17dfcbd6722..51ab2eac676 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -4748,7 +4748,7 @@ (define_insn_and_split "*got_disp<mode>"
(match_operand:P 1 "got_disp_operand" ""))]
"TARGET_EXPLICIT_RELOCS && !mips_split_p[SYMBOL_GOT_DISP]"
"#"
- "&& reload_completed"
+ "&& reload_completed && !(TARGET_PCREL_PIC && SYMBOL_REF_LOCAL_P (operands[1]) && !SYMBOL_REF_EXTERNAL_P (operands[1]))"
[(set (match_dup 0) (match_dup 2))]
{ operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_DISP); }
[(set_attr "got" "load")
@@ -4978,6 +4978,34 @@ (define_expand "mov<mode>"
DONE;
})
+;; PCREL uses NAL to get PC on pre-R6. NAL will clobber $RA.
+(define_peephole2
+ [(set (match_operand:P 0 "register_operand")
+ (high:P (match_operand:P 1 "symbol_ref_operand")))]
+ "TARGET_PCREL_PIC && !TARGET_PCREL_INSN
+ && GET_CODE (operands[1]) == SYMBOL_REF
+ && SYMBOL_REF_LOCAL_P (operands[1]) && !SYMBOL_REF_EXTERNAL_P (operands[1])"
+ [(parallel [(clobber (reg:P RETURN_ADDR_REGNUM))
+ (set (match_dup 0)
+ (high:P (match_dup 1)))])]
+ "")
+
+(define_insn "*mov<mode>_pcrel"
+ [(clobber (reg:P RETURN_ADDR_REGNUM))
+ (set (match_operand:P 0 "register_operand" "=d")
+ (match_operand:P 1 "move_operand" "Yd"))]
+ "TARGET_PCREL_PIC
+ && GET_CODE (operands[1]) == HIGH
+ && contains_symbol_ref_p (XEXP (operands[1], 0))
+ && SYMBOL_REF_LOCAL_P (get_first_code_subrtx (XEXP (operands[1], 0), SYMBOL_REF))
+ && !SYMBOL_REF_EXTERNAL_P (get_first_code_subrtx (XEXP (operands[1], 0), SYMBOL_REF))"
+ { return mips_output_move (operands[0], operands[1]); }
+ [(set_attr "move_type" "move")
+ (set (attr "insn_count")
+ (if_then_else (match_test "TARGET_PCREL_INSN")
+ (const_int 1)
+ (const_int 3)))])
+
;; The difference between these two is whether or not ints are allowed
;; in FP registers (off by default, use -mdebugh to enable).
@@ -5603,7 +5631,7 @@ (define_insn_and_split "loadgp_newabi_<mode>"
(unspec:P [(match_operand:P 1)
(match_operand:P 2 "register_operand" "d")]
UNSPEC_LOADGP))]
- "mips_current_loadgp_style () == LOADGP_NEWABI"
+ "mips_current_loadgp_style () == LOADGP_NEWABI && !TARGET_PCREL_PIC"
{ return mips_must_initialize_gp_p () ? "#" : ""; }
"&& mips_must_initialize_gp_p ()"
[(set (match_dup 0) (match_dup 3))
@@ -5616,6 +5644,23 @@ (define_insn_and_split "loadgp_newabi_<mode>"
}
[(set_attr "type" "ghost")])
+(define_insn_and_split "loadgp_newabi_pcrel_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=&d")
+ (unspec:P [(match_operand:P 1)
+ (match_operand:P 2 "register_operand" "d")]
+ UNSPEC_LOADGP))]
+ "mips_current_loadgp_style () == LOADGP_NEWABI && TARGET_PCREL_PIC"
+ { return mips_must_initialize_gp_p () ? "#" : ""; }
+ "&& mips_must_initialize_gp_p ()"
+ [(parallel [(clobber (reg:P RETURN_ADDR_REGNUM))
+ (set (match_dup 0) (match_dup 3))])
+ (set (match_dup 0) (match_dup 4))]
+{
+ operands[3] = gen_rtx_HIGH (Pmode, operands[1]);
+ operands[4] = gen_rtx_LO_SUM (Pmode, operands[0], operands[1]);
+}
+ [(set_attr "type" "ghost")])
+
;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol.
(define_insn_and_split "loadgp_absolute_<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index e8b411a8ffe..e5c62fcf8c7 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -54,6 +54,10 @@ mabicalls
Target Mask(ABICALLS)
Generate code that can be used in SVR4-style dynamic objects.
+mforce-pcrel
+Target Mask(FORCE_PCREL)
+Use PC-relative operations even with significant performance degrading.
+
mmad
Target Var(TARGET_MAD)
Use PMC-style 'mad' instructions.
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 2370d608161..55945131040 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3600,6 +3600,7 @@ extern void set_insn_deleted (rtx_insn *);
extern rtx single_set_2 (const rtx_insn *, const_rtx);
extern rtx simple_regno_set (rtx, unsigned int);
+extern const_rtx get_first_code_subrtx (const_rtx, enum rtx_code);
extern bool contains_symbol_ref_p (const_rtx);
extern bool contains_symbolic_reference_p (const_rtx);
extern bool contains_constant_pool_address_p (const_rtx);
diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc
index ec65cf173b4..3e5fa65bb53 100644
--- a/gcc/rtlanal.cc
+++ b/gcc/rtlanal.cc
@@ -6840,17 +6840,25 @@ get_index_code (const struct address_info *info)
return SCRATCH;
}
-/* Return true if RTL X contains a SYMBOL_REF. */
+/* Return first subrtx with CODE of RTL X. */
-bool
-contains_symbol_ref_p (const_rtx x)
+const_rtx
+get_first_code_subrtx (const_rtx x, enum rtx_code code)
{
subrtx_iterator::array_type array;
FOR_EACH_SUBRTX (iter, array, x, ALL)
- if (SYMBOL_REF_P (*iter))
- return true;
+ if (GET_CODE (*iter) == code)
+ return *iter;
- return false;
+ return NULL_RTX;
+}
+
+/* Return true if RTL X contains a SYMBOL_REF. */
+
+bool
+contains_symbol_ref_p (const_rtx x)
+{
+ return !! get_first_code_subrtx (x, SYMBOL_REF);
}
/* Return true if RTL X contains a SYMBOL_REF or LABEL_REF. */
--
2.39.2
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-01-15 6:04 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-25 7:16 MIPS: the method of getting GOT address for PIC code YunQiang Su
2024-01-15 6:04 ` YunQiang Su
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).