Commit ba49cb7b by Kenneth Zadeck Committed by Kenneth Zadeck

ra-conflict.c: New file.

2007-09-02  Kenneth Zadeck <zadeck@naturalbridge.com>

	* ra-conflict.c: New file.
	* ra.h: New file.
	* reload.c (push_reload, find_dummy_reload): Change DF_RA_LIVE
	usage to DF_LIVE usage.
	* rtlanal.c (subreg_nregs_with_regno): New function.  
	* df-scan.c (df_def_record_1, df_uses_record): Add code to set
	DF_REF_EXTRACT, DF_REF_STRICT_LOWER_PART, and DF_REF_SUBREG flags.
	(df_has_eh_preds): Removed.
	(df_bb_refs_collect, df_bb_refs_collect, df_bb_refs_collect,
	df_exit_block_uses_collect): Changed call from df_has_eh_preds to
	bb_has_eh_pred.
	* global.c (allocno, max_allocno, conflicts, allocno_row_words,
	reg_allocno, EXECUTE_IF_SET_IN_ALLOCNO_SET): Moved to ra.h
	(SET_ALLOCNO_LIVE, CLEAR_ALLOCNO_LIVE): Moved to ra-conflicts.c.
	(regs_set, record_one_conflict, record_conflicts, mark_reg_store,
	mark_reg_clobber, mark_reg_conflicts, mark_reg_death): Deleted.
	(global_alloc): Turn off rescanning insns after call to
	global_conflicts and added call to set_preferences.
	(global_conflicts): Moved to ra-alloc.c.
	(set_preferences_1, set_preferences): New function.
	(mirror_conflicts): Changed types for various variables.
	(mark_elimination): Change DF_RA_LIVE
	usage to DF_LIVE usage.
	(build_insn_chain): Rewritten from scratch and made local.
	(print_insn_chain, print_insn_chains): New functions.
	(dump_conflicts): Do not print conflicts for fixed_regs.
	(rest_of_handle_global_alloc): Turn off insn rescanning.
	* hard-reg-set.h: Fixed comment.
	* local-alloc.c (update_equiv_regs): Change DF_RA_LIVE
	usage to DF_LIVE usage and delete refs to TOP sets.
	(block_alloc): Mark regs as live if they are in the artificial
	defs at top of block.
	(find_stack_regs): New function.
	(rest_of_handle_local_alloc): Changed urec problem to live
	problem and do not turn off df rescanning.
	* df.h (DF_UREC, DF_UREC_BB_INFO, DF_LIVE_TOP, DF_RA_LIVE_IN,
	DF_RA_LIVE_TOP, DF_RA_LIVE_OUT, df_urec_bb_info, df_urec,
	df_urec_add_problem, df_urec_get_bb_info, df_has_eh_preds): Removed.
	(DF_CHAIN, DF_NOTE, DF_CHAIN): Renumbered.
	(DF_REF_EXTRACT, DF_REF_STRICT_LOWER_PART, DF_REF_SUBREG): New
	fields in df_ref_flags.  The rest have been renumbered.  
	* init-regs.c (initialize_uninitialized_regs): Enhanced debugging
	at -O1.
	* rtl.h (subreg_nregs_with_regno): New function.
	* df-problems.c: (df_get_live_out, df_get_live_in,
	df_get_live_top): Removed reference to DF_RA_LIVE.
	(df_lr_reset, df_lr_transfer_function, df_live_free_bb_info,
	df_live_alloc, df_live_reset, df_live_local_finalize,
	df_live_free): Make top set only if different from in set.
	(df_lr_top_dump, df_live_top_dump): Only print top set if
	different from in set.
	(df_lr_bb_local_compute): Removed unnecessary check.
	(df_urec_problem_data, df_urec_set_bb_info, df_urec_free_bb_info, 
	df_urec_alloc, df_urec_mark_reg_change, earlyclobber_regclass, 
	df_urec_check_earlyclobber, df_urec_mark_reg_use_for_earlyclobber,
	df_urec_mark_reg_use_for_earlyclobber_1, df_urec_bb_local_compute,
	df_urec_local_compute, df_urec_init, df_urec_local_finalize, 
	df_urec_confluence_n, df_urec_transfer_function, df_urec_free, 
	df_urec_top_dump, df_urec_bottom_dump, problem_UREC,
	df_urec_add_problem): Removed.
	(df_simulate_fixup_sets): Changed call from df_has_eh_preds to
	bb_has_eh_pred. 
	* Makefile.in (ra-conflict.o, ra.h): New dependencies.
	* basic_block.h (bb_has_abnormal_pred): New function.
	* reload1.c (compute_use_by_pseudos): Change DF_RA_LIVE
	usage to DF_LIVE usage.

From-SVN: r128957
parent 746025f4
2007-09-02 Kenneth Zadeck <zadeck@naturalbridge.com>
* ra-conflict.c: New file.
* ra.h: New file.
* reload.c (push_reload, find_dummy_reload): Change DF_RA_LIVE
usage to DF_LIVE usage.
* rtlanal.c (subreg_nregs_with_regno): New function.
* df-scan.c (df_def_record_1, df_uses_record): Add code to set
DF_REF_EXTRACT, DF_REF_STRICT_LOWER_PART, and DF_REF_SUBREG flags.
(df_has_eh_preds): Removed.
(df_bb_refs_collect, df_bb_refs_collect, df_bb_refs_collect,
df_exit_block_uses_collect): Changed call from df_has_eh_preds to
bb_has_eh_pred.
* global.c (allocno, max_allocno, conflicts, allocno_row_words,
reg_allocno, EXECUTE_IF_SET_IN_ALLOCNO_SET): Moved to ra.h
(SET_ALLOCNO_LIVE, CLEAR_ALLOCNO_LIVE): Moved to ra-conflicts.c.
(regs_set, record_one_conflict, record_conflicts, mark_reg_store,
mark_reg_clobber, mark_reg_conflicts, mark_reg_death): Deleted.
(global_alloc): Turn off rescanning insns after call to
global_conflicts and added call to set_preferences.
(global_conflicts): Moved to ra-alloc.c.
(set_preferences_1, set_preferences): New function.
(mirror_conflicts): Changed types for various variables.
(mark_elimination): Change DF_RA_LIVE
usage to DF_LIVE usage.
(build_insn_chain): Rewritten from scratch and made local.
(print_insn_chain, print_insn_chains): New functions.
(dump_conflicts): Do not print conflicts for fixed_regs.
(rest_of_handle_global_alloc): Turn off insn rescanning.
* hard-reg-set.h: Fixed comment.
* local-alloc.c (update_equiv_regs): Change DF_RA_LIVE
usage to DF_LIVE usage and delete refs to TOP sets.
(block_alloc): Mark regs as live if they are in the artificial
defs at top of block.
(find_stack_regs): New function.
(rest_of_handle_local_alloc): Changed urec problem to live
problem and do not turn off df rescanning.
* df.h (DF_UREC, DF_UREC_BB_INFO, DF_LIVE_TOP, DF_RA_LIVE_IN,
DF_RA_LIVE_TOP, DF_RA_LIVE_OUT, df_urec_bb_info, df_urec,
df_urec_add_problem, df_urec_get_bb_info, df_has_eh_preds): Removed.
(DF_CHAIN, DF_NOTE, DF_CHAIN): Renumbered.
(DF_REF_EXTRACT, DF_REF_STRICT_LOWER_PART, DF_REF_SUBREG): New
fields in df_ref_flags. The rest have been renumbered.
* init-regs.c (initialize_uninitialized_regs): Enhanced debugging
at -O1.
* rtl.h (subreg_nregs_with_regno): New function.
* df-problems.c: (df_get_live_out, df_get_live_in,
df_get_live_top): Removed reference to DF_RA_LIVE.
(df_lr_reset, df_lr_transfer_function, df_live_free_bb_info,
df_live_alloc, df_live_reset, df_live_local_finalize,
df_live_free): Make top set only if different from in set.
(df_lr_top_dump, df_live_top_dump): Only print top set if
different from in set.
(df_lr_bb_local_compute): Removed unnecessary check.
(df_urec_problem_data, df_urec_set_bb_info, df_urec_free_bb_info,
df_urec_alloc, df_urec_mark_reg_change, earlyclobber_regclass,
df_urec_check_earlyclobber, df_urec_mark_reg_use_for_earlyclobber,
df_urec_mark_reg_use_for_earlyclobber_1, df_urec_bb_local_compute,
df_urec_local_compute, df_urec_init, df_urec_local_finalize,
df_urec_confluence_n, df_urec_transfer_function, df_urec_free,
df_urec_top_dump, df_urec_bottom_dump, problem_UREC,
df_urec_add_problem): Removed.
(df_simulate_fixup_sets): Changed call from df_has_eh_preds to
bb_has_eh_pred.
* Makefile.in (ra-conflict.o, ra.h): New dependencies.
* basic_block.h (bb_has_abnormal_pred): New function.
* reload1.c (compute_use_by_pseudos): Change DF_RA_LIVE
usage to DF_LIVE usage.
2007-10-02 Revital Eres <eres@il.ibm.com> 2007-10-02 Revital Eres <eres@il.ibm.com>
* config/rs6000/predicates.md (easy_vector_constant): Return false * config/rs6000/predicates.md (easy_vector_constant): Return false
...@@ -791,6 +791,7 @@ FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H) ...@@ -791,6 +791,7 @@ FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H)
EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) $(MACHMODE_H) $(EMIT_RTL_H) EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) $(MACHMODE_H) $(EMIT_RTL_H)
OPTABS_H = optabs.h insn-codes.h OPTABS_H = optabs.h insn-codes.h
REGS_H = regs.h varray.h $(MACHMODE_H) $(OBSTACK_H) $(BASIC_BLOCK_H) $(FUNCTION_H) REGS_H = regs.h varray.h $(MACHMODE_H) $(OBSTACK_H) $(BASIC_BLOCK_H) $(FUNCTION_H)
RA_H = ra.h $(REGS_H)
RESOURCE_H = resource.h hard-reg-set.h RESOURCE_H = resource.h hard-reg-set.h
SCHED_INT_H = sched-int.h $(INSN_ATTR_H) $(BASIC_BLOCK_H) $(RTL_H) $(DF_H) SCHED_INT_H = sched-int.h $(INSN_ATTR_H) $(BASIC_BLOCK_H) $(RTL_H) $(DF_H)
INTEGRATE_H = integrate.h $(VARRAY_H) INTEGRATE_H = integrate.h $(VARRAY_H)
...@@ -1100,6 +1101,7 @@ OBJS-common = \ ...@@ -1100,6 +1101,7 @@ OBJS-common = \
print-rtl.o \ print-rtl.o \
print-tree.o \ print-tree.o \
profile.o \ profile.o \
ra-conflict.o \
real.o \ real.o \
recog.o \ recog.o \
reg-stack.o \ reg-stack.o \
...@@ -2702,7 +2704,11 @@ bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ ...@@ -2702,7 +2704,11 @@ bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) reload.h $(FUNCTION_H) $(RECOG_H) $(REGS_H) hard-reg-set.h \ $(FLAGS_H) reload.h $(FUNCTION_H) $(RECOG_H) $(REGS_H) hard-reg-set.h \
insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H) tree-pass.h \ insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H) tree-pass.h \
$(TIMEVAR_H) vecprim.h $(DF_H) $(TIMEVAR_H) vecprim.h $(DF_H) $(DBGCNT_H) $(RA_H)
ra-conflict.o : ra-conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) reload.h $(FUNCTION_H) $(RECOG_H) $(REGS_H) hard-reg-set.h \
insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H) tree-pass.h \
$(TIMEVAR_H) vecprim.h $(DF_H) $(RA_H) sbitmap.h
varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \ varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
$(HASHTAB_H) $(BCONFIG_H) $(VARRAY_H) toplev.h $(HASHTAB_H) $(BCONFIG_H) $(VARRAY_H) toplev.h
vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h vec.h $(GGC_H) \ vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h vec.h $(GGC_H) \
......
...@@ -1135,6 +1135,21 @@ bb_has_eh_pred (basic_block bb) ...@@ -1135,6 +1135,21 @@ bb_has_eh_pred (basic_block bb)
return false; return false;
} }
/* Return true when one of the predecessor edges of BB is marked with EDGE_ABNORMAL. */
static inline bool
bb_has_abnormal_pred (basic_block bb)
{
edge e;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, bb->preds)
{
if (e->flags & EDGE_ABNORMAL)
return true;
}
return false;
}
/* In cfgloopmanip.c. */ /* In cfgloopmanip.c. */
extern edge mfb_kj_edge; extern edge mfb_kj_edge;
bool mfb_keep_just (edge); bool mfb_keep_just (edge);
......
...@@ -573,8 +573,8 @@ dce_process_block (basic_block bb, bool redo_out) ...@@ -573,8 +573,8 @@ dce_process_block (basic_block bb, bool redo_out)
/* These regs are considered always live so if they end up dying /* These regs are considered always live so if they end up dying
because of some def, we need to bring the back again. because of some def, we need to bring the back again.
Calling df_simulate_fixup_sets has the disadvantage of calling Calling df_simulate_fixup_sets has the disadvantage of calling
df_has_eh_preds once per insn, so we cache the information here. */ bb_has_eh_pred once per insn, so we cache the information here. */
if (df_has_eh_preds (bb)) if (bb_has_eh_pred (bb))
au = df->eh_block_artificial_uses; au = df->eh_block_artificial_uses;
else else
au = df->regular_block_artificial_uses; au = df->regular_block_artificial_uses;
......
...@@ -2752,23 +2752,37 @@ df_def_record_1 (struct df_collection_rec *collection_rec, ...@@ -2752,23 +2752,37 @@ df_def_record_1 (struct df_collection_rec *collection_rec,
|| GET_CODE (dst) == ZERO_EXTRACT) || GET_CODE (dst) == ZERO_EXTRACT)
{ {
flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL; flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL;
if (GET_CODE (dst) == ZERO_EXTRACT)
flags |= DF_REF_EXTRACT;
else
flags |= DF_REF_STRICT_LOWER_PART;
loc = &XEXP (dst, 0); loc = &XEXP (dst, 0);
dst = *loc; dst = *loc;
} }
if (df_read_modify_subreg_p (dst)) /* At this point if we do not have a reg or a subreg, just return. */
flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL; if (REG_P (dst))
{
df_ref_record (collection_rec,
dst, loc, bb, insn, DF_REF_REG_DEF, flags);
if (REG_P (dst) /* We want to keep sp alive everywhere - by making all
|| (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst)))) writes to sp also use of sp. */
df_ref_record (collection_rec, if (REGNO (dst) == STACK_POINTER_REGNUM)
dst, loc, bb, insn, DF_REF_REG_DEF, flags); df_ref_record (collection_rec,
dst, NULL, bb, insn, DF_REF_REG_USE, flags);
}
else if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst)))
{
if (df_read_modify_subreg_p (dst))
flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL;
/* We want to keep sp alive everywhere - by making all flags |= DF_REF_SUBREG;
writes to sp also use of sp. */
if (REG_P (dst) && REGNO (dst) == STACK_POINTER_REGNUM) df_ref_record (collection_rec,
df_ref_record (collection_rec, dst, loc, bb, insn, DF_REF_REG_DEF, flags);
dst, NULL, bb, insn, DF_REF_REG_USE, flags); }
} }
...@@ -2880,7 +2894,8 @@ df_uses_record (struct df_collection_rec *collection_rec, ...@@ -2880,7 +2894,8 @@ df_uses_record (struct df_collection_rec *collection_rec,
if (df_read_modify_subreg_p (dst)) if (df_read_modify_subreg_p (dst))
{ {
df_uses_record (collection_rec, &SUBREG_REG (dst), df_uses_record (collection_rec, &SUBREG_REG (dst),
DF_REF_REG_USE, bb, insn, flags | DF_REF_READ_WRITE); DF_REF_REG_USE, bb, insn,
flags | DF_REF_READ_WRITE | DF_REF_SUBREG);
break; break;
} }
/* Fall through. */ /* Fall through. */
...@@ -2902,13 +2917,15 @@ df_uses_record (struct df_collection_rec *collection_rec, ...@@ -2902,13 +2917,15 @@ df_uses_record (struct df_collection_rec *collection_rec,
dst = XEXP (dst, 0); dst = XEXP (dst, 0);
df_uses_record (collection_rec, df_uses_record (collection_rec,
(GET_CODE (dst) == SUBREG) ? &SUBREG_REG (dst) : temp, (GET_CODE (dst) == SUBREG) ? &SUBREG_REG (dst) : temp,
DF_REF_REG_USE, bb, insn, DF_REF_READ_WRITE); DF_REF_REG_USE, bb, insn,
DF_REF_READ_WRITE | DF_REF_STRICT_LOWER_PART);
} }
break; break;
case ZERO_EXTRACT: case ZERO_EXTRACT:
case SIGN_EXTRACT: case SIGN_EXTRACT:
df_uses_record (collection_rec, &XEXP (dst, 0), df_uses_record (collection_rec, &XEXP (dst, 0),
DF_REF_REG_USE, bb, insn, DF_REF_READ_WRITE); DF_REF_REG_USE, bb, insn,
DF_REF_READ_WRITE | DF_REF_EXTRACT);
df_uses_record (collection_rec, &XEXP (dst, 1), df_uses_record (collection_rec, &XEXP (dst, 1),
DF_REF_REG_USE, bb, insn, flags); DF_REF_REG_USE, bb, insn, flags);
df_uses_record (collection_rec, &XEXP (dst, 2), df_uses_record (collection_rec, &XEXP (dst, 2),
...@@ -3180,23 +3197,6 @@ df_insn_refs_collect (struct df_collection_rec* collection_rec, ...@@ -3180,23 +3197,6 @@ df_insn_refs_collect (struct df_collection_rec* collection_rec,
df_canonize_collection_rec (collection_rec); df_canonize_collection_rec (collection_rec);
} }
/* Return true if any pred of BB is an eh. */
bool
df_has_eh_preds (basic_block bb)
{
edge e;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, bb->preds)
{
if (e->flags & EDGE_EH)
return true;
}
return false;
}
/* Recompute the luids for the insns in BB. */ /* Recompute the luids for the insns in BB. */
void void
...@@ -3261,7 +3261,7 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb) ...@@ -3261,7 +3261,7 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
} }
#ifdef EH_RETURN_DATA_REGNO #ifdef EH_RETURN_DATA_REGNO
if (df_has_eh_preds (bb)) if (bb_has_eh_pred (bb))
{ {
unsigned int i; unsigned int i;
/* Mark the registers that will contain data for the handler. */ /* Mark the registers that will contain data for the handler. */
...@@ -3278,7 +3278,7 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb) ...@@ -3278,7 +3278,7 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
#ifdef EH_USES #ifdef EH_USES
if (df_has_eh_preds (bb)) if (bb_has_eh_pred (bb))
{ {
unsigned int i; unsigned int i;
/* This code is putting in an artificial ref for the use at the /* This code is putting in an artificial ref for the use at the
...@@ -3310,7 +3310,7 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb) ...@@ -3310,7 +3310,7 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
{ {
bitmap_iterator bi; bitmap_iterator bi;
unsigned int regno; unsigned int regno;
bitmap au = df_has_eh_preds (bb) bitmap au = bb_has_eh_pred (bb)
? df->eh_block_artificial_uses ? df->eh_block_artificial_uses
: df->regular_block_artificial_uses; : df->regular_block_artificial_uses;
...@@ -3481,8 +3481,6 @@ df_mark_reg (rtx reg, void *vset) ...@@ -3481,8 +3481,6 @@ df_mark_reg (rtx reg, void *vset)
} }
/* Set the bit for regs that are considered being defined at the entry. */ /* Set the bit for regs that are considered being defined at the entry. */
static void static void
...@@ -3780,7 +3778,7 @@ df_exit_block_uses_collect (struct df_collection_rec *collection_rec, bitmap exi ...@@ -3780,7 +3778,7 @@ df_exit_block_uses_collect (struct df_collection_rec *collection_rec, bitmap exi
I do not know why. */ I do not know why. */
if (reload_completed if (reload_completed
&& !bitmap_bit_p (exit_block_uses, ARG_POINTER_REGNUM) && !bitmap_bit_p (exit_block_uses, ARG_POINTER_REGNUM)
&& df_has_eh_preds (EXIT_BLOCK_PTR) && bb_has_eh_pred (EXIT_BLOCK_PTR)
&& fixed_regs[ARG_POINTER_REGNUM]) && fixed_regs[ARG_POINTER_REGNUM])
df_ref_record (collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL, df_ref_record (collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL,
EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0); EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0);
......
...@@ -380,7 +380,7 @@ hard_reg_set_empty_p (const HARD_REG_SET x) ...@@ -380,7 +380,7 @@ hard_reg_set_empty_p (const HARD_REG_SET x)
return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0; return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0;
} }
#else /* FIRST_PSEUDO_REGISTER > 3*HOST_BITS_PER_WIDEST_FAST_INT */ #else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */
#define CLEAR_HARD_REG_SET(TO) \ #define CLEAR_HARD_REG_SET(TO) \
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
......
...@@ -117,7 +117,11 @@ initialize_uninitialized_regs (void) ...@@ -117,7 +117,11 @@ initialize_uninitialized_regs (void)
} }
if (optimize == 1) if (optimize == 1)
df_remove_problem (df_live); {
if (dump_file)
df_dump (dump_file);
df_remove_problem (df_live);
}
BITMAP_FREE (already_genned); BITMAP_FREE (already_genned);
} }
......
...@@ -1211,13 +1211,9 @@ update_equiv_regs (void) ...@@ -1211,13 +1211,9 @@ update_equiv_regs (void)
if (!bitmap_empty_p (cleared_regs)) if (!bitmap_empty_p (cleared_regs))
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
bitmap_and_compl_into (DF_RA_LIVE_IN (bb), cleared_regs); bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
if (DF_RA_LIVE_TOP (bb)) bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
bitmap_and_compl_into (DF_RA_LIVE_TOP (bb), cleared_regs);
bitmap_and_compl_into (DF_RA_LIVE_OUT (bb), cleared_regs);
bitmap_and_compl_into (DF_LR_IN (bb), cleared_regs); bitmap_and_compl_into (DF_LR_IN (bb), cleared_regs);
if (DF_LR_TOP (bb))
bitmap_and_compl_into (DF_LR_TOP (bb), cleared_regs);
bitmap_and_compl_into (DF_LR_OUT (bb), cleared_regs); bitmap_and_compl_into (DF_LR_OUT (bb), cleared_regs);
} }
...@@ -1277,6 +1273,7 @@ block_alloc (int b) ...@@ -1277,6 +1273,7 @@ block_alloc (int b)
int max_uid = get_max_uid (); int max_uid = get_max_uid ();
int *qty_order; int *qty_order;
int no_conflict_combined_regno = -1; int no_conflict_combined_regno = -1;
struct df_ref ** def_rec;
/* Count the instructions in the basic block. */ /* Count the instructions in the basic block. */
...@@ -1299,7 +1296,19 @@ block_alloc (int b) ...@@ -1299,7 +1296,19 @@ block_alloc (int b)
/* Initialize table of hardware registers currently live. */ /* Initialize table of hardware registers currently live. */
REG_SET_TO_HARD_REG_SET (regs_live, DF_LR_TOP (BASIC_BLOCK (b))); REG_SET_TO_HARD_REG_SET (regs_live, DF_LR_IN (BASIC_BLOCK (b)));
/* This is conservative, as this would include registers that are
artificial-def'ed-but-not-used. However, artificial-defs are
rare, and such uninitialized use is rarer still, and the chance
of this having any performance impact is even less, while the
benefit is not having to compute and keep the TOP set around. */
for (def_rec = df_get_artificial_defs (b); *def_rec; def_rec++)
{
int regno = DF_REF_REGNO (*def_rec);
if (regno < FIRST_PSEUDO_REGISTER)
SET_HARD_REG_BIT (regs_live, regno);
}
/* This loop scans the instructions of the basic block /* This loop scans the instructions of the basic block
and assigns quantities to registers. and assigns quantities to registers.
...@@ -2502,6 +2511,49 @@ dump_local_alloc (FILE *file) ...@@ -2502,6 +2511,49 @@ dump_local_alloc (FILE *file)
fprintf (file, ";; Register %d in %d.\n", i, reg_renumber[i]); fprintf (file, ";; Register %d in %d.\n", i, reg_renumber[i]);
} }
#ifdef STACK_REGS
static void
find_stack_regs (void)
{
bitmap stack_regs = BITMAP_ALLOC (NULL);
int i;
HARD_REG_SET stack_hard_regs, used;
basic_block bb;
/* Any register that MAY be allocated to a register stack (like the
387) is treated poorly. Each such register is marked as being
live everywhere. This keeps the register allocator and the
subsequent passes from doing anything useful with these values.
FIXME: This seems like an incredibly poor idea. */
CLEAR_HARD_REG_SET (stack_hard_regs);
for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
SET_HARD_REG_BIT (stack_hard_regs, i);
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
{
COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]);
IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]);
AND_HARD_REG_SET (used, stack_hard_regs);
if (!hard_reg_set_empty_p (used))
bitmap_set_bit (stack_regs, i);
}
if (dump_file)
bitmap_print (dump_file, stack_regs, "stack regs:", "\n");
FOR_EACH_BB (bb)
{
bitmap_ior_into (DF_LIVE_IN (bb), stack_regs);
bitmap_and_into (DF_LIVE_IN (bb), DF_LR_IN (bb));
bitmap_ior_into (DF_LIVE_OUT (bb), stack_regs);
bitmap_and_into (DF_LIVE_OUT (bb), DF_LR_OUT (bb));
}
BITMAP_FREE (stack_regs);
}
#endif
/* Run old register allocator. Return TRUE if we must exit /* Run old register allocator. Return TRUE if we must exit
rest_of_compilation upon return. */ rest_of_compilation upon return. */
static unsigned int static unsigned int
...@@ -2512,26 +2564,22 @@ rest_of_handle_local_alloc (void) ...@@ -2512,26 +2564,22 @@ rest_of_handle_local_alloc (void)
df_note_add_problem (); df_note_add_problem ();
if (optimize > 1) if (optimize == 1)
df_remove_problem (df_live); {
/* Create a new version of df that has the special version of UR if df_live_add_problem ();
we are doing optimization. */ df_live_set_all_dirty ();
if (optimize) }
df_urec_add_problem ();
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
df->changeable_flags |= DF_VERIFY_SCHEDULED; df->changeable_flags |= DF_VERIFY_SCHEDULED;
#endif #endif
df_analyze (); df_analyze ();
#ifdef STACK_REGS
if (optimize)
find_stack_regs ();
#endif
regstat_init_n_sets_and_refs (); regstat_init_n_sets_and_refs ();
regstat_compute_ri (); regstat_compute_ri ();
/* There is just too much going on in the register allocators to
keep things up to date. At the end we have to rescan anyway
because things change when the reload_completed flag is set.
So we just turn off scanning and we will rescan by hand. */
df_set_flags (DF_NO_INSN_RESCAN);
/* If we are not optimizing, then this is the only place before /* If we are not optimizing, then this is the only place before
register allocation where dataflow is done. And that is needed register allocation where dataflow is done. And that is needed
to generate these warnings. */ to generate these warnings. */
......
/* Define per-register tables for data flow info and register allocation.
Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_RA_H
#define GCC_RA_H
#include "regs.h"
struct allocno
{
int reg;
/* Gives the number of consecutive hard registers needed by that
pseudo reg. */
int size;
/* Number of calls crossed by each allocno. */
int calls_crossed;
/* Number of calls that might throw crossed by each allocno. */
int throwing_calls_crossed;
/* Number of refs to each allocno. */
int n_refs;
/* Frequency of uses of each allocno. */
int freq;
/* Guess at live length of each allocno.
This is actually the max of the live lengths of the regs. */
int live_length;
/* Set of hard regs conflicting with allocno N. */
HARD_REG_SET hard_reg_conflicts;
/* Set of hard regs preferred by allocno N.
This is used to make allocnos go into regs that are copied to or from them,
when possible, to reduce register shuffling. */
HARD_REG_SET hard_reg_preferences;
/* Similar, but just counts register preferences made in simple copy
operations, rather than arithmetic. These are given priority because
we can always eliminate an insn by using these, but using a register
in the above list won't always eliminate an insn. */
HARD_REG_SET hard_reg_copy_preferences;
/* Similar to hard_reg_preferences, but includes bits for subsequent
registers when an allocno is multi-word. The above variable is used for
allocation while this is used to build reg_someone_prefers, below. */
HARD_REG_SET hard_reg_full_preferences;
/* Set of hard registers that some later allocno has a preference for. */
HARD_REG_SET regs_someone_prefers;
#ifdef STACK_REGS
/* Set to true if allocno can't be allocated in the stack register. */
bool no_stack_reg;
#endif
};
extern struct allocno *allocno;
/* In ra-conflict.c */
/* Number of pseudo-registers which are candidates for allocation. */
extern int max_allocno;
/* max_allocno by max_allocno array of bits, recording whether two
allocno's conflict (can't go in the same hardware register).
`conflicts' is symmetric after the call to mirror_conflicts. */
extern HOST_WIDE_INT *conflicts;
/* Number of ints required to hold max_allocno bits.
This is the length of a row in `conflicts'. */
extern int allocno_row_words;
/* Indexed by (pseudo) reg number, gives the allocno, or -1
for pseudo registers which are not to be allocated. */
extern int *reg_allocno;
extern void global_conflicts (void);
/* In global.c */
/* For any allocno set in ALLOCNO_SET, set ALLOCNO to that allocno,
and execute CODE. */
#define EXECUTE_IF_SET_IN_ALLOCNO_SET(ALLOCNO_SET, ALLOCNO, CODE) \
do { \
int i_; \
int allocno_; \
HOST_WIDE_INT *p_ = (ALLOCNO_SET); \
\
for (i_ = allocno_row_words - 1, allocno_ = 0; i_ >= 0; \
i_--, allocno_ += HOST_BITS_PER_WIDE_INT) \
{ \
unsigned HOST_WIDE_INT word_ = (unsigned HOST_WIDE_INT) *p_++; \
\
for ((ALLOCNO) = allocno_; word_; word_ >>= 1, (ALLOCNO)++) \
{ \
if (word_ & 1) \
{CODE;} \
} \
} \
} while (0)
extern void ra_init_live_subregs (bool, sbitmap *, int *, int, rtx reg);
#endif /* GCC_RA_H */
...@@ -1521,7 +1521,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, ...@@ -1521,7 +1521,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
/* Check that we don't use a hardreg for an uninitialized /* Check that we don't use a hardreg for an uninitialized
pseudo. See also find_dummy_reload(). */ pseudo. See also find_dummy_reload(). */
&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER && (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
|| ! bitmap_bit_p (DF_RA_LIVE_OUT (ENTRY_BLOCK_PTR), || ! bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
ORIGINAL_REGNO (XEXP (note, 0)))) ORIGINAL_REGNO (XEXP (note, 0))))
&& ! refers_to_regno_for_reload_p (regno, && ! refers_to_regno_for_reload_p (regno,
end_hard_regno (rel_mode, end_hard_regno (rel_mode,
...@@ -2000,7 +2000,7 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc, ...@@ -2000,7 +2000,7 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
as they would clobber the other live pseudo using the same. as they would clobber the other live pseudo using the same.
See also PR20973. */ See also PR20973. */
&& (ORIGINAL_REGNO (in) < FIRST_PSEUDO_REGISTER && (ORIGINAL_REGNO (in) < FIRST_PSEUDO_REGISTER
|| ! bitmap_bit_p (DF_RA_LIVE_OUT (ENTRY_BLOCK_PTR), || ! bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
ORIGINAL_REGNO (in)))) ORIGINAL_REGNO (in))))
{ {
unsigned int regno = REGNO (in) + in_offset; unsigned int regno = REGNO (in) + in_offset;
......
...@@ -548,7 +548,7 @@ compute_use_by_pseudos (HARD_REG_SET *to, regset from) ...@@ -548,7 +548,7 @@ compute_use_by_pseudos (HARD_REG_SET *to, regset from)
if (r < 0) if (r < 0)
{ {
/* reload_combine uses the information from /* reload_combine uses the information from
DF_RA_LIVE_IN (BASIC_BLOCK), which might still DF_LIVE_IN (BASIC_BLOCK), which might still
contain registers that have not actually been allocated contain registers that have not actually been allocated
since they have an equivalence. */ since they have an equivalence. */
gcc_assert (reload_completed); gcc_assert (reload_completed);
...@@ -1158,10 +1158,7 @@ reload (rtx first, int global) ...@@ -1158,10 +1158,7 @@ reload (rtx first, int global)
if (! frame_pointer_needed) if (! frame_pointer_needed)
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ bitmap_clear_bit (df_get_live_in (bb), HARD_FRAME_POINTER_REGNUM);
bitmap_clear_bit (df_get_live_in (bb), HARD_FRAME_POINTER_REGNUM);
bitmap_clear_bit (df_get_live_top (bb), HARD_FRAME_POINTER_REGNUM);
}
/* Come here (with failure set nonzero) if we can't get enough spill /* Come here (with failure set nonzero) if we can't get enough spill
regs. */ regs. */
......
...@@ -1063,6 +1063,7 @@ extern bool subreg_offset_representable_p (unsigned int, enum machine_mode, ...@@ -1063,6 +1063,7 @@ extern bool subreg_offset_representable_p (unsigned int, enum machine_mode,
unsigned int, enum machine_mode); unsigned int, enum machine_mode);
extern unsigned int subreg_regno (const_rtx); extern unsigned int subreg_regno (const_rtx);
extern unsigned int subreg_nregs (const_rtx); extern unsigned int subreg_nregs (const_rtx);
extern unsigned int subreg_nregs_with_regno (unsigned int, const_rtx);
extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, enum machine_mode); extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, enum machine_mode);
extern unsigned int num_sign_bit_copies (const_rtx, enum machine_mode); extern unsigned int num_sign_bit_copies (const_rtx, enum machine_mode);
extern bool constant_pool_constant_p (rtx); extern bool constant_pool_constant_p (rtx);
...@@ -2172,7 +2173,6 @@ extern void dump_global_regs (FILE *); ...@@ -2172,7 +2173,6 @@ extern void dump_global_regs (FILE *);
/* Yes, this ifdef is silly, but HARD_REG_SET is not always defined. */ /* Yes, this ifdef is silly, but HARD_REG_SET is not always defined. */
extern void retry_global_alloc (int, HARD_REG_SET); extern void retry_global_alloc (int, HARD_REG_SET);
#endif #endif
extern void build_insn_chain (rtx);
/* In regclass.c */ /* In regclass.c */
extern int reg_classes_intersect_p (enum reg_class, enum reg_class); extern int reg_classes_intersect_p (enum reg_class, enum reg_class);
......
...@@ -3263,15 +3263,25 @@ subreg_regno (const_rtx x) ...@@ -3263,15 +3263,25 @@ subreg_regno (const_rtx x)
unsigned int unsigned int
subreg_nregs (const_rtx x) subreg_nregs (const_rtx x)
{ {
return subreg_nregs_with_regno (REGNO (SUBREG_REG (x)), x);
}
/* Return the number of registers that a subreg REG with REGNO
expression refers to. This is a copy of the rtlanal.c:subreg_nregs
changed so that the regno can be passed in. */
unsigned int
subreg_nregs_with_regno (unsigned int regno, const_rtx x)
{
struct subreg_info info; struct subreg_info info;
rtx subreg = SUBREG_REG (x); rtx subreg = SUBREG_REG (x);
int regno = REGNO (subreg);
subreg_get_info (regno, GET_MODE (subreg), SUBREG_BYTE (x), GET_MODE (x), subreg_get_info (regno, GET_MODE (subreg), SUBREG_BYTE (x), GET_MODE (x),
&info); &info);
return info.nregs; return info.nregs;
} }
struct parms_set_data struct parms_set_data
{ {
int nregs; int nregs;
......
...@@ -46,25 +46,25 @@ template<typename T> ...@@ -46,25 +46,25 @@ template<typename T>
void test01() void test01()
{ {
do_test<bool>(); // do_test<bool>();
do_test<char>(); // do_test<char>();
do_test<signed char>(); // do_test<signed char>();
do_test<unsigned char>(); // do_test<unsigned char>();
do_test<short>(); // do_test<short>();
do_test<int>(); // do_test<int>();
do_test<long>(); // do_test<long>();
do_test<unsigned short>(); // do_test<unsigned short>();
do_test<unsigned int>(); // do_test<unsigned int>();
do_test<unsigned long>(); // do_test<unsigned long>();
do_test<int*>(); // do_test<int*>();
do_test<std::string>(); // do_test<std::string>();
do_test<float>(); // do_test<float>();
do_test<double>(); // do_test<double>();
do_test<long double>(); do_test<long double>();
#ifdef _GLIBCXX_USE_WCHAR_T #ifdef _GLIBCXX_USE_WCHAR_T
do_test<wchar_t>(); // do_test<wchar_t>();
do_test<std::wstring>(); // do_test<std::wstring>();
#endif #endif
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment