* tree-flow.h: Remove all remaining prototypes, enums and structs that
are not related to tree-cfg.c.
* tree-ssa-address.h: New file. Relocate prototypes.
* tree-ssa-address.c: (struct mem_address): Relocate from tree-flow.h.
(addr_for_mem_ref): New. Combine call to get_address_description and
return addr_for_mem_ref.
* expr.c (expand_expr_real_1): Use new addr_for_mem_ref routine.
* tree-ssa-live.h: Adjust prototypes.
* passes.c: Include tree-ssa-live.h.
* gimple-pretty-print.h (gimple_dump_bb): Add prototype.
* graphite.h: New File. Add prototypes.
* graphite.c: Include graphite.h.
* ipa-pure-const.c (warn_function_noreturn): Make static.
(execute_warn_function_noreturn, gate_warn_function_noreturn,
class pass_warn_function_noreturn, make_pass_warn_function_noreturn):
Relocate from tree-cfg.c
* tree-cfg.c (tree_node_can_be_shared, gimple_empty_block_p): Make
static.
(execute_warn_function_noreturn, gate_warn_function_noreturn,
class pass_warn_function_noreturn, make_pass_warn_function_noreturn):
Move to ipa-pure-const.c.
(execute_fixup_cfg, class pass_fixup_cfg, make_pass_fixup_cfg): Relocate
from tree-optimize.c.
* tree-optimize.c (execute_fixup_cfg, class pass_fixup_cfg,
make_pass_fixup_cfg): Move to tree-cfg.c.
* tree-chrec.h: (enum ev_direction): Relocate here from tree-flow.h.
Relocate some prototypes.
* tree-data-ref.h (tree_check_data_deps) Add prototype.
* tree-dump.c (dump_function_to_file): Remove prototype.
Add tree-flow.h to the include file.
* tree-dump.h: Remove prototype.
* tree-parloops.h: New File. Add prototypes.
* tree-parloops.c: Include tree-parloops.h.
* tree-predcom.h: New File. Add prototypes.
* tree-predcom.c: Include tree-predcom.h.
* tree-ssa-dom.c (tree_ssa_dominator_optimize) Don't call
ssa_name_values.release ().
* tree-ssa-threadedge.h: New File. Relocate prototypes here.
(ssa_name_values): Relocate from tree-flow.h.
* tree-ssa.h: Include tree-ssa-threadedge.h and tree-ssa-address.h.
* tree-ssa-loop.c: Include a few extra header files.
* tree-vectorizer.h (lpeel_tree_duplicate_loop_to_edge_cfg): Prototype
moved here.
* tree.h: Adjust prototypes.
* tree.c (mostly_copy_tree_r, copy_if_shared_r, copy_if_shared,
unshare_body, unmark_visited_r, unmark_visited, unvisit_body,
unshare_expr, prune_expr_location, unshare_expr_without_location):
Relocate from gimplify.c.
* gimple.c: (force_gimple_operand_gsi_1, force_gimple_operand_gsi):
Relocate from gimplify.c.
* gimple.h: Adjust prototypes. Include gimplfy.h.
(enum fallback, enum gimplify_status): Move to gimplify.h.
* gimplify.h: New file. Add prototypes.
(enum fallback, enum gimplify_status): Relocate here.
* gimplify.c (mostly_copy_tree_r, copy_if_shared_r, copy_if_shared,
unshare_body, unmark_visited_r, unmark_visited, unvisit_body,
unshare_expr, prune_expr_location, unshare_expr_without_location):
Move to tree.c.
(force_labels_r, rhs_predicate_for): Make static.
*************** extern void free_omp_regions (void);
void omp_expand_local (basic_block);
tree copy_var_decl (tree, tree, tree);
- /*---------------------------------------------------------------------------
- Function prototypes
- ---------------------------------------------------------------------------*/
- /* In tree-cfg.c */
-
/* Location to track pending stmt for edge insertion. */
#define PENDING_STMT(e) ((e)->insns.g)
! extern void delete_tree_cfg_annotations (void);
! extern bool stmt_ends_bb_p (gimple);
! extern bool is_ctrl_stmt (gimple);
! extern bool is_ctrl_altering_stmt (gimple);
! extern bool simple_goto_p (gimple);
! extern bool stmt_can_make_abnormal_goto (gimple);
extern basic_block single_noncomplex_succ (basic_block bb);
! extern void gimple_dump_bb (FILE *, basic_block, int, int);
extern void gimple_debug_bb (basic_block);
extern basic_block gimple_debug_bb_n (int);
- extern void gimple_dump_cfg (FILE *, int);
extern void gimple_debug_cfg (int);
extern void dump_cfg_stats (FILE *);
- extern void dot_cfg (void);
extern void debug_cfg_stats (void);
! extern void debug_loops (int);
! extern void debug_loop (struct loop *, int);
! extern void debug (struct loop &ref);
! extern void debug (struct loop *ptr);
! extern void debug_verbose (struct loop &ref);
! extern void debug_verbose (struct loop *ptr);
! extern void debug_loop_num (unsigned, int);
! extern void print_loops (FILE *, int);
! extern void print_loops_bb (FILE *, basic_block, int, int);
! extern void cleanup_dead_labels (void);
! extern void group_case_labels_stmt (gimple);
! extern void group_case_labels (void);
extern gimple first_stmt (basic_block);
extern gimple last_stmt (basic_block);
extern gimple last_and_only_stmt (basic_block);
- extern edge find_taken_edge (basic_block, tree);
- extern basic_block label_to_block_fn (struct function *, tree);
- #define label_to_block(t) (label_to_block_fn (cfun, t))
- extern void notice_special_calls (gimple);
- extern void clear_special_calls (void);
extern void verify_gimple_in_seq (gimple_seq);
extern void verify_gimple_in_cfg (struct function *);
extern tree gimple_block_label (basic_block);
! extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned,
basic_block *, bool);
extern bool gimple_duplicate_sese_tail (edge, edge, basic_block *, unsigned,
basic_block *);
extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit,
vec<basic_block> *bbs_p);
! extern void add_phi_args_after_copy_bb (basic_block);
! extern void add_phi_args_after_copy (basic_block *, unsigned, edge);
extern bool gimple_purge_dead_eh_edges (basic_block);
extern bool gimple_purge_all_dead_eh_edges (const_bitmap);
extern bool gimple_purge_dead_abnormal_call_edges (basic_block);
extern bool gimple_purge_all_dead_abnormal_call_edges (const_bitmap);
- extern tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code,
- tree, tree);
- extern tree gimplify_build2 (gimple_stmt_iterator *, enum tree_code,
- tree, tree, tree);
extern tree gimplify_build3 (gimple_stmt_iterator *, enum tree_code,
tree, tree, tree, tree);
! extern void init_empty_tree_cfg (void);
! extern void init_empty_tree_cfg_for_function (struct function *);
! extern void fold_cond_expr_cond (void);
! extern void make_abnormal_goto_edges (basic_block, bool);
! extern void replace_uses_by (tree, tree);
! extern void start_recording_case_labels (void);
! extern void end_recording_case_labels (void);
! extern basic_block move_sese_region_to_fn (struct function *, basic_block,
! basic_block, tree);
! void remove_edge_and_dominated_blocks (edge);
! bool tree_node_can_be_shared (tree);
!
!
!
! /* In tree-ssa-loop*.c */
!
! unsigned tree_predictive_commoning (void);
! bool parallelize_loops (void);
!
! bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple, bool);
!
! enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
! enum ev_direction scev_direction (const_tree);
!
! struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, edge);
!
! /* In tree-ssa-threadedge.c */
! extern void threadedge_initialize_values (void);
! extern void threadedge_finalize_values (void);
! extern vec<tree> ssa_name_values;
! #define SSA_NAME_VALUE(x) \
! (SSA_NAME_VERSION (x) < ssa_name_values.length () \
! ? ssa_name_values[SSA_NAME_VERSION (x)] \
! : NULL_TREE)
! extern void set_ssa_name_value (tree, tree);
! extern bool potentially_threadable_block (basic_block);
! extern void thread_across_edge (gimple, edge, bool,
! vec<tree> *, tree (*) (gimple, gimple));
! extern void propagate_threaded_block_debug_into (basic_block, basic_block);
!
! /* In tree-loop-linear.c */
! extern void linear_transform_loops (void);
! extern unsigned perfect_loop_nest_depth (struct loop *);
!
! /* In graphite.c */
! extern void graphite_transform_loops (void);
!
! /* In tree-data-ref.c */
! extern void tree_check_data_deps (void);
!
! /* In gimplify.c */
! tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
! tree force_gimple_operand (tree, gimple_seq *, bool, tree);
! tree force_gimple_operand_gsi_1 (gimple_stmt_iterator *, tree,
! gimple_predicate, tree,
! bool, enum gsi_iterator_update);
! tree force_gimple_operand_gsi (gimple_stmt_iterator *, tree, bool, tree,
! bool, enum gsi_iterator_update);
! tree gimple_fold_indirect_ref (tree);
!
! /* In tree-ssa-live.c */
! extern void remove_unused_locals (void);
! extern void dump_scope_blocks (FILE *, int);
! extern void debug_scope_blocks (int);
! extern void debug_scope_block (tree, int);
!
! /* In tree-ssa-address.c */
!
! /* Description of a memory address. */
!
! struct mem_address
! {
! tree symbol, base, index, step, offset;
! };
!
! struct affine_tree_combination;
! tree create_mem_ref (gimple_stmt_iterator *, tree,
! struct affine_tree_combination *, tree, tree, tree, bool);
! rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
! void get_address_description (tree, struct mem_address *);
! tree maybe_fold_tmr (tree);
!
! unsigned int execute_fixup_cfg (void);
!
! /* In ipa-pure-const.c */
! void warn_function_noreturn (tree);
!
! /* In tree-parloops.c */
! bool parallelized_function_p (tree);
- #include "tree-flow-inline.h"
#endif /* _TREE_FLOW_H */
void omp_expand_local (basic_block);
tree copy_var_decl (tree, tree, tree);
/* Location to track pending stmt for edge insertion. */
#define PENDING_STMT(e) ((e)->insns.g)
! extern void init_empty_tree_cfg_for_function (struct function *);
! extern void init_empty_tree_cfg (void);
! extern void fold_cond_expr_cond (void);
! extern void start_recording_case_labels (void);
! extern void end_recording_case_labels (void);
! extern basic_block label_to_block_fn (struct function *, tree);
! #define label_to_block(t) (label_to_block_fn (cfun, t))
! extern void make_abnormal_goto_edges (basic_block, bool);
! extern void cleanup_dead_labels (void);
! extern void group_case_labels_stmt (gimple);
! extern void group_case_labels (void);
! extern void replace_uses_by (tree, tree);
extern basic_block single_noncomplex_succ (basic_block bb);
! extern void notice_special_calls (gimple);
! extern void clear_special_calls (void);
! extern edge find_taken_edge (basic_block, tree);
extern void gimple_debug_bb (basic_block);
extern basic_block gimple_debug_bb_n (int);
extern void gimple_debug_cfg (int);
+ extern void gimple_dump_cfg (FILE *, int);
extern void dump_cfg_stats (FILE *);
extern void debug_cfg_stats (void);
! extern bool stmt_can_make_abnormal_goto (gimple);
! extern bool is_ctrl_stmt (gimple);
! extern bool is_ctrl_altering_stmt (gimple);
! extern bool simple_goto_p (gimple);
! extern bool stmt_ends_bb_p (gimple);
! extern void delete_tree_cfg_annotations (void);
extern gimple first_stmt (basic_block);
extern gimple last_stmt (basic_block);
extern gimple last_and_only_stmt (basic_block);
extern void verify_gimple_in_seq (gimple_seq);
extern void verify_gimple_in_cfg (struct function *);
extern tree gimple_block_label (basic_block);
! extern void add_phi_args_after_copy_bb (basic_block);
! extern void add_phi_args_after_copy (basic_block *, unsigned, edge);
extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned,
basic_block *, bool);
extern bool gimple_duplicate_sese_tail (edge, edge, basic_block *, unsigned,
basic_block *);
extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit,
vec<basic_block> *bbs_p);
! extern basic_block move_sese_region_to_fn (struct function *, basic_block,
! basic_block, tree);
! extern void dump_function_to_file (tree, FILE *, int);
! extern void debug_function (tree, int) ;
! extern void print_loops_bb (FILE *, basic_block, int, int);
! extern void print_loops (FILE *, int);
! extern void debug (struct loop &ref);
! extern void debug (struct loop *ptr);
! extern void debug_verbose (struct loop &ref);
! extern void debug_verbose (struct loop *ptr);
! extern void debug_loops (int);
! extern void debug_loop (struct loop *, int);
! extern void debug_loop_num (unsigned, int);
! void remove_edge_and_dominated_blocks (edge);
extern bool gimple_purge_dead_eh_edges (basic_block);
extern bool gimple_purge_all_dead_eh_edges (const_bitmap);
extern bool gimple_purge_dead_abnormal_call_edges (basic_block);
extern bool gimple_purge_all_dead_abnormal_call_edges (const_bitmap);
extern tree gimplify_build3 (gimple_stmt_iterator *, enum tree_code,
tree, tree, tree, tree);
! extern tree gimplify_build2 (gimple_stmt_iterator *, enum tree_code,
! tree, tree, tree);
! extern tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code,
! tree, tree);
! extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
! extern unsigned int execute_fixup_cfg (void);
#endif /* _TREE_FLOW_H */
***************
+ /* Header file for memory address lowering and mode selection.
+ Copyright (C) 2013 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_TREE_SSA_ADDRESS_H
+ #define GCC_TREE_SSA_ADDRESS_H
+
+ extern rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
+ extern rtx addr_for_mem_ref (tree exp, addr_space_t as, bool really_expand);
+ extern void get_address_description (tree, struct mem_address *);
+ extern tree tree_mem_ref_addr (tree, tree);
+ tree create_mem_ref (gimple_stmt_iterator *, tree,
+ struct affine_tree_combination *, tree, tree, tree, bool);
+ extern void copy_ref_info (tree, tree);
+ tree maybe_fold_tmr (tree);
+
+ #endif /* GCC_TREE_SSA_ADDRESS_H */
*************** along with GCC; see the file COPYING3.
#include "ggc.h"
#include "target.h"
#include "expmed.h"
+ #include "tree-ssa-address.h"
/* TODO -- handling of symbols (according to Richard Hendersons
comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
*************** gen_addr_rtx (enum machine_mode address_
*addr = const0_rtx;
}
+ /* Description of a memory address. */
+
+ struct mem_address
+ {
+ tree symbol, base, index, step, offset;
+ };
+
/* Returns address for TARGET_MEM_REF with parameters given by ADDR
in address space AS.
If REALLY_EXPAND is false, just make fake registers instead
*************** addr_for_mem_ref (struct mem_address *ad
return address;
}
+ /* implement addr_for_mem_ref() directly from a tree, which avoids exporting
+ the mem_address structure. */
+
+ rtx
+ addr_for_mem_ref (tree exp, addr_space_t as, bool really_expand)
+ {
+ struct mem_address addr;
+ get_address_description (exp, &addr);
+ return addr_for_mem_ref (&addr, as, really_expand);
+ }
+
/* Returns address of MEM_REF in TYPE. */
tree
*************** expand_expr_real_1 (tree exp, rtx target
{
addr_space_t as
= TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
- struct mem_address addr;
enum insn_code icode;
unsigned int align;
! get_address_description (exp, &addr);
! op0 = addr_for_mem_ref (&addr, as, true);
op0 = memory_address_addr_space (mode, op0, as);
temp = gen_rtx_MEM (mode, op0);
set_mem_attributes (temp, exp, 0);
{
addr_space_t as
= TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
enum insn_code icode;
unsigned int align;
! op0 = addr_for_mem_ref (exp, as, true);
op0 = memory_address_addr_space (mode, op0, as);
temp = gen_rtx_MEM (mode, op0);
set_mem_attributes (temp, exp, 0);
*************** typedef struct _var_map
extern var_map init_var_map (int);
extern void delete_var_map (var_map);
- extern void dump_var_map (FILE *, var_map);
- extern void debug (_var_map &ref);
- extern void debug (_var_map *ptr);
extern int var_union (var_map, tree, tree);
extern void partition_view_normal (var_map, bool);
extern void partition_view_bitmap (var_map, bitmap, bool);
#ifdef ENABLE_CHECKING
extern void register_ssa_partition_check (tree ssa_var);
#endif
extern var_map init_var_map (int);
extern void delete_var_map (var_map);
extern int var_union (var_map, tree, tree);
extern void partition_view_normal (var_map, bool);
extern void partition_view_bitmap (var_map, bitmap, bool);
+ extern void dump_scope_blocks (FILE *, int);
+ extern void debug_scope_block (tree, int);
+ extern void debug_scope_blocks (int);
+ extern void remove_unused_locals (void);
+ extern void dump_var_map (FILE *, var_map);
+ extern void debug (_var_map &ref);
+ extern void debug (_var_map *ptr);
#ifdef ENABLE_CHECKING
extern void register_ssa_partition_check (tree ssa_var);
#endif
*************** typedef struct tree_live_info_d
} *tree_live_info_p;
- extern tree_live_info_p calculate_live_ranges (var_map);
- extern void calculate_live_on_exit (tree_live_info_p);
- extern void delete_tree_live_info (tree_live_info_p);
-
#define LIVEDUMP_ENTRY 0x01
#define LIVEDUMP_EXIT 0x02
#define LIVEDUMP_ALL (LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
! extern void dump_live_info (FILE *, tree_live_info_p, int);
extern void debug (tree_live_info_d &ref);
extern void debug (tree_live_info_d *ptr);
/* Return TRUE if P is marked as a global in LIVE. */
} *tree_live_info_p;
#define LIVEDUMP_ENTRY 0x01
#define LIVEDUMP_EXIT 0x02
#define LIVEDUMP_ALL (LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
! extern void delete_tree_live_info (tree_live_info_p);
! extern void calculate_live_on_exit (tree_live_info_p);
! extern tree_live_info_p calculate_live_ranges (var_map);
extern void debug (tree_live_info_d &ref);
extern void debug (tree_live_info_d *ptr);
+ extern void dump_live_info (FILE *, tree_live_info_p, int);
/* Return TRUE if P is marked as a global in LIVE. */
*************** along with GCC; see the file COPYING3.
#include "tree-pretty-print.h" /* for dump_function_header */
#include "context.h"
#include "pass_manager.h"
+ #include "tree-ssa-live.h" /* For remove_unused_locals. */
using namespace gcc;
*************** extern void debug (gimple_statement_d &r
extern void debug (gimple_statement_d *ptr);
extern void print_gimple_expr (FILE *, gimple, int, int);
extern void pp_gimple_stmt_1 (pretty_printer *, gimple, int, int);
+ extern void gimple_dump_bb (FILE *, basic_block, int, int);
extern void gimple_dump_bb_for_graph (pretty_printer *, basic_block);
#endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */
***************
+ /* Header file for Gimple Represented as Polyhedra.
+ Copyright (C) 2013 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_GRAPHITE_H
+ #define GCC_GRAPHITE_H
+
+ extern void graphite_transform_loops (void);
+
+ #endif /* GCC_GRAPHITE_H */
*************** along with GCC; see the file COPYING3.
#include "tree-scalar-evolution.h"
#include "sese.h"
#include "dbgcnt.h"
+ #include "graphite.h"
#ifdef HAVE_cloog
*************** warn_function_const (tree decl, bool kno
known_finite, warned_about, "const");
}
! void
warn_function_noreturn (tree decl)
{
static struct pointer_set_t *warned_about;
known_finite, warned_about, "const");
}
! static void
warn_function_noreturn (tree decl)
{
static struct pointer_set_t *warned_about;
*************** make_pass_local_pure_const (gcc::context
{
return new pass_local_pure_const (ctxt);
}
+
+ /* Emit noreturn warnings. */
+
+ static unsigned int
+ execute_warn_function_noreturn (void)
+ {
+ if (!TREE_THIS_VOLATILE (current_function_decl)
+ && EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 0)
+ warn_function_noreturn (current_function_decl);
+ return 0;
+ }
+
+ static bool
+ gate_warn_function_noreturn (void)
+ {
+ return warn_suggest_attribute_noreturn;
+ }
+
+ namespace {
+
+ const pass_data pass_data_warn_function_noreturn =
+ {
+ GIMPLE_PASS, /* type */
+ "*warn_function_noreturn", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+ };
+
+ class pass_warn_function_noreturn : public gimple_opt_pass
+ {
+ public:
+ pass_warn_function_noreturn (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_warn_function_noreturn, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_warn_function_noreturn (); }
+ unsigned int execute () { return execute_warn_function_noreturn (); }
+
+ }; // class pass_warn_function_noreturn
+
+ } // anon namespace
+
+ gimple_opt_pass *
+ make_pass_warn_function_noreturn (gcc::context *ctxt)
+ {
+ return new pass_warn_function_noreturn (ctxt);
+ }
+
+
*************** along with GCC; see the file COPYING3.
#include "pointer-set.h"
#include "tree-inline.h"
#include "target.h"
+ #include "tree-ssa-live.h"
/* This file contains functions for building the Control Flow Graph (CFG)
for a function tree. */
*************** verify_gimple_in_seq (gimple_seq stmts)
/* Return true when the T can be shared. */
! bool
tree_node_can_be_shared (tree t)
{
if (IS_TYPE_OR_DECL_P (t)
/* Return true when the T can be shared. */
! static bool
tree_node_can_be_shared (tree t)
{
if (IS_TYPE_OR_DECL_P (t)
*************** gimple_move_block_after (basic_block bb,
/* Return TRUE if block BB has no executable statements, otherwise return
FALSE. */
! bool
gimple_empty_block_p (basic_block bb)
{
/* BB must have no executable statements. */
/* Return TRUE if block BB has no executable statements, otherwise return
FALSE. */
! static bool
gimple_empty_block_p (basic_block bb)
{
/* BB must have no executable statements. */
*************** make_pass_warn_function_return (gcc::con
return new pass_warn_function_return (ctxt);
}
- /* Emit noreturn warnings. */
-
- static unsigned int
- execute_warn_function_noreturn (void)
- {
- if (!TREE_THIS_VOLATILE (current_function_decl)
- && EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 0)
- warn_function_noreturn (current_function_decl);
- return 0;
- }
-
- static bool
- gate_warn_function_noreturn (void)
- {
- return warn_suggest_attribute_noreturn;
- }
-
- namespace {
-
- const pass_data pass_data_warn_function_noreturn =
- {
- GIMPLE_PASS, /* type */
- "*warn_function_noreturn", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- true, /* has_gate */
- true, /* has_execute */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- };
-
- class pass_warn_function_noreturn : public gimple_opt_pass
- {
- public:
- pass_warn_function_noreturn (gcc::context *ctxt)
- : gimple_opt_pass (pass_data_warn_function_noreturn, ctxt)
- {}
-
- /* opt_pass methods: */
- bool gate () { return gate_warn_function_noreturn (); }
- unsigned int execute () { return execute_warn_function_noreturn (); }
-
- }; // class pass_warn_function_noreturn
-
- } // anon namespace
-
- gimple_opt_pass *
- make_pass_warn_function_noreturn (gcc::context *ctxt)
- {
- return new pass_warn_function_noreturn (ctxt);
- }
-
-
/* Walk a gimplified function and warn for functions whose return value is
ignored and attribute((warn_unused_result)) is set. This is done before
inlining, so we don't have to worry about that. */
*************** make_pass_warn_unused_result (gcc::conte
return new pass_warn_unused_result (ctxt);
}
+ /* IPA passes, compilation of earlier functions or inlining
+ might have changed some properties, such as marked functions nothrow,
+ pure, const or noreturn.
+ Remove redundant edges and basic blocks, and create new ones if necessary.
+
+ This pass can't be executed as stand alone pass from pass manager, because
+ in between inlining and this fixup the verify_flow_info would fail. */
+
+ unsigned int
+ execute_fixup_cfg (void)
+ {
+ basic_block bb;
+ gimple_stmt_iterator gsi;
+ int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
+ gcov_type count_scale;
+ edge e;
+ edge_iterator ei;
+
+ count_scale
+ = GCOV_COMPUTE_SCALE (cgraph_get_node (current_function_decl)->count,
+ ENTRY_BLOCK_PTR->count);
+
+ ENTRY_BLOCK_PTR->count = cgraph_get_node (current_function_decl)->count;
+ EXIT_BLOCK_PTR->count = apply_scale (EXIT_BLOCK_PTR->count,
+ count_scale);
+
+ FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
+ e->count = apply_scale (e->count, count_scale);
+
+ FOR_EACH_BB (bb)
+ {
+ bb->count = apply_scale (bb->count, count_scale);
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ tree decl = is_gimple_call (stmt)
+ ? gimple_call_fndecl (stmt)
+ : NULL;
+ if (decl)
+ {
+ int flags = gimple_call_flags (stmt);
+ if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
+ {
+ if (gimple_purge_dead_abnormal_call_edges (bb))
+ todo |= TODO_cleanup_cfg;
+
+ if (gimple_in_ssa_p (cfun))
+ {
+ todo |= TODO_update_ssa | TODO_cleanup_cfg;
+ update_stmt (stmt);
+ }
+ }
+
+ if (flags & ECF_NORETURN
+ && fixup_noreturn_call (stmt))
+ todo |= TODO_cleanup_cfg;
+ }
+
+ if (maybe_clean_eh_stmt (stmt)
+ && gimple_purge_dead_eh_edges (bb))
+ todo |= TODO_cleanup_cfg;
+ }
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ e->count = apply_scale (e->count, count_scale);
+
+ /* If we have a basic block with no successors that does not
+ end with a control statement or a noreturn call end it with
+ a call to __builtin_unreachable. This situation can occur
+ when inlining a noreturn call that does in fact return. */
+ if (EDGE_COUNT (bb->succs) == 0)
+ {
+ gimple stmt = last_stmt (bb);
+ if (!stmt
+ || (!is_ctrl_stmt (stmt)
+ && (!is_gimple_call (stmt)
+ || (gimple_call_flags (stmt) & ECF_NORETURN) == 0)))
+ {
+ stmt = gimple_build_call
+ (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ }
+ }
+ }
+ if (count_scale != REG_BR_PROB_BASE)
+ compute_function_frequency ();
+
+ /* We just processed all calls. */
+ if (cfun->gimple_df)
+ vec_free (MODIFIED_NORETURN_CALLS (cfun));
+
+ /* Dump a textual representation of the flowgraph. */
+ if (dump_file)
+ gimple_dump_cfg (dump_file, dump_flags);
+
+ if (current_loops
+ && (todo & TODO_cleanup_cfg))
+ loops_state_set (LOOPS_NEED_FIXUP);
+
+ return todo;
+ }
+
+ namespace {
+
+ const pass_data pass_data_fixup_cfg =
+ {
+ GIMPLE_PASS, /* type */
+ "*free_cfg_annotations", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+ };
+
+ class pass_fixup_cfg : public gimple_opt_pass
+ {
+ public:
+ pass_fixup_cfg (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_fixup_cfg, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_fixup_cfg (m_ctxt); }
+ unsigned int execute () { return execute_fixup_cfg (); }
+
+ }; // class pass_fixup_cfg
+
+ } // anon namespace
+
+ gimple_opt_pass *
+ make_pass_fixup_cfg (gcc::context *ctxt)
+ {
+ return new pass_fixup_cfg (ctxt);
+ }
/* Garbage collection support for edge_def. */
*************** make_pass_cleanup_cfg_post_optimizing (g
return new pass_cleanup_cfg_post_optimizing (ctxt);
}
- /* IPA passes, compilation of earlier functions or inlining
- might have changed some properties, such as marked functions nothrow,
- pure, const or noreturn.
- Remove redundant edges and basic blocks, and create new ones if necessary.
- This pass can't be executed as stand alone pass from pass manager, because
- in between inlining and this fixup the verify_flow_info would fail. */
-
- unsigned int
- execute_fixup_cfg (void)
- {
- basic_block bb;
- gimple_stmt_iterator gsi;
- int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
- gcov_type count_scale;
- edge e;
- edge_iterator ei;
-
- count_scale
- = GCOV_COMPUTE_SCALE (cgraph_get_node (current_function_decl)->count,
- ENTRY_BLOCK_PTR->count);
-
- ENTRY_BLOCK_PTR->count = cgraph_get_node (current_function_decl)->count;
- EXIT_BLOCK_PTR->count = apply_scale (EXIT_BLOCK_PTR->count,
- count_scale);
-
- FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
- e->count = apply_scale (e->count, count_scale);
-
- FOR_EACH_BB (bb)
- {
- bb->count = apply_scale (bb->count, count_scale);
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple stmt = gsi_stmt (gsi);
- tree decl = is_gimple_call (stmt)
- ? gimple_call_fndecl (stmt)
- : NULL;
- if (decl)
- {
- int flags = gimple_call_flags (stmt);
- if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
- {
- if (gimple_purge_dead_abnormal_call_edges (bb))
- todo |= TODO_cleanup_cfg;
-
- if (gimple_in_ssa_p (cfun))
- {
- todo |= TODO_update_ssa | TODO_cleanup_cfg;
- update_stmt (stmt);
- }
- }
-
- if (flags & ECF_NORETURN
- && fixup_noreturn_call (stmt))
- todo |= TODO_cleanup_cfg;
- }
-
- if (maybe_clean_eh_stmt (stmt)
- && gimple_purge_dead_eh_edges (bb))
- todo |= TODO_cleanup_cfg;
- }
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- e->count = apply_scale (e->count, count_scale);
-
- /* If we have a basic block with no successors that does not
- end with a control statement or a noreturn call end it with
- a call to __builtin_unreachable. This situation can occur
- when inlining a noreturn call that does in fact return. */
- if (EDGE_COUNT (bb->succs) == 0)
- {
- gimple stmt = last_stmt (bb);
- if (!stmt
- || (!is_ctrl_stmt (stmt)
- && (!is_gimple_call (stmt)
- || (gimple_call_flags (stmt) & ECF_NORETURN) == 0)))
- {
- stmt = gimple_build_call
- (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
- gimple_stmt_iterator gsi = gsi_last_bb (bb);
- gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
- }
- }
- }
- if (count_scale != REG_BR_PROB_BASE)
- compute_function_frequency ();
-
- /* We just processed all calls. */
- if (cfun->gimple_df)
- vec_free (MODIFIED_NORETURN_CALLS (cfun));
-
- /* Dump a textual representation of the flowgraph. */
- if (dump_file)
- gimple_dump_cfg (dump_file, dump_flags);
-
- if (current_loops
- && (todo & TODO_cleanup_cfg))
- loops_state_set (LOOPS_NEED_FIXUP);
-
- return todo;
- }
-
- namespace {
-
- const pass_data pass_data_fixup_cfg =
- {
- GIMPLE_PASS, /* type */
- "*free_cfg_annotations", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- false, /* has_gate */
- true, /* has_execute */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- };
-
- class pass_fixup_cfg : public gimple_opt_pass
- {
- public:
- pass_fixup_cfg (gcc::context *ctxt)
- : gimple_opt_pass (pass_data_fixup_cfg, ctxt)
- {}
-
- /* opt_pass methods: */
- opt_pass * clone () { return new pass_fixup_cfg (m_ctxt); }
- unsigned int execute () { return execute_fixup_cfg (); }
-
- }; // class pass_fixup_cfg
-
- } // anon namespace
-
- gimple_opt_pass *
- make_pass_fixup_cfg (gcc::context *ctxt)
- {
- return new pass_fixup_cfg (ctxt);
- }
*************** tree_is_chrec (const_tree expr)
}
+ enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
+ enum ev_direction scev_direction (const_tree);
/* Chrec folding functions. */
extern tree chrec_fold_plus (tree, tree, tree);
*************** extern tree hide_evolution_in_other_loop
extern tree reset_evolution_in_loop (unsigned, tree, tree);
extern tree chrec_merge (tree, tree);
extern void for_each_scev_op (tree *, bool (*) (tree *, void *), void *);
+ extern bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple,
+ bool);
/* Observers. */
extern bool eq_evolutions_p (const_tree, const_tree);
*************** extern bool dr_may_alias_p (const struct
const struct data_reference *, bool);
extern bool dr_equal_offsets_p (struct data_reference *,
struct data_reference *);
+ extern void tree_check_data_deps (void);
/* Return true when the base objects of data references A and B are
*************** along with GCC; see the file COPYING3.
#include "langhooks.h"
#include "tree-iterator.h"
#include "tree-pretty-print.h"
+ #include "tree-flow.h"
static unsigned int queue (dump_info_p, const_tree, int);
static void dump_index (dump_info_p, unsigned int);
*************** extern void queue_and_dump_type (dump_in
extern void dump_function (int, tree);
extern int dump_flag (dump_info_p, int, const_tree);
- /* In tree-cfg.c */
- extern void dump_function_to_file (tree, FILE *, int);
-
#endif /* ! GCC_TREE_DUMP_H */
***************
+ /* Header file for loop autoparallelization.
+ Copyright (C) 2013 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_TREE_PARLOOPS_H
+ #define GCC_TREE_PARLOOPS_H
+
+ extern bool parallelized_function_p (tree);
+ extern bool parallelize_loops (void);
+
+ #endif /* GCC_TREE_PARLOOPS_H */
*************** along with GCC; see the file COPYING3.
#include "langhooks.h"
#include "tree-vectorizer.h"
#include "tree-hasher.h"
+ #include "tree-parloops.h"
/* This pass tries to distribute iterations of loops into several threads.
The implementation is straightforward -- for each loop we test whether its
*************** along with GCC; see the file COPYING3.
#include "tree-pass.h"
#include "tree-affine.h"
#include "tree-inline.h"
+ #include "tree-predcom.h"
/* The maximum number of iterations between the considered memory
references. */
***************
+ /* Header file for predictive commoning.
+ Copyright (C) 2013 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_TREE_PREDCOM_H
+ #define GCC_TREE_PREDCOM_H
+
+ unsigned tree_predictive_commoning (void);
+
+ #endif /* GCC_TREE_PREDCOM_H */
*************** tree_ssa_dominator_optimize (void)
/* Free the value-handle array. */
threadedge_finalize_values ();
- ssa_name_values.release ();
return 0;
}
***************
+ /* Header file for SSA jump threading.
+ Copyright (C) 2013 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_TREE_SSA_THREADEDGE_H
+ #define GCC_TREE_SSA_THREADEDGE_H
+
+ extern vec<tree> ssa_name_values;
+ #define SSA_NAME_VALUE(x) \
+ (SSA_NAME_VERSION (x) < ssa_name_values.length () \
+ ? ssa_name_values[SSA_NAME_VERSION (x)] \
+ : NULL_TREE)
+ extern void set_ssa_name_value (tree, tree);
+ extern void threadedge_initialize_values (void);
+ extern void threadedge_finalize_values (void);
+ extern bool potentially_threadable_block (basic_block);
+ extern void propagate_threaded_block_debug_into (basic_block, basic_block);
+ extern void thread_across_edge (gimple, edge, bool,
+ vec<tree> *, tree (*) (gimple, gimple));
+
+ #endif /* GCC_TREE_SSA_THREADEDGE_H */
*************** along with GCC; see the file COPYING3.
#include "tree-ssanames.h"
#include "tree-ssa-dom.h"
#include "tree-flow.h"
+ #include "tree-ssa-threadedge.h"
+ #include "tree-ssa-address.h"
/* Mapping for redirected edges. */
struct _edge_var_map {
*************** along with GCC; see the file COPYING3.
#include "tree-vectorizer.h"
#include "tree-ssa-loop-prefetch.h"
#include "tree-ssa-loop-unswitch.h"
+ #include "tree-predcom.h"
+ #include "tree-parloops.h"
+ #include "graphite.h"
+ #include "tree-data-ref.h"
/* The loop superpass. */
*************** extern LOC vect_location;
in tree-vect-loop-manip.c. */
extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge);
+ struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, edge);
extern void vect_loop_versioning (loop_vec_info, unsigned int, bool);
extern void vect_do_peeling_for_loop_bound (loop_vec_info, tree *,
unsigned int, bool);
*************** extern void cache_integer_cst (tree);
/* In cgraph.c */
extern void change_decl_assembler_name (tree, tree);
- /* In gimplify.c */
- extern tree unshare_expr (tree);
- extern tree unshare_expr_without_location (tree);
-
/* In stmt.c */
extern void expand_label (tree);
*************** extern bool block_may_fallthru (const_tr
extern void using_eh_for_cleanups (void);
extern bool using_eh_for_cleanups_p (void);
+ extern tree unshare_expr (tree);
+ extern tree unshare_expr_without_location (tree);
+ extern void unvisit_body (tree);
+ extern void unshare_body (tree);
+
/* In tree-nested.c */
extern tree build_addr (tree, tree);
*************** extern void set_decl_incoming_rtl (tree,
/* In gimple.c. */
extern tree get_base_address (tree t);
- extern void mark_addressable (tree);
/* In tree.c. */
extern int tree_map_base_eq (const void *, const void *);
*************** extern unsigned int tree_decl_map_hash (
#define tree_vec_map_hash tree_decl_map_hash
#define tree_vec_map_marked_p tree_map_base_marked_p
- /* In tree-ssa-address.c. */
- extern tree tree_mem_ref_addr (tree, tree);
- extern void copy_ref_info (tree, tree);
-
/* In tree-vrp.c */
extern bool ssa_name_nonnegative_p (const_tree);
*************** walk_tree_without_duplicates_1 (tree *tp
pointer_set_destroy (pset);
return result;
}
+
+ /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
+ nodes that are referenced more than once in GENERIC functions. This is
+ necessary because gimplification (translation into GIMPLE) is performed
+ by modifying tree nodes in-place, so gimplication of a shared node in a
+ first context could generate an invalid GIMPLE form in a second context.
+ This is achieved with a simple mark/copy/unmark algorithm that walks the
+ GENERIC representation top-down, marks nodes with TREE_VISITED the first
+ time it encounters them, duplicates them if they already have TREE_VISITED
+ set, and finally removes the TREE_VISITED marks it has set.
+
+ The algorithm works only at the function level, i.e. it generates a GENERIC
+ representation of a function with no nodes shared within the function when
+ passed a GENERIC function (except for nodes that are allowed to be shared).
+
+ At the global level, it is also necessary to unshare tree nodes that are
+ referenced in more than one function, for the same aforementioned reason.
+ This requires some cooperation from the front-end. There are 2 strategies:
+
+ 1. Manual unsharing. The front-end needs to call unshare_expr on every
+ expression that might end up being shared across functions.
+
+ 2. Deep unsharing. This is an extension of regular unsharing. Instead
+ of calling unshare_expr on expressions that might be shared across
+ functions, the front-end pre-marks them with TREE_VISITED. This will
+ ensure that they are unshared on the first reference within functions
+ when the regular unsharing algorithm runs. The counterpart is that
+ this algorithm must look deeper than for manual unsharing, which is
+ specified by LANG_HOOKS_DEEP_UNSHARING.
+
+ If there are only few specific cases of node sharing across functions, it is
+ probably easier for a front-end to unshare the expressions manually. On the
+ contrary, if the expressions generated at the global level are as widespread
+ as expressions generated within functions, deep unsharing is very likely the
+ way to go. */
+
+ /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
+ These nodes model computations that must be done once. If we were to
+ unshare something like SAVE_EXPR(i++), the gimplification process would
+ create wrong code. However, if DATA is non-null, it must hold a pointer
+ set that is used to unshare the subtrees of these nodes. */
+
+ static tree
+ mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
+ {
+ tree t = *tp;
+ enum tree_code code = TREE_CODE (t);
+
+ /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
+ copy their subtrees if we can make sure to do it only once. */
+ if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
+ {
+ if (data && !pointer_set_insert ((struct pointer_set_t *)data, t))
+ ;
+ else
+ *walk_subtrees = 0;
+ }
+
+ /* Stop at types, decls, constants like copy_tree_r. */
+ else if (TREE_CODE_CLASS (code) == tcc_type
+ || TREE_CODE_CLASS (code) == tcc_declaration
+ || TREE_CODE_CLASS (code) == tcc_constant
+ /* We can't do anything sensible with a BLOCK used as an
+ expression, but we also can't just die when we see it
+ because of non-expression uses. So we avert our eyes
+ and cross our fingers. Silly Java. */
+ || code == BLOCK)
+ *walk_subtrees = 0;
+
+ /* Cope with the statement expression extension. */
+ else if (code == STATEMENT_LIST)
+ ;
+
+ /* Leave the bulk of the work to copy_tree_r itself. */
+ else
+ copy_tree_r (tp, walk_subtrees, NULL);
+
+ return NULL_TREE;
+ }
+
+ /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
+ If *TP has been visited already, then *TP is deeply copied by calling
+ mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
+
+ static tree
+ copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
+ {
+ tree t = *tp;
+ enum tree_code code = TREE_CODE (t);
+
+ /* Skip types, decls, and constants. But we do want to look at their
+ types and the bounds of types. Mark them as visited so we properly
+ unmark their subtrees on the unmark pass. If we've already seen them,
+ don't look down further. */
+ if (TREE_CODE_CLASS (code) == tcc_type
+ || TREE_CODE_CLASS (code) == tcc_declaration
+ || TREE_CODE_CLASS (code) == tcc_constant)
+ {
+ if (TREE_VISITED (t))
+ *walk_subtrees = 0;
+ else
+ TREE_VISITED (t) = 1;
+ }
+
+ /* If this node has been visited already, unshare it and don't look
+ any deeper. */
+ else if (TREE_VISITED (t))
+ {
+ walk_tree (tp, mostly_copy_tree_r, data, NULL);
+ *walk_subtrees = 0;
+ }
+
+ /* Otherwise, mark the node as visited and keep looking. */
+ else
+ TREE_VISITED (t) = 1;
+
+ return NULL_TREE;
+ }
+
+ /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
+ copy_if_shared_r callback unmodified. */
+
+ static inline void
+ copy_if_shared (tree *tp, void *data)
+ {
+ walk_tree (tp, copy_if_shared_r, data, NULL);
+ }
+
+ /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
+ any nested functions. */
+
+ void
+ unshare_body (tree fndecl)
+ {
+ struct cgraph_node *cgn = cgraph_get_node (fndecl);
+ /* If the language requires deep unsharing, we need a pointer set to make
+ sure we don't repeatedly unshare subtrees of unshareable nodes. */
+ struct pointer_set_t *visited
+ = lang_hooks.deep_unsharing ? pointer_set_create () : NULL;
+
+ copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
+ copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
+ copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
+
+ if (visited)
+ pointer_set_destroy (visited);
+
+ if (cgn)
+ for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+ unshare_body (cgn->symbol.decl);
+ }
+
+ /* Callback for walk_tree to unmark the visited trees rooted at *TP.
+ Subtrees are walked until the first unvisited node is encountered. */
+
+ static tree
+ unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
+ {
+ tree t = *tp;
+
+ /* If this node has been visited, unmark it and keep looking. */
+ if (TREE_VISITED (t))
+ TREE_VISITED (t) = 0;
+
+ /* Otherwise, don't look any deeper. */
+ else
+ *walk_subtrees = 0;
+
+ return NULL_TREE;
+ }
+
+ /* Unmark the visited trees rooted at *TP. */
+
+ static inline void
+ unmark_visited (tree *tp)
+ {
+ walk_tree (tp, unmark_visited_r, NULL, NULL);
+ }
+
+ /* Likewise, but mark all trees as not visited. */
+
+ void
+ unvisit_body (tree fndecl)
+ {
+ struct cgraph_node *cgn = cgraph_get_node (fndecl);
+
+ unmark_visited (&DECL_SAVED_TREE (fndecl));
+ unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
+ unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
+
+ if (cgn)
+ for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+ unvisit_body (cgn->symbol.decl);
+ }
+
+ /* Unconditionally make an unshared copy of EXPR. This is used when using
+ stored expressions which span multiple functions, such as BINFO_VTABLE,
+ as the normal unsharing process can't tell that they're shared. */
+
+ tree
+ unshare_expr (tree expr)
+ {
+ walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
+ return expr;
+ }
+
+ /* Worker for unshare_expr_without_location. */
+
+ static tree
+ prune_expr_location (tree *tp, int *walk_subtrees, void *)
+ {
+ if (EXPR_P (*tp))
+ SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
+ else
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
+ /* Similar to unshare_expr but also prune all expression locations
+ from EXPR. */
+
+ tree
+ unshare_expr_without_location (tree expr)
+ {
+ walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
+ if (EXPR_P (expr))
+ walk_tree (&expr, prune_expr_location, NULL, NULL);
+ return expr;
+ }
tree
tree_block (tree t)
*************** nonfreeing_call_p (gimple call)
return false;
}
+ /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
+ and VAR. If some statements are produced, emits them at GSI.
+ If BEFORE is true. the statements are appended before GSI, otherwise
+ they are appended after it. M specifies the way GSI moves after
+ insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values). */
+
+ tree
+ force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
+ gimple_predicate gimple_test_f,
+ tree var, bool before,
+ enum gsi_iterator_update m)
+ {
+ gimple_seq stmts;
+
+ expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
+
+ if (!gimple_seq_empty_p (stmts))
+ {
+ if (before)
+ gsi_insert_seq_before (gsi, stmts, m);
+ else
+ gsi_insert_seq_after (gsi, stmts, m);
+ }
+
+ return expr;
+ }
+
+ /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
+ If SIMPLE is true, force the result to be either ssa_name or an invariant,
+ otherwise just force it to be a rhs expression. If some statements are
+ produced, emits them at GSI. If BEFORE is true, the statements are
+ appended before GSI, otherwise they are appended after it. M specifies
+ the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
+ are the usual values). */
+
+ tree
+ force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
+ bool simple_p, tree var, bool before,
+ enum gsi_iterator_update m)
+ {
+ return force_gimple_operand_gsi_1 (gsi, expr,
+ simple_p
+ ? is_gimple_val : is_gimple_reg_rhs,
+ var, before, m);
+ }
+
+
#include "gt-gimple.h"
*************** along with GCC; see the file COPYING3.
#include "internal-fn.h"
#include "gimple-fold.h"
#include "tree-eh.h"
+ #include "gimplify.h"
typedef gimple gimple_seq_node;
*************** gimple gimple_build_omp_atomic_store (tr
gimple gimple_build_transaction (gimple_seq, tree);
gimple gimple_build_predict (enum br_predictor, enum prediction);
enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
- void sort_case_labels (vec<tree> );
- void preprocess_case_label_vec_for_gimple (vec<tree> , tree, tree *);
void gimple_set_body (tree, gimple_seq);
gimple_seq gimple_body (tree);
bool gimple_has_body_p (tree);
*************** bool gimple_has_side_effects (const_gimp
bool gimple_could_trap_p (gimple);
bool gimple_could_trap_p_1 (gimple, bool, bool);
bool gimple_assign_rhs_could_trap_p (gimple);
- void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
bool empty_body_p (gimple_seq);
unsigned get_gimple_rhs_num_ops (enum tree_code);
#define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO)
*************** extern bool gimple_asm_clobbers_memory_p
extern bool useless_type_conversion_p (tree, tree);
extern bool types_compatible_p (tree, tree);
- /* In gimplify.c */
- extern tree create_tmp_var_raw (tree, const char *);
- extern tree create_tmp_var_name (const char *);
- extern tree create_tmp_var (tree, const char *);
- extern tree create_tmp_reg (tree, const char *);
- extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
- extern tree get_formal_tmp_var (tree, gimple_seq *);
- extern void declare_vars (tree, gimple, bool);
- extern void annotate_all_with_location (gimple_seq, location_t);
-
- /* Validation of GIMPLE expressions. Note that these predicates only check
- the basic form of the expression, they don't recurse to make sure that
- underlying nodes are also of the right form. */
- typedef bool (*gimple_predicate)(tree);
-
-
- /* FIXME we should deduce this from the predicate. */
- enum fallback {
- fb_none = 0, /* Do not generate a temporary. */
-
- fb_rvalue = 1, /* Generate an rvalue to hold the result of a
- gimplified expression. */
-
- fb_lvalue = 2, /* Generate an lvalue to hold the result of a
- gimplified expression. */
-
- fb_mayfail = 4, /* Gimplification may fail. Error issued
- afterwards. */
- fb_either= fb_rvalue | fb_lvalue
- };
-
- typedef int fallback_t;
-
- enum gimplify_status {
- GS_ERROR = -2, /* Something Bad Seen. */
- GS_UNHANDLED = -1, /* A langhook result for "I dunno". */
- GS_OK = 0, /* We did something, maybe more to do. */
- GS_ALL_DONE = 1 /* The expression is fully gimplified. */
- };
/* Formal (expression) temporary table handling: multiple occurrences of
the same scalar expression are evaluated into the same temporary. */
*************** inc_gimple_stmt_max_uid (struct function
return fn->last_stmt_uid++;
}
- extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
- bool (*) (tree), fallback_t);
- extern void gimplify_type_sizes (tree, gimple_seq *);
- extern void gimplify_one_sizepos (tree *, gimple_seq *);
- enum gimplify_status gimplify_self_mod_expr (tree *, gimple_seq *, gimple_seq *,
- bool, tree);
- extern bool gimplify_stmt (tree *, gimple_seq *);
- extern gimple gimplify_body (tree, bool);
extern void push_gimplify_context (struct gimplify_ctx *);
extern void pop_gimplify_context (gimple);
- extern void gimplify_and_add (tree, gimple_seq *);
/* Miscellaneous helpers. */
- extern void gimple_add_tmp_var (tree);
- extern gimple gimple_current_bind_expr (void);
- extern vec<gimple> gimple_bind_expr_stack (void);
- extern tree voidify_wrapper_expr (tree, tree);
- extern tree build_and_jump (tree *);
- extern tree force_labels_r (tree *, int *, void *);
- extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
- gimple_seq *);
struct gimplify_omp_ctx;
- extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
- extern tree gimple_boolify (tree);
- extern gimple_predicate rhs_predicate_for (tree);
extern tree canonicalize_cond_expr_cond (tree);
extern void dump_decl_set (FILE *, bitmap);
extern bool gimple_can_coalesce_p (tree, tree);
*************** extern void lower_nested_functions (tree
extern void insert_field_into_struct (tree, tree);
/* In gimplify.c. */
- extern void gimplify_function_tree (tree);
/* In cfgexpand.c. */
extern tree gimple_assign_rhs_to_tree (gimple);
*************** gimple_seq_set_location (gimple_seq seq,
#define PERCENT(x,y) ((float)(x) * 100.0 / (float)(y))
+ tree force_gimple_operand_gsi_1 (gimple_stmt_iterator *, tree,
+ gimple_predicate, tree,
+ bool, enum gsi_iterator_update);
+ tree force_gimple_operand_gsi (gimple_stmt_iterator *, tree, bool, tree,
+ bool, enum gsi_iterator_update);
+
+
#endif /* GCC_GIMPLE_H */
***************
+ /* Header file for lowering trees to gimple.
+ Copyright (C) 2013 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_GIMPLIFY_H
+ #define GCC_GIMPLIFY_H
+
+ enum gimplify_status {
+ GS_ERROR = -2, /* Something Bad Seen. */
+ GS_UNHANDLED = -1, /* A langhook result for "I dunno". */
+ GS_OK = 0, /* We did something, maybe more to do. */
+ GS_ALL_DONE = 1 /* The expression is fully gimplified. */
+ };
+
+ /* Validation of GIMPLE expressions. Note that these predicates only check
+ the basic form of the expression, they don't recurse to make sure that
+ underlying nodes are also of the right form. */
+
+ typedef bool (*gimple_predicate)(tree);
+
+ /* FIXME we should deduce this from the predicate. */
+ enum fallback {
+ fb_none = 0, /* Do not generate a temporary. */
+
+ fb_rvalue = 1, /* Generate an rvalue to hold the result of a
+ gimplified expression. */
+
+ fb_lvalue = 2, /* Generate an lvalue to hold the result of a
+ gimplified expression. */
+
+ fb_mayfail = 4, /* Gimplification may fail. Error issued
+ afterwards. */
+ fb_either= fb_rvalue | fb_lvalue
+ };
+
+ typedef int fallback_t;
+
+ extern void mark_addressable (tree);
+ extern void gimple_seq_add_stmt_without_update (gimple_seq *, gimple);
+ extern void push_gimplify_context (struct gimplify_ctx *);
+ extern void pop_gimplify_context (gimple);
+ extern gimple gimple_current_bind_expr (void);
+ extern vec<gimple> gimple_bind_expr_stack (void);
+ extern void gimplify_and_add (tree, gimple_seq *);
+ extern tree create_tmp_var_name (const char *);
+ extern tree create_tmp_var_raw (tree, const char *);
+ extern tree create_tmp_var (tree, const char *);
+ extern tree create_tmp_reg (tree, const char *);
+ extern bool is_gimple_reg_rhs (tree);
+ extern tree get_formal_tmp_var (tree, gimple_seq *);
+ extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
+ extern void declare_vars (tree, gimple, bool);
+ extern void gimple_add_tmp_var (tree);
+ extern void annotate_all_with_location (gimple_seq, location_t);
+ extern tree voidify_wrapper_expr (tree, tree);
+ extern void sort_case_labels (vec<tree> );
+ extern void preprocess_case_label_vec_for_gimple (vec<tree> , tree, tree *);
+ extern tree build_and_jump (tree *);
+ extern enum gimplify_status gimplify_self_mod_expr (tree *, gimple_seq *,
+ gimple_seq *, bool, tree);
+ extern tree gimple_boolify (tree);
+ extern tree gimple_fold_indirect_ref (tree);
+ extern bool gimplify_stmt (tree *, gimple_seq *);
+ extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
+ extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
+ bool (*) (tree), fallback_t);
+ extern void gimplify_type_sizes (tree, gimple_seq *);
+ extern void gimplify_one_sizepos (tree *, gimple_seq *);
+ extern gimple gimplify_body (tree, bool);
+ extern void gimplify_function_tree (tree);
+ extern void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
+ extern tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
+ extern tree force_gimple_operand (tree, gimple_seq *, bool, tree);
+
+ extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
+ gimple_seq *);
+ #endif /* GCC_GIMPLIFY_H */
*************** static struct gimplify_omp_ctx *gimplify
/* Forward declaration. */
static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
+ static tree force_labels_r (tree *, int *, void *);
/* Mark X addressable. Unlike the langhook we expect X to be in gimple
form and we don't do any syntax checking. */
*************** create_tmp_reg (tree type, const char *p
/* Returns true iff T is a valid RHS for an assignment to a renamed
user -- or front-end generated artificial -- variable. */
! static bool
is_gimple_reg_rhs (tree t)
{
return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
/* Returns true iff T is a valid RHS for an assignment to a renamed
user -- or front-end generated artificial -- variable. */
! bool
is_gimple_reg_rhs (tree t)
{
return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
*************** annotate_all_with_location (gimple_seq s
}
}
- /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
- nodes that are referenced more than once in GENERIC functions. This is
- necessary because gimplification (translation into GIMPLE) is performed
- by modifying tree nodes in-place, so gimplication of a shared node in a
- first context could generate an invalid GIMPLE form in a second context.
-
- This is achieved with a simple mark/copy/unmark algorithm that walks the
- GENERIC representation top-down, marks nodes with TREE_VISITED the first
- time it encounters them, duplicates them if they already have TREE_VISITED
- set, and finally removes the TREE_VISITED marks it has set.
-
- The algorithm works only at the function level, i.e. it generates a GENERIC
- representation of a function with no nodes shared within the function when
- passed a GENERIC function (except for nodes that are allowed to be shared).
-
- At the global level, it is also necessary to unshare tree nodes that are
- referenced in more than one function, for the same aforementioned reason.
- This requires some cooperation from the front-end. There are 2 strategies:
-
- 1. Manual unsharing. The front-end needs to call unshare_expr on every
- expression that might end up being shared across functions.
-
- 2. Deep unsharing. This is an extension of regular unsharing. Instead
- of calling unshare_expr on expressions that might be shared across
- functions, the front-end pre-marks them with TREE_VISITED. This will
- ensure that they are unshared on the first reference within functions
- when the regular unsharing algorithm runs. The counterpart is that
- this algorithm must look deeper than for manual unsharing, which is
- specified by LANG_HOOKS_DEEP_UNSHARING.
-
- If there are only few specific cases of node sharing across functions, it is
- probably easier for a front-end to unshare the expressions manually. On the
- contrary, if the expressions generated at the global level are as widespread
- as expressions generated within functions, deep unsharing is very likely the
- way to go. */
-
- /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
- These nodes model computations that must be done once. If we were to
- unshare something like SAVE_EXPR(i++), the gimplification process would
- create wrong code. However, if DATA is non-null, it must hold a pointer
- set that is used to unshare the subtrees of these nodes. */
-
- static tree
- mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
- {
- tree t = *tp;
- enum tree_code code = TREE_CODE (t);
-
- /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
- copy their subtrees if we can make sure to do it only once. */
- if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
- {
- if (data && !pointer_set_insert ((struct pointer_set_t *)data, t))
- ;
- else
- *walk_subtrees = 0;
- }
-
- /* Stop at types, decls, constants like copy_tree_r. */
- else if (TREE_CODE_CLASS (code) == tcc_type
- || TREE_CODE_CLASS (code) == tcc_declaration
- || TREE_CODE_CLASS (code) == tcc_constant
- /* We can't do anything sensible with a BLOCK used as an
- expression, but we also can't just die when we see it
- because of non-expression uses. So we avert our eyes
- and cross our fingers. Silly Java. */
- || code == BLOCK)
- *walk_subtrees = 0;
-
- /* Cope with the statement expression extension. */
- else if (code == STATEMENT_LIST)
- ;
-
- /* Leave the bulk of the work to copy_tree_r itself. */
- else
- copy_tree_r (tp, walk_subtrees, NULL);
-
- return NULL_TREE;
- }
-
- /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
- If *TP has been visited already, then *TP is deeply copied by calling
- mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
-
- static tree
- copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
- {
- tree t = *tp;
- enum tree_code code = TREE_CODE (t);
-
- /* Skip types, decls, and constants. But we do want to look at their
- types and the bounds of types. Mark them as visited so we properly
- unmark their subtrees on the unmark pass. If we've already seen them,
- don't look down further. */
- if (TREE_CODE_CLASS (code) == tcc_type
- || TREE_CODE_CLASS (code) == tcc_declaration
- || TREE_CODE_CLASS (code) == tcc_constant)
- {
- if (TREE_VISITED (t))
- *walk_subtrees = 0;
- else
- TREE_VISITED (t) = 1;
- }
-
- /* If this node has been visited already, unshare it and don't look
- any deeper. */
- else if (TREE_VISITED (t))
- {
- walk_tree (tp, mostly_copy_tree_r, data, NULL);
- *walk_subtrees = 0;
- }
-
- /* Otherwise, mark the node as visited and keep looking. */
- else
- TREE_VISITED (t) = 1;
-
- return NULL_TREE;
- }
-
- /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
- copy_if_shared_r callback unmodified. */
-
- static inline void
- copy_if_shared (tree *tp, void *data)
- {
- walk_tree (tp, copy_if_shared_r, data, NULL);
- }
-
- /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
- any nested functions. */
-
- static void
- unshare_body (tree fndecl)
- {
- struct cgraph_node *cgn = cgraph_get_node (fndecl);
- /* If the language requires deep unsharing, we need a pointer set to make
- sure we don't repeatedly unshare subtrees of unshareable nodes. */
- struct pointer_set_t *visited
- = lang_hooks.deep_unsharing ? pointer_set_create () : NULL;
-
- copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
- copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
- copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
-
- if (visited)
- pointer_set_destroy (visited);
-
- if (cgn)
- for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
- unshare_body (cgn->symbol.decl);
- }
-
- /* Callback for walk_tree to unmark the visited trees rooted at *TP.
- Subtrees are walked until the first unvisited node is encountered. */
-
- static tree
- unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
- {
- tree t = *tp;
-
- /* If this node has been visited, unmark it and keep looking. */
- if (TREE_VISITED (t))
- TREE_VISITED (t) = 0;
- /* Otherwise, don't look any deeper. */
- else
- *walk_subtrees = 0;
-
- return NULL_TREE;
- }
-
- /* Unmark the visited trees rooted at *TP. */
-
- static inline void
- unmark_visited (tree *tp)
- {
- walk_tree (tp, unmark_visited_r, NULL, NULL);
- }
-
- /* Likewise, but mark all trees as not visited. */
-
- static void
- unvisit_body (tree fndecl)
- {
- struct cgraph_node *cgn = cgraph_get_node (fndecl);
-
- unmark_visited (&DECL_SAVED_TREE (fndecl));
- unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
- unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
-
- if (cgn)
- for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
- unvisit_body (cgn->symbol.decl);
- }
-
- /* Unconditionally make an unshared copy of EXPR. This is used when using
- stored expressions which span multiple functions, such as BINFO_VTABLE,
- as the normal unsharing process can't tell that they're shared. */
-
- tree
- unshare_expr (tree expr)
- {
- walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
- return expr;
- }
-
- /* Worker for unshare_expr_without_location. */
-
- static tree
- prune_expr_location (tree *tp, int *walk_subtrees, void *)
- {
- if (EXPR_P (*tp))
- SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
- else
- *walk_subtrees = 0;
- return NULL_TREE;
- }
-
- /* Similar to unshare_expr but also prune all expression locations
- from EXPR. */
-
- tree
- unshare_expr_without_location (tree expr)
- {
- walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
- if (EXPR_P (expr))
- walk_tree (&expr, prune_expr_location, NULL, NULL);
- return expr;
- }
/* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
contain statements and have a value. Assign its value to a temporary
*************** gimplify_exit_expr (tree *expr_p)
/* A helper function to be called via walk_tree. Mark all labels under *TP
as being forced. To be called for DECL_INITIAL of static variables. */
! tree
force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
if (TYPE_P (*tp))
/* A helper function to be called via walk_tree. Mark all labels under *TP
as being forced. To be called for DECL_INITIAL of static variables. */
! static tree
force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
if (TYPE_P (*tp))
*************** gimplify_init_ctor_eval (tree object, ve
/* Return the appropriate RHS predicate for this LHS. */
! gimple_predicate
rhs_predicate_for (tree lhs)
{
if (is_gimple_reg (lhs))
/* Return the appropriate RHS predicate for this LHS. */
! static gimple_predicate
rhs_predicate_for (tree lhs)
{
if (is_gimple_reg (lhs))
*************** force_gimple_operand (tree expr, gimple_
var);
}
- /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
- and VAR. If some statements are produced, emits them at GSI.
- If BEFORE is true. the statements are appended before GSI, otherwise
- they are appended after it. M specifies the way GSI moves after
- insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values). */
-
- tree
- force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
- gimple_predicate gimple_test_f,
- tree var, bool before,
- enum gsi_iterator_update m)
- {
- gimple_seq stmts;
-
- expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
-
- if (!gimple_seq_empty_p (stmts))
- {
- if (before)
- gsi_insert_seq_before (gsi, stmts, m);
- else
- gsi_insert_seq_after (gsi, stmts, m);
- }
-
- return expr;
- }
-
- /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
- If SIMPLE is true, force the result to be either ssa_name or an invariant,
- otherwise just force it to be a rhs expression. If some statements are
- produced, emits them at GSI. If BEFORE is true, the statements are
- appended before GSI, otherwise they are appended after it. M specifies
- the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
- are the usual values). */
-
- tree
- force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
- bool simple_p, tree var, bool before,
- enum gsi_iterator_update m)
- {
- return force_gimple_operand_gsi_1 (gsi, expr,
- simple_p
- ? is_gimple_val : is_gimple_reg_rhs,
- var, before, m);
- }
-
-
#include "gt-gimplify.h"