summaryrefslogtreecommitdiff
path: root/gcc/flow.c
diff options
context:
space:
mode:
authorsamuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-04-06 21:22:49 +0000
committersamuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-04-06 21:22:49 +0000
commit8a5b87add74ad4a1effac2cecfab19eb0f4fb68b (patch)
tree03b76aa3f87cb424bd3389a8c22d97e1312c57ac /gcc/flow.c
parentd823001a5b4e39c8551fec25f9d219ca78641a5a (diff)
downloadgcc-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.c40
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;