Commit cc806ac1 by Richard Sandiford Committed by Kenneth Zadeck

dbgcnt.def (ra_byte_scan): Added.

2008-04-24  Richard Sandiford  <rsandifo@nildram.co.uk>
	    Kenneth Zadeck <zadeck@naturalbridge.com>

	* dbgcnt.def (ra_byte_scan): Added.
	* dbgcnt.c (dbg_cnt): Added code to print message to dump_file
	when the last hit happens for a counter.  
	* timevar.def (TV_DF_BYTE_LR): New variable.
	* tree-pass.h (pass_fast_rtl_byte_dce): New pass.
	* passes.c (pass_fast_rtl_byte_dce): New pass.
	* fwprop.c (update_df): Added mode to call df_ref_create.
	Renamed DF_REF_WIDTH and DF_REF_OFFSET to DF_REF_EXTRACT_WIDTH and
	DF_REF_EXTRACT_OFFSET.
	* df.h (DF_BYTE_LR, DF_BYTE_LR_BB_INFO, DF_BYTE_LR_IN, 
	DF_BYTE_LR_OUT, df_byte_lr): New macro.
	(df_mm): New enum.
	(df_ref_extract): Added mode field.
	(DF_REF_WIDTH, DF_REF_OFFSET) Renamed to DF_REF_EXTRACT_WIDTH and
	DF_REF_EXTRACT_OFFSET.
	(DF_REF_EXTRACT_MODE): New macro.
	(df_byte_lr_bb_info): New structure.
	(df_print_byte_regset, df_compute_accessed_bytes, 
	df_byte_lr_add_problem, df_byte_lr_get_regno_start,
	df_byte_lr_get_regno_len, df_byte_lr_simulate_defs,
	df_byte_lr_simulate_uses,
	df_byte_lr_simulate_artificial_refs_at_top,
	df_byte_lr_simulate_artificial_refs_at_end,
	df_compute_accessed_bytes): New function.
	(df_ref_create): Add parameter.
	(df_byte_lr_get_bb_info): New inline function.
	* df-scan.c (df_ref_record, df_uses_record,
	df_ref_create_structure): Added mode parameter.
	(df_ref_create, df_notes_rescan, df_ref_record, df_def_record_1, 
	df_defs_record, df_uses_record, df_get_conditional_uses,
	df_get_call_refs, df_insn_refs_collect, df_bb_refs_collect, 
	df_entry_block_defs_collect, df_exit_block_uses_collect):
	Added mode parameter to calls to df_ref_record, df_uses_record,
	df_ref_create_structure.
       	(df_ref_equal_p, df_ref_compare): Added test for modes.
	(df_ref_create_structure): Added code to set mode.  Renamed
	DF_REF_WIDTH and DF_REF_OFFSET to DF_REF_EXTRACT_WIDTH and
	DF_REF_EXTRACT_OFFSET.
	* df-core.c (df_print_byte_regset): New function.
	* df-byte-scan.c: New file.
	* df-problems.c (df_rd_transfer_function): Removed unnecessary
	calls to BITMAP_FREE.  
	(df_byte_lr_problem_data, df_problem problem_BYTE_LR): New structure.
	(df_byte_lr_get_regno_start, df_byte_lr_get_regno_len,
	df_byte_lr_set_bb_info, df_byte_lr_free_bb_info, 
	df_byte_lr_check_regs, df_byte_lr_expand_bitmap, 
	df_byte_lr_alloc, df_byte_lr_reset, df_byte_lr_bb_local_compute,
	df_byte_lr_local_compute, df_byte_lr_init,
	df_byte_lr_confluence_0, df_byte_lr_confluence_n, 
	df_byte_lr_transfer_function, df_byte_lr_free, 
	df_byte_lr_top_dump, df_byte_lr_bottom_dump,
	df_byte_lr_add_problem, df_byte_lr_simulate_defs, 
	df_byte_lr_simulate_uses,
	df_byte_lr_simulate_artificial_refs_at_top,
	df_byte_lr_simulate_artificial_refs_at_end): New function.
	* dce.c (byte_dce_process_block): New function.
	(dce_process_block): au is now passed in rather than computed
	locally.  Changed loops that look at artificial defs to not look
	for conditional or partial ones, because there never are any.  
	(fast_dce): Now is able to drive byte_dce_process_block or 
	dce_process_block depending on the kind of dce being done.
	(rest_of_handle_fast_dce): Add parameter to fast_dce.
	(rest_of_handle_fast_byte_dce): New function.
	(rtl_opt_pass pass_fast_rtl_byte_dce): New pass.
	* Makefile.in (df-byte-scan.o, debugcnt.o): Added dependencies.




Co-Authored-By: Kenneth Zadeck <zadeck@naturalbridge.com>

From-SVN: r134523
parent f7546fa7
2008-04-24 Richard Sandiford <rsandifo@nildram.co.uk>
Kenneth Zadeck <zadeck@naturalbridge.com>
* dbgcnt.def (ra_byte_scan): Added.
* dbgcnt.c (dbg_cnt): Added code to print message to dump_file
when the last hit happens for a counter.
* timevar.def (TV_DF_BYTE_LR): New variable.
* tree-pass.h (pass_fast_rtl_byte_dce): New pass.
* passes.c (pass_fast_rtl_byte_dce): New pass.
* fwprop.c (update_df): Added mode to call df_ref_create.
Renamed DF_REF_WIDTH and DF_REF_OFFSET to DF_REF_EXTRACT_WIDTH and
DF_REF_EXTRACT_OFFSET.
* df.h (DF_BYTE_LR, DF_BYTE_LR_BB_INFO, DF_BYTE_LR_IN,
DF_BYTE_LR_OUT, df_byte_lr): New macro.
(df_mm): New enum.
(df_ref_extract): Added mode field.
(DF_REF_WIDTH, DF_REF_OFFSET) Renamed to DF_REF_EXTRACT_WIDTH and
DF_REF_EXTRACT_OFFSET.
(DF_REF_EXTRACT_MODE): New macro.
(df_byte_lr_bb_info): New structure.
(df_print_byte_regset, df_compute_accessed_bytes,
df_byte_lr_add_problem, df_byte_lr_get_regno_start,
df_byte_lr_get_regno_len, df_byte_lr_simulate_defs,
df_byte_lr_simulate_uses,
df_byte_lr_simulate_artificial_refs_at_top,
df_byte_lr_simulate_artificial_refs_at_end,
df_compute_accessed_bytes): New function.
(df_ref_create): Add parameter.
(df_byte_lr_get_bb_info): New inline function.
* df-scan.c (df_ref_record, df_uses_record,
df_ref_create_structure): Added mode parameter.
(df_ref_create, df_notes_rescan, df_ref_record, df_def_record_1,
df_defs_record, df_uses_record, df_get_conditional_uses,
df_get_call_refs, df_insn_refs_collect, df_bb_refs_collect,
df_entry_block_defs_collect, df_exit_block_uses_collect):
Added mode parameter to calls to df_ref_record, df_uses_record,
df_ref_create_structure.
(df_ref_equal_p, df_ref_compare): Added test for modes.
(df_ref_create_structure): Added code to set mode. Renamed
DF_REF_WIDTH and DF_REF_OFFSET to DF_REF_EXTRACT_WIDTH and
DF_REF_EXTRACT_OFFSET.
* df-core.c (df_print_byte_regset): New function.
* df-byte-scan.c: New file.
* df-problems.c (df_rd_transfer_function): Removed unnecessary
calls to BITMAP_FREE.
(df_byte_lr_problem_data, df_problem problem_BYTE_LR): New structure.
(df_byte_lr_get_regno_start, df_byte_lr_get_regno_len,
df_byte_lr_set_bb_info, df_byte_lr_free_bb_info,
df_byte_lr_check_regs, df_byte_lr_expand_bitmap,
df_byte_lr_alloc, df_byte_lr_reset, df_byte_lr_bb_local_compute,
df_byte_lr_local_compute, df_byte_lr_init,
df_byte_lr_confluence_0, df_byte_lr_confluence_n,
df_byte_lr_transfer_function, df_byte_lr_free,
df_byte_lr_top_dump, df_byte_lr_bottom_dump,
df_byte_lr_add_problem, df_byte_lr_simulate_defs,
df_byte_lr_simulate_uses,
df_byte_lr_simulate_artificial_refs_at_top,
df_byte_lr_simulate_artificial_refs_at_end): New function.
* dce.c (byte_dce_process_block): New function.
(dce_process_block): au is now passed in rather than computed
locally. Changed loops that look at artificial defs to not look
for conditional or partial ones, because there never are any.
(fast_dce): Now is able to drive byte_dce_process_block or
dce_process_block depending on the kind of dce being done.
(rest_of_handle_fast_dce): Add parameter to fast_dce.
(rest_of_handle_fast_byte_dce): New function.
(rtl_opt_pass pass_fast_rtl_byte_dce): New pass.
* Makefile.in (df-byte-scan.o, debugcnt.o): Added dependencies.
2008-04-21 Daniel Franke <franke.daniel@gmail.com> 2008-04-21 Daniel Franke <franke.daniel@gmail.com>
PR fortran/35019 PR fortran/35019
......
...@@ -797,7 +797,7 @@ IPA_UTILS_H = ipa-utils.h $(TREE_H) $(CGRAPH_H) ...@@ -797,7 +797,7 @@ IPA_UTILS_H = ipa-utils.h $(TREE_H) $(CGRAPH_H)
IPA_REFERENCE_H = ipa-reference.h bitmap.h $(TREE_H) IPA_REFERENCE_H = ipa-reference.h bitmap.h $(TREE_H)
IPA_TYPE_ESCAPE_H = ipa-type-escape.h $(TREE_H) IPA_TYPE_ESCAPE_H = ipa-type-escape.h $(TREE_H)
CGRAPH_H = cgraph.h $(TREE_H) CGRAPH_H = cgraph.h $(TREE_H)
DF_H = df.h bitmap.h $(BASIC_BLOCK_H) alloc-pool.h DF_H = df.h bitmap.h $(BASIC_BLOCK_H) alloc-pool.h
RESOURCE_H = resource.h hard-reg-set.h $(DF_H) RESOURCE_H = resource.h hard-reg-set.h $(DF_H)
DDG_H = ddg.h sbitmap.h $(DF_H) DDG_H = ddg.h sbitmap.h $(DF_H)
GCC_H = gcc.h version.h GCC_H = gcc.h version.h
...@@ -1026,6 +1026,7 @@ OBJS-common = \ ...@@ -1026,6 +1026,7 @@ OBJS-common = \
dce.o \ dce.o \
ddg.o \ ddg.o \
debug.o \ debug.o \
df-byte-scan.o \
df-core.o \ df-core.o \
df-problems.o \ df-problems.o \
df-scan.o \ df-scan.o \
...@@ -2617,6 +2618,8 @@ df-scan.o : df-scan.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ ...@@ -2617,6 +2618,8 @@ df-scan.o : df-scan.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \ insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \
hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h $(TM_P_H) \ hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h $(TM_P_H) \
$(FLAGS_H) $(TARGET_H) $(TARGET_DEF_H) $(TREE_H) output.h tree-pass.h $(FLAGS_H) $(TARGET_H) $(TARGET_DEF_H) $(TREE_H) output.h tree-pass.h
df-byte-scan.o : df-byte-scan.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(DF_H) output.h $(DBGCNT_H)
regstat.o : regstat.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ regstat.o : regstat.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TM_P_H) $(FLAGS_H) $(REGS_H) output.h except.h hard-reg-set.h \ $(TM_P_H) $(FLAGS_H) $(REGS_H) output.h except.h hard-reg-set.h \
$(BASIC_BLOCK_H) $(TIMEVAR_H) $(DF_H) $(BASIC_BLOCK_H) $(TIMEVAR_H) $(DF_H)
...@@ -2729,7 +2732,7 @@ global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ ...@@ -2729,7 +2732,7 @@ global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
ra-conflict.o : ra-conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_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 \ $(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) $(RA_H) sbitmap.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) \
...@@ -2882,7 +2885,8 @@ hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(HOOKS_H) ...@@ -2882,7 +2885,8 @@ hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(HOOKS_H)
pretty-print.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h $(PRETTY_PRINT_H) \ pretty-print.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h $(PRETTY_PRINT_H) \
$(TREE_H) $(TREE_H)
errors.o : errors.c $(CONFIG_H) $(SYSTEM_H) errors.h $(BCONFIG_H) errors.o : errors.c $(CONFIG_H) $(SYSTEM_H) errors.h $(BCONFIG_H)
dbgcnt.o: dbgcnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DBGCNT_H) dbgcnt.o: dbgcnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DBGCNT_H) $(TM_H) \
$(RTL_H) output.h
lower-subreg.o : lower-subreg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ lower-subreg.o : lower-subreg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(MACHMODE_H) $(TM_H) $(RTL_H) $(TM_P_H) $(TIMEVAR_H) $(FLAGS_H) \ $(MACHMODE_H) $(TM_H) $(RTL_H) $(TM_P_H) $(TIMEVAR_H) $(FLAGS_H) \
insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) $(OBSTACK_H) bitmap.h \ insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) $(OBSTACK_H) bitmap.h \
......
...@@ -23,6 +23,9 @@ See dbgcnt.def for usage information. */ ...@@ -23,6 +23,9 @@ See dbgcnt.def for usage information. */
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
#include "errors.h" #include "errors.h"
#include "tm.h"
#include "rtl.h"
#include "output.h"
#include "dbgcnt.h" #include "dbgcnt.h"
...@@ -58,6 +61,10 @@ bool ...@@ -58,6 +61,10 @@ bool
dbg_cnt (enum debug_counter index) dbg_cnt (enum debug_counter index)
{ {
count[index]++; count[index]++;
if (dump_file && count[index] == limit[index])
fprintf (dump_file, "***dbgcnt: limit reached for %s.***\n",
map[index].name);
return dbg_cnt_is_enabled (index); return dbg_cnt_is_enabled (index);
} }
...@@ -132,7 +139,8 @@ dbg_cnt_process_opt (const char *arg) ...@@ -132,7 +139,8 @@ dbg_cnt_process_opt (const char *arg)
/* Print name, limit and count of all counters. */ /* Print name, limit and count of all counters. */
void dbg_cnt_list_all_counters (void) void
dbg_cnt_list_all_counters (void)
{ {
int i; int i;
printf (" %-30s %-5s %-5s\n", "counter name", "limit", "value"); printf (" %-30s %-5s %-5s\n", "counter name", "limit", "value");
......
...@@ -61,6 +61,83 @@ along with GCC; see the file COPYING3. If not see ...@@ -61,6 +61,83 @@ along with GCC; see the file COPYING3. If not see
Use -fdbg-cnt=counter1:N,counter2:M,... Use -fdbg-cnt=counter1:N,counter2:M,...
which sets the limit for counter1 to N, and the limit for counter2 to M, etc. which sets the limit for counter1 to N, and the limit for counter2 to M, etc.
e.g. setting a limit to zero will make dbg_cnt () return false *always*. e.g. setting a limit to zero will make dbg_cnt () return false *always*.
The following shell file can then be used to binary search for
exact transformation that causes the bug. A second shell script
should be written, say "tryTest", which exits with 1 if the
compiled program fails and exits with 0 if the program succeeds.
This shell script should take 1 parameter, the value to be passed
to set the counter of the compilation command in tryTest. Then,
assuming that the following script is called binarySearch,
the command:
binarySearch tryTest
will automatically find the highest value of the counter for which
the program fails. If tryTest never fails, binarySearch will
produce unpredictable results as it will try to find an upper bound
that does not exist.
When dbgcnt does hits the limit, it writes a comment in the current
dump_file of the form:
***dbgcnt: limit reached for %s.***
Assuming that the dump file is logging the analysis/transformations
it is making, this pinpoints the exact position in the log file
where the problem transformation is being logged.
=====================================
#!/bin/bash
while getopts "l:u:i:" opt
do
case $opt in
l) lb="$OPTARG";;
u) ub="$OPTARG";;
i) init="$OPTARG";;
?) usage; exit 3;;
esac
done
shift $(($OPTIND - 1))
echo $@
cmd=${1+"${@}"}
lb=${lb:=0}
init=${init:=100}
$cmd $lb
lb_val=$?
if [ -z "$ub" ]; then
# find the upper bound
ub=$(($init + $lb))
true
while [ $? -eq $lb_val ]; do
ub=$(($ub * 10))
#ub=`expr $ub \* 10`
$cmd $ub
done
fi
echo command: $cmd
true
while [ `expr $ub - $lb` -gt 1 ]; do
try=$(($lb + ( $ub - $lb ) / 2))
$cmd $try
if [ $? -eq $lb_val ]; then
lb=$try
else
ub=$try
fi
done
echo lbound: $lb
echo ubound: $ub
=====================================
*/ */
/* Debug counter definitions. */ /* Debug counter definitions. */
...@@ -73,6 +150,7 @@ DEBUG_COUNTER (dce) ...@@ -73,6 +150,7 @@ DEBUG_COUNTER (dce)
DEBUG_COUNTER (dce_fast) DEBUG_COUNTER (dce_fast)
DEBUG_COUNTER (dce_ud) DEBUG_COUNTER (dce_ud)
DEBUG_COUNTER (delete_trivial_dead) DEBUG_COUNTER (delete_trivial_dead)
DEBUG_COUNTER (df_byte_scan)
DEBUG_COUNTER (dse) DEBUG_COUNTER (dse)
DEBUG_COUNTER (dse1) DEBUG_COUNTER (dse1)
DEBUG_COUNTER (dse2) DEBUG_COUNTER (dse2)
......
...@@ -1875,6 +1875,69 @@ df_print_regset (FILE *file, bitmap r) ...@@ -1875,6 +1875,69 @@ df_print_regset (FILE *file, bitmap r)
} }
/* Write information about registers and basic blocks into FILE. The
bitmap is in the form used by df_byte_lr. This is part of making a
debugging dump. */
void
df_print_byte_regset (FILE *file, bitmap r)
{
unsigned int max_reg = max_reg_num ();
bitmap_iterator bi;
if (r == NULL)
fputs (" (nil)", file);
else
{
unsigned int i;
for (i = 0; i < max_reg; i++)
{
unsigned int first = df_byte_lr_get_regno_start (i);
unsigned int len = df_byte_lr_get_regno_len (i);
if (len > 1)
{
bool found = false;
unsigned int j;
EXECUTE_IF_SET_IN_BITMAP (r, first, j, bi)
{
found = j < first + len;
break;
}
if (found)
{
const char * sep = "";
fprintf (file, " %d", i);
if (i < FIRST_PSEUDO_REGISTER)
fprintf (file, " [%s]", reg_names[i]);
fprintf (file, "(");
EXECUTE_IF_SET_IN_BITMAP (r, first, j, bi)
{
if (j > first + len - 1)
break;
fprintf (file, "%s%d", sep, j-first);
sep = ", ";
}
fprintf (file, ")");
}
}
else
{
if (bitmap_bit_p (r, first))
{
fprintf (file, " %d", i);
if (i < FIRST_PSEUDO_REGISTER)
fprintf (file, " [%s]", reg_names[i]);
}
}
}
}
fprintf (file, "\n");
}
/* Dump dataflow info. */ /* Dump dataflow info. */
void void
......
...@@ -42,12 +42,13 @@ struct df_link; ...@@ -42,12 +42,13 @@ struct df_link;
a uniform manner. The last four problems can be added or deleted a uniform manner. The last four problems can be added or deleted
at any time are always defined (though LIVE is always there at -O2 at any time are always defined (though LIVE is always there at -O2
or higher); the others are always there. */ or higher); the others are always there. */
#define DF_SCAN 0 #define DF_SCAN 0
#define DF_LR 1 /* Live Registers backward. */ #define DF_LR 1 /* Live Registers backward. */
#define DF_LIVE 2 /* Live Registers & Uninitialized Registers */ #define DF_LIVE 2 /* Live Registers & Uninitialized Registers */
#define DF_RD 3 /* Reaching Defs. */ #define DF_RD 3 /* Reaching Defs. */
#define DF_CHAIN 4 /* Def-Use and/or Use-Def Chains. */ #define DF_CHAIN 4 /* Def-Use and/or Use-Def Chains. */
#define DF_NOTE 5 /* REG_DEF and REG_UNUSED notes. */ #define DF_BYTE_LR 5 /* Subreg tracking lr. */
#define DF_NOTE 6 /* REG_DEF and REG_UNUSED notes. */
#define DF_LAST_PROBLEM_PLUS1 (DF_NOTE + 1) #define DF_LAST_PROBLEM_PLUS1 (DF_NOTE + 1)
...@@ -59,6 +60,13 @@ enum df_flow_dir ...@@ -59,6 +60,13 @@ enum df_flow_dir
DF_BACKWARD DF_BACKWARD
}; };
/* Used in the byte scanning to determine if may or must info is to be
returned. */
enum df_mm
{
DF_MM_MAY,
DF_MM_MUST
};
/* The first of these is a set of a register. The remaining three are /* The first of these is a set of a register. The remaining three are
all uses of a register (the mem_load and mem_store relate to how all uses of a register (the mem_load and mem_store relate to how
...@@ -398,6 +406,7 @@ struct df_ref_extract ...@@ -398,6 +406,7 @@ struct df_ref_extract
struct df_ref ref; struct df_ref ref;
int width; int width;
int offset; int offset;
enum machine_mode mode;
}; };
/* These links are used for two purposes: /* These links are used for two purposes:
...@@ -573,6 +582,7 @@ struct df ...@@ -573,6 +582,7 @@ struct df
#define DF_RD_BB_INFO(BB) (df_rd_get_bb_info((BB)->index)) #define DF_RD_BB_INFO(BB) (df_rd_get_bb_info((BB)->index))
#define DF_LR_BB_INFO(BB) (df_lr_get_bb_info((BB)->index)) #define DF_LR_BB_INFO(BB) (df_lr_get_bb_info((BB)->index))
#define DF_LIVE_BB_INFO(BB) (df_live_get_bb_info((BB)->index)) #define DF_LIVE_BB_INFO(BB) (df_live_get_bb_info((BB)->index))
#define DF_BYTE_LR_BB_INFO(BB) (df_byte_lr_get_bb_info((BB)->index))
/* Most transformations that wish to use live register analysis will /* Most transformations that wish to use live register analysis will
use these macros. This info is the and of the lr and live sets. */ use these macros. This info is the and of the lr and live sets. */
...@@ -585,6 +595,12 @@ struct df ...@@ -585,6 +595,12 @@ struct df
#define DF_LR_IN(BB) (DF_LR_BB_INFO(BB)->in) #define DF_LR_IN(BB) (DF_LR_BB_INFO(BB)->in)
#define DF_LR_OUT(BB) (DF_LR_BB_INFO(BB)->out) #define DF_LR_OUT(BB) (DF_LR_BB_INFO(BB)->out)
/* These macros are used by passes that are not tolerant of
uninitialized variables. This intolerance should eventually
be fixed. */
#define DF_BYTE_LR_IN(BB) (DF_BYTE_LR_BB_INFO(BB)->in)
#define DF_BYTE_LR_OUT(BB) (DF_BYTE_LR_BB_INFO(BB)->out)
/* Macros to access the elements within the ref structure. */ /* Macros to access the elements within the ref structure. */
...@@ -619,8 +635,9 @@ struct df ...@@ -619,8 +635,9 @@ struct df
#define DF_REF_PREV_REG(REF) ((REF)->prev_reg) #define DF_REF_PREV_REG(REF) ((REF)->prev_reg)
/* The following two macros may only be applied if one of /* The following two macros may only be applied if one of
DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT is true. */ DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT is true. */
#define DF_REF_WIDTH(REF) (((struct df_ref_extract *)(REF))->width) #define DF_REF_EXTRACT_WIDTH(REF) (((struct df_ref_extract *)(REF))->width)
#define DF_REF_OFFSET(REF) (((struct df_ref_extract *)(REF))->offset) #define DF_REF_EXTRACT_OFFSET(REF) (((struct df_ref_extract *)(REF))->offset)
#define DF_REF_EXTRACT_MODE(REF) (((struct df_ref_extract *)(REF))->mode)
/* Macros to determine the reference type. */ /* Macros to determine the reference type. */
#define DF_REF_REG_DEF_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_DEF) #define DF_REF_REG_DEF_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_DEF)
...@@ -775,16 +792,33 @@ struct df_live_bb_info ...@@ -775,16 +792,33 @@ struct df_live_bb_info
}; };
/* Live registers, a backwards dataflow problem. These bitmaps are
indexed by the df_byte_lr_offset array which is indexed by pseudo. */
struct df_byte_lr_bb_info
{
/* Local sets to describe the basic blocks. */
bitmap def; /* The set of registers set in this block
- except artificial defs at the top. */
bitmap use; /* The set of registers used in this block. */
/* The results of the dataflow problem. */
bitmap in; /* Just before the block itself. */
bitmap out; /* At the bottom of the block. */
};
/* This is used for debugging and for the dumpers to find the latest /* This is used for debugging and for the dumpers to find the latest
instance so that the df info can be added to the dumps. This instance so that the df info can be added to the dumps. This
should not be used by regular code. */ should not be used by regular code. */
extern struct df *df; extern struct df *df;
#define df_scan (df->problems_by_index[DF_SCAN]) #define df_scan (df->problems_by_index[DF_SCAN])
#define df_rd (df->problems_by_index[DF_RD]) #define df_rd (df->problems_by_index[DF_RD])
#define df_lr (df->problems_by_index[DF_LR]) #define df_lr (df->problems_by_index[DF_LR])
#define df_live (df->problems_by_index[DF_LIVE]) #define df_live (df->problems_by_index[DF_LIVE])
#define df_chain (df->problems_by_index[DF_CHAIN]) #define df_chain (df->problems_by_index[DF_CHAIN])
#define df_note (df->problems_by_index[DF_NOTE]) #define df_byte_lr (df->problems_by_index[DF_BYTE_LR])
#define df_note (df->problems_by_index[DF_NOTE])
/* This symbol turns on checking that each modification of the cfg has /* This symbol turns on checking that each modification of the cfg has
been identified to the appropriate df routines. It is not part of been identified to the appropriate df routines. It is not part of
...@@ -831,6 +865,7 @@ extern struct df_ref *df_find_use (rtx, rtx); ...@@ -831,6 +865,7 @@ extern struct df_ref *df_find_use (rtx, rtx);
extern bool df_reg_used (rtx, rtx); extern bool df_reg_used (rtx, rtx);
extern void df_worklist_dataflow (struct dataflow *,bitmap, int *, int); extern void df_worklist_dataflow (struct dataflow *,bitmap, int *, int);
extern void df_print_regset (FILE *file, bitmap r); extern void df_print_regset (FILE *file, bitmap r);
extern void df_print_byte_regset (FILE *file, bitmap r);
extern void df_dump (FILE *); extern void df_dump (FILE *);
extern void df_dump_region (FILE *); extern void df_dump_region (FILE *);
extern void df_dump_start (FILE *); extern void df_dump_start (FILE *);
...@@ -867,6 +902,13 @@ extern void df_live_verify_transfer_functions (void); ...@@ -867,6 +902,13 @@ extern void df_live_verify_transfer_functions (void);
extern void df_live_add_problem (void); extern void df_live_add_problem (void);
extern void df_live_set_all_dirty (void); extern void df_live_set_all_dirty (void);
extern void df_chain_add_problem (enum df_chain_flags); extern void df_chain_add_problem (enum df_chain_flags);
extern void df_byte_lr_add_problem (void);
extern int df_byte_lr_get_regno_start (unsigned int);
extern int df_byte_lr_get_regno_len (unsigned int);
extern void df_byte_lr_simulate_defs (rtx, bitmap);
extern void df_byte_lr_simulate_uses (rtx, bitmap);
extern void df_byte_lr_simulate_artificial_refs_at_top (basic_block, bitmap);
extern void df_byte_lr_simulate_artificial_refs_at_end (basic_block, bitmap);
extern void df_note_add_problem (void); extern void df_note_add_problem (void);
extern void df_simulate_find_defs (rtx, bitmap); extern void df_simulate_find_defs (rtx, bitmap);
extern void df_simulate_defs (rtx, bitmap); extern void df_simulate_defs (rtx, bitmap);
...@@ -885,7 +927,7 @@ extern void df_grow_insn_info (void); ...@@ -885,7 +927,7 @@ extern void df_grow_insn_info (void);
extern void df_scan_blocks (void); extern void df_scan_blocks (void);
extern struct df_ref *df_ref_create (rtx, rtx *, rtx,basic_block, extern struct df_ref *df_ref_create (rtx, rtx *, rtx,basic_block,
enum df_ref_type, enum df_ref_flags, enum df_ref_type, enum df_ref_flags,
int, int); int, int, enum machine_mode);
extern void df_ref_remove (struct df_ref *); extern void df_ref_remove (struct df_ref *);
extern struct df_insn_info * df_insn_create_insn_record (rtx); extern struct df_insn_info * df_insn_create_insn_record (rtx);
extern void df_insn_delete (basic_block, unsigned int); extern void df_insn_delete (basic_block, unsigned int);
...@@ -911,6 +953,10 @@ extern void df_compute_regs_ever_live (bool); ...@@ -911,6 +953,10 @@ extern void df_compute_regs_ever_live (bool);
extern bool df_read_modify_subreg_p (rtx); extern bool df_read_modify_subreg_p (rtx);
extern void df_scan_verify (void); extern void df_scan_verify (void);
/* Functions defined in df-byte-scan.c. */
extern bool df_compute_accessed_bytes (struct df_ref *, enum df_mm,
unsigned int *, unsigned int *);
/* Get basic block info. */ /* Get basic block info. */
...@@ -950,6 +996,15 @@ df_live_get_bb_info (unsigned int index) ...@@ -950,6 +996,15 @@ df_live_get_bb_info (unsigned int index)
return NULL; return NULL;
} }
static inline struct df_byte_lr_bb_info *
df_byte_lr_get_bb_info (unsigned int index)
{
if (index < df_byte_lr->block_info_size)
return (struct df_byte_lr_bb_info *) df_byte_lr->block_info[index];
else
return NULL;
}
/* Get the artificial defs for a basic block. */ /* Get the artificial defs for a basic block. */
static inline struct df_ref ** static inline struct df_ref **
......
...@@ -679,6 +679,7 @@ update_df (rtx insn, rtx *loc, struct df_ref **use_rec, enum df_ref_type type, ...@@ -679,6 +679,7 @@ update_df (rtx insn, rtx *loc, struct df_ref **use_rec, enum df_ref_type type,
struct df_ref *orig_use = use, *new_use; struct df_ref *orig_use = use, *new_use;
int width = -1; int width = -1;
int offset = -1; int offset = -1;
enum machine_mode mode = 0;
rtx *new_loc = find_occurrence (loc, DF_REF_REG (orig_use)); rtx *new_loc = find_occurrence (loc, DF_REF_REG (orig_use));
use_rec++; use_rec++;
...@@ -687,15 +688,17 @@ update_df (rtx insn, rtx *loc, struct df_ref **use_rec, enum df_ref_type type, ...@@ -687,15 +688,17 @@ update_df (rtx insn, rtx *loc, struct df_ref **use_rec, enum df_ref_type type,
if (DF_REF_FLAGS_IS_SET (orig_use, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT)) if (DF_REF_FLAGS_IS_SET (orig_use, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
{ {
width = DF_REF_WIDTH (orig_use); width = DF_REF_EXTRACT_WIDTH (orig_use);
offset = DF_REF_OFFSET (orig_use); offset = DF_REF_EXTRACT_OFFSET (orig_use);
mode = DF_REF_EXTRACT_MODE (orig_use);
} }
/* Add a new insn use. Use the original type, because it says if the /* Add a new insn use. Use the original type, because it says if the
use was within a MEM. */ use was within a MEM. */
new_use = df_ref_create (DF_REF_REG (orig_use), new_loc, new_use = df_ref_create (DF_REF_REG (orig_use), new_loc,
insn, BLOCK_FOR_INSN (insn), insn, BLOCK_FOR_INSN (insn),
type, DF_REF_FLAGS (orig_use) | new_flags, width, offset); type, DF_REF_FLAGS (orig_use) | new_flags,
width, offset, mode);
/* Set up the use-def chain. */ /* Set up the use-def chain. */
df_chain_copy (new_use, DF_REF_CHAIN (orig_use)); df_chain_copy (new_use, DF_REF_CHAIN (orig_use));
......
...@@ -731,6 +731,7 @@ init_optimization_passes (void) ...@@ -731,6 +731,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_partition_blocks); NEXT_PASS (pass_partition_blocks);
NEXT_PASS (pass_regmove); NEXT_PASS (pass_regmove);
NEXT_PASS (pass_split_all_insns); NEXT_PASS (pass_split_all_insns);
NEXT_PASS (pass_fast_rtl_byte_dce);
NEXT_PASS (pass_lower_subreg2); NEXT_PASS (pass_lower_subreg2);
NEXT_PASS (pass_df_initialize_no_opt); NEXT_PASS (pass_df_initialize_no_opt);
NEXT_PASS (pass_stack_ptr_mod); NEXT_PASS (pass_stack_ptr_mod);
......
...@@ -64,6 +64,7 @@ DEFTIMEVAR (TV_DF_LR , "df live regs") ...@@ -64,6 +64,7 @@ DEFTIMEVAR (TV_DF_LR , "df live regs")
DEFTIMEVAR (TV_DF_LIVE , "df live&initialized regs") DEFTIMEVAR (TV_DF_LIVE , "df live&initialized regs")
DEFTIMEVAR (TV_DF_UREC , "df uninitialized regs 2") DEFTIMEVAR (TV_DF_UREC , "df uninitialized regs 2")
DEFTIMEVAR (TV_DF_CHAIN , "df use-def / def-use chains") DEFTIMEVAR (TV_DF_CHAIN , "df use-def / def-use chains")
DEFTIMEVAR (TV_DF_BYTE_LR , "df live byte regs")
DEFTIMEVAR (TV_DF_NOTE , "df reg dead/unused notes") DEFTIMEVAR (TV_DF_NOTE , "df reg dead/unused notes")
DEFTIMEVAR (TV_REG_STATS , "register information") DEFTIMEVAR (TV_REG_STATS , "register information")
......
...@@ -423,6 +423,7 @@ extern struct rtl_opt_pass pass_partition_blocks; ...@@ -423,6 +423,7 @@ extern struct rtl_opt_pass pass_partition_blocks;
extern struct rtl_opt_pass pass_match_asm_constraints; extern struct rtl_opt_pass pass_match_asm_constraints;
extern struct rtl_opt_pass pass_regmove; extern struct rtl_opt_pass pass_regmove;
extern struct rtl_opt_pass pass_split_all_insns; extern struct rtl_opt_pass pass_split_all_insns;
extern struct rtl_opt_pass pass_fast_rtl_byte_dce;
extern struct rtl_opt_pass pass_lower_subreg2; extern struct rtl_opt_pass pass_lower_subreg2;
extern struct rtl_opt_pass pass_mode_switching; extern struct rtl_opt_pass pass_mode_switching;
extern struct rtl_opt_pass pass_see; extern struct rtl_opt_pass pass_see;
......
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