This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix bogus source locations with optimization
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 28 Mar 2011 11:00:56 +0200
- Subject: [patch] Fix bogus source locations with optimization
Hi,
when optimization is enabled, especially -O2 and above, you can have lines in
the assembly file with really bogus source location info. The scenario is as
follows: an optimization pass at the Tree level (typically PRE) creates a new
statement and inserts it at some place in the dominator tree, creating a new
basic block; this statement is (rightfully) given "unknown" location. When
RTL is being expanded, this statement inherits the current source location,
which is the location of the last statement of the previous basic block. Then
basic block reordering kicks in and the statement is moved to another place,
still carrying the inherited source location down to the assembly file.
The proposed fix is to allow RTL statements to have "unknown" location ("zero"
locator) like Tree statements. They of course will be assigned the current
source location but only in the assembly file, thus becoming sort of silent.
Tested on {i586,x86_64}-suse-linux, OK for the mainline?
2011-03-28 Eric Botcazou <ebotcazou@adacore.com>
* cfgexpand.c (expand_gimple_cond): Always set the source location and
block before expanding the statement.
(expand_gimple_stmt_1): Likewise. Set them here...
(expand_gimple_stmt): ...and not here. Tidy.
* cfglayout.c (curr_insn_locator): Return 0 if the current location is
unknown.
--
Eric Botcazou
Index: cfgexpand.c
===================================================================
--- cfgexpand.c (revision 171572)
+++ cfgexpand.c (working copy)
@@ -1745,11 +1745,8 @@ expand_gimple_cond (basic_block bb, gimp
last2 = last = get_last_insn ();
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
- if (gimple_has_location (stmt))
- {
- set_curr_insn_source_location (gimple_location (stmt));
- set_curr_insn_block (gimple_block (stmt));
- }
+ set_curr_insn_source_location (gimple_location (stmt));
+ set_curr_insn_block (gimple_block (stmt));
/* These flags have no purpose in RTL land. */
true_edge->flags &= ~EDGE_TRUE_VALUE;
@@ -1896,6 +1893,10 @@ static void
expand_gimple_stmt_1 (gimple stmt)
{
tree op0;
+
+ set_curr_insn_source_location (gimple_location (stmt));
+ set_curr_insn_block (gimple_block (stmt));
+
switch (gimple_code (stmt))
{
case GIMPLE_GOTO:
@@ -2052,32 +2053,21 @@ expand_gimple_stmt_1 (gimple stmt)
static rtx
expand_gimple_stmt (gimple stmt)
{
- int lp_nr = 0;
- rtx last = NULL;
location_t saved_location = input_location;
+ rtx last = get_last_insn ();
+ int lp_nr;
- last = get_last_insn ();
-
- /* If this is an expression of some kind and it has an associated line
- number, then emit the line number before expanding the expression.
-
- We need to save and restore the file and line information so that
- errors discovered during expansion are emitted with the right
- information. It would be better of the diagnostic routines
- used the file/line information embedded in the tree nodes rather
- than globals. */
gcc_assert (cfun);
+ /* We need to save and restore the current source location so that errors
+ discovered during expansion are emitted with the right location. But
+ it would be better if the diagnostic routines used the source location
+ embedded in the tree nodes rather than globals. */
if (gimple_has_location (stmt))
- {
- input_location = gimple_location (stmt);
- set_curr_insn_source_location (input_location);
-
- /* Record where the insns produced belong. */
- set_curr_insn_block (gimple_block (stmt));
- }
+ input_location = gimple_location (stmt);
expand_gimple_stmt_1 (stmt);
+
/* Free any temporaries used to evaluate this statement. */
free_temp_slots ();
Index: cfglayout.c
===================================================================
--- cfglayout.c (revision 171572)
+++ cfglayout.c (working copy)
@@ -323,7 +323,7 @@ get_curr_insn_block (void)
int
curr_insn_locator (void)
{
- if (curr_rtl_loc == -1)
+ if (curr_rtl_loc == -1 || curr_location == UNKNOWN_LOCATION)
return 0;
if (last_block != curr_block)
{