mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-12 22:14:18 +08:00
[multiple changes]
2006-05-04 Leehod Baruch <leehod@il.ibm.com> * see.c: New file. * Makefile.in (OBJS-common): Add see.o. (see.o): Add dependencies. * common.opt (fsee): New flag for the see optimization was added. * opts.c (flag_see): Initialized. * passes.c (init_optimization_passes, pass_see): New pass. * rtl.h (see_main): Declaration as extern. * timevar.def (TV_SEE): New. * tree-pass.h (pass_see): Declaration as extern. * invoke.texi (-fsee): Document. * recog.c (validate_simplify_insn): New function. * recog.h (validate_simplify_insn): Declaration as extern. * df-problems.c (df_chain_dump): Check for NULL. 2006-05-04 Kenneth Zadeck <zadeck@naturalbridge.com> Daniel Berlin <dberlin@dberlin.org> * cfgrtl.c (insert_insn_bb_end_new): New function. * basic-block.h (insert_insn_bb_end_new): Declaration as extern. 2006-05-04 Leehod Baruch <leehod.baruch@weizmann.ac.il> * df.h (struct web_entry): Moved from web.c. (union_defs): Declaration as extern. (unionfind_root): Likewise. (unionfind_union): Likewise. * web.c (struct web_entry): Moved to df.h. (unionfind_root): Remove static declaration. (unionfind_union): Likewise. (union_defs): Likewise and generalize to use callback function. (web_main): Update arguments for union_defs function call. From-SVN: r113518
This commit is contained in:
parent
23ba9627f4
commit
8cd37d0b6c
@ -1,3 +1,37 @@
|
||||
2006-05-04 Leehod Baruch <leehod@il.ibm.com>
|
||||
|
||||
* see.c: New file.
|
||||
* Makefile.in (OBJS-common): Add see.o.
|
||||
(see.o): Add dependencies.
|
||||
* common.opt (fsee): New flag for the see optimization was added.
|
||||
* opts.c (flag_see): Initialized.
|
||||
* passes.c (init_optimization_passes, pass_see): New pass.
|
||||
* rtl.h (see_main): Declaration as extern.
|
||||
* timevar.def (TV_SEE): New.
|
||||
* tree-pass.h (pass_see): Declaration as extern.
|
||||
* invoke.texi (-fsee): Document.
|
||||
* recog.c (validate_simplify_insn): New function.
|
||||
* recog.h (validate_simplify_insn): Declaration as extern.
|
||||
* df-problems.c (df_chain_dump): Check for NULL.
|
||||
|
||||
2006-05-04 Kenneth Zadeck <zadeck@naturalbridge.com>
|
||||
Daniel Berlin <dberlin@dberlin.org>
|
||||
|
||||
* cfgrtl.c (insert_insn_bb_end_new): New function.
|
||||
* basic-block.h (insert_insn_bb_end_new): Declaration as extern.
|
||||
|
||||
2006-05-04 Leehod Baruch <leehod.baruch@weizmann.ac.il>
|
||||
|
||||
* df.h (struct web_entry): Moved from web.c.
|
||||
(union_defs): Declaration as extern.
|
||||
(unionfind_root): Likewise.
|
||||
(unionfind_union): Likewise.
|
||||
* web.c (struct web_entry): Moved to df.h.
|
||||
(unionfind_root): Remove static declaration.
|
||||
(unionfind_union): Likewise.
|
||||
(union_defs): Likewise and generalize to use callback function.
|
||||
(web_main): Update arguments for union_defs function call.
|
||||
|
||||
2006-05-04 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/26447
|
||||
|
@ -995,7 +995,7 @@ OBJS-common = \
|
||||
real.o recog.o reg-stack.o regclass.o regmove.o regrename.o \
|
||||
reload.o reload1.o reorg.o resource.o rtl.o rtlanal.o rtl-error.o \
|
||||
sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o \
|
||||
simplify-rtx.o sreal.o stmt.o stor-layout.o stringpool.o \
|
||||
see.o simplify-rtx.o sreal.o stmt.o stor-layout.o stringpool.o \
|
||||
struct-equiv.o targhooks.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
|
||||
varasm.o varray.o vec.o version.o vmsdbgout.o xcoffout.o alloc-pool.o \
|
||||
et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o \
|
||||
@ -2314,6 +2314,9 @@ cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
|
||||
web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h \
|
||||
$(DF_H) $(OBSTACK_H) timevar.h tree-pass.h
|
||||
see.o : see.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) function.h output.h toplev.h \
|
||||
$(DF_H) $(OBSTACK_H) timevar.h tree-pass.h
|
||||
gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
$(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(GGC_H) \
|
||||
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h \
|
||||
|
@ -1001,6 +1001,8 @@ extern basic_block get_bb_original (basic_block);
|
||||
extern void set_bb_copy (basic_block, basic_block);
|
||||
extern basic_block get_bb_copy (basic_block);
|
||||
|
||||
extern rtx insert_insn_end_bb_new (rtx, basic_block);
|
||||
|
||||
#include "cfghooks.h"
|
||||
|
||||
/* In struct-equiv.c */
|
||||
|
88
gcc/cfgrtl.c
88
gcc/cfgrtl.c
@ -2899,6 +2899,93 @@ init_rtl_bb_info (basic_block bb)
|
||||
}
|
||||
|
||||
|
||||
/* Add EXPR to the end of basic block BB. */
|
||||
|
||||
rtx
|
||||
insert_insn_end_bb_new (rtx pat, basic_block bb)
|
||||
{
|
||||
rtx insn = BB_END (bb);
|
||||
rtx new_insn;
|
||||
rtx pat_end = pat;
|
||||
|
||||
while (NEXT_INSN (pat_end) != NULL_RTX)
|
||||
pat_end = NEXT_INSN (pat_end);
|
||||
|
||||
/* If the last insn is a jump, insert EXPR in front [taking care to
|
||||
handle cc0, etc. properly]. Similarly we need to care trapping
|
||||
instructions in presence of non-call exceptions. */
|
||||
|
||||
if (JUMP_P (insn)
|
||||
|| (NONJUMP_INSN_P (insn)
|
||||
&& (!single_succ_p (bb)
|
||||
|| single_succ_edge (bb)->flags & EDGE_ABNORMAL)))
|
||||
{
|
||||
#ifdef HAVE_cc0
|
||||
rtx note;
|
||||
#endif
|
||||
/* If this is a jump table, then we can't insert stuff here. Since
|
||||
we know the previous real insn must be the tablejump, we insert
|
||||
the new instruction just before the tablejump. */
|
||||
if (GET_CODE (PATTERN (insn)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
|
||||
insn = prev_real_insn (insn);
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
/* FIXME: 'twould be nice to call prev_cc0_setter here but it aborts
|
||||
if cc0 isn't set. */
|
||||
note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
|
||||
if (note)
|
||||
insn = XEXP (note, 0);
|
||||
else
|
||||
{
|
||||
rtx maybe_cc0_setter = prev_nonnote_insn (insn);
|
||||
if (maybe_cc0_setter
|
||||
&& INSN_P (maybe_cc0_setter)
|
||||
&& sets_cc0_p (PATTERN (maybe_cc0_setter)))
|
||||
insn = maybe_cc0_setter;
|
||||
}
|
||||
#endif
|
||||
/* FIXME: What if something in cc0/jump uses value set in new
|
||||
insn? */
|
||||
new_insn = emit_insn_before_noloc (pat, insn);
|
||||
}
|
||||
|
||||
/* Likewise if the last insn is a call, as will happen in the presence
|
||||
of exception handling. */
|
||||
else if (CALL_P (insn)
|
||||
&& (!single_succ_p (bb)
|
||||
|| single_succ_edge (bb)->flags & EDGE_ABNORMAL))
|
||||
{
|
||||
/* Keeping in mind SMALL_REGISTER_CLASSES and parameters in registers,
|
||||
we search backward and place the instructions before the first
|
||||
parameter is loaded. Do this for everyone for consistency and a
|
||||
presumption that we'll get better code elsewhere as well. */
|
||||
|
||||
/* Since different machines initialize their parameter registers
|
||||
in different orders, assume nothing. Collect the set of all
|
||||
parameter registers. */
|
||||
insn = find_first_parameter_load (insn, BB_HEAD (bb));
|
||||
|
||||
/* If we found all the parameter loads, then we want to insert
|
||||
before the first parameter load.
|
||||
|
||||
If we did not find all the parameter loads, then we might have
|
||||
stopped on the head of the block, which could be a CODE_LABEL.
|
||||
If we inserted before the CODE_LABEL, then we would be putting
|
||||
the insn in the wrong basic block. In that case, put the insn
|
||||
after the CODE_LABEL. Also, respect NOTE_INSN_BASIC_BLOCK. */
|
||||
while (LABEL_P (insn)
|
||||
|| NOTE_INSN_BASIC_BLOCK_P (insn))
|
||||
insn = NEXT_INSN (insn);
|
||||
|
||||
new_insn = emit_insn_before_noloc (pat, insn);
|
||||
}
|
||||
else
|
||||
new_insn = emit_insn_after_noloc (pat, insn);
|
||||
|
||||
return new_insn;
|
||||
}
|
||||
|
||||
/* Implementation of CFG manipulation for linearized RTL. */
|
||||
struct cfg_hooks rtl_cfg_hooks = {
|
||||
"rtl",
|
||||
@ -2973,4 +3060,3 @@ struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
|
||||
rtl_extract_cond_bb_edges, /* extract_cond_bb_edges */
|
||||
NULL /* flush_pending_stmts */
|
||||
};
|
||||
|
||||
|
@ -809,6 +809,10 @@ frtl-abstract-sequences
|
||||
Common Report Var(flag_rtl_seqabstr)
|
||||
Perform sequence abstraction optimization on RTL
|
||||
|
||||
fsee
|
||||
Common Report Var(flag_see) Init(0)
|
||||
Eliminate redundant sign extensions using LCM.
|
||||
|
||||
fshow-column
|
||||
Common C ObjC C++ ObjC++ Report Var(flag_show_column) Init(1)
|
||||
Show column numbers in diagnostics, when available. Default on
|
||||
|
@ -2992,7 +2992,9 @@ df_chains_dump (struct dataflow *dflow, FILE *file)
|
||||
{
|
||||
fprintf (file, "d%d bb %d luid %d insn %d reg %d ",
|
||||
j, DF_REF_BBNO (def),
|
||||
DF_INSN_LUID (df, DF_REF_INSN (def)),
|
||||
DF_REF_INSN (def) ?
|
||||
DF_INSN_LUID (df, DF_REF_INSN (def)):
|
||||
-1,
|
||||
DF_REF_INSN (def) ? DF_REF_INSN_UID (def) : -1,
|
||||
DF_REF_REGNO (def));
|
||||
if (def->flags & DF_REF_READ_WRITE)
|
||||
|
19
gcc/df.h
19
gcc/df.h
@ -593,4 +593,23 @@ extern void df_hard_reg_init (void);
|
||||
extern bool df_read_modify_subreg_p (rtx);
|
||||
|
||||
|
||||
/* web */
|
||||
|
||||
/* This entry is allocated for each reference in the insn stream. */
|
||||
struct web_entry
|
||||
{
|
||||
/* Pointer to the parent in the union/find tree. */
|
||||
struct web_entry *pred;
|
||||
/* Newly assigned register to the entry. Set only for roots. */
|
||||
rtx reg;
|
||||
void* extra_info;
|
||||
};
|
||||
|
||||
extern struct web_entry *unionfind_root (struct web_entry *);
|
||||
extern bool unionfind_union (struct web_entry *, struct web_entry *);
|
||||
extern void union_defs (struct df *, struct df_ref *,
|
||||
struct web_entry *, struct web_entry *,
|
||||
bool (*fun) (struct web_entry *, struct web_entry *));
|
||||
|
||||
|
||||
#endif /* GCC_DF_H */
|
||||
|
@ -334,7 +334,7 @@ Objective-C and Objective-C++ Dialects}.
|
||||
-fsched-spec-load-dangerous @gol
|
||||
-fsched-stalled-insns=@var{n} -fsched-stalled-insns-dep=@var{n} @gol
|
||||
-fsched2-use-superblocks @gol
|
||||
-fsched2-use-traces -freschedule-modulo-scheduled-loops @gol
|
||||
-fsched2-use-traces -fsee -freschedule-modulo-scheduled-loops @gol
|
||||
-fsection-anchors -fsignaling-nans -fsingle-precision-constant @gol
|
||||
-fstack-protector -fstack-protector-all @gol
|
||||
-fstrict-aliasing -ftracer -fthread-jumps @gol
|
||||
@ -5008,6 +5008,12 @@ match the reality and hurt the performance. This only makes
|
||||
sense when scheduling after register allocation, i.e.@: with
|
||||
@option{-fschedule-insns2} or at @option{-O2} or higher.
|
||||
|
||||
@item -fsee
|
||||
@opindex fsee
|
||||
Eliminates redundant extension instructions and move the non redundant
|
||||
ones to optimal placement using LCM.
|
||||
Enabled at level @option{-O3}.
|
||||
|
||||
@item -freschedule-modulo-scheduled-loops
|
||||
@opindex fscheduling-in-modulo-scheduled-loops
|
||||
The modulo scheduling comes before the traditional scheduling, if a loop was modulo scheduled
|
||||
|
@ -592,6 +592,7 @@ decode_options (unsigned int argc, const char **argv)
|
||||
flag_inline_functions = 1;
|
||||
flag_unswitch_loops = 1;
|
||||
flag_gcse_after_reload = 1;
|
||||
flag_see = 1;
|
||||
}
|
||||
|
||||
if (optimize < 2 || optimize_size)
|
||||
|
@ -652,6 +652,7 @@ init_optimization_passes (void)
|
||||
NEXT_PASS (pass_regmove);
|
||||
NEXT_PASS (pass_split_all_insns);
|
||||
NEXT_PASS (pass_mode_switching);
|
||||
NEXT_PASS (pass_see);
|
||||
NEXT_PASS (pass_recompute_reg_usage);
|
||||
NEXT_PASS (pass_sms);
|
||||
NEXT_PASS (pass_sched);
|
||||
|
40
gcc/recog.c
40
gcc/recog.c
@ -698,6 +698,46 @@ validate_replace_src_group (rtx from, rtx to, rtx insn)
|
||||
d.insn = insn;
|
||||
note_uses (&PATTERN (insn), validate_replace_src_1, &d);
|
||||
}
|
||||
|
||||
/* Try simplify INSN.
|
||||
Invoke simplify_rtx () on every SET_SRC and SET_DEST inside the INSN's
|
||||
pattern and return true if something was simplified. */
|
||||
|
||||
bool
|
||||
validate_simplify_insn (rtx insn)
|
||||
{
|
||||
int i;
|
||||
rtx pat = NULL;
|
||||
rtx newpat = NULL;
|
||||
|
||||
pat = PATTERN (insn);
|
||||
|
||||
if (GET_CODE (pat) == SET)
|
||||
{
|
||||
newpat = simplify_rtx (SET_SRC (pat));
|
||||
if (newpat && !rtx_equal_p (SET_SRC (pat), newpat))
|
||||
validate_change (insn, &SET_SRC (pat), newpat, 1);
|
||||
newpat = simplify_rtx (SET_DEST (pat));
|
||||
if (newpat && !rtx_equal_p (SET_DEST (pat), newpat))
|
||||
validate_change (insn, &SET_DEST (pat), newpat, 1);
|
||||
}
|
||||
else if (GET_CODE (pat) == PARALLEL)
|
||||
for (i = 0; i < XVECLEN (pat, 0); i++)
|
||||
{
|
||||
rtx s = XVECEXP (pat, 0, i);
|
||||
|
||||
if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
|
||||
{
|
||||
newpat = simplify_rtx (SET_SRC (s));
|
||||
if (newpat && !rtx_equal_p (SET_SRC (s), newpat))
|
||||
validate_change (insn, &SET_SRC (s), newpat, 1);
|
||||
newpat = simplify_rtx (SET_DEST (s));
|
||||
if (newpat && !rtx_equal_p (SET_DEST (s), newpat))
|
||||
validate_change (insn, &SET_DEST (s), newpat, 1);
|
||||
}
|
||||
}
|
||||
return ((num_changes_pending () > 0) && (apply_change_group () > 0));
|
||||
}
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
/* Return 1 if the insn using CC0 set by INSN does not contain
|
||||
|
@ -87,6 +87,7 @@ extern int strict_memory_address_p (enum machine_mode, rtx);
|
||||
extern int validate_replace_rtx (rtx, rtx, rtx);
|
||||
extern void validate_replace_rtx_group (rtx, rtx, rtx);
|
||||
extern void validate_replace_src_group (rtx, rtx, rtx);
|
||||
extern bool validate_simplify_insn (rtx insn);
|
||||
extern int num_changes_pending (void);
|
||||
#ifdef HAVE_cc0
|
||||
extern int next_insn_tests_no_inequality (rtx);
|
||||
|
@ -145,6 +145,7 @@ DEFTIMEVAR (TV_VPT , "value profile opts")
|
||||
DEFTIMEVAR (TV_FLOW , "flow analysis")
|
||||
DEFTIMEVAR (TV_COMBINE , "combiner")
|
||||
DEFTIMEVAR (TV_IFCVT , "if-conversion")
|
||||
DEFTIMEVAR (TV_SEE , "see")
|
||||
DEFTIMEVAR (TV_REGMOVE , "regmove")
|
||||
DEFTIMEVAR (TV_MODE_SWITCH , "mode switching")
|
||||
DEFTIMEVAR (TV_SMS , "sms modulo scheduling")
|
||||
|
@ -356,6 +356,7 @@ extern struct tree_opt_pass pass_partition_blocks;
|
||||
extern struct tree_opt_pass pass_regmove;
|
||||
extern struct tree_opt_pass pass_split_all_insns;
|
||||
extern struct tree_opt_pass pass_mode_switching;
|
||||
extern struct tree_opt_pass pass_see;
|
||||
extern struct tree_opt_pass pass_recompute_reg_usage;
|
||||
extern struct tree_opt_pass pass_sms;
|
||||
extern struct tree_opt_pass pass_sched;
|
||||
|
76
gcc/web.c
76
gcc/web.c
@ -61,25 +61,12 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
#include "tree-pass.h"
|
||||
|
||||
|
||||
/* This entry is allocated for each reference in the insn stream. */
|
||||
struct web_entry
|
||||
{
|
||||
/* Pointer to the parent in the union/find tree. */
|
||||
struct web_entry *pred;
|
||||
/* Newly assigned register to the entry. Set only for roots. */
|
||||
rtx reg;
|
||||
};
|
||||
|
||||
static struct web_entry *unionfind_root (struct web_entry *);
|
||||
static void unionfind_union (struct web_entry *, struct web_entry *);
|
||||
static void union_defs (struct df *, struct df_ref *, struct web_entry *,
|
||||
struct web_entry *);
|
||||
static rtx entry_register (struct web_entry *, struct df_ref *, char *);
|
||||
static void replace_ref (struct df_ref *, rtx);
|
||||
|
||||
/* Find the root of unionfind tree (the representative of set). */
|
||||
|
||||
static struct web_entry *
|
||||
struct web_entry *
|
||||
unionfind_root (struct web_entry *element)
|
||||
{
|
||||
struct web_entry *element1 = element, *element2;
|
||||
@ -95,30 +82,48 @@ unionfind_root (struct web_entry *element)
|
||||
return element;
|
||||
}
|
||||
|
||||
/* Union sets. */
|
||||
/* Union sets.
|
||||
Return true if FIRST and SECOND points to the same web entry structure and
|
||||
nothing is done. Otherwise, return false. */
|
||||
|
||||
static void
|
||||
bool
|
||||
unionfind_union (struct web_entry *first, struct web_entry *second)
|
||||
{
|
||||
first = unionfind_root (first);
|
||||
second = unionfind_root (second);
|
||||
if (first == second)
|
||||
return;
|
||||
return true;
|
||||
second->pred = first;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* For each use, all possible defs reaching it must come in the same
|
||||
register, union them. */
|
||||
register, union them.
|
||||
FUN is the function that does the union. */
|
||||
|
||||
static void
|
||||
void
|
||||
union_defs (struct df *df, struct df_ref *use, struct web_entry *def_entry,
|
||||
struct web_entry *use_entry)
|
||||
struct web_entry *use_entry,
|
||||
bool (*fun) (struct web_entry *, struct web_entry *))
|
||||
{
|
||||
rtx insn = DF_REF_INSN (use);
|
||||
struct df_link *link = DF_REF_CHAIN (use);
|
||||
struct df_ref *use_link = DF_INSN_USES (df, insn);
|
||||
struct df_ref *def_link = DF_INSN_DEFS (df, insn);
|
||||
rtx set = single_set (insn);
|
||||
struct df_ref *use_link;
|
||||
struct df_ref *def_link;
|
||||
rtx set;
|
||||
|
||||
if (insn)
|
||||
{
|
||||
use_link = DF_INSN_USES (df, insn);
|
||||
def_link = DF_INSN_DEFS (df, insn);
|
||||
set = single_set (insn);
|
||||
}
|
||||
else
|
||||
{
|
||||
use_link = NULL;
|
||||
def_link = NULL;
|
||||
set = NULL;
|
||||
}
|
||||
|
||||
/* Some instructions may use match_dup for their operands. In case the
|
||||
operands are dead, we will assign them different pseudos, creating
|
||||
@ -129,8 +134,8 @@ union_defs (struct df *df, struct df_ref *use, struct web_entry *def_entry,
|
||||
{
|
||||
if (use != use_link
|
||||
&& DF_REF_REAL_REG (use) == DF_REF_REAL_REG (use_link))
|
||||
unionfind_union (use_entry + DF_REF_ID (use),
|
||||
use_entry + DF_REF_ID (use_link));
|
||||
(*fun) (use_entry + DF_REF_ID (use),
|
||||
use_entry + DF_REF_ID (use_link));
|
||||
use_link = use_link->next_ref;
|
||||
}
|
||||
|
||||
@ -145,15 +150,15 @@ union_defs (struct df *df, struct df_ref *use, struct web_entry *def_entry,
|
||||
while (def_link)
|
||||
{
|
||||
if (DF_REF_REAL_REG (use) == DF_REF_REAL_REG (def_link))
|
||||
unionfind_union (use_entry + DF_REF_ID (use),
|
||||
def_entry + DF_REF_ID (def_link));
|
||||
(*fun) (use_entry + DF_REF_ID (use),
|
||||
def_entry + DF_REF_ID (def_link));
|
||||
def_link = def_link->next_ref;
|
||||
}
|
||||
}
|
||||
while (link)
|
||||
{
|
||||
unionfind_union (use_entry + DF_REF_ID (use),
|
||||
def_entry + DF_REF_ID (link->ref));
|
||||
(*fun) (use_entry + DF_REF_ID (use),
|
||||
def_entry + DF_REF_ID (link->ref));
|
||||
link = link->next;
|
||||
}
|
||||
|
||||
@ -161,13 +166,18 @@ union_defs (struct df *df, struct df_ref *use, struct web_entry *def_entry,
|
||||
register. Find it and union. */
|
||||
if (use->flags & DF_REF_READ_WRITE)
|
||||
{
|
||||
struct df_ref *link = DF_INSN_DEFS (df, DF_REF_INSN (use));
|
||||
struct df_ref *link;
|
||||
|
||||
if (DF_REF_INSN (use))
|
||||
link = DF_INSN_DEFS (df, DF_REF_INSN (use));
|
||||
else
|
||||
link = NULL;
|
||||
|
||||
while (link)
|
||||
{
|
||||
if (DF_REF_REAL_REG (link) == DF_REF_REAL_REG (use))
|
||||
unionfind_union (use_entry + DF_REF_ID (use),
|
||||
def_entry + DF_REF_ID (link));
|
||||
(*fun) (use_entry + DF_REF_ID (use),
|
||||
def_entry + DF_REF_ID (link));
|
||||
link = link->next_ref;
|
||||
}
|
||||
}
|
||||
@ -258,7 +268,7 @@ web_main (void)
|
||||
|
||||
/* Produce the web. */
|
||||
for (i = 0; i < DF_USES_SIZE (df); i++)
|
||||
union_defs (df, DF_USES_GET (df, i), def_entry, use_entry);
|
||||
union_defs (df, DF_USES_GET (df, i), def_entry, use_entry, unionfind_union);
|
||||
|
||||
/* Update the instruction stream, allocating new registers for split pseudos
|
||||
in progress. */
|
||||
|
Loading…
Reference in New Issue
Block a user