diff options
author | Vladimir N. Makarov <vmakarov@redhat.com> | 2020-11-13 12:45:59 -0500 |
---|---|---|
committer | Vladimir N. Makarov <vmakarov@redhat.com> | 2020-11-13 13:01:51 -0500 |
commit | e3b3b59683c1e7d31a9d313dd97394abebf644be (patch) | |
tree | 34a176a8e704a5a27a214f391da1c5ca041a2462 /gcc/lra.c | |
parent | 67100cb50ea22e1fc855360b887959f874fafe2c (diff) | |
download | gcc-e3b3b59683c1e7d31a9d313dd97394abebf644be.zip gcc-e3b3b59683c1e7d31a9d313dd97394abebf644be.tar.gz gcc-e3b3b59683c1e7d31a9d313dd97394abebf644be.tar.bz2 |
[PATCH] Implementation of asm goto outputs
gcc/
* cfgexpand.c (expand_asm_stmt): Output asm goto with outputs too.
Place insns after asm goto on edges.
* doc/extend.texi: Reflect the changes in asm goto documentation.
* gimple.c (gimple_build_asm_1): Remove an assert checking output
absence for asm goto.
* gimple.h (gimple_asm_label_op, gimple_asm_set_label_op): Take
possible asm goto outputs into account.
* ira.c (ira): Remove critical edges for potential asm goto output
reloads.
(ira_nullify_asm_goto): New function.
* ira.h (ira_nullify_asm_goto): New prototype.
* lra-assigns.c (lra_split_hard_reg_for): Use ira_nullify_asm_goto.
Check that splitting is done inside a basic block.
* lra-constraints.c (curr_insn_transform): Permit output reloads
for any jump insn.
* lra-spills.c (lra_final_code_change): Remove USEs added in ira
for asm gotos.
* lra.c (lra_process_new_insns): Place output reload insns after
jumps in the beginning of destination BBs.
* reload.c (find_reloads): Report error for asm gotos with
outputs. Modify them to keep CFG consistency to avoid crashes.
* tree-into-ssa.c (rewrite_stmt): Don't put debug stmt after asm
goto.
gcc/c/
* c-parser.c (c_parser_asm_statement): Parse outputs for asm
goto too.
* c-typeck.c (build_asm_expr): Remove an assert checking output
absence for asm goto.
gcc/cp
* parser.c (cp_parser_asm_definition): Parse outputs for asm
goto too.
gcc/testsuite/
* c-c++-common/asmgoto-2.c: Permit output in asm goto.
* gcc.c-torture/compile/asmgoto-2.c: New.
* gcc.c-torture/compile/asmgoto-3.c: New.
* gcc.c-torture/compile/asmgoto-4.c: New.
* gcc.c-torture/compile/asmgoto-5.c: New.
Diffstat (limited to 'gcc/lra.c')
-rw-r--r-- | gcc/lra.c | 69 |
1 files changed, 56 insertions, 13 deletions
@@ -1852,8 +1852,6 @@ void lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after, const char *title) { - rtx_insn *last; - if (before == NULL_RTX && after == NULL_RTX) return; if (lra_dump_file != NULL) @@ -1864,12 +1862,6 @@ lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after, fprintf (lra_dump_file," %s before:\n", title); dump_rtl_slim (lra_dump_file, before, NULL, -1, 0); } - if (after != NULL_RTX) - { - fprintf (lra_dump_file, " %s after:\n", title); - dump_rtl_slim (lra_dump_file, after, NULL, -1, 0); - } - fprintf (lra_dump_file, "\n"); } if (before != NULL_RTX) { @@ -1883,12 +1875,63 @@ lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after, { if (cfun->can_throw_non_call_exceptions) copy_reg_eh_region_note_forward (insn, after, NULL); - for (last = after; NEXT_INSN (last) != NULL_RTX; last = NEXT_INSN (last)) - ; - emit_insn_after (after, insn); - push_insns (last, insn); - setup_sp_offset (after, last); + if (! JUMP_P (insn)) + { + rtx_insn *last; + + if (lra_dump_file != NULL) + { + fprintf (lra_dump_file, " %s after:\n", title); + dump_rtl_slim (lra_dump_file, after, NULL, -1, 0); + } + for (last = after; + NEXT_INSN (last) != NULL_RTX; + last = NEXT_INSN (last)) + ; + emit_insn_after (after, insn); + push_insns (last, insn); + setup_sp_offset (after, last); + } + else + { + /* Put output reload insns on successor BBs: */ + edge_iterator ei; + edge e; + + FOR_EACH_EDGE (e, ei, BLOCK_FOR_INSN (insn)->succs) + if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)) + { + /* We already made the edge no-critical in ira.c::ira */ + lra_assert (!EDGE_CRITICAL_P (e)); + rtx_insn *tmp = BB_HEAD (e->dest); + if (LABEL_P (tmp)) + tmp = NEXT_INSN (tmp); + if (NOTE_INSN_BASIC_BLOCK_P (tmp)) + tmp = NEXT_INSN (tmp); + start_sequence (); + for (rtx_insn *curr = after; + curr != NULL_RTX; + curr = NEXT_INSN (curr)) + emit_insn (copy_insn (PATTERN (curr))); + rtx_insn *copy = get_insns (), *last = get_last_insn (); + end_sequence (); + if (lra_dump_file != NULL) + { + fprintf (lra_dump_file, " %s after in bb%d:\n", title, + e->dest->index); + dump_rtl_slim (lra_dump_file, copy, NULL, -1, 0); + } + emit_insn_before (copy, tmp); + push_insns (last, PREV_INSN (copy)); + setup_sp_offset (copy, last); + /* We can ignore BB live info here as it and reg notes + will be updated before the next assignment + sub-pass. */ + } + } } + if (lra_dump_file != NULL) + fprintf (lra_dump_file, "\n"); if (cfun->can_throw_non_call_exceptions) { rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); |