diff options
author | samuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-04-06 21:22:49 +0000 |
---|---|---|
committer | samuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-04-06 21:22:49 +0000 |
commit | 8a5b87add74ad4a1effac2cecfab19eb0f4fb68b (patch) | |
tree | 03b76aa3f87cb424bd3389a8c22d97e1312c57ac /gcc/flow.c | |
parent | d823001a5b4e39c8551fec25f9d219ca78641a5a (diff) | |
download | gcc-8a5b87add74ad4a1effac2cecfab19eb0f4fb68b.tar.gz |
* rtl.h (INSN_P): New macro.
(successor_phi_fn): New typedef.
(for_each_successor_phi): New prototype.
(in_ssa_form): New variable.
(PHI_NODE_P): Likewise.
* flow.c (calculate_global_regs_live): Add to new_live_at_end from
phi nodes in successors.
(mark_used_regs): Add PHI case.
(set_phi_alternative_reg): New function.
(life_analysis): Assert that dead code elimination is not selected
when in SSA form.
* toplev.c (to_ssa_time): New variable.
(from_ssa_time): Likewise.
(compile_file): Zero to_ssa_time and from_ssa_time.
Print time to convert to and from SSA.
(rest_of_compilation): Time convert_to_ssa and convert_from_ssa.
(print_time): Compute percent fraction as integer.
* ssa.c (PHI_NODE_P): Moved to rtl.h.
(convert_to_ssa): Check if we're already in SSA.
Don't eliminate dead code in life_analysis.
Rerun flow and life analysis at bottom.
(eliminate_phi): Use canonical regnos when adding nodes.
(mark_reg_in_phi): New function.
(mark_phi_and_copy_regs): Likewise.
(convert_from_ssa): Rerun life analysis at top.
Use coalesced partition.
Check for removing a phi node at the end of the block.
(compute_coalesced_reg_partition): New function.
(coalesce_regs_in_copies): Likewise.
(coalesce_reg_in_phi): Likewise.
(coalesce_regs_in_sucessor_phi_nodes): Likewise.
(for_each_successor_phi): Likewise.
(rename_context): New struct.
(rename_block): Use a rename_context with rename_insn_1. When
renaming sets of a subreg, emit a copy of the entire reg first.
(rename_insn_1): Treat data as a rename_context *. Save current
insn in set_data.
(rename_set_data): Add field set_insn.
* Makefile.in (HASHTAB_H): Move up in file.
(OBSTACK_H): New macro.
(collect2.o): Use OBSTACK_H in dependencies.
(sdbout.o): Likewise.
(emit-rtl.o): Likewise.
(simplify-rtx.o): Likewise.
(fix-header.o): Likewise.
(OBJS): Add conflict.o.
(conflict.o): New rule.
* basic-block.h: Include partition.h.
(conflict_graph): New typedef.
(conflict_graph_enum_fn): Likewise.
(conflict_graph_new): New prototype.
(conflict_graph_delete): Likewise.
(conflict_graph_add): Likewise.
(conflict_graph_conflict_p): Likewise.
(conflict_graph_enum): Likewise.
(conflict_graph_merge_regs): Likewise.
(conflict_graph_print): Likewise.
(conflict_graph_compute): Likewise.
* conflict.c: New file.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32979 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/flow.c')
-rw-r--r-- | gcc/flow.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/flow.c b/gcc/flow.c index 32693e41d71..4fd65dca569 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -317,6 +317,7 @@ static void notice_stack_pointer_modification_1 PARAMS ((rtx, rtx, void *)); static void notice_stack_pointer_modification PARAMS ((rtx)); static void mark_reg PARAMS ((rtx, void *)); static void mark_regs_live_at_end PARAMS ((regset)); +static int set_phi_alternative_reg PARAMS ((rtx, int, int, void *)); static void calculate_global_regs_live PARAMS ((sbitmap, sbitmap, int)); static void propagate_block PARAMS ((basic_block, regset, regset, int)); @@ -2486,6 +2487,15 @@ life_analysis (f, nregs, file, remove_dead_code) #endif int flags; sbitmap all_blocks; + + /* Dead code elimination changes basic block structure and therefore + breaks the SSA phi representation. Particularly, a phi node + can have an alternative value for each incoming block, referenced + by the block number. Removing dead code can bump entire blocks + and therefore cause blocks to be renumbered, invalidating the + numbering of phi alternatives. */ + if (remove_dead_code && in_ssa_form) + abort (); /* Record which registers will be eliminated. We use this in mark_used_regs. */ @@ -2960,6 +2970,22 @@ mark_regs_live_at_end (set) diddle_return_value (mark_reg, set); } +/* Callback function for for_each_successor_phi. DATA is a regset. + Sets the SRC_REGNO, the regno of the phi alternative for phi node + INSN, in the regset. */ + +static int +set_phi_alternative_reg (insn, dest_regno, src_regno, data) + rtx insn ATTRIBUTE_UNUSED; + int dest_regno ATTRIBUTE_UNUSED; + int src_regno; + void *data; +{ + regset live = (regset) data; + SET_REGNO_REG_SET (live, src_regno); + return 0; +} + /* Propagate global life info around the graph of basic blocks. Begin considering blocks with their corresponding bit set in BLOCKS_IN. BLOCKS_OUT is set for every block that was changed. */ @@ -3020,6 +3046,13 @@ calculate_global_regs_live (blocks_in, blocks_out, flags) IOR_REG_SET (new_live_at_end, sb->global_live_at_start); } + /* Regs used in phi nodes are not included in + global_live_at_start, since they are live only along a + particular edge. Set those regs that are live because of a + phi node alternative corresponding to this particular block. */ + for_each_successor_phi (bb->index, &set_phi_alternative_reg, + new_live_at_end); + if (bb == ENTRY_BLOCK_PTR) { COPY_REG_SET (bb->global_live_at_end, new_live_at_end); @@ -4688,6 +4721,13 @@ mark_used_regs (needed, live, x, flags, insn) break; } + case PHI: + /* We _do_not_ want to scan operands of phi nodes. Operands of + a phi function are evaluated only when control reaches this + block along a particular edge. Therefore, regs that appear + as arguments to phi should not be added to the global live at + start. */ + return; default: break; |