OSDN Git Service

Index: gcc/ChangeLog
[pf3gnuchains/gcc-fork.git] / gcc / tree-inline.h
index 0f36148..e191105 100644 (file)
 /* Tree inlining hooks and declarations.
-   Copyright 2001 Free Software Foundation, Inc.
+   Copyright 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Alexandre Oliva  <aoliva@redhat.com>
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
 any later version.
 
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #ifndef GCC_TREE_INLINE_H
 #define GCC_TREE_INLINE_H
 
+#include "varray.h"
+#include "pointer-set.h"
+
+
+/* Data required for function body duplication.  */
+
+typedef struct copy_body_data
+{
+  /* FUNCTION_DECL for function being inlined, or in general the
+     source function providing the original trees.  */
+  tree src_fn;
+  /* FUNCTION_DECL for function being inlined into, or in general
+     the destination function receiving the new trees.  */
+  tree dst_fn;
+  /* Callgraph node of the source function.  */
+  struct cgraph_node *src_node;
+  /* Callgraph node of the destination function.  */
+  struct cgraph_node *dst_node;
+  /* struct function for function being inlined.  Usually this is the same
+     as DECL_STRUCT_FUNCTION (src_fn), but can be different if saved_cfg
+     and saved_eh are in use.  */
+  struct function *src_cfun;
+
+  /* The VAR_DECL for the return value.  */
+  tree retvar;
+  /* The map from local declarations in the inlined function to
+     equivalents in the function into which it is being inlined.  */
+  struct pointer_map_t *decl_map;
+
+  /* Create a new decl to replace DECL in the destination function.  */
+  tree (*copy_decl) (tree, struct copy_body_data *);
+
+  /* Current BLOCK.  */
+  tree block;
+
+  /* Exception region the inlined call lie in.  */
+  int eh_region;
+  /* Take region number in the function being copied, add this value and
+     get eh region number of the duplicate in the function we inline into.  */
+  int eh_region_offset;
+
+  /* We use the same mechanism do all sorts of different things.  Rather
+     than enumerating the different cases, we categorize the behavior
+     in the various situations.  */
+
+  /* Indicate the desired behavior wrt call graph edges.  We can either
+     duplicate the edge (inlining, cloning), move the edge (versioning,
+     parallelization), or move the edges of the clones (saving).  */
+  enum copy_body_cge_which {
+    CB_CGE_DUPLICATE,
+    CB_CGE_MOVE,
+    CB_CGE_MOVE_CLONES
+  } transform_call_graph_edges;
+
+  /* True if a new CFG should be created.  False for inlining, true for
+     everything else.  */
+  bool transform_new_cfg;
+
+  /* True if RETURN_EXPRs should be transformed to just the contained
+     MODIFY_EXPR.  The branch semantics of the return will be handled
+     by manipulating the CFG rather than a statement.  */
+  bool transform_return_to_modify;
+
+  /* True if lang_hooks.decls.insert_block should be invoked when
+     duplicating BLOCK nodes.  */
+  bool transform_lang_insert_block;
+
+  /* Statements that might be possibly folded.  */
+  struct pointer_set_t *statements_to_fold;
+} copy_body_data;
+
+/* Weights of constructions for estimate_num_insns.  */
+
+typedef struct eni_weights_d
+{
+  /* Cost per call.  */
+  unsigned call_cost;
+
+  /* Cost of "expensive" div and mod operations.  */
+  unsigned div_mod_cost;
+
+  /* Cost of switch statement.  */
+  unsigned switch_cost;
+
+  /* Cost for omp construct.  */
+  unsigned omp_cost;
+} eni_weights;
+
+/* Weights that estimate_num_insns uses for heuristics in inlining.  */
+
+extern eni_weights eni_inlining_weights;
+
+/* Weights that estimate_num_insns uses to estimate the size of the
+   produced code.  */
+
+extern eni_weights eni_size_weights;
+
+/* Weights that estimate_num_insns uses to estimate the time necessary
+   to execute the produced code.  */
+
+extern eni_weights eni_time_weights;
+
 /* Function prototypes.  */
 
-void optimize_inline_calls PARAMS ((tree));
-int tree_inlinable_function_p PARAMS ((tree));
-tree walk_tree PARAMS ((tree*, walk_tree_fn, void*, void*));
-tree walk_tree_without_duplicates PARAMS ((tree*, walk_tree_fn, void*));
-tree copy_tree_r PARAMS ((tree*, int*, void*));
-void clone_body PARAMS ((tree, tree, void*));
-void remap_save_expr PARAMS ((tree*, void*, tree, int*));
-
-/* LANG_WALK_SUBTREES is called by walk_tree() after handling common
-   cases, but before walking code-specific sub-trees.  If
-   lang_walk_subtrees is defined for a language, it should handle
-   language-specific tree codes, as well as language-specific
-   information associated to common tree codes.  If a tree node is
-   completely handled within this function, it should set *SUBTREES to
-   0, so that generic handling isn't attempted.  For language-specific
-   tree codes, generic handling would abort(), so make sure it is set
-   properly.  Both SUBTREES and *SUBTREES is guaranteed to be non-zero
-   when the function is called.  */
-
-#define LANG_WALK_SUBTREES(TP,SUBTREES,FUNC,DATA,HTAB) \
-  (lang_walk_subtrees \
-   ? (*lang_walk_subtrees)((TP),(SUBTREES),(FUNC),(DATA),(HTAB)) \
-   : 0)
-typedef tree treeopt_walk_subtrees_type PARAMS ((tree*, int*, walk_tree_fn,
-                                                void*, void*));
-extern treeopt_walk_subtrees_type *lang_walk_subtrees;
-
-/* LANG_CANNOT_INLINE_TREE_FN is called to determine whether there are
-   language-specific reasons for not inlining a given function.  */
-
-#define LANG_CANNOT_INLINE_TREE_FN(FNP) \
-  (lang_cannot_inline_tree_fn ? (*lang_cannot_inline_tree_fn)(FNP) : 0)
-typedef int treeopt_cannot_inline_tree_fn_type PARAMS ((tree*));
-extern treeopt_cannot_inline_tree_fn_type *lang_cannot_inline_tree_fn;
-
-/* LANG_DISREGARD_INLINE_LIMITS is called to determine whether a
-   function should be inlined even if it would exceed inlining limits.  */
-
-#define LANG_DISREGARD_INLINE_LIMITS(FN) \
-  (lang_disregard_inline_limits ? (*lang_disregard_inline_limits)(FN) : 0)
-typedef int treeopt_disregard_inline_limits_type PARAMS ((tree));
-extern treeopt_disregard_inline_limits_type *lang_disregard_inline_limits;
-
-/* LANG_ADD_PENDING_FN_DECLS is called before starting to inline a
-   function, to push any language-specific functions that should not
-   be inlined into the current function, into VAFNP.  PFN is the top
-   of varray, and should be returned if no functions are pushed into
-   VAFNP.  The top of the varray should be returned.  */
-
-#define LANG_ADD_PENDING_FN_DECLS(VAFNP,PFN) \
-  (lang_add_pending_fn_decls \
-   ? (*lang_add_pending_fn_decls)((VAFNP),(PFN)) \
-   : (PFN))
-typedef tree treeopt_add_pending_fn_decls_type PARAMS ((void*,tree));
-extern treeopt_add_pending_fn_decls_type *lang_add_pending_fn_decls;
-
-/* LANG_TREE_CHAIN_MATTERS_P indicates whether the TREE_CHAIN of a
-   language-specific tree node is relevant, i.e., whether it should be
-   walked, copied and preserved across copies.  */
-
-#define LANG_TREE_CHAIN_MATTERS_P(T) \
-  (lang_tree_chain_matters_p ? (*lang_tree_chain_matters_p)(T) : 0)
-typedef int treeopt_tree_chain_matters_p_type PARAMS ((tree));
-extern treeopt_tree_chain_matters_p_type *lang_tree_chain_matters_p;
-
-/* LANG_AUTO_VAR_IN_FN_P is called to determine whether VT is an
-   automatic variable defined in function FT.  */
-
-#define LANG_AUTO_VAR_IN_FN_P(VT,FT) \
-  (lang_auto_var_in_fn_p ? (*lang_auto_var_in_fn_p)((VT),(FT)) \
-   : (DECL_P (VT) && DECL_CONTEXT (VT) == (FT) \
-      && (((TREE_CODE (VT) == VAR_DECL || TREE_CODE (VT) == PARM_DECL) \
-          && ! TREE_STATIC (VT)) \
-         || TREE_CODE (VT) == LABEL_DECL \
-         || TREE_CODE (VT) == RESULT_DECL)))
-typedef int treeopt_auto_var_in_fn_p_type PARAMS ((tree,tree));
-extern treeopt_auto_var_in_fn_p_type *lang_auto_var_in_fn_p;
-
-/* LANG_COPY_RES_DECL_FOR_INLINING should return a declaration for the
-   result RES of function FN to be inlined into CALLER.  NDP points to
-   an integer that should be set in case a new declaration wasn't
-   created (presumably because RES was of aggregate type, such that a
-   TARGET_EXPR is used for the result).  TEXPS is a pointer to a
-   varray with the stack of TARGET_EXPRs seen while inlining functions
-   into caller; the top of TEXPS is supposed to match RES.  */
-
-#define LANG_COPY_RES_DECL_FOR_INLINING(RES,FN,CALLER,DM,NDP,TEXPS) \
-  (lang_copy_res_decl_for_inlining \
-   ? (*lang_copy_res_decl_for_inlining)((RES),(FN),(CALLER),\
-                                       (DM),(NDP),(TEXPS)) \
-   : copy_decl_for_inlining ((RES), (FN), (CALLER)))
-typedef tree treeopt_copy_res_decl_for_inlining_type PARAMS ((tree, tree,
-                                                             tree, void*,
-                                                             int*, void*));
-extern treeopt_copy_res_decl_for_inlining_type
-*lang_copy_res_decl_for_inlining;
-
-/* LANG_ANON_AGGR_TYPE_P determines whether T is a type node
-   representing an anonymous aggregate (union, struct, etc), i.e., one
-   whose members are in the same scope as the union itself.  */
-
-#define LANG_ANON_AGGR_TYPE_P(T) \
-  (lang_anon_aggr_type_p ? (*lang_anon_aggr_type_p)(T) : 0)
-typedef int treeopt_anon_aggr_type_p PARAMS ((tree));
-extern treeopt_anon_aggr_type_p *lang_anon_aggr_type_p;
+extern tree copy_body_r (tree *, int *, void *);
+extern void insert_decl_map (copy_body_data *, tree, tree);
+
+unsigned int optimize_inline_calls (tree);
+bool tree_inlinable_function_p (tree);
+tree copy_tree_r (tree *, int *, void *);
+void clone_body (tree, tree, void *);
+void save_body (tree, tree *, tree *);
+int estimate_move_cost (tree type);
+void push_cfun (struct function *new_cfun);
+void pop_cfun (void);
+int estimate_num_insns (tree expr, eni_weights *);
+bool tree_versionable_function_p (tree);
+void tree_function_versioning (tree, tree, varray_type, bool);
+
+extern tree remap_decl (tree decl, copy_body_data *id);
+extern tree remap_type (tree type, copy_body_data *id);
+
+extern HOST_WIDE_INT estimated_stack_frame_size (void);
 
 /* 0 if we should not perform inlining.
-   1 if we should expand functions calls inline at the tree level.  
-   2 if we should consider *all* functions to be inline 
+   1 if we should expand functions calls inline at the tree level.
+   2 if we should consider *all* functions to be inline
    candidates.  */
 
 extern int flag_inline_trees;