This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
BIND_EXPR lowering part 1 (Was Re: [tree-ssa] COND_EXPR lowering.)
Hello,
> I think you're missing the change to lower_stmt that uses
> data->block. Otherwise ok.
oops... sure. I am just leaving for a week; Honza, could you
please retest the patch and commit it if it passes?
Zdenek
* Makefile.in (gimple-low.o): Add function.h dependency.
* gimple-low.c (struct lower_data): New field block.
(lower_function_body, lower_stmt, lower_bind_expr): Record
the block at statements.
* cfglayout.c (insn_locators_initialize): Use new info about
* blocks.
* expr.c (expand_expr): Record block changes.
* function.c (blocks_nreverse): Export.
(uninitialized_vars_warning): Use DECL_RTL_SET_P to test for presence
of rtl.
(reset_block_changes, record_block_change, finalize_block_changes,
check_block_change, free_block_changes): New functions.
* function.h (struct function): New bitfield dont_emit_block_notes.
New field ib_boundaries_block.
(blocks_nreverse, reset_block_changes, record_block_change,
finalize_block_changes, check_block_change, free_block_changes):
Declare.
* sibcall.c (optimize_sibling_and_tail_recursive_call): Don't call
reorder_blocks when dont_emit_block_notes.
* stmt.c (expand_start_bindings_and_block, expand_end_bindings):
Don't emit block notes when dont_emit_block_notes.
* toplev.c (rest_of_compilation): Don't call reorder_blocks when
dont_emit_block_notes.
* tree.c (build1): Initialize TREE_BLOCK field.
* tree-flow.h (lower_function_body): Declare.
* tree-optimize.c: Include function.h.
(optimize_function_tree): Call lower_function_body.
* tree.h (struct tree_exp): Add block field.
(TREE_BLOCK): New macro.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.124
diff -c -3 -p -r1.903.2.124 Makefile.in
*** Makefile.in 25 Oct 2003 17:48:22 -0000 1.903.2.124
--- Makefile.in 26 Oct 2003 07:08:02 -0000
*************** gimplify.o : gimplify.c $(CONFIG_H) $(SY
*** 1579,1585 ****
gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
diagnostic.h $(TREE_SIMPLE_H) tree-inline.h varray.h langhooks.h \
langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h except.h \
! flags.h $(RTL_H)
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) errors.h tree-inline.h diagnostic.h $(HASHTAB_H) \
$(TM_H) coretypes.h
--- 1579,1585 ----
gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
diagnostic.h $(TREE_SIMPLE_H) tree-inline.h varray.h langhooks.h \
langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h except.h \
! flags.h $(RTL_H) function.h
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) errors.h tree-inline.h diagnostic.h $(HASHTAB_H) \
$(TM_H) coretypes.h
Index: cfglayout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfglayout.c,v
retrieving revision 1.19.2.13
diff -c -3 -p -r1.19.2.13 cfglayout.c
*** cfglayout.c 6 Oct 2003 17:36:14 -0000 1.19.2.13
--- cfglayout.c 26 Oct 2003 07:08:02 -0000
*************** insn_locators_initialize (void)
*** 310,319 ****
--- 310,323 ----
switch (NOTE_LINE_NUMBER (insn))
{
case NOTE_INSN_BLOCK_BEG:
+ if (cfun->dont_emit_block_notes)
+ abort ();
block = NOTE_BLOCK (insn);
delete_insn (insn);
break;
case NOTE_INSN_BLOCK_END:
+ if (cfun->dont_emit_block_notes)
+ abort ();
block = BLOCK_SUPERCONTEXT (block);
if (block && TREE_CODE (block) == FUNCTION_DECL)
block = 0;
*************** insn_locators_initialize (void)
*** 328,338 ****
--- 332,348 ----
break;
}
}
+
+ if (cfun->dont_emit_block_notes)
+ check_block_change (insn, &block);
}
/* Tag the blocks with a depth number so that change_scope can find
the common parent easily. */
set_block_levels (DECL_INITIAL (cfun->decl), 0);
+
+ if (cfun->dont_emit_block_notes)
+ free_block_changes ();
}
/* For each lexical block, set BLOCK_NUMBER to the depth at which it is
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.56
diff -c -3 -p -r1.467.2.56 expr.c
*** expr.c 18 Oct 2003 23:59:44 -0000 1.467.2.56
--- expr.c 26 Oct 2003 07:08:02 -0000
*************** expand_expr (tree exp, rtx target, enum
*** 6229,6234 ****
--- 6229,6238 ----
input_location = *EXPR_LOCUS (exp);
emit_line_note (input_location);
+ /* Record where the insns produced belong. */
+ if (cfun->dont_emit_block_notes)
+ record_block_change (TREE_BLOCK (exp));
+
ret = expand_expr_1 (exp, target, tmode, modifier);
input_location = saved_location;
*************** expand_expr_1 (tree exp, rtx target, enu
*** 8416,8422 ****
{
expand_start_else ();
if (EXPR_LOCUS (exp))
! emit_line_note (*(EXPR_LOCUS (exp)));
expand_elseif (TREE_OPERAND (exp, 0));
expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, 0);
}
--- 8420,8430 ----
{
expand_start_else ();
if (EXPR_LOCUS (exp))
! {
! emit_line_note (*(EXPR_LOCUS (exp)));
! if (cfun->dont_emit_block_notes)
! record_block_change (TREE_BLOCK (exp));
! }
expand_elseif (TREE_OPERAND (exp, 0));
expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, 0);
}
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.374.2.29
diff -c -3 -p -r1.374.2.29 function.c
*** function.c 18 Oct 2003 23:59:46 -0000 1.374.2.29
--- function.c 26 Oct 2003 07:08:02 -0000
*************** static tree *identify_blocks_1 (rtx, tre
*** 265,271 ****
static void reorder_blocks_0 (tree);
static void reorder_blocks_1 (rtx, tree, varray_type *);
static void reorder_fix_fragments (tree);
- static tree blocks_nreverse (tree);
static int all_blocks (tree, tree *);
static tree *get_block_vector (tree, int *);
extern tree debug_find_var_in_block_tree (tree, tree);
--- 265,270 ----
*************** uninitialized_vars_warning (tree block)
*** 5607,5613 ****
flow.c that the entire aggregate was initialized.
Unions are troublesome because members may be shorter. */
&& ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
! && DECL_RTL (decl) != 0
&& GET_CODE (DECL_RTL (decl)) == REG
/* Global optimizations can make it difficult to determine if a
particular variable has been initialized. However, a VAR_DECL
--- 5606,5612 ----
flow.c that the entire aggregate was initialized.
Unions are troublesome because members may be shorter. */
&& ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
! && DECL_RTL_SET_P (decl)
&& GET_CODE (DECL_RTL (decl)) == REG
/* Global optimizations can make it difficult to determine if a
particular variable has been initialized. However, a VAR_DECL
*************** uninitialized_vars_warning (tree block)
*** 5622,5628 ****
decl, decl);
if (extra_warnings
&& TREE_CODE (decl) == VAR_DECL
! && DECL_RTL (decl) != 0
&& GET_CODE (DECL_RTL (decl)) == REG
&& regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
warning ("%Jvariable '%D' might be clobbered by `longjmp' or `vfork'",
--- 5621,5627 ----
decl, decl);
if (extra_warnings
&& TREE_CODE (decl) == VAR_DECL
! && DECL_RTL_SET_P (decl)
&& GET_CODE (DECL_RTL (decl)) == REG
&& regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
warning ("%Jvariable '%D' might be clobbered by `longjmp' or `vfork'",
*************** reorder_fix_fragments (tree block)
*** 6186,6192 ****
/* Reverse the order of elements in the chain T of blocks,
and return the new head of the chain (old last element). */
! static tree
blocks_nreverse (tree t)
{
tree prev = 0, decl, next;
--- 6185,6191 ----
/* Reverse the order of elements in the chain T of blocks,
and return the new head of the chain (old last element). */
! tree
blocks_nreverse (tree t)
{
tree prev = 0, decl, next;
*************** init_function_once (void)
*** 7955,7958 ****
--- 7954,8009 ----
VARRAY_INT_INIT (sibcall_epilogue, 0, "sibcall_epilogue");
}
+ /* Resets insn_block_boundaries array. */
+
+ void
+ reset_block_changes ()
+ {
+ VARRAY_TREE_INIT (cfun->ib_boundaries_block, 100, "ib_boundaries_block");
+ VARRAY_PUSH_TREE (cfun->ib_boundaries_block, NULL_TREE);
+ }
+
+ /* Record the boundary for BLOCK. */
+ void
+ record_block_change (tree block)
+ {
+ int i, n;
+ tree last_block;
+
+ if (!block)
+ return;
+
+ last_block = VARRAY_TOP_TREE (cfun->ib_boundaries_block);
+ VARRAY_POP (cfun->ib_boundaries_block);
+ n = get_max_uid ();
+ for (i = VARRAY_ACTIVE_SIZE (cfun->ib_boundaries_block); i < n; i++)
+ VARRAY_PUSH_TREE (cfun->ib_boundaries_block, last_block);
+
+ VARRAY_PUSH_TREE (cfun->ib_boundaries_block, block);
+ }
+
+ /* Finishes record of boundaries. */
+ void finalize_block_changes ()
+ {
+ record_block_change (DECL_INITIAL (current_function_decl));
+ }
+
+ /* For INSN return the BLOCK it belongs to. */
+ void
+ check_block_change (rtx insn, tree *block)
+ {
+ unsigned uid = INSN_UID (insn);
+
+ if (uid >= VARRAY_ACTIVE_SIZE (cfun->ib_boundaries_block))
+ return;
+
+ *block = VARRAY_TREE (cfun->ib_boundaries_block, uid);
+ }
+
+ /* Releases the ib_boundaries_block records. */
+ void
+ free_block_changes ()
+ {
+ cfun->ib_boundaries_block = NULL;
+ }
#include "gt-function.h"
Index: function.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.h,v
retrieving revision 1.83.2.15
diff -c -3 -p -r1.83.2.15 function.h
*** function.h 6 Oct 2003 17:36:33 -0000 1.83.2.15
--- function.h 26 Oct 2003 07:08:02 -0000
*************** struct function GTY(())
*** 392,397 ****
--- 392,401 ----
delay list for them is recorded here. */
rtx epilogue_delay_list;
+ /* Nonzero if NOTE_INSN_BLOCK_BEG / NOTE_INSN_BLOCK_END notes should not
+ be emitted. */
+ unsigned int dont_emit_block_notes : 1;
+
/* How commonly executed the function is. Initialized during branch
probabilities pass. */
enum function_frequency {
*************** struct function GTY(())
*** 412,417 ****
--- 416,424 ----
/* Line number of the end of the function. */
location_t function_end_locus;
+ /* Array mapping insn uids to blocks. */
+ struct varray_head_tag *ib_boundaries_block;
+
/* Collected bit flags. */
/* Nonzero if function being compiled needs to be given an address
*************** extern void reorder_blocks (void);
*** 603,608 ****
--- 610,622 ----
/* Set BLOCK_NUMBER for all the blocks in FN. */
extern void number_blocks (tree);
+
+ extern tree blocks_nreverse (tree);
+ extern void reset_block_changes (void);
+ extern void record_block_change (tree);
+ extern void finalize_block_changes (void);
+ extern void check_block_change (rtx, tree *);
+ extern void free_block_changes (void);
/* Return size needed for stack frame based on slots so far allocated.
This size counts from zero. It is not rounded to STACK_BOUNDARY;
Index: gimple-low.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimple-low.c,v
retrieving revision 1.1.4.1
diff -c -3 -p -r1.1.4.1 gimple-low.c
*** gimple-low.c 25 Oct 2003 17:48:23 -0000 1.1.4.1
--- gimple-low.c 26 Oct 2003 07:08:02 -0000
*************** Software Foundation, 59 Temple Place - S
*** 43,49 ****
struct lower_data
{
! void *dummy; /* To get rid of an empty structure warning. */
};
static void lower_stmt_body (tree *, struct lower_data *);
--- 43,50 ----
struct lower_data
{
! /* Block the current statement belongs to. */
! tree block;
};
static void lower_stmt_body (tree *, struct lower_data *);
*************** lower_function_body (tree *body)
*** 63,69 ****
--- 64,79 ----
if (TREE_CODE (*body) != BIND_EXPR)
abort ();
+ data.block = DECL_INITIAL (current_function_decl);
+ BLOCK_SUBBLOCKS (data.block) = NULL_TREE;
+ BLOCK_CHAIN (data.block) = NULL_TREE;
+
lower_stmt_body (&BIND_EXPR_BODY (*body), &data);
+
+ if (data.block != DECL_INITIAL (current_function_decl))
+ abort ();
+ BLOCK_SUBBLOCKS (data.block) =
+ blocks_nreverse (BLOCK_SUBBLOCKS (data.block));
}
/* Lowers the EXPR. Unlike gimplification the statements are not relowered
*************** lower_stmt (tree_stmt_iterator *tsi, str
*** 85,90 ****
--- 95,103 ----
{
tree stmt = tsi_stmt (*tsi);
+ if (EXPR_LOCUS (stmt))
+ TREE_BLOCK (stmt) = data->block;
+
switch (TREE_CODE (stmt))
{
case BIND_EXPR:
*************** lower_stmt (tree_stmt_iterator *tsi, str
*** 130,138 ****
--- 143,174 ----
static void
lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data)
{
+ tree old_block = data->block;
tree stmt = tsi_stmt (*tsi);
+ if (BIND_EXPR_BLOCK (stmt))
+ {
+ data->block = BIND_EXPR_BLOCK (stmt);
+
+ /* Block tree may get clobbered by inlining. Normally this would be
+ fixed in rest_of_decl_compilation using block notes, but since we
+ are not going to emit them, it is up to us. */
+ BLOCK_CHAIN (data->block) = BLOCK_SUBBLOCKS (old_block);
+ BLOCK_SUBBLOCKS (old_block) = data->block;
+ BLOCK_SUBBLOCKS (data->block) = NULL_TREE;
+ BLOCK_SUPERCONTEXT (data->block) = old_block;
+ }
lower_stmt_body (&BIND_EXPR_BODY (stmt), data);
+
+ if (BIND_EXPR_BLOCK (stmt))
+ {
+ if (data->block != BIND_EXPR_BLOCK (stmt))
+ abort ();
+
+ BLOCK_SUBBLOCKS (data->block) =
+ blocks_nreverse (BLOCK_SUBBLOCKS (data->block));
+ data->block = old_block;
+ }
}
/* Checks whether EXPR is a simple local goto. */
Index: sibcall.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sibcall.c,v
retrieving revision 1.38.2.6
diff -c -3 -p -r1.38.2.6 sibcall.c
*** sibcall.c 23 Jul 2003 16:59:57 -0000 1.38.2.6
--- sibcall.c 26 Oct 2003 07:08:02 -0000
*************** optimize_sibling_and_tail_recursive_call
*** 748,754 ****
/* There may have been NOTE_INSN_BLOCK_{BEGIN,END} notes in the
CALL_PLACEHOLDER alternatives that we didn't emit. Rebuild the
lexical block tree to correspond to the notes that still exist. */
! if (replaced_call_placeholder)
reorder_blocks ();
/* This information will be invalid after inline expansion. Kill it now. */
--- 748,755 ----
/* There may have been NOTE_INSN_BLOCK_{BEGIN,END} notes in the
CALL_PLACEHOLDER alternatives that we didn't emit. Rebuild the
lexical block tree to correspond to the notes that still exist. */
! if (replaced_call_placeholder
! && !cfun->dont_emit_block_notes)
reorder_blocks ();
/* This information will be invalid after inline expansion. Kill it now. */
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.267.2.36
diff -c -3 -p -r1.267.2.36 stmt.c
*** stmt.c 9 Oct 2003 17:09:34 -0000 1.267.2.36
--- stmt.c 26 Oct 2003 07:08:03 -0000
*************** expand_start_bindings_and_block (int fla
*** 3399,3405 ****
abort ();
/* Create a note to mark the beginning of the block. */
! if (block_flag)
{
note = emit_note (NOTE_INSN_BLOCK_BEG);
NOTE_BLOCK (note) = block;
--- 3399,3405 ----
abort ();
/* Create a note to mark the beginning of the block. */
! if (block_flag && !cfun->dont_emit_block_notes)
{
note = emit_note (NOTE_INSN_BLOCK_BEG);
NOTE_BLOCK (note) = block;
*************** expand_end_bindings (tree vars, int mark
*** 3819,3825 ****
We do this now, after running cleanups on the variables
just going out of scope, so they are in scope for their cleanups. */
! if (mark_ends)
{
rtx note = emit_note (NOTE_INSN_BLOCK_END);
NOTE_BLOCK (note) = NOTE_BLOCK (thisblock->data.block.first_insn);
--- 3819,3825 ----
We do this now, after running cleanups on the variables
just going out of scope, so they are in scope for their cleanups. */
! if (mark_ends && !cfun->dont_emit_block_notes)
{
rtx note = emit_note (NOTE_INSN_BLOCK_END);
NOTE_BLOCK (note) = NOTE_BLOCK (thisblock->data.block.first_insn);
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.654.2.69
diff -c -3 -p -r1.654.2.69 toplev.c
*** toplev.c 18 Oct 2003 23:59:51 -0000 1.654.2.69
--- toplev.c 26 Oct 2003 07:08:03 -0000
*************** rest_of_compilation (tree decl)
*** 3165,3179 ****
have been run to re-initialize it. */
cse_not_expected = ! optimize;
! /* First, make sure that NOTE_BLOCK is set correctly for each
! NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note. */
! if (!cfun->x_whole_function_mode_p)
! identify_blocks ();
!
! /* In function-at-a-time mode, we do not attempt to keep the BLOCK
! tree in sensible shape. So, we just recalculate it here. */
! if (cfun->x_whole_function_mode_p)
! reorder_blocks ();
init_flow ();
--- 3165,3184 ----
have been run to re-initialize it. */
cse_not_expected = ! optimize;
! if (!cfun->dont_emit_block_notes)
! {
! /* First, make sure that NOTE_BLOCK is set correctly for each
! NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note. */
! if (!cfun->x_whole_function_mode_p)
! identify_blocks ();
!
! /* In function-at-a-time mode, we do not attempt to keep the BLOCK
! tree in sensible shape. So, we just recalculate it here. */
! if (cfun->x_whole_function_mode_p)
! reorder_blocks ();
! }
! else
! finalize_block_changes ();
init_flow ();
*************** rest_of_compilation (tree decl)
*** 3201,3207 ****
over the instruction sequence faster, and allow the garbage
collector to reclaim the memory used by the notes. */
remove_unnecessary_notes ();
! reorder_blocks ();
ggc_collect ();
--- 3206,3213 ----
over the instruction sequence faster, and allow the garbage
collector to reclaim the memory used by the notes. */
remove_unnecessary_notes ();
! if (!cfun->dont_emit_block_notes)
! reorder_blocks ();
ggc_collect ();
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.134
diff -c -3 -p -r1.1.4.134 tree-flow.h
*** tree-flow.h 25 Oct 2003 17:48:23 -0000 1.1.4.134
--- tree-flow.h 26 Oct 2003 07:08:03 -0000
*************** extern void mark_new_vars_to_rename (tre
*** 489,494 ****
--- 489,496 ----
#define TDFA_USE_OPS 1 << 0
#define TDFA_USE_VOPS 1 << 1
+ /* In gimple-low.c */
+ void lower_function_body (tree *);
/* In tree-ssa.c */
extern void init_tree_ssa (void);
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.60
diff -c -3 -p -r1.1.4.60 tree-optimize.c
*** tree-optimize.c 25 Oct 2003 17:48:24 -0000 1.1.4.60
--- tree-optimize.c 26 Oct 2003 07:08:03 -0000
*************** optimize_function_tree (tree fndecl)
*** 64,69 ****
--- 64,74 ----
/* Build the flowgraph. */
init_flow ();
+ lower_function_body (&DECL_SAVED_TREE (fndecl));
+ /* Avoid producing notes for blocks. */
+ cfun->dont_emit_block_notes = 1;
+ reset_block_changes ();
+
build_tree_cfg (DECL_SAVED_TREE (fndecl));
/* Begin analysis and optimization passes. After the function is
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.263.2.63
diff -c -3 -p -r1.263.2.63 tree.c
*** tree.c 24 Oct 2003 03:24:45 -0000 1.263.2.63
--- tree.c 26 Oct 2003 07:08:03 -0000
*************** build1 (enum tree_code code, tree type,
*** 2448,2453 ****
--- 2448,2454 ----
SET_EXPR_LOCUS (t, NULL);
TREE_COMPLEXITY (t) = 0;
TREE_OPERAND (t, 0) = node;
+ TREE_BLOCK (t) = NULL_TREE;
if (node && first_rtl_op (code) != 0)
{
TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.114
diff -c -3 -p -r1.342.2.114 tree.h
*** tree.h 24 Oct 2003 04:28:55 -0000 1.342.2.114
--- tree.h 26 Oct 2003 07:08:03 -0000
*************** extern void tree_operand_check_failed (i
*** 432,437 ****
--- 432,439 ----
#endif
+ #define TREE_BLOCK(NODE) ((NODE)->exp.block)
+
#include "tree-check.h"
#define TYPE_CHECK(T) TREE_CLASS_CHECK (T, 't')
*************** struct tree_exp GTY(())
*** 994,999 ****
--- 996,1002 ----
struct tree_common common;
location_t *locus;
int complexity;
+ tree block;
tree GTY ((special ("tree_exp"),
desc ("TREE_CODE ((tree) &%0)")))
operands[1];