This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Reduce size of df_ref
- From: Jan Hubicka <jh at suse dot cz>
- To: zadeck at naturalbridge dot com, gcc-patches at gcc dot gnu dot org
- Date: Thu, 11 Sep 2008 16:50:59 +0200
- Subject: Reduce size of df_ref
Hi,
looking at top memory consumers at -O0 compilation of PR middle-end/37448
Allocpools:
allocnos 434 45686480 42628176 0
df_scan_ref pool 868 299190624 674472576 0
df_scan_insn pool 868 78427840 39589968 0
Bitmaps:
reload1.c:526 (new_insn_chain) 614091 36265800 36265800 36265800 0
reload1.c:527 (new_insn_chain) 614091 33119880 33119880 33119880 1032650
Vectors:
ira-build.c:405 (initiate_allocnos) 0: 0.0% 2502640 434: 0.4%
ira-build.c:409 (initiate_allocnos) 0: 0.0% 2502640 434: 0.4%
final.c:958 (shorten_branches) 0: 0.0% 2562404 434: 0.4%
ira-build.c:928 (initiate_copies) 0: 0.0% 5124072 434: 0.4%
GGC
tree-ssanames.c:141 (make_ssa_name_fn) 15898560: 3.2% 0: 0.0% 0: 0.0% 1059904: 2.1% 132488
c-typeck.c:3216 (build_unary_op) 16098624: 3.3% 0: 0.0% 0: 0.0% 1788736: 3.6% 223592
ggc-common.c:187 (ggc_calloc) 15786984: 3.2% 0: 0.0% 2502848:18.2% 24824: 0.0% 4343
gimplify.c:522 (create_tmp_var_raw) 21675192: 4.4% 0: 0.0% 0: 0.0% 1032152: 2.1% 129019
gimple.c:287 (gimple_build_call_1) 22671720: 4.6% 0: 0.0% 0: 0.0% 1111272: 2.2% 166477
tree-inline.c:3591 (copy_tree_r) 22805864: 4.6% 0: 0.0% 0: 0.0% 1378024: 2.8% 288420
lists.c:143 (alloc_EXPR_LIST) 28357080: 5.8% 0: 0.0% 0: 0.0% 5671416:11.4% 708927
cgraph.c:643 (cgraph_create_edge) 31961856: 6.5% 0: 0.0% 0: 0.0% 0: 0.0% 332936
emit-rtl.c:426 (gen_raw_REG) 33121984: 6.7% 0: 0.0% 38656: 0.3% 0: 0.0% 1036270
emit-rtl.c:3343 (make_insn_raw) 36543408: 7.4% 0: 0.0% 0: 0.0% 3322128: 6.7% 415266
the most outstanding is df_scan_ref_pool. This patch makes it 128bits smaller
by removing BB pointer that seems easier to look up from instruction when
needed and rearanging items in the structure. I don't see why it should
live in reference info at all.
Kenny, df_scan_ref seems to contain quite some redundant data and some items
that are not alive all the time, can't we move them elsewhere?
Bootstrapping/regtesting i686-linux, OK if it passes?
Honza
PR middle-end/37448
* df-scan.c (df_ref_record): Drop BB argument.
(df_ref_create_structure): Likewise.
(df_ref_chain_change_bb): Remove.
(df_insn_change_bb): Do not call df_ref_chain_change_bb.
(df_ref_equal_p): Do not check DF_REF_BB.
(df_ref_record, df_def_record_1, df_uses_record, df_get_conditional_uses, df_get_call_refs,
df_get_call_refs, df_insn_refs_collect, df_bb_refs_collect,
df_exit_block_uses_collect): Update calls of df_ref_create_structure and df_ref_record_1.
* df.h (df_ref): Remove BB filed; reorder in element size.
(DF_REF_BB): Use insn info.
Index: df-scan.c
===================================================================
--- df-scan.c (revision 140286)
+++ df-scan.c (working copy)
@@ -109,7 +109,7 @@ static struct df_mw_hardreg * df_null_mw
static void df_ref_record (struct df_collection_rec *,
rtx, rtx *,
- basic_block, struct df_insn_info *,
+ struct df_insn_info *,
enum df_ref_type, enum df_ref_flags,
int, int, enum machine_mode);
static void df_def_record_1 (struct df_collection_rec *, rtx,
@@ -125,7 +125,7 @@ static void df_uses_record (struct df_co
int, int, enum machine_mode);
static struct df_ref *df_ref_create_structure (struct df_collection_rec *, rtx, rtx *,
- basic_block, struct df_insn_info *,
+ struct df_insn_info *,
enum df_ref_type, enum df_ref_flags,
int, int, enum machine_mode);
@@ -677,7 +677,7 @@ df_ref_create (rtx reg, rtx *loc, rtx in
/* You cannot hack artificial refs. */
gcc_assert (insn);
- ref = df_ref_create_structure (NULL, reg, loc, bb, DF_INSN_INFO_GET (insn),
+ ref = df_ref_create_structure (NULL, reg, loc, DF_INSN_INFO_GET (insn),
ref_type, ref_flags,
width, offset, mode);
@@ -1813,25 +1813,6 @@ df_maybe_reorganize_def_refs (enum df_re
}
-/* Change the BB of all refs in the ref chain from OLD_BB to NEW_BB.
- Assumes that all refs in the chain have the same BB. */
-
-static void
-df_ref_chain_change_bb (struct df_ref **ref_rec,
- basic_block old_bb,
- basic_block new_bb)
-{
- while (*ref_rec)
- {
- struct df_ref *ref = *ref_rec;
-
- gcc_assert (DF_REF_BB (ref) == old_bb);
- DF_REF_BB (ref) = new_bb;
- ref_rec++;
- }
-}
-
-
/* Change all of the basic block references in INSN to use the insn's
current basic block. This function is called from routines that move
instructions from one block to another. */
@@ -1866,10 +1847,6 @@ df_insn_change_bb (rtx insn, basic_block
if (!INSN_P (insn))
return;
- df_ref_chain_change_bb (insn_info->defs, old_bb, new_bb);
- df_ref_chain_change_bb (insn_info->uses, old_bb, new_bb);
- df_ref_chain_change_bb (insn_info->eq_uses, old_bb, new_bb);
-
df_set_bb_dirty (new_bb);
if (old_bb)
{
@@ -2192,8 +2169,7 @@ df_ref_equal_p (struct df_ref *ref1, str
&& DF_REF_INSN_INFO (ref1) == DF_REF_INSN_INFO (ref2)
&& DF_REF_TYPE (ref1) == DF_REF_TYPE (ref2)
&& ((DF_REF_FLAGS (ref1) & ~(DF_REF_REG_MARKER + DF_REF_MW_HARDREG))
- == (DF_REF_FLAGS (ref2) & ~(DF_REF_REG_MARKER + DF_REF_MW_HARDREG)))
- && DF_REF_BB (ref1) == DF_REF_BB (ref2));
+ == (DF_REF_FLAGS (ref2) & ~(DF_REF_REG_MARKER + DF_REF_MW_HARDREG))));
}
@@ -2625,7 +2601,7 @@ df_refs_add_to_chains (struct df_collect
static struct df_ref *
df_ref_create_structure (struct df_collection_rec *collection_rec,
rtx reg, rtx *loc,
- basic_block bb, struct df_insn_info *info,
+ struct df_insn_info *info,
enum df_ref_type ref_type,
enum df_ref_flags ref_flags,
int width, int offset, enum machine_mode mode)
@@ -2652,7 +2628,6 @@ df_ref_create_structure (struct df_colle
DF_REF_CHAIN (this_ref) = NULL;
DF_REF_TYPE (this_ref) = ref_type;
DF_REF_FLAGS (this_ref) = ref_flags;
- DF_REF_BB (this_ref) = bb;
DF_REF_NEXT_REG (this_ref) = NULL;
DF_REF_PREV_REG (this_ref) = NULL;
DF_REF_ORDER (this_ref) = df->ref_order++;
@@ -2703,7 +2678,7 @@ df_ref_create_structure (struct df_colle
static void
df_ref_record (struct df_collection_rec *collection_rec,
rtx reg, rtx *loc,
- basic_block bb, struct df_insn_info *insn_info,
+ struct df_insn_info *insn_info,
enum df_ref_type ref_type,
enum df_ref_flags ref_flags,
int width, int offset, enum machine_mode mode)
@@ -2755,7 +2730,7 @@ df_ref_record (struct df_collection_rec
for (i = regno; i < endregno; i++)
{
ref = df_ref_create_structure (collection_rec, regno_reg_rtx[i], loc,
- bb, insn_info, ref_type, ref_flags,
+ insn_info, ref_type, ref_flags,
width, offset, mode);
gcc_assert (ORIGINAL_REGNO (DF_REF_REG (ref)) == i);
@@ -2764,7 +2739,7 @@ df_ref_record (struct df_collection_rec
else
{
struct df_ref *ref;
- ref = df_ref_create_structure (collection_rec, reg, loc, bb, insn_info,
+ ref = df_ref_create_structure (collection_rec, reg, loc, insn_info,
ref_type, ref_flags, width, offset, mode);
}
}
@@ -2857,14 +2832,14 @@ df_def_record_1 (struct df_collection_re
if (REG_P (dst))
{
df_ref_record (collection_rec,
- dst, loc, bb, insn_info, DF_REF_REG_DEF, flags,
+ dst, loc, insn_info, DF_REF_REG_DEF, flags,
width, offset, mode);
/* We want to keep sp alive everywhere - by making all
writes to sp also use of sp. */
if (REGNO (dst) == STACK_POINTER_REGNUM)
df_ref_record (collection_rec,
- dst, NULL, bb, insn_info, DF_REF_REG_USE, flags,
+ dst, NULL, insn_info, DF_REF_REG_USE, flags,
width, offset, mode);
}
else if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst)))
@@ -2875,7 +2850,7 @@ df_def_record_1 (struct df_collection_re
flags |= DF_REF_SUBREG;
df_ref_record (collection_rec,
- dst, loc, bb, insn_info, DF_REF_REG_DEF, flags,
+ dst, loc, insn_info, DF_REF_REG_DEF, flags,
width, offset, mode);
}
}
@@ -2985,7 +2960,7 @@ df_uses_record (struct df_collection_rec
case REG:
df_ref_record (collection_rec,
- x, loc, bb, insn_info,
+ x, loc, insn_info,
ref_type, flags,
width, offset, mode);
return;
@@ -3147,7 +3122,7 @@ df_uses_record (struct df_collection_rec
case POST_MODIFY:
/* Catch the def of the register being modified. */
df_ref_record (collection_rec, XEXP (x, 0), &XEXP (x, 0),
- bb, insn_info,
+ insn_info,
DF_REF_REG_DEF,
flags | DF_REF_READ_WRITE | DF_REF_PRE_POST_MODIFY,
width, offset, mode);
@@ -3217,7 +3192,7 @@ df_get_conditional_uses (struct df_colle
}
use = df_ref_create_structure (collection_rec, DF_REF_REG (ref),
- DF_REF_LOC (ref), DF_REF_BB (ref),
+ DF_REF_LOC (ref),
DF_REF_INSN_INFO (ref), DF_REF_REG_USE,
DF_REF_FLAGS (ref) & ~DF_REF_CONDITIONAL,
width, offset, mode);
@@ -3276,7 +3251,7 @@ df_get_call_refs (struct df_collection_r
/* The stack ptr is used (honorarily) by a CALL insn. */
df_ref_record (collection_rec, regno_reg_rtx[STACK_POINTER_REGNUM],
- NULL, bb, insn_info, DF_REF_REG_USE,
+ NULL, insn_info, DF_REF_REG_USE,
DF_REF_CALL_STACK_USAGE | flags,
-1, -1, 0);
@@ -3286,9 +3261,9 @@ df_get_call_refs (struct df_collection_r
if (global_regs[i])
{
df_ref_record (collection_rec, regno_reg_rtx[i],
- NULL, bb, insn_info, DF_REF_REG_USE, flags, -1, -1, 0);
+ NULL, insn_info, DF_REF_REG_USE, flags, -1, -1, 0);
df_ref_record (collection_rec, regno_reg_rtx[i],
- NULL, bb, insn_info, DF_REF_REG_DEF, flags, -1, -1, 0);
+ NULL, insn_info, DF_REF_REG_DEF, flags, -1, -1, 0);
}
is_sibling_call = SIBLING_CALL_P (insn_info->insn);
@@ -3301,7 +3276,7 @@ df_get_call_refs (struct df_collection_r
|| refers_to_regno_p (ui, ui+1,
crtl->return_rtx, NULL)))
df_ref_record (collection_rec, regno_reg_rtx[ui],
- NULL, bb, insn_info, DF_REF_REG_DEF,
+ NULL, insn_info, DF_REF_REG_DEF,
DF_REF_MAY_CLOBBER | flags,
-1, -1, 0);
}
@@ -3347,12 +3322,12 @@ df_insn_refs_collect (struct df_collecti
/* The frame ptr is used by a non-local goto. */
df_ref_record (collection_rec,
regno_reg_rtx[FRAME_POINTER_REGNUM],
- NULL, bb, insn_info,
+ NULL, insn_info,
DF_REF_REG_USE, 0, -1, -1, 0);
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
df_ref_record (collection_rec,
regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
- NULL, bb, insn_info,
+ NULL, insn_info,
DF_REF_REG_USE, 0, -1, -1, 0);
#endif
break;
@@ -3451,7 +3426,7 @@ df_bb_refs_collect (struct df_collection
if (regno == INVALID_REGNUM)
break;
df_ref_record (collection_rec, regno_reg_rtx[regno], NULL,
- bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP, -1, -1, 0);
+ NULL, DF_REF_REG_DEF, DF_REF_AT_TOP, -1, -1, 0);
}
}
#endif
@@ -3475,7 +3450,7 @@ df_bb_refs_collect (struct df_collection
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (EH_USES (i))
df_ref_record (collection_rec, regno_reg_rtx[i], NULL,
- bb, NULL, DF_REF_REG_USE, DF_REF_AT_TOP, -1, -1, 0);
+ NULL, DF_REF_REG_USE, DF_REF_AT_TOP, -1, -1, 0);
}
#endif
@@ -3483,7 +3458,7 @@ df_bb_refs_collect (struct df_collection
non-local goto. */
if (bb->flags & BB_NON_LOCAL_GOTO_TARGET)
df_ref_record (collection_rec, hard_frame_pointer_rtx, NULL,
- bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP, -1, -1, 0);
+ NULL, DF_REF_REG_DEF, DF_REF_AT_TOP, -1, -1, 0);
/* Add the artificial uses. */
if (bb->index >= NUM_FIXED_BLOCKS)
@@ -3497,7 +3472,7 @@ df_bb_refs_collect (struct df_collection
EXECUTE_IF_SET_IN_BITMAP (au, 0, regno, bi)
{
df_ref_record (collection_rec, regno_reg_rtx[regno], NULL,
- bb, NULL, DF_REF_REG_USE, 0, -1, -1, 0);
+ NULL, DF_REF_REG_USE, 0, -1, -1, 0);
}
}
@@ -3790,7 +3765,7 @@ df_entry_block_defs_collect (struct df_c
EXECUTE_IF_SET_IN_BITMAP (entry_block_defs, 0, i, bi)
{
df_ref_record (collection_rec, regno_reg_rtx[i], NULL,
- ENTRY_BLOCK_PTR, NULL, DF_REF_REG_DEF, 0, -1, -1, 0);
+ NULL, DF_REF_REG_DEF, 0, -1, -1, 0);
}
df_canonize_collection_rec (collection_rec);
@@ -3951,7 +3926,7 @@ df_exit_block_uses_collect (struct df_co
EXECUTE_IF_SET_IN_BITMAP (exit_block_uses, 0, i, bi)
df_ref_record (collection_rec, regno_reg_rtx[i], NULL,
- EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0, -1, -1, 0);
+ NULL, DF_REF_REG_USE, 0, -1, -1, 0);
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
/* It is deliberate that this is not put in the exit block uses but
@@ -3961,7 +3936,7 @@ df_exit_block_uses_collect (struct df_co
&& bb_has_eh_pred (EXIT_BLOCK_PTR)
&& fixed_regs[ARG_POINTER_REGNUM])
df_ref_record (collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL,
- EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0, -1, -1, 0);
+ NULL, DF_REF_REG_USE, 0, -1, -1, 0);
#endif
df_canonize_collection_rec (collection_rec);
Index: df.h
===================================================================
--- df.h (revision 140286)
+++ df.h (working copy)
@@ -368,7 +368,6 @@ struct df_insn_info
struct df_ref
{
rtx reg; /* The register referenced. */
- basic_block bb; /* Basic block containing the instruction. */
/* Insn info for the insn containing ref. This will be null if this is
an artificial reference. */
@@ -376,6 +375,13 @@ struct df_ref
rtx *loc; /* The location of the reg. */
struct df_link *chain; /* Head of def-use, use-def. */
+
+ /* For each regno, there are three chains of refs, one for the uses,
+ the eq_uses and the defs. These chains go thru the refs
+ themselves rather than using an external structure. */
+ struct df_ref *next_reg; /* Next ref with same regno and type. */
+ struct df_ref *prev_reg; /* Prev ref with same regno and type. */
+
/* Location in the ref table. This is only valid after a call to
df_maybe_reorganize_[use,def]_refs which is an expensive operation. */
int id;
@@ -390,12 +396,6 @@ struct df_ref
/* Type of ref. */
ENUM_BITFIELD(df_ref_flags) flags : 16;
/* Various flags. */
-
- /* For each regno, there are three chains of refs, one for the uses,
- the eq_uses and the defs. These chains go thru the refs
- themselves rather than using an external structure. */
- struct df_ref *next_reg; /* Next ref with same regno and type. */
- struct df_ref *prev_reg; /* Prev ref with same regno and type. */
};
/* A df_ref_extract is just a df_ref with a width and offset field at
@@ -611,7 +611,7 @@ struct df
? &SUBREG_REG (*((REF)->loc)) : ((REF)->loc))
#define DF_REF_REG(REF) ((REF)->reg)
#define DF_REF_LOC(REF) ((REF)->loc)
-#define DF_REF_BB(REF) ((REF)->bb)
+#define DF_REF_BB(REF) (BLOCK_FOR_INSN ((REF)->insn_info->insn))
#define DF_REF_BBNO(REF) (DF_REF_BB (REF)->index)
#define DF_REF_INSN_INFO(REF) ((REF)->insn_info)
#define DF_REF_INSN(REF) ((REF)->insn_info->insn)