canonicalize_insn attempts to replace pseudo-registers with the canonical ones
during the CSE pass and it does so inside ASM_OPERANDS (only for the inputs)
and inside PARALLELs, but not inside ASM_OPERANDS which are themselves inside
a PARALLEL. The latter case occurs for targets that automatically clobber the
CC register for inline assembly statements, for example Visium and x86.
Tested on x86_64-suse-linux, applied on the mainline.
2016-06-21 Eric Botcazou <ebotca...@adacore.com>
* cse.c (canon_asm_operands): New function extracted from...
(canonicalize_insn): ...here. Call it to canonicalize an ASM_OPERANDS
either standalone or member of a PARALLEL.
--
Eric Botcazou
Index: cse.c
===================================================================
--- cse.c (revision 237571)
+++ cse.c (working copy)
@@ -4298,6 +4298,22 @@ find_sets_in_insn (rtx_insn *insn, struc
return n_sets;
}
+/* Subroutine of canonicalize_insn. X is an ASM_OPERANDS in INSN. */
+
+static void
+canon_asm_operands (rtx x, rtx_insn *insn)
+{
+ for (int i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
+ {
+ rtx input = ASM_OPERANDS_INPUT (x, i);
+ if (!(REG_P (input) && HARD_REGISTER_P (input)))
+ {
+ input = canon_reg (input, insn);
+ validate_change (insn, &ASM_OPERANDS_INPUT (x, i), input, 1);
+ }
+ }
+}
+
/* Where possible, substitute every register reference in the N_SETS
number of SETS in INSN with the canonical register.
@@ -4361,17 +4377,7 @@ canonicalize_insn (rtx_insn *insn, struc
/* Canonicalize a USE of a pseudo register or memory location. */
canon_reg (x, insn);
else if (GET_CODE (x) == ASM_OPERANDS)
- {
- for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
- {
- rtx input = ASM_OPERANDS_INPUT (x, i);
- if (!(REG_P (input) && REGNO (input) < FIRST_PSEUDO_REGISTER))
- {
- input = canon_reg (input, insn);
- validate_change (insn, &ASM_OPERANDS_INPUT (x, i), input, 1);
- }
- }
- }
+ canon_asm_operands (x, insn);
else if (GET_CODE (x) == CALL)
{
canon_reg (x, insn);
@@ -4400,6 +4406,8 @@ canonicalize_insn (rtx_insn *insn, struc
&& ! (REG_P (XEXP (y, 0))
&& REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER))
canon_reg (y, insn);
+ else if (GET_CODE (y) == ASM_OPERANDS)
+ canon_asm_operands (y, insn);
else if (GET_CODE (y) == CALL)
{
canon_reg (y, insn);