aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2017-11-09 16:53:41 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2017-11-09 16:53:41 +0100
commitd7871114286c18b184f5fca2ff1506927f6cc3cf (patch)
treea7d8e9fe00b298f4cc5b16784f33744a0092ef95 /gcc
parent4d99a8487287e94b9bd42807cbe864991a0d1d3b (diff)
downloadgcc-d7871114286c18b184f5fca2ff1506927f6cc3cf.zip
gcc-d7871114286c18b184f5fca2ff1506927f6cc3cf.tar.gz
gcc-d7871114286c18b184f5fca2ff1506927f6cc3cf.tar.bz2
rs6000: Separate shrink-wrapping for the TOC register
This makes the TOC register save a component. If -msave-toc-indirect is not explicitly disabled, it enables it, and then moves the prologue code generated for that to a better place. So far this only matters for indirect calls (for direct calls the save is done in the PLT stub). The restore is always done directly after the bl insn (the compiler generates a nop there, the linker replaces it with a load). * config/rs6000/rs6000.c (machine_function): Add a bool, "toc_is_wrapped_separately". (rs6000_option_override_internal): Enable OPTION_MASK_SAVE_TOC_INDIRECT if it wasn't explicitly set or unset, we are optimizing for speed, and doing separate shrink-wrapping. (rs6000_get_separate_components): Enable the TOC component if saving the TOC register in the prologue. (rs6000_components_for_bb): Handle the TOC component. (rs6000_emit_prologue_components): Store the TOC register where needed. (rs6000_set_handled_components): Mark TOC as handled, if handled. (rs6000_emit_prologue): Don't save the TOC if that is already done. From-SVN: r254599
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/rs6000/rs6000.c33
2 files changed, 46 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2dd56dd..b223f61 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2017-11-09 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.c (machine_function): Add a bool,
+ "toc_is_wrapped_separately".
+ (rs6000_option_override_internal): Enable OPTION_MASK_SAVE_TOC_INDIRECT
+ if it wasn't explicitly set or unset, we are optimizing for speed, and
+ doing separate shrink-wrapping.
+ (rs6000_get_separate_components): Enable the TOC component if
+ saving the TOC register in the prologue.
+ (rs6000_components_for_bb): Handle the TOC component.
+ (rs6000_emit_prologue_components): Store the TOC register where needed.
+ (rs6000_set_handled_components): Mark TOC as handled, if handled.
+ (rs6000_emit_prologue): Don't save the TOC if that is already done.
+
2017-11-09 Martin Jambor <mjambor@suse.cz>
* ipa-param-manipulation.c: New file.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index aacf3f1..2c80a2f 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -171,6 +171,7 @@ typedef struct GTY(()) machine_function
bool gpr_is_wrapped_separately[32];
bool fpr_is_wrapped_separately[32];
bool lr_is_wrapped_separately;
+ bool toc_is_wrapped_separately;
} machine_function;
/* Support targetm.vectorize.builtin_mask_for_load. */
@@ -4426,6 +4427,13 @@ rs6000_option_override_internal (bool global_init_p)
&& ((rs6000_isa_flags_explicit & OPTION_MASK_QUAD_MEMORY_ATOMIC) == 0))
rs6000_isa_flags |= OPTION_MASK_QUAD_MEMORY_ATOMIC;
+ /* If we can shrink-wrap the TOC register save separately, then use
+ -msave-toc-indirect unless explicitly disabled. */
+ if ((rs6000_isa_flags_explicit & OPTION_MASK_SAVE_TOC_INDIRECT) == 0
+ && flag_shrink_wrap_separate
+ && optimize_function_for_speed_p (cfun))
+ rs6000_isa_flags |= OPTION_MASK_SAVE_TOC_INDIRECT;
+
/* Enable power8 fusion if we are tuning for power8, even if we aren't
generating power8 instructions. */
if (!(rs6000_isa_flags_explicit & OPTION_MASK_P8_FUSION))
@@ -26721,6 +26729,7 @@ rs6000_get_separate_components (void)
&& !(info->savres_strategy & REST_MULTIPLE));
/* Component 0 is the save/restore of LR (done via GPR0).
+ Component 2 is the save of the TOC (GPR2).
Components 13..31 are the save/restore of GPR13..GPR31.
Components 46..63 are the save/restore of FPR14..FPR31. */
@@ -26795,6 +26804,10 @@ rs6000_get_separate_components (void)
bitmap_set_bit (components, 0);
}
+ /* Optimize saving the TOC. This is component 2. */
+ if (cfun->machine->save_toc_in_prologue)
+ bitmap_set_bit (components, 2);
+
return components;
}
@@ -26833,6 +26846,12 @@ rs6000_components_for_bb (basic_block bb)
|| bitmap_bit_p (kill, LR_REGNO))
bitmap_set_bit (components, 0);
+ /* The TOC save. */
+ if (bitmap_bit_p (in, TOC_REGNUM)
+ || bitmap_bit_p (gen, TOC_REGNUM)
+ || bitmap_bit_p (kill, TOC_REGNUM))
+ bitmap_set_bit (components, 2);
+
return components;
}
@@ -26887,6 +26906,14 @@ rs6000_emit_prologue_components (sbitmap components)
add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, lr));
}
+ /* Prologue for TOC. */
+ if (bitmap_bit_p (components, 2))
+ {
+ rtx reg = gen_rtx_REG (reg_mode, TOC_REGNUM);
+ rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
+ emit_insn (gen_frame_store (reg, sp_reg, RS6000_TOC_SAVE_SLOT));
+ }
+
/* Prologue for the GPRs. */
int offset = info->gp_save_offset;
if (info->push_p)
@@ -27011,6 +27038,9 @@ rs6000_set_handled_components (sbitmap components)
if (bitmap_bit_p (components, 0))
cfun->machine->lr_is_wrapped_separately = true;
+
+ if (bitmap_bit_p (components, 2))
+ cfun->machine->toc_is_wrapped_separately = true;
}
/* VRSAVE is a bit vector representing which AltiVec registers
@@ -27968,7 +27998,8 @@ rs6000_emit_prologue (void)
unwinder to interpret it. R2 changes, apart from the
calls_eh_return case earlier in this function, are handled by
linux-unwind.h frob_update_context. */
- if (rs6000_save_toc_in_prologue_p ())
+ if (rs6000_save_toc_in_prologue_p ()
+ && !cfun->machine->toc_is_wrapped_separately)
{
rtx reg = gen_rtx_REG (reg_mode, TOC_REGNUM);
emit_insn (gen_frame_store (reg, sp_reg_rtx, RS6000_TOC_SAVE_SLOT));