From bc8e8e97b4ff381c66c3346682ad19f81d613685 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 9 Apr 2002 22:22:33 -0700 Subject: [PATCH] alpha.md (movdi_er_maybe_g): New. * config/alpha/alpha.md (movdi_er_maybe_g): New. * config/alpha/alpha.c (alpha_expand_mov): Use it. From-SVN: r52113 --- gcc/ChangeLog | 5 +++++ gcc/config/alpha/alpha.c | 21 ++++++++++++++++++++- gcc/config/alpha/alpha.md | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1def463bd49..e5047f286d6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2002-04-09 Richard Henderson + + * config/alpha/alpha.md (movdi_er_maybe_g): New. + * config/alpha/alpha.c (alpha_expand_mov): Use it. + 2002-04-10 Alan Modra PR optimization/6233 diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index e5b1ce37c08..915d6e48996 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -2537,7 +2537,26 @@ alpha_expand_mov (mode, operands) /* Allow legitimize_address to perform some simplifications. */ if (mode == Pmode && symbolic_operand (operands[1], mode)) { - rtx tmp = alpha_legitimize_address (operands[1], operands[0], mode); + rtx tmp; + + /* With RTL inlining, at -O3, rtl is generated, stored, then actually + compiled at the end of compilation. In the meantime, someone can + re-encode-section-info on some symbol changing it e.g. from global + to local-not-small. If this happens, we'd have emitted a plain + load rather than a high+losum load and not recognize the insn. + + So if rtl inlining is in effect, we delay the global/not-global + decision until rest_of_compilation by wrapping it in an + UNSPEC_SYMBOL. */ + if (TARGET_EXPLICIT_RELOCS && flag_inline_functions + && rtx_equal_function_value_matters + && global_symbolic_operand (operands[1], mode)) + { + emit_insn (gen_movdi_er_maybe_g (operands[0], operands[1])); + return true; + } + + tmp = alpha_legitimize_address (operands[1], operands[0], mode); if (tmp) { operands[1] = tmp; diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 9db923c5df6..785a61df01e 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -39,6 +39,7 @@ (UNSPEC_LITERAL 11) (UNSPEC_LITUSE 12) (UNSPEC_SIBCALL 13) + (UNSPEC_SYMBOL 14) ]) ;; UNSPEC_VOLATILE: @@ -5547,6 +5548,41 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (const_int 0)] UNSPEC_LITERAL))] "operands[2] = pic_offset_table_rtx;") +;; With RTL inlining, at -O3, rtl is generated, stored, then actually +;; compiled at the end of compilation. In the meantime, someone can +;; re-encode-section-info on some symbol changing it e.g. from global +;; to local-not-small. If this happens, we'd have emitted a plain +;; load rather than a high+losum load and not recognize the insn. +;; +;; So if rtl inlining is in effect, we delay the global/not-global +;; decision until rest_of_compilation by wrapping it in an UNSPEC_SYMBOL. + +(define_insn_and_split "movdi_er_maybe_g" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] + UNSPEC_SYMBOL))] + "TARGET_EXPLICIT_RELOCS && flag_inline_functions" + "#" + "" + [(set (match_dup 0) (match_dup 1))] +{ + if (local_symbolic_operand (operands[1], Pmode) + && !small_symbolic_operand (operands[1], Pmode)) + { + rtx subtarget = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); + rtx tmp; + + tmp = gen_rtx_HIGH (Pmode, operands[1]); + if (reload_completed) + tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp); + emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp)); + + tmp = gen_rtx_LO_SUM (Pmode, subtarget, operands[1]); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp)); + DONE; + } +}) + (define_insn "*movdi_er_nofix" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q") (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))] -- 2.30.2