Commit a7e5372d by Zdenek Dvorak Committed by Zdenek Dvorak

tree-ssa-loop-im.c: New file.

	* tree-ssa-loop-im.c: New file.
	* Makefile.in (tree-ssa-loop-im.o): Add.
	* cfgloop.c (superloop_at_depth): New function.
	* cfgloop.h (superloop_at_depth): Declare.
	* common.opt (ftree-lim): New flag.
	* expr.c (array_ref_up_bound): New function.
	* params.def (PARAM_LIM_EXPENSIVE): New parameter.
	* timevar.def (TV_LIM): New timevar.
	* tree-dfa.c (compute_immediate_uses): Respect TDFA_USE flags when
	computing immediate uses of a phi node.
	* tree-flow.h (struct tree_ann_common_d): Add aux field.
	(loop_commit_inserts, for_each_index, tree_ssa_lim): Declare.
	* tree-optimize.c (init_tree_optimization_passes): Add pass_lim.
	* tree-pass.h (pass_lim): Declare.
	* tree-ssa-loop.c (tree_ssa_loop_im, gate_tree_ssa_loop_im): New
	functions.
	(pass_lim): New pass structure.
	* tree-eh.c (tree_could_trap_p): Handle ARRAY_REFs correctly.
	* tree.c (in_array_bounds_p): New function.
	* tree.h (TREE_THIS_NOTRAP): Define also for ARRAY_REFs.
	(in_array_bounds_p, array_ref_up_bound): Declare.
	* doc/invoke.texi (-ftree-lim, --param lim-expensive): Document.
	* doc/passes.texi (tree-ssa-loop-im.c): Document.

From-SVN: r84441
parent ad6e2a18
2004-07-09 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* tree-ssa-loop-im.c: New file.
* Makefile.in (tree-ssa-loop-im.o): Add.
* cfgloop.c (superloop_at_depth): New function.
* cfgloop.h (superloop_at_depth): Declare.
* common.opt (ftree-lim): New flag.
* expr.c (array_ref_up_bound): New function.
* params.def (PARAM_LIM_EXPENSIVE): New parameter.
* timevar.def (TV_LIM): New timevar.
* tree-dfa.c (compute_immediate_uses): Respect TDFA_USE flags when
computing immediate uses of a phi node.
* tree-flow.h (struct tree_ann_common_d): Add aux field.
(loop_commit_inserts, for_each_index, tree_ssa_lim): Declare.
* tree-optimize.c (init_tree_optimization_passes): Add pass_lim.
* tree-pass.h (pass_lim): Declare.
* tree-ssa-loop.c (tree_ssa_loop_im, gate_tree_ssa_loop_im): New
functions.
(pass_lim): New pass structure.
* tree-eh.c (tree_could_trap_p): Handle ARRAY_REFs correctly.
* tree.c (in_array_bounds_p): New function.
* tree.h (TREE_THIS_NOTRAP): Define also for ARRAY_REFs.
(in_array_bounds_p, array_ref_up_bound): Declare.
* doc/invoke.texi (-ftree-lim, --param lim-expensive): Document.
* doc/passes.texi (tree-ssa-loop-im.c): Document.
2004-07-09 Richard Henderson <rth@redhat.com> 2004-07-09 Richard Henderson <rth@redhat.com>
* builtins.c (expand_builtin_stpcpy): Don't modify len. * builtins.c (expand_builtin_stpcpy): Don't modify len.
......
...@@ -901,7 +901,7 @@ OBJS-common = \ ...@@ -901,7 +901,7 @@ OBJS-common = \
cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o \ cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o \
cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o loop-unroll.o \ cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o loop-unroll.o \
cfgrtl.o combine.o conflict.o convert.o coverage.o cse.o cselib.o \ cfgrtl.o combine.o conflict.o convert.o coverage.o cse.o cselib.o \
dbxout.o ddg.o tree-ssa-loop-ch.o loop-invariant.o \ dbxout.o ddg.o tree-ssa-loop-ch.o loop-invariant.o tree-ssa-loop-im.o \
debug.o df.o diagnostic.o dojump.o dominance.o loop-doloop.o \ debug.o df.o diagnostic.o dojump.o dominance.o loop-doloop.o \
dwarf2asm.o dwarf2out.o emit-rtl.o except.o explow.o loop-iv.o \ dwarf2asm.o dwarf2out.o emit-rtl.o except.o explow.o loop-iv.o \
expmed.o expr.o final.o flow.o fold-const.o function.o gcse.o \ expmed.o expr.o final.o flow.o fold-const.o function.o gcse.o \
...@@ -1686,6 +1686,10 @@ tree-ssa-loop-ch.o : tree-ssa-loop-ch.c $(TREE_FLOW_H) $(CONFIG_H) \ ...@@ -1686,6 +1686,10 @@ tree-ssa-loop-ch.o : tree-ssa-loop-ch.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) tree-inline.h \ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) tree-inline.h \
output.h diagnostic.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ output.h diagnostic.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
tree-pass.h flags.h tree-pass.h flags.h
tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h $(PARAMS_H)\
output.h diagnostic.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
tree-pass.h flags.h
tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) tree-inline.h $(FLAGS_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) tree-inline.h $(FLAGS_H) \
function.h $(TIMEVAR_H) tree-alias-common.h convert.h $(TM_H) coretypes.h \ function.h $(TIMEVAR_H) tree-alias-common.h convert.h $(TM_H) coretypes.h \
......
...@@ -101,6 +101,20 @@ flow_loop_nested_p (const struct loop *outer, const struct loop *loop) ...@@ -101,6 +101,20 @@ flow_loop_nested_p (const struct loop *outer, const struct loop *loop)
&& loop->pred[outer->depth] == outer; && loop->pred[outer->depth] == outer;
} }
/* Returns superloop of LOOP at given DEPTH. */
struct loop *
superloop_at_depth (struct loop *loop, unsigned depth)
{
if (depth > (unsigned) loop->depth)
abort ();
if (depth == (unsigned) loop->depth)
return loop;
return loop->pred[depth];
}
/* Dump the loop information specified by LOOP to the stream FILE /* Dump the loop information specified by LOOP to the stream FILE
using auxiliary dump callback function LOOP_DUMP_AUX if non null. */ using auxiliary dump callback function LOOP_DUMP_AUX if non null. */
......
...@@ -256,6 +256,7 @@ extern bool flow_loop_outside_edge_p (const struct loop *, edge); ...@@ -256,6 +256,7 @@ extern bool flow_loop_outside_edge_p (const struct loop *, edge);
extern bool flow_loop_nested_p (const struct loop *, const struct loop *); extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
extern bool flow_bb_inside_loop_p (const struct loop *, const basic_block); extern bool flow_bb_inside_loop_p (const struct loop *, const basic_block);
extern struct loop * find_common_loop (struct loop *, struct loop *); extern struct loop * find_common_loop (struct loop *, struct loop *);
struct loop *superloop_at_depth (struct loop *, unsigned);
extern int num_loop_insns (struct loop *); extern int num_loop_insns (struct loop *);
extern int average_num_loop_insns (struct loop *); extern int average_num_loop_insns (struct loop *);
extern unsigned get_loop_level (const struct loop *); extern unsigned get_loop_level (const struct loop *);
......
...@@ -844,6 +844,10 @@ ftree-fre ...@@ -844,6 +844,10 @@ ftree-fre
Common Report Var(flag_tree_fre) Common Report Var(flag_tree_fre)
Enable Full Redundancy Elimination (FRE) on trees Enable Full Redundancy Elimination (FRE) on trees
ftree-lim
Common Report Var(flag_tree_lim) Init(1)
Enable loop invariant motion on trees
ftree-loop-optimize ftree-loop-optimize
Common Report Var(flag_tree_loop_optimize) Init(1) Common Report Var(flag_tree_loop_optimize) Init(1)
Enable loop optimizations on tree level Enable loop optimizations on tree level
......
...@@ -313,6 +313,7 @@ in the following sections. ...@@ -313,6 +313,7 @@ in the following sections.
-funroll-all-loops -funroll-loops -fpeel-loops @gol -funroll-all-loops -funroll-loops -fpeel-loops @gol
-funswitch-loops -fold-unroll-loops -fold-unroll-all-loops @gol -funswitch-loops -fold-unroll-loops -fold-unroll-all-loops @gol
-ftree-pre -ftree-ccp -ftree-dce -ftree-loop-optimize @gol -ftree-pre -ftree-ccp -ftree-dce -ftree-loop-optimize @gol
-ftree-lim @gol
-ftree-dominator-opts -ftree-dse -ftree-copyrename @gol -ftree-dominator-opts -ftree-dse -ftree-copyrename @gol
-ftree-ch -ftree-sra -ftree-ter -ftree-lrs -ftree-fre @gol -ftree-ch -ftree-sra -ftree-ter -ftree-lrs -ftree-fre @gol
--param @var{name}=@var{value} --param @var{name}=@var{value}
...@@ -4401,6 +4402,14 @@ usually increases code size. ...@@ -4401,6 +4402,14 @@ usually increases code size.
Perform loop optimizations on trees. This flag is enabled by default at -O Perform loop optimizations on trees. This flag is enabled by default at -O
and higher. and higher.
@item -ftree-lim
Perform loop invariant motion on trees. This pass moves only invartiants that
would be hard to handle on rtl level (function calls, operations that expand to
nontrivial sequences of insns). With @option{-funswitch-loops} it also moves
operands of conditions that are invariant out of the loop, so that we can use
just trivial invariantness analysis in loop unswitching. The pass also includes
store motion.
@item -ftree-sra @item -ftree-sra
Perform scalar replacement of aggregates. This pass replaces structure Perform scalar replacement of aggregates. This pass replaces structure
references with scalars to prevent committing structures to memory too references with scalars to prevent committing structures to memory too
...@@ -5174,6 +5183,9 @@ The maximum number of insns of an unswitched loop. ...@@ -5174,6 +5183,9 @@ The maximum number of insns of an unswitched loop.
@item max-unswitch-level @item max-unswitch-level
The maximum number of branches unswitched in a single loop. The maximum number of branches unswitched in a single loop.
@item lim-expensive
The minimum cost of an expensive expression in the loop invariant motion.
@item max-iterations-to-track @item max-iterations-to-track
The maximum number of iterations of a loop the brute force algorithm The maximum number of iterations of a loop the brute force algorithm
......
...@@ -363,9 +363,20 @@ and is described by @code{pass_pre}. ...@@ -363,9 +363,20 @@ and is described by @code{pass_pre}.
@item Loop optimization @item Loop optimization
TODO: Presumably we're going to do something with loops here. At The main driver of the pass is placed in @file{tree-ssa-loop.c}
present we don't, and this is a placeholder. The pass is located and described by @code{pass_loop}.
in @file{tree-ssa-loop.c} and is described by @code{pass_loop}.
The optimizations performed by this pass are:
Loop invariant motion. This pass moves only invariants that
would be hard to handle on rtl level (function calls, operations that expand to
nontrivial sequences of insns). With @option{-funswitch-loops} it also moves
operands of conditions that are invariant out of the loop, so that we can use
just trivial invariantness analysis in loop unswitching. The pass also includes
store motion. The pass is implemented in @file{tree-ssa-loop-im.c}.
The optimizations also use various utility functions contained in
@file{cfgloop.c}, @file{cfgloopanal.c} and @file{cfgloopmanip.c}.
@item Conditional constant propagation @item Conditional constant propagation
......
...@@ -5706,6 +5706,23 @@ array_ref_low_bound (tree exp) ...@@ -5706,6 +5706,23 @@ array_ref_low_bound (tree exp)
return fold_convert (TREE_TYPE (TREE_OPERAND (exp, 1)), integer_zero_node); return fold_convert (TREE_TYPE (TREE_OPERAND (exp, 1)), integer_zero_node);
} }
/* Return a tree representing the upper bound of the array mentioned in
EXP, an ARRAY_REF. */
tree
array_ref_up_bound (tree exp)
{
tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
/* If there is a domain type and it has an upper bound, use it, substituting
for a PLACEHOLDER_EXPR as needed. */
if (domain_type && TYPE_MAX_VALUE (domain_type))
return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp);
/* Otherwise fail. */
return NULL_TREE;
}
/* Return a tree representing the offset, in bytes, of the field referenced /* Return a tree representing the offset, in bytes, of the field referenced
by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */ by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
......
...@@ -312,6 +312,13 @@ DEFPARAM(PARAM_MAX_CSE_PATH_LENGTH, ...@@ -312,6 +312,13 @@ DEFPARAM(PARAM_MAX_CSE_PATH_LENGTH,
"The maximum length of path considered in cse", "The maximum length of path considered in cse",
10) 10)
/* The cost of expression in loop invariant motion that is considered
expensive. */
DEFPARAM(PARAM_LIM_EXPENSIVE,
"lim-expensive",
"The minimum cost of an expensive expression in the loop invariant motion",
20)
/* The product of the next two is used to decide whether or not to /* The product of the next two is used to decide whether or not to
use .GLOBAL_VAR. See tree-dfa.c. */ use .GLOBAL_VAR. See tree-dfa.c. */
DEFPARAM(PARAM_GLOBAL_VAR_THRESHOLD, DEFPARAM(PARAM_GLOBAL_VAR_THRESHOLD,
......
...@@ -82,6 +82,7 @@ DEFTIMEVAR (TV_TREE_DCE , "tree conservative DCE") ...@@ -82,6 +82,7 @@ DEFTIMEVAR (TV_TREE_DCE , "tree conservative DCE")
DEFTIMEVAR (TV_TREE_CD_DCE , "tree aggressive DCE") DEFTIMEVAR (TV_TREE_CD_DCE , "tree aggressive DCE")
DEFTIMEVAR (TV_TREE_DSE , "tree DSE") DEFTIMEVAR (TV_TREE_DSE , "tree DSE")
DEFTIMEVAR (TV_TREE_LOOP , "tree loop optimization") DEFTIMEVAR (TV_TREE_LOOP , "tree loop optimization")
DEFTIMEVAR (TV_LIM , "loop invariant motion")
DEFTIMEVAR (TV_TREE_CH , "tree copy headers") DEFTIMEVAR (TV_TREE_CH , "tree copy headers")
DEFTIMEVAR (TV_TREE_SSA_TO_NORMAL , "tree SSA to normal") DEFTIMEVAR (TV_TREE_SSA_TO_NORMAL , "tree SSA to normal")
DEFTIMEVAR (TV_TREE_NRV , "tree NRV optimization") DEFTIMEVAR (TV_TREE_NRV , "tree NRV optimization")
......
...@@ -178,7 +178,20 @@ compute_immediate_uses (int flags, bool (*calc_for)(tree)) ...@@ -178,7 +178,20 @@ compute_immediate_uses (int flags, bool (*calc_for)(tree))
tree phi; tree phi;
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
compute_immediate_uses_for_phi (phi, calc_for); {
if (is_gimple_reg (PHI_RESULT (phi)))
{
if (!(flags & TDFA_USE_OPS))
continue;
}
else
{
if (!(flags & TDFA_USE_VOPS))
continue;
}
compute_immediate_uses_for_phi (phi, calc_for);
}
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si)) for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
{ {
......
...@@ -1705,7 +1705,7 @@ tree_could_trap_p (tree expr) ...@@ -1705,7 +1705,7 @@ tree_could_trap_p (tree expr)
bool honor_nans = false; bool honor_nans = false;
bool honor_snans = false; bool honor_snans = false;
bool fp_operation = false; bool fp_operation = false;
tree t; tree t, base, idx;
if (TREE_CODE_CLASS (code) == '<' if (TREE_CODE_CLASS (code) == '<'
|| TREE_CODE_CLASS (code) == '1' || TREE_CODE_CLASS (code) == '1'
...@@ -1722,14 +1722,32 @@ tree_could_trap_p (tree expr) ...@@ -1722,14 +1722,32 @@ tree_could_trap_p (tree expr)
switch (code) switch (code)
{ {
case ARRAY_REF:
case ARRAY_RANGE_REF:
case COMPONENT_REF: case COMPONENT_REF:
case REALPART_EXPR: case REALPART_EXPR:
case IMAGPART_EXPR: case IMAGPART_EXPR:
case BIT_FIELD_REF: case BIT_FIELD_REF:
t = get_base_address (expr); t = TREE_OPERAND (expr, 0);
return !t || tree_could_trap_p (t); return tree_could_trap_p (t);
case ARRAY_RANGE_REF:
/* Let us be conservative here for now. We might be checking bounds of
the access similarly to the case below. */
if (!TREE_THIS_NOTRAP (expr))
return true;
base = TREE_OPERAND (expr, 0);
return tree_could_trap_p (base);
case ARRAY_REF:
base = TREE_OPERAND (expr, 0);
idx = TREE_OPERAND (expr, 1);
if (tree_could_trap_p (base))
return true;
if (TREE_THIS_NOTRAP (expr))
return false;
return !in_array_bounds_p (expr);
case INDIRECT_REF: case INDIRECT_REF:
return !TREE_THIS_NOTRAP (expr); return !TREE_THIS_NOTRAP (expr);
......
...@@ -83,6 +83,10 @@ struct tree_ann_common_d GTY(()) ...@@ -83,6 +83,10 @@ struct tree_ann_common_d GTY(())
/* Annotation type. */ /* Annotation type. */
enum tree_ann_type type; enum tree_ann_type type;
/* Auxiliary info specific to a pass. At all times, this
should either point to valid data or be NULL. */
PTR GTY ((skip (""))) aux;
/* The value handle for this expression. Used by GVN-PRE. */ /* The value handle for this expression. Used by GVN-PRE. */
tree GTY((skip)) value_handle; tree GTY((skip)) value_handle;
}; };
...@@ -636,6 +640,8 @@ struct tree_niter_desc ...@@ -636,6 +640,8 @@ struct tree_niter_desc
/* In tree-ssa-loop*.c */ /* In tree-ssa-loop*.c */
void tree_ssa_lim (struct loops *);
void number_of_iterations_cond (tree, tree, tree, enum tree_code, tree, tree, void number_of_iterations_cond (tree, tree, tree, enum tree_code, tree, tree,
struct tree_niter_desc *); struct tree_niter_desc *);
bool number_of_iterations_exit (struct loop *, edge, bool number_of_iterations_exit (struct loop *, edge,
...@@ -645,6 +651,8 @@ tree find_loop_niter_by_eval (struct loop *, edge *); ...@@ -645,6 +651,8 @@ tree find_loop_niter_by_eval (struct loop *, edge *);
void estimate_numbers_of_iterations (struct loops *); void estimate_numbers_of_iterations (struct loops *);
tree can_count_iv_in_wider_type (struct loop *, tree, tree, tree, tree); tree can_count_iv_in_wider_type (struct loop *, tree, tree, tree, tree);
void free_numbers_of_iterations_estimates (struct loops *); void free_numbers_of_iterations_estimates (struct loops *);
void loop_commit_inserts (void);
bool for_each_index (tree *, bool (*) (tree, tree *, void *), void *);
/* In tree-flow-inline.h */ /* In tree-flow-inline.h */
static inline int phi_arg_from_edge (tree, edge); static inline int phi_arg_from_edge (tree, edge);
......
...@@ -328,6 +328,7 @@ init_tree_optimization_passes (void) ...@@ -328,6 +328,7 @@ init_tree_optimization_passes (void)
p = &pass_loop.sub; p = &pass_loop.sub;
NEXT_PASS (pass_loop_init); NEXT_PASS (pass_loop_init);
NEXT_PASS (pass_lim);
NEXT_PASS (pass_loop_done); NEXT_PASS (pass_loop_done);
*p = NULL; *p = NULL;
......
...@@ -107,6 +107,7 @@ extern struct tree_opt_pass pass_tail_recursion; ...@@ -107,6 +107,7 @@ extern struct tree_opt_pass pass_tail_recursion;
extern struct tree_opt_pass pass_tail_calls; extern struct tree_opt_pass pass_tail_calls;
extern struct tree_opt_pass pass_loop; extern struct tree_opt_pass pass_loop;
extern struct tree_opt_pass pass_loop_init; extern struct tree_opt_pass pass_loop_init;
extern struct tree_opt_pass pass_lim;
extern struct tree_opt_pass pass_loop_done; extern struct tree_opt_pass pass_loop_done;
extern struct tree_opt_pass pass_ch; extern struct tree_opt_pass pass_ch;
extern struct tree_opt_pass pass_ccp; extern struct tree_opt_pass pass_ccp;
......
...@@ -111,6 +111,39 @@ struct tree_opt_pass pass_loop_init = ...@@ -111,6 +111,39 @@ struct tree_opt_pass pass_loop_init =
0 /* todo_flags_finish */ 0 /* todo_flags_finish */
}; };
/* Loop invariant motion pass. */
static void
tree_ssa_loop_im (void)
{
if (!current_loops)
return;
tree_ssa_lim (current_loops);
}
static bool
gate_tree_ssa_loop_im (void)
{
return flag_tree_lim != 0;
}
struct tree_opt_pass pass_lim =
{
"lim", /* name */
gate_tree_ssa_loop_im, /* gate */
tree_ssa_loop_im, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_LIM, /* tv_id */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func /* todo_flags_finish */
};
/* Loop optimizer finalization. */ /* Loop optimizer finalization. */
static void static void
......
...@@ -5650,6 +5650,34 @@ build_empty_stmt (void) ...@@ -5650,6 +5650,34 @@ build_empty_stmt (void)
} }
/* Returns true if it is possible to prove that the index of
an array access REF (an ARRAY_REF expression) falls into the
array bounds. */
bool
in_array_bounds_p (tree ref)
{
tree idx = TREE_OPERAND (ref, 1);
tree min, max;
if (TREE_CODE (idx) != INTEGER_CST)
return false;
min = array_ref_low_bound (ref);
max = array_ref_up_bound (ref);
if (!min
|| !max
|| TREE_CODE (min) != INTEGER_CST
|| TREE_CODE (max) != INTEGER_CST)
return false;
if (tree_int_cst_lt (idx, min)
|| tree_int_cst_lt (max, idx))
return false;
return true;
}
/* Return true if T (assumed to be a DECL) must be assigned a memory /* Return true if T (assumed to be a DECL) must be assigned a memory
location. */ location. */
......
...@@ -303,7 +303,7 @@ struct tree_common GTY(()) ...@@ -303,7 +303,7 @@ struct tree_common GTY(())
..._TYPE ..._TYPE
TREE_THIS_NOTRAP in TREE_THIS_NOTRAP in
INDIRECT_REF INDIRECT_REF, ARRAY_REF, ARRAY_RANGE_REF
deprecated_flag: deprecated_flag:
...@@ -798,7 +798,12 @@ extern void tree_operand_check_failed (int, enum tree_code, ...@@ -798,7 +798,12 @@ extern void tree_operand_check_failed (int, enum tree_code,
/* Nonzero means this node will not trap. In an INDIRECT_REF, means /* Nonzero means this node will not trap. In an INDIRECT_REF, means
accessing the memory pointed to won't generate a trap. However, accessing the memory pointed to won't generate a trap. However,
this only applies to an object when used appropriately: it doesn't this only applies to an object when used appropriately: it doesn't
mean that writing a READONLY mem won't trap. */ mean that writing a READONLY mem won't trap.
In ARRAY_REF and ARRAY_RANGE_REF means that we know that the index
(or slice of the array) always belongs to the range of the array.
I.e. that the access will not trap, provided that the access to
the base to the array will not trap. */
#define TREE_THIS_NOTRAP(NODE) ((NODE)->common.nothrow_flag) #define TREE_THIS_NOTRAP(NODE) ((NODE)->common.nothrow_flag)
/* In a VAR_DECL, PARM_DECL or FIELD_DECL, or any kind of ..._REF node, /* In a VAR_DECL, PARM_DECL or FIELD_DECL, or any kind of ..._REF node,
...@@ -2722,6 +2727,7 @@ extern tree build_method_type (tree, tree); ...@@ -2722,6 +2727,7 @@ extern tree build_method_type (tree, tree);
extern tree build_offset_type (tree, tree); extern tree build_offset_type (tree, tree);
extern tree build_complex_type (tree); extern tree build_complex_type (tree);
extern tree array_type_nelts (tree); extern tree array_type_nelts (tree);
extern bool in_array_bounds_p (tree);
extern tree value_member (tree, tree); extern tree value_member (tree, tree);
extern tree purpose_member (tree, tree); extern tree purpose_member (tree, tree);
...@@ -3256,6 +3262,11 @@ extern tree array_ref_element_size (tree); ...@@ -3256,6 +3262,11 @@ extern tree array_ref_element_size (tree);
extern tree array_ref_low_bound (tree); extern tree array_ref_low_bound (tree);
/* Return a tree representing the upper bound of the array mentioned in
EXP, an ARRAY_REF. */
extern tree array_ref_up_bound (tree);
/* Return a tree representing the offset, in bytes, of the field referenced /* Return a tree representing the offset, in bytes, of the field referenced
by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */ by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
......
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