+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.
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. */
&& ((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))
&& !(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. */
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;
}
|| 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;
}
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)
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
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));