@@ -1941,7 +1941,7 @@ make_pass_stv (gcc::context *ctxt)
static void
rest_of_insert_endbr_and_patchable_area (bool need_endbr,
- bool need_patchable_area)
+ unsigned int patchable_area_size)
{
rtx endbr;
rtx_insn *insn;
@@ -1980,7 +1980,7 @@ rest_of_insert_endbr_and_patchable_area (bool need_endbr,
}
}
- if (need_patchable_area)
+ if (patchable_area_size)
{
if (crtl->profile && flag_fentry)
{
@@ -1992,10 +1992,9 @@ rest_of_insert_endbr_and_patchable_area (bool need_endbr,
}
else
{
- /* ix86_print_patchable_function_entry will provide actual
- size. */
- rtx patchable_area = gen_patchable_area (GEN_INT (0),
- GEN_INT (0));
+ rtx patchable_area
+ = gen_patchable_area (GEN_INT (patchable_area_size),
+ GEN_INT (cfun->patch_area_entry == 0));
if (endbr_insn)
emit_insn_after (patchable_area, endbr_insn);
else
@@ -2123,25 +2122,22 @@ public:
virtual bool gate (function *fun)
{
need_endbr = (flag_cf_protection & CF_BRANCH) != 0;
- need_patchable_area
- = (function_entry_patch_area_size
- || lookup_attribute ("patchable_function_entry",
- DECL_ATTRIBUTES (fun->decl)));
- return need_endbr || need_patchable_area;
+ patchable_area_size = fun->patch_area_size - fun->patch_area_entry;
+ return need_endbr || patchable_area_size;
}
virtual unsigned int execute (function *)
{
timevar_push (TV_MACH_DEP);
rest_of_insert_endbr_and_patchable_area (need_endbr,
- need_patchable_area);
+ patchable_area_size);
timevar_pop (TV_MACH_DEP);
return 0;
}
private:
bool need_endbr;
- bool need_patchable_area;
+ unsigned int patchable_area_size;
}; // class pass_insert_endbr_and_patchable_area
} // anon namespace
@@ -9130,53 +9130,11 @@ ix86_print_patchable_function_entry (FILE *file,
{
if (cfun->machine->function_label_emitted)
{
- /* The insert_endbr_and_patchable_area pass inserted a dummy
- UNSPECV_PATCHABLE_AREA with 0 patchable area size. If the
- patchable area is placed after the function label, we replace
- 0 patchable area size with the real one. Otherwise, the
- dummy UNSPECV_PATCHABLE_AREA will be ignored. */
- if (cfun->machine->insn_queued_at_entrance)
- {
- /* Record the patchable area. Both ENDBR and patchable area
- will be inserted by x86_function_profiler later. */
- cfun->machine->patch_area_size = patch_area_size;
- cfun->machine->record_patch_area = record_p;
- return;
- }
-
- /* We can have
-
- UNSPECV_NOP_ENDBR
- UNSPECV_PATCHABLE_AREA
-
- or just
-
- UNSPECV_PATCHABLE_AREA
- */
- rtx_insn *patchable_insn;
- rtx_insn *insn = next_real_nondebug_insn (get_insns ());
- if (insn
- && INSN_P (insn)
- && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
- && XINT (PATTERN (insn), 1) == UNSPECV_NOP_ENDBR)
- patchable_insn = next_real_nondebug_insn (insn);
- else
- patchable_insn = insn;
-
- if (patchable_insn && INSN_P (patchable_insn))
- {
- /* Replace the dummy patchable area size with the real one. */
- rtx pattern = PATTERN (patchable_insn);
- if (GET_CODE (pattern) == UNSPEC_VOLATILE
- && XINT (pattern, 1) == UNSPECV_PATCHABLE_AREA)
- {
- XVECEXP (pattern, 0, 0) = GEN_INT (patch_area_size);
- XVECEXP (pattern, 0, 1) = GEN_INT (record_p);
- }
- return;
- }
-
- gcc_unreachable ();
+ /* NB: When ix86_print_patchable_function_entry is called after
+ function table has been emitted, we have inserted or queued
+ a pseudo UNSPECV_PATCHABLE_AREA instruction at the proper
+ place. There is nothing to do here. */
+ return;
}
default_print_patchable_function_entry (file, patch_area_size,
@@ -20232,9 +20190,11 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
{
if (cfun->machine->insn_queued_at_entrance == TYPE_ENDBR)
fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
- if (cfun->machine->patch_area_size)
- ix86_output_patchable_area (cfun->machine->patch_area_size,
- cfun->machine->record_patch_area);
+ unsigned int patch_area_size
+ = cfun->patch_area_size - cfun->patch_area_entry;
+ if (patch_area_size)
+ ix86_output_patchable_area (patch_area_size,
+ cfun->patch_area_entry == 0);
}
const char *mcount_name = MCOUNT_NAME;
@@ -2774,12 +2774,6 @@ struct GTY(()) machine_function {
structure. */
rtx split_stack_varargs_pointer;
- /* The size of the patchable area at function entry. */
- unsigned int patch_area_size;
-
- /* If true, record patchable area at function entry. */
- BOOL_BITFIELD record_patch_area : 1;
-
/* This value is used for amd64 targets and specifies the current abi
to be used. MS_ABI means ms abi. Otherwise SYSV_ABI means sysv abi. */
ENUM_BITFIELD(calling_abi) call_abi : 8;
@@ -21289,11 +21289,13 @@ (define_insn "patchable_area"
UNSPECV_PATCHABLE_AREA)]
""
{
- if (INTVAL (operands[0]))
- ix86_output_patchable_area (INTVAL (operands[0]),
- INTVAL (operands[1]) != 0);
+ ix86_output_patchable_area (INTVAL (operands[0]),
+ INTVAL (operands[1]) != 0);
return "";
-})
+}
+ [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
+ (set_attr "length_immediate" "0")
+ (set_attr "modrm" "0")])
(include "mmx.md")
(include "sse.md")