Set insn_last_address in final_1

Message ID 87bmes6zt3.fsf@linaro.org
State New
Headers show
Series
  • Set insn_last_address in final_1
Related show

Commit Message

Richard Sandiford April 9, 2018, 5:43 p.m.
final_1 already sets insn_current_address for each instruction, making
it possible to use some of the address functions in final.c during
assembly generation.  This patch also sets insn_last_address, since
as the comment says, we can treat final as a shorten_branches pass that
does nothing.  It's then possible to use insn_current_reference_address
during final as well.

This is needed for the aarch64.md definitions of far_branch to work:

   (set (attr "far_branch")
	(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
			   (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
		      (const_int 0)
		      (const_int 1)))]

This value (tested only during final) uses the difference between
the INSN_ADDRESSES of operand 2 and insn_current_reference_address
to calculate a conservatively-correct estimate of the branch distance.
It takes into account the worst-case gap due to alignment, whereas
a direct comparison of INSN_ADDRESSES would give an unreliable,
optimistic result.

Tested on aarch64-linux-gnu and x86_64-linux-gnu.  Sameera confirms
that it fixes the original bug, but there's no sharable testcase.
OK to install?

Richard


2018-04-09  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* final.c (final_1): Set insn_last_address as well as
	insn_current_address.

Comments

Richard Biener April 10, 2018, 6:49 a.m. | #1
On Mon, Apr 9, 2018 at 7:43 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> final_1 already sets insn_current_address for each instruction, making

> it possible to use some of the address functions in final.c during

> assembly generation.  This patch also sets insn_last_address, since

> as the comment says, we can treat final as a shorten_branches pass that

> does nothing.  It's then possible to use insn_current_reference_address

> during final as well.

>

> This is needed for the aarch64.md definitions of far_branch to work:

>

>    (set (attr "far_branch")

>         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))

>                            (lt (minus (match_dup 2) (pc)) (const_int 1048572)))

>                       (const_int 0)

>                       (const_int 1)))]

>

> This value (tested only during final) uses the difference between

> the INSN_ADDRESSES of operand 2 and insn_current_reference_address

> to calculate a conservatively-correct estimate of the branch distance.

> It takes into account the worst-case gap due to alignment, whereas

> a direct comparison of INSN_ADDRESSES would give an unreliable,

> optimistic result.

>

> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  Sameera confirms

> that it fixes the original bug, but there's no sharable testcase.

> OK to install?


OK.

Richard.

> Richard

>

>

> 2018-04-09  Richard Sandiford  <richard.sandiford@linaro.org>

>

> gcc/

>         * final.c (final_1): Set insn_last_address as well as

>         insn_current_address.

>

> Index: gcc/final.c

> ===================================================================

> --- gcc/final.c 2018-04-09 18:40:26.887628387 +0100

> +++ gcc/final.c 2018-04-09 18:40:27.033624471 +0100

> @@ -2081,6 +2081,9 @@ final_1 (rtx_insn *first, FILE *file, in

>             }

>           else

>             insn_current_address = INSN_ADDRESSES (INSN_UID (insn));

> +         /* final can be seen as an iteration of shorten_branches that

> +            does nothing (since a fixed point has already been reached).  */

> +         insn_last_address = insn_current_address;

>         }

>

>        dump_basic_block_info (file, insn, start_to_bb, end_to_bb,

Patch

Index: gcc/final.c
===================================================================
--- gcc/final.c	2018-04-09 18:40:26.887628387 +0100
+++ gcc/final.c	2018-04-09 18:40:27.033624471 +0100
@@ -2081,6 +2081,9 @@  final_1 (rtx_insn *first, FILE *file, in
 	    }
 	  else
 	    insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
+	  /* final can be seen as an iteration of shorten_branches that
+	     does nothing (since a fixed point has already been reached).  */
+	  insn_last_address = insn_current_address;
 	}
 
       dump_basic_block_info (file, insn, start_to_bb, end_to_bb,