+2015-01-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/55023
+ PR middle-end/64388
+ * dse.c (struct insn_info): Mention frame_read set also
+ before reload for tail calls on some targets.
+ (scan_insn): Revert 2014-12-22 change. Set frame_read
+ also before reload for tail calls if
+ HARD_FRAME_POINTER_IS_ARG_POINTER. Call add_wild_read
+ instead of add_non_frame_wild_read for non-const/memset
+ tail calls after reload.
+
2015-01-08 Jason Merrill <jason@redhat.com>
* ubsan.c (do_ubsan_in_current_function): New.
either stack pointer or hard frame pointer based. This means
that we have no other choice than also killing all the frame
pointer based stores upon encountering a const function call.
- This field is set after reload for const function calls. Having
- this set is less severe than a wild read, it just means that all
- the frame related stores are killed rather than all the stores. */
+ This field is set after reload for const function calls and before
+ reload for const tail function calls on targets where arg pointer
+ is the frame pointer. Having this set is less severe than a wild
+ read, it just means that all the frame related stores are killed
+ rather than all the stores. */
bool frame_read;
/* This field is only used for the processing of const functions.
insn_info->cannot_delete = true;
- /* Arguments for a sibling call that are pushed to memory are passed
- using the incoming argument pointer of the current function. These
- may or may not be frame related depending on the target. Since
- argument pointer related stores are not currently tracked, we treat
- a sibling call as though it does a wild read. */
- if (SIBLING_CALL_P (insn))
- {
- add_wild_read (bb_info);
- return;
- }
-
/* Const functions cannot do anything bad i.e. read memory,
however, they can read their parameters which may have
been pushed onto the stack.
const_call ? "const" : "memset", INSN_UID (insn));
/* See the head comment of the frame_read field. */
- if (reload_completed)
+ if (reload_completed
+ /* Tail calls are storing their arguments using
+ arg pointer. If it is a frame pointer on the target,
+ even before reload we need to kill frame pointer based
+ stores. */
+ || (SIBLING_CALL_P (insn)
+ && HARD_FRAME_POINTER_IS_ARG_POINTER))
insn_info->frame_read = true;
/* Loop over the active stores and remove those which are
}
}
}
-
+ else if (SIBLING_CALL_P (insn) && reload_completed)
+ /* Arguments for a sibling call that are pushed to memory are passed
+ using the incoming argument pointer of the current function. After
+ reload that might be (and likely is) frame pointer based. */
+ add_wild_read (bb_info);
else
/* Every other call, including pure functions, may read any memory
that is not relative to the frame. */