Commit cf2d1b38 by Andrew Macleod

tree-flow.h: Include new .h files.


	* tree-flow.h: Include new .h files.  Move prototypes.
	* tree-cfgcleanup.h: New file.  Add prototypes from tree-flow.h.
	* tree-dfa.h: New File.  Add prototypes from tree-flow.h.
	(get_addr_base_and_unit_offset_1) Move from tree-flow-inline.h.
	* tree-pretty-print.h: Add prototypes from tree-flow.h.
	* tree-into-ssa.h: New File.  Add prototypes from tree-flow.h.
	({debug|dump}*): Move debugging prototypes out of tree-into-ssa.c.
	* tree-into-ssa.c ({debug|dump}*): Move prototypes to header file.
	* tree.h (get_ref_base_and_extent): Move prototype out.
	* tree-flow-inline.h (get_addr_base_and_unit_offset_1): Move to 
	tree-dfa.h.
	* gimple-low.h: New File.  Add prototypes from tree-flow.h.
	* gimple-low.c (try_catch_may_fallthru, block_may_fallthru): Move to...
	* tree.c (try_catch_may_fallthru, block_may_fallthru): Here.
	* tree-scalar-evolution.c: Include tree.h.
	* sese.c: Include tree.h.
	* dumpfile.c: Move gimple-pretty-print.h include after tree.h.
	* dwarf2out.c: Include tree-dfa.h.
	* tree-chrec.c: Include tree.h.
	* tree-data-ref.c: Include tree.h.

From-SVN: r203113
parent 1d2151c6
...@@ -22,8 +22,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -22,8 +22,8 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h" #include "coretypes.h"
#include "diagnostic-core.h" #include "diagnostic-core.h"
#include "dumpfile.h" #include "dumpfile.h"
#include "gimple-pretty-print.h"
#include "tree.h" #include "tree.h"
#include "gimple-pretty-print.h"
/* If non-NULL, return one past-the-end of the matching SUBPART of /* If non-NULL, return one past-the-end of the matching SUBPART of
the WHOLE string. */ the WHOLE string. */
......
...@@ -92,6 +92,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -92,6 +92,7 @@ along with GCC; see the file COPYING3. If not see
#include "lra.h" #include "lra.h"
#include "dumpfile.h" #include "dumpfile.h"
#include "opts.h" #include "opts.h"
#include "tree-dfa.h"
static void dwarf2out_source_line (unsigned int, const char *, int, bool); static void dwarf2out_source_line (unsigned int, const char *, int, bool);
static rtx last_var_location_insn; static rtx last_var_location_insn;
......
...@@ -598,56 +598,9 @@ lower_try_catch (gimple_stmt_iterator *gsi, struct lower_data *data) ...@@ -598,56 +598,9 @@ lower_try_catch (gimple_stmt_iterator *gsi, struct lower_data *data)
gsi_next (gsi); gsi_next (gsi);
} }
/* Try to determine whether a TRY_CATCH expression can fall through.
This is a subroutine of block_may_fallthru. */
static bool
try_catch_may_fallthru (const_tree stmt)
{
tree_stmt_iterator i;
/* If the TRY block can fall through, the whole TRY_CATCH can
fall through. */
if (block_may_fallthru (TREE_OPERAND (stmt, 0)))
return true;
i = tsi_start (TREE_OPERAND (stmt, 1));
switch (TREE_CODE (tsi_stmt (i)))
{
case CATCH_EXPR:
/* We expect to see a sequence of CATCH_EXPR trees, each with a
catch expression and a body. The whole TRY_CATCH may fall
through iff any of the catch bodies falls through. */
for (; !tsi_end_p (i); tsi_next (&i))
{
if (block_may_fallthru (CATCH_BODY (tsi_stmt (i))))
return true;
}
return false;
case EH_FILTER_EXPR:
/* The exception filter expression only matters if there is an
exception. If the exception does not match EH_FILTER_TYPES,
we will execute EH_FILTER_FAILURE, and we will fall through
if that falls through. If the exception does match
EH_FILTER_TYPES, the stack unwinder will continue up the
stack, so we will not fall through. We don't know whether we
will throw an exception which matches EH_FILTER_TYPES or not,
so we just ignore EH_FILTER_TYPES and assume that we might
throw an exception which doesn't match. */
return block_may_fallthru (EH_FILTER_FAILURE (tsi_stmt (i)));
default: /* Try to determine whether a TRY_CATCH expression can fall through.
/* This case represents statements to be executed when an This is a subroutine of gimple_stmt_may_fallthru. */
exception occurs. Those statements are implicitly followed
by a RESX statement to resume execution after the exception.
So in this case the TRY_CATCH never falls through. */
return false;
}
}
/* Same as above, but for a GIMPLE_TRY_CATCH. */
static bool static bool
gimple_try_catch_may_fallthru (gimple stmt) gimple_try_catch_may_fallthru (gimple stmt)
...@@ -698,81 +651,6 @@ gimple_try_catch_may_fallthru (gimple stmt) ...@@ -698,81 +651,6 @@ gimple_try_catch_may_fallthru (gimple stmt)
} }
/* Try to determine if we can fall out of the bottom of BLOCK. This guess
need not be 100% accurate; simply be conservative and return true if we
don't know. This is used only to avoid stupidly generating extra code.
If we're wrong, we'll just delete the extra code later. */
bool
block_may_fallthru (const_tree block)
{
/* This CONST_CAST is okay because expr_last returns its argument
unmodified and we assign it to a const_tree. */
const_tree stmt = expr_last (CONST_CAST_TREE (block));
switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
{
case GOTO_EXPR:
case RETURN_EXPR:
/* Easy cases. If the last statement of the block implies
control transfer, then we can't fall through. */
return false;
case SWITCH_EXPR:
/* If SWITCH_LABELS is set, this is lowered, and represents a
branch to a selected label and hence can not fall through.
Otherwise SWITCH_BODY is set, and the switch can fall
through. */
return SWITCH_LABELS (stmt) == NULL_TREE;
case COND_EXPR:
if (block_may_fallthru (COND_EXPR_THEN (stmt)))
return true;
return block_may_fallthru (COND_EXPR_ELSE (stmt));
case BIND_EXPR:
return block_may_fallthru (BIND_EXPR_BODY (stmt));
case TRY_CATCH_EXPR:
return try_catch_may_fallthru (stmt);
case TRY_FINALLY_EXPR:
/* The finally clause is always executed after the try clause,
so if it does not fall through, then the try-finally will not
fall through. Otherwise, if the try clause does not fall
through, then when the finally clause falls through it will
resume execution wherever the try clause was going. So the
whole try-finally will only fall through if both the try
clause and the finally clause fall through. */
return (block_may_fallthru (TREE_OPERAND (stmt, 0))
&& block_may_fallthru (TREE_OPERAND (stmt, 1)));
case MODIFY_EXPR:
if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
stmt = TREE_OPERAND (stmt, 1);
else
return true;
/* FALLTHRU */
case CALL_EXPR:
/* Functions that do not return do not fall through. */
return (call_expr_flags (stmt) & ECF_NORETURN) == 0;
case CLEANUP_POINT_EXPR:
return block_may_fallthru (TREE_OPERAND (stmt, 0));
case TARGET_EXPR:
return block_may_fallthru (TREE_OPERAND (stmt, 1));
case ERROR_MARK:
return true;
default:
return lang_hooks.block_may_fallthru (stmt);
}
}
/* Try to determine if we can continue executing the statement /* Try to determine if we can continue executing the statement
immediately following STMT. This guess need not be 100% accurate; immediately following STMT. This guess need not be 100% accurate;
simply be conservative and return true if we don't know. This is simply be conservative and return true if we don't know. This is
......
/* Header file for gimple lowering pass.
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_GIMPLE_LOW_H
#define GCC_GIMPLE_LOW_H
extern bool gimple_check_call_matching_types (gimple, tree, bool);
extern bool gimple_stmt_may_fallthru (gimple);
extern bool gimple_seq_may_fallthru (gimple_seq);
extern void record_vars_into (tree, tree);
extern void record_vars (tree);
#endif /* GCC_GIMPLE_LOW_H */
...@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
#include "hash-table.h" #include "hash-table.h"
#include "tree.h"
#include "tree-pretty-print.h" #include "tree-pretty-print.h"
#include "tree-ssa.h" #include "tree-ssa.h"
#include "cfgloop.h" #include "cfgloop.h"
......
/* Header file for CFG cleanup for trees.
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_CFGCLEANUP_H
#define GCC_TREE_CFGCLEANUP_H
/* In tree-cfgcleanup.c */
extern bitmap cfgcleanup_altered_bbs;
extern bool cleanup_tree_cfg (void);
extern bool fixup_noreturn_call (gimple stmt);
#endif /* GCC_TREE_CFGCLEANUP_H */
...@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
#include "tree.h"
#include "tree-pretty-print.h" #include "tree-pretty-print.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "tree-ssa.h" #include "tree-ssa.h"
......
...@@ -76,6 +76,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -76,6 +76,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
#include "tree.h"
#include "gimple-pretty-print.h" #include "gimple-pretty-print.h"
#include "tree-ssa.h" #include "tree-ssa.h"
#include "cfgloop.h" #include "cfgloop.h"
......
/* Header file for tree data flow functions.
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_DFA_H
#define GCC_TREE_DFA_H
extern void renumber_gimple_stmt_uids (void);
extern void renumber_gimple_stmt_uids_in_blocks (basic_block *, int);
extern void dump_variable (FILE *, tree);
extern void debug_variable (tree);
extern void dump_dfa_stats (FILE *);
extern void debug_dfa_stats (void);
extern tree ssa_default_def (struct function *, tree);
extern void set_ssa_default_def (struct function *, tree, tree);
extern tree get_or_create_ssa_default_def (struct function *, tree);
extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
HOST_WIDE_INT *, HOST_WIDE_INT *);
extern tree get_addr_base_and_unit_offset (tree, HOST_WIDE_INT *);
extern bool stmt_references_abnormal_ssa_name (gimple);
extern void dump_enumerated_decls (FILE *, int);
/* Returns the base object and a constant BITS_PER_UNIT offset in *POFFSET that
denotes the starting address of the memory access EXP.
Returns NULL_TREE if the offset is not constant or any component
is not BITS_PER_UNIT-aligned.
VALUEIZE if non-NULL is used to valueize SSA names. It should return
its argument or a constant if the argument is known to be constant. */
/* ??? This is a static inline here to avoid the overhead of the indirect calls
to VALUEIZE. But is this overhead really that significant? And should we
perhaps just rely on WHOPR to specialize the function? */
static inline tree
get_addr_base_and_unit_offset_1 (tree exp, HOST_WIDE_INT *poffset,
tree (*valueize) (tree))
{
HOST_WIDE_INT byte_offset = 0;
/* Compute cumulative byte-offset for nested component-refs and array-refs,
and find the ultimate containing object. */
while (1)
{
switch (TREE_CODE (exp))
{
case BIT_FIELD_REF:
{
HOST_WIDE_INT this_off = TREE_INT_CST_LOW (TREE_OPERAND (exp, 2));
if (this_off % BITS_PER_UNIT)
return NULL_TREE;
byte_offset += this_off / BITS_PER_UNIT;
}
break;
case COMPONENT_REF:
{
tree field = TREE_OPERAND (exp, 1);
tree this_offset = component_ref_field_offset (exp);
HOST_WIDE_INT hthis_offset;
if (!this_offset
|| TREE_CODE (this_offset) != INTEGER_CST
|| (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field))
% BITS_PER_UNIT))
return NULL_TREE;
hthis_offset = TREE_INT_CST_LOW (this_offset);
hthis_offset += (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field))
/ BITS_PER_UNIT);
byte_offset += hthis_offset;
}
break;
case ARRAY_REF:
case ARRAY_RANGE_REF:
{
tree index = TREE_OPERAND (exp, 1);
tree low_bound, unit_size;
if (valueize
&& TREE_CODE (index) == SSA_NAME)
index = (*valueize) (index);
/* If the resulting bit-offset is constant, track it. */
if (TREE_CODE (index) == INTEGER_CST
&& (low_bound = array_ref_low_bound (exp),
TREE_CODE (low_bound) == INTEGER_CST)
&& (unit_size = array_ref_element_size (exp),
TREE_CODE (unit_size) == INTEGER_CST))
{
HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index);
hindex -= TREE_INT_CST_LOW (low_bound);
hindex *= TREE_INT_CST_LOW (unit_size);
byte_offset += hindex;
}
else
return NULL_TREE;
}
break;
case REALPART_EXPR:
break;
case IMAGPART_EXPR:
byte_offset += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (exp)));
break;
case VIEW_CONVERT_EXPR:
break;
case MEM_REF:
{
tree base = TREE_OPERAND (exp, 0);
if (valueize
&& TREE_CODE (base) == SSA_NAME)
base = (*valueize) (base);
/* Hand back the decl for MEM[&decl, off]. */
if (TREE_CODE (base) == ADDR_EXPR)
{
if (!integer_zerop (TREE_OPERAND (exp, 1)))
{
double_int off = mem_ref_offset (exp);
gcc_assert (off.high == -1 || off.high == 0);
byte_offset += off.to_shwi ();
}
exp = TREE_OPERAND (base, 0);
}
goto done;
}
case TARGET_MEM_REF:
{
tree base = TREE_OPERAND (exp, 0);
if (valueize
&& TREE_CODE (base) == SSA_NAME)
base = (*valueize) (base);
/* Hand back the decl for MEM[&decl, off]. */
if (TREE_CODE (base) == ADDR_EXPR)
{
if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
return NULL_TREE;
if (!integer_zerop (TMR_OFFSET (exp)))
{
double_int off = mem_ref_offset (exp);
gcc_assert (off.high == -1 || off.high == 0);
byte_offset += off.to_shwi ();
}
exp = TREE_OPERAND (base, 0);
}
goto done;
}
default:
goto done;
}
exp = TREE_OPERAND (exp, 0);
}
done:
*poffset = byte_offset;
return exp;
}
#endif /* GCC_TREE_DFA_H */
...@@ -42,52 +42,6 @@ gimple_vop (const struct function *fun) ...@@ -42,52 +42,6 @@ gimple_vop (const struct function *fun)
return fun->gimple_df->vop; return fun->gimple_df->vop;
} }
/* Initialize the hashtable iterator HTI to point to hashtable TABLE */
static inline void *
first_htab_element (htab_iterator *hti, htab_t table)
{
hti->htab = table;
hti->slot = table->entries;
hti->limit = hti->slot + htab_size (table);
do
{
PTR x = *(hti->slot);
if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
break;
} while (++(hti->slot) < hti->limit);
if (hti->slot < hti->limit)
return *(hti->slot);
return NULL;
}
/* Return current non-empty/deleted slot of the hashtable pointed to by HTI,
or NULL if we have reached the end. */
static inline bool
end_htab_p (const htab_iterator *hti)
{
if (hti->slot >= hti->limit)
return true;
return false;
}
/* Advance the hashtable iterator pointed to by HTI to the next element of the
hashtable. */
static inline void *
next_htab_element (htab_iterator *hti)
{
while (++(hti->slot) < hti->limit)
{
PTR x = *(hti->slot);
if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
return x;
};
return NULL;
}
/* Get the number of the next statement uid to be allocated. */ /* Get the number of the next statement uid to be allocated. */
static inline unsigned int static inline unsigned int
gimple_stmt_max_uid (struct function *fn) gimple_stmt_max_uid (struct function *fn)
...@@ -240,149 +194,4 @@ gimple_ssa_operands (const struct function *fun) ...@@ -240,149 +194,4 @@ gimple_ssa_operands (const struct function *fun)
return &fun->gimple_df->ssa_operands; return &fun->gimple_df->ssa_operands;
} }
/* Returns the base object and a constant BITS_PER_UNIT offset in *POFFSET that
denotes the starting address of the memory access EXP.
Returns NULL_TREE if the offset is not constant or any component
is not BITS_PER_UNIT-aligned.
VALUEIZE if non-NULL is used to valueize SSA names. It should return
its argument or a constant if the argument is known to be constant. */
/* ??? This is a static inline here to avoid the overhead of the indirect calls
to VALUEIZE. But is this overhead really that significant? And should we
perhaps just rely on WHOPR to specialize the function? */
static inline tree
get_addr_base_and_unit_offset_1 (tree exp, HOST_WIDE_INT *poffset,
tree (*valueize) (tree))
{
HOST_WIDE_INT byte_offset = 0;
/* Compute cumulative byte-offset for nested component-refs and array-refs,
and find the ultimate containing object. */
while (1)
{
switch (TREE_CODE (exp))
{
case BIT_FIELD_REF:
{
HOST_WIDE_INT this_off = TREE_INT_CST_LOW (TREE_OPERAND (exp, 2));
if (this_off % BITS_PER_UNIT)
return NULL_TREE;
byte_offset += this_off / BITS_PER_UNIT;
}
break;
case COMPONENT_REF:
{
tree field = TREE_OPERAND (exp, 1);
tree this_offset = component_ref_field_offset (exp);
HOST_WIDE_INT hthis_offset;
if (!this_offset
|| TREE_CODE (this_offset) != INTEGER_CST
|| (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field))
% BITS_PER_UNIT))
return NULL_TREE;
hthis_offset = TREE_INT_CST_LOW (this_offset);
hthis_offset += (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field))
/ BITS_PER_UNIT);
byte_offset += hthis_offset;
}
break;
case ARRAY_REF:
case ARRAY_RANGE_REF:
{
tree index = TREE_OPERAND (exp, 1);
tree low_bound, unit_size;
if (valueize
&& TREE_CODE (index) == SSA_NAME)
index = (*valueize) (index);
/* If the resulting bit-offset is constant, track it. */
if (TREE_CODE (index) == INTEGER_CST
&& (low_bound = array_ref_low_bound (exp),
TREE_CODE (low_bound) == INTEGER_CST)
&& (unit_size = array_ref_element_size (exp),
TREE_CODE (unit_size) == INTEGER_CST))
{
HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index);
hindex -= TREE_INT_CST_LOW (low_bound);
hindex *= TREE_INT_CST_LOW (unit_size);
byte_offset += hindex;
}
else
return NULL_TREE;
}
break;
case REALPART_EXPR:
break;
case IMAGPART_EXPR:
byte_offset += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (exp)));
break;
case VIEW_CONVERT_EXPR:
break;
case MEM_REF:
{
tree base = TREE_OPERAND (exp, 0);
if (valueize
&& TREE_CODE (base) == SSA_NAME)
base = (*valueize) (base);
/* Hand back the decl for MEM[&decl, off]. */
if (TREE_CODE (base) == ADDR_EXPR)
{
if (!integer_zerop (TREE_OPERAND (exp, 1)))
{
double_int off = mem_ref_offset (exp);
gcc_assert (off.high == -1 || off.high == 0);
byte_offset += off.to_shwi ();
}
exp = TREE_OPERAND (base, 0);
}
goto done;
}
case TARGET_MEM_REF:
{
tree base = TREE_OPERAND (exp, 0);
if (valueize
&& TREE_CODE (base) == SSA_NAME)
base = (*valueize) (base);
/* Hand back the decl for MEM[&decl, off]. */
if (TREE_CODE (base) == ADDR_EXPR)
{
if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
return NULL_TREE;
if (!integer_zerop (TMR_OFFSET (exp)))
{
double_int off = mem_ref_offset (exp);
gcc_assert (off.high == -1 || off.high == 0);
byte_offset += off.to_shwi ();
}
exp = TREE_OPERAND (base, 0);
}
goto done;
}
default:
goto done;
}
exp = TREE_OPERAND (exp, 0);
}
done:
*poffset = byte_offset;
return exp;
}
#endif /* _TREE_FLOW_INLINE_H */ #endif /* _TREE_FLOW_INLINE_H */
...@@ -30,7 +30,11 @@ along with GCC; see the file COPYING3. If not see ...@@ -30,7 +30,11 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h" #include "cgraph.h"
#include "ipa-reference.h" #include "ipa-reference.h"
#include "tree-ssa-alias.h" #include "tree-ssa-alias.h"
#include "tree-cfgcleanup.h"
#include "tree-dfa.h"
#include "tree-pretty-print.h"
#include "gimple-low.h"
#include "tree-into-ssa.h"
/* This structure is used to map a gimple statement to a label, /* This structure is used to map a gimple statement to a label,
or list of labels to represent transaction restart. */ or list of labels to represent transaction restart. */
...@@ -92,21 +96,6 @@ struct GTY(()) gimple_df { ...@@ -92,21 +96,6 @@ struct GTY(()) gimple_df {
htab_t GTY ((param_is (struct tm_restart_node))) tm_restart; htab_t GTY ((param_is (struct tm_restart_node))) tm_restart;
}; };
typedef struct
{
htab_t htab;
PTR *slot;
PTR *limit;
} htab_iterator;
/* Iterate through the elements of hashtable HTAB, using htab_iterator ITER,
storing each element in RESULT, which is of type TYPE. */
#define FOR_EACH_HTAB_ELEMENT(HTAB, RESULT, TYPE, ITER) \
for (RESULT = (TYPE) first_htab_element (&(ITER), (HTAB)); \
!end_htab_p (&(ITER)); \
RESULT = (TYPE) next_htab_element (&(ITER)))
static inline int get_lineno (const_gimple); static inline int get_lineno (const_gimple);
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
...@@ -255,48 +244,6 @@ extern basic_block move_sese_region_to_fn (struct function *, basic_block, ...@@ -255,48 +244,6 @@ extern basic_block move_sese_region_to_fn (struct function *, basic_block,
void remove_edge_and_dominated_blocks (edge); void remove_edge_and_dominated_blocks (edge);
bool tree_node_can_be_shared (tree); bool tree_node_can_be_shared (tree);
/* In tree-cfgcleanup.c */
extern bitmap cfgcleanup_altered_bbs;
extern bool cleanup_tree_cfg (void);
/* In tree-pretty-print.c. */
extern void dump_generic_bb (FILE *, basic_block, int, int);
extern int op_code_prio (enum tree_code);
extern int op_prio (const_tree);
extern const char *op_symbol_code (enum tree_code);
/* In tree-dfa.c */
extern void renumber_gimple_stmt_uids (void);
extern void renumber_gimple_stmt_uids_in_blocks (basic_block *, int);
extern void dump_dfa_stats (FILE *);
extern void debug_dfa_stats (void);
extern void dump_variable (FILE *, tree);
extern void debug_variable (tree);
extern void set_ssa_default_def (struct function *, tree, tree);
extern tree ssa_default_def (struct function *, tree);
extern tree get_or_create_ssa_default_def (struct function *, tree);
extern bool stmt_references_abnormal_ssa_name (gimple);
extern tree get_addr_base_and_unit_offset (tree, HOST_WIDE_INT *);
extern void dump_enumerated_decls (FILE *, int);
/* In gimple-low.c */
extern void record_vars_into (tree, tree);
extern void record_vars (tree);
extern bool gimple_seq_may_fallthru (gimple_seq);
extern bool gimple_stmt_may_fallthru (gimple);
extern bool gimple_check_call_matching_types (gimple, tree, bool);
/* In tree-into-ssa.c */
void update_ssa (unsigned);
void delete_update_ssa (void);
tree create_new_def_for (tree, gimple, def_operand_p);
bool need_ssa_update_p (struct function *);
bool name_registered_for_update_p (tree);
void release_ssa_name_after_update_ssa (tree);
void mark_virtual_operands_for_renaming (struct function *);
tree get_current_def (tree);
void set_current_def (tree, tree);
/* In tree-ssa-ccp.c */ /* In tree-ssa-ccp.c */
tree fold_const_aggregate_ref (tree); tree fold_const_aggregate_ref (tree);
tree gimple_fold_stmt_to_constant (gimple, tree (*)(tree)); tree gimple_fold_stmt_to_constant (gimple, tree (*)(tree));
...@@ -539,7 +486,6 @@ void get_address_description (tree, struct mem_address *); ...@@ -539,7 +486,6 @@ void get_address_description (tree, struct mem_address *);
tree maybe_fold_tmr (tree); tree maybe_fold_tmr (tree);
unsigned int execute_fixup_cfg (void); unsigned int execute_fixup_cfg (void);
bool fixup_noreturn_call (gimple stmt);
/* In ipa-pure-const.c */ /* In ipa-pure-const.c */
void warn_function_noreturn (tree); void warn_function_noreturn (tree);
......
...@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "domwalk.h" #include "domwalk.h"
#include "params.h" #include "params.h"
#include "diagnostic-core.h" #include "diagnostic-core.h"
#include "tree-into-ssa.h"
/* This file builds the SSA form for a function as described in: /* This file builds the SSA form for a function as described in:
...@@ -253,27 +254,6 @@ enum rewrite_mode { ...@@ -253,27 +254,6 @@ enum rewrite_mode {
REWRITE_UPDATE REWRITE_UPDATE
}; };
/* Prototypes for debugging functions. */
extern void dump_tree_ssa (FILE *);
extern void debug_tree_ssa (void);
extern void debug_def_blocks (void);
extern void dump_tree_ssa_stats (FILE *);
extern void debug_tree_ssa_stats (void);
extern void dump_update_ssa (FILE *);
extern void debug_update_ssa (void);
extern void dump_names_replaced_by (FILE *, tree);
extern void debug_names_replaced_by (tree);
extern void dump_var_infos (FILE *);
extern void debug_var_infos (void);
extern void dump_defs_stack (FILE *, int);
extern void debug_defs_stack (int);
extern void dump_currdefs (FILE *);
extern void debug_currdefs (void);
/* The set of symbols we ought to re-write into SSA form in update_ssa. */ /* The set of symbols we ought to re-write into SSA form in update_ssa. */
static bitmap symbols_to_rename_set; static bitmap symbols_to_rename_set;
static vec<tree> symbols_to_rename; static vec<tree> symbols_to_rename;
......
/* Header file for normal form into SSA.
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_INTO_SSA_H
#define GCC_TREE_INTO_SSA_H
extern tree get_current_def (tree);
extern void set_current_def (tree, tree);
void delete_update_ssa (void);
tree create_new_def_for (tree, gimple, def_operand_p);
void mark_virtual_operands_for_renaming (struct function *);
bool need_ssa_update_p (struct function *);
bool name_registered_for_update_p (tree);
void release_ssa_name_after_update_ssa (tree);
void update_ssa (unsigned);
/* Prototypes for debugging functions. */
extern void debug_decl_set (bitmap set);
extern void dump_defs_stack (FILE *, int);
extern void debug_defs_stack (int);
extern void dump_currdefs (FILE *);
extern void debug_currdefs (void);
extern void dump_tree_ssa (FILE *);
extern void debug_tree_ssa (void);
extern void dump_tree_ssa_stats (FILE *);
extern void debug_tree_ssa_stats (void);
extern void dump_var_infos (FILE *);
extern void debug_var_infos (void);
extern void dump_names_replaced_by (FILE *, tree);
extern void debug_names_replaced_by (tree);
extern void dump_update_ssa (FILE *);
extern void debug_update_ssa (void);
#endif /* GCC_TREE_INTO_SSA_H */
...@@ -31,24 +31,24 @@ along with GCC; see the file COPYING3. If not see ...@@ -31,24 +31,24 @@ along with GCC; see the file COPYING3. If not see
#define pp_ti_abstract_origin(TI) ((tree *) (TI)->x_data) #define pp_ti_abstract_origin(TI) ((tree *) (TI)->x_data)
extern void pp_tree_identifier (pretty_printer *, tree);
/* In tree-pretty-print.c */ extern void debug_generic_expr (tree);
extern void print_declaration (pretty_printer *, tree, int, int); extern void debug_generic_stmt (tree);
extern int dump_generic_node (pretty_printer *, tree, int, int, bool); extern void debug_tree_chain (tree);
extern void print_generic_decl (FILE *, tree, int);
extern void print_generic_stmt (FILE *, tree, int); extern void print_generic_stmt (FILE *, tree, int);
extern void print_generic_stmt_indented (FILE *, tree, int, int); extern void print_generic_stmt_indented (FILE *, tree, int, int);
extern void print_generic_expr (FILE *, tree, int); extern void print_generic_expr (FILE *, tree, int);
extern void print_generic_decl (FILE *, tree, int);
extern void dump_omp_clauses (pretty_printer *, tree, int, int); extern void dump_omp_clauses (pretty_printer *, tree, int, int);
extern int dump_generic_node (pretty_printer *, tree, int, int, bool);
extern void print_declaration (pretty_printer *, tree, int, int);
extern int op_code_prio (enum tree_code);
extern int op_prio (const_tree);
extern const char *op_symbol_code (enum tree_code);
extern void print_call_name (pretty_printer *, tree, int); extern void print_call_name (pretty_printer *, tree, int);
extern void debug_generic_expr (tree);
extern void debug_generic_stmt (tree);
extern void debug_tree_chain (tree);
extern void percent_K_format (text_info *); extern void percent_K_format (text_info *);
extern void pp_tree_identifier (pretty_printer *, tree);
extern void dump_function_header (FILE *, tree, int); extern void dump_function_header (FILE *, tree, int);
extern void pp_double_int (pretty_printer *pp, double_int d, bool uns); extern void pp_double_int (pretty_printer *pp, double_int d, bool uns);
/* In c-pretty-print.c */
extern void debug_c_tree (tree);
#endif /* ! GCC_TREE_PRETTY_PRINT_H */ #endif /* ! GCC_TREE_PRETTY_PRINT_H */
...@@ -256,6 +256,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -256,6 +256,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
#include "tree.h"
#include "hash-table.h" #include "hash-table.h"
#include "gimple-pretty-print.h" #include "gimple-pretty-print.h"
#include "tree-ssa.h" #include "tree-ssa.h"
......
...@@ -12125,4 +12125,126 @@ contains_bitfld_component_ref_p (const_tree ref) ...@@ -12125,4 +12125,126 @@ contains_bitfld_component_ref_p (const_tree ref)
return false; return false;
} }
/* Try to determine whether a TRY_CATCH expression can fall through.
This is a subroutine of block_may_fallthru. */
static bool
try_catch_may_fallthru (const_tree stmt)
{
tree_stmt_iterator i;
/* If the TRY block can fall through, the whole TRY_CATCH can
fall through. */
if (block_may_fallthru (TREE_OPERAND (stmt, 0)))
return true;
i = tsi_start (TREE_OPERAND (stmt, 1));
switch (TREE_CODE (tsi_stmt (i)))
{
case CATCH_EXPR:
/* We expect to see a sequence of CATCH_EXPR trees, each with a
catch expression and a body. The whole TRY_CATCH may fall
through iff any of the catch bodies falls through. */
for (; !tsi_end_p (i); tsi_next (&i))
{
if (block_may_fallthru (CATCH_BODY (tsi_stmt (i))))
return true;
}
return false;
case EH_FILTER_EXPR:
/* The exception filter expression only matters if there is an
exception. If the exception does not match EH_FILTER_TYPES,
we will execute EH_FILTER_FAILURE, and we will fall through
if that falls through. If the exception does match
EH_FILTER_TYPES, the stack unwinder will continue up the
stack, so we will not fall through. We don't know whether we
will throw an exception which matches EH_FILTER_TYPES or not,
so we just ignore EH_FILTER_TYPES and assume that we might
throw an exception which doesn't match. */
return block_may_fallthru (EH_FILTER_FAILURE (tsi_stmt (i)));
default:
/* This case represents statements to be executed when an
exception occurs. Those statements are implicitly followed
by a RESX statement to resume execution after the exception.
So in this case the TRY_CATCH never falls through. */
return false;
}
}
/* Try to determine if we can fall out of the bottom of BLOCK. This guess
need not be 100% accurate; simply be conservative and return true if we
don't know. This is used only to avoid stupidly generating extra code.
If we're wrong, we'll just delete the extra code later. */
bool
block_may_fallthru (const_tree block)
{
/* This CONST_CAST is okay because expr_last returns its argument
unmodified and we assign it to a const_tree. */
const_tree stmt = expr_last (CONST_CAST_TREE (block));
switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
{
case GOTO_EXPR:
case RETURN_EXPR:
/* Easy cases. If the last statement of the block implies
control transfer, then we can't fall through. */
return false;
case SWITCH_EXPR:
/* If SWITCH_LABELS is set, this is lowered, and represents a
branch to a selected label and hence can not fall through.
Otherwise SWITCH_BODY is set, and the switch can fall
through. */
return SWITCH_LABELS (stmt) == NULL_TREE;
case COND_EXPR:
if (block_may_fallthru (COND_EXPR_THEN (stmt)))
return true;
return block_may_fallthru (COND_EXPR_ELSE (stmt));
case BIND_EXPR:
return block_may_fallthru (BIND_EXPR_BODY (stmt));
case TRY_CATCH_EXPR:
return try_catch_may_fallthru (stmt);
case TRY_FINALLY_EXPR:
/* The finally clause is always executed after the try clause,
so if it does not fall through, then the try-finally will not
fall through. Otherwise, if the try clause does not fall
through, then when the finally clause falls through it will
resume execution wherever the try clause was going. So the
whole try-finally will only fall through if both the try
clause and the finally clause fall through. */
return (block_may_fallthru (TREE_OPERAND (stmt, 0))
&& block_may_fallthru (TREE_OPERAND (stmt, 1)));
case MODIFY_EXPR:
if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
stmt = TREE_OPERAND (stmt, 1);
else
return true;
/* FALLTHRU */
case CALL_EXPR:
/* Functions that do not return do not fall through. */
return (call_expr_flags (stmt) & ECF_NORETURN) == 0;
case CLEANUP_POINT_EXPR:
return block_may_fallthru (TREE_OPERAND (stmt, 0));
case TARGET_EXPR:
return block_may_fallthru (TREE_OPERAND (stmt, 1));
case ERROR_MARK:
return true;
default:
return lang_hooks.block_may_fallthru (stmt);
}
}
#include "gt-tree.h" #include "gt-tree.h"
...@@ -4528,10 +4528,9 @@ extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree); ...@@ -4528,10 +4528,9 @@ extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
extern bool virtual_method_call_p (tree); extern bool virtual_method_call_p (tree);
extern tree obj_type_ref_class (tree ref); extern tree obj_type_ref_class (tree ref);
extern bool types_same_for_odr (tree type1, tree type2); extern bool types_same_for_odr (tree type1, tree type2);
extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
HOST_WIDE_INT *, HOST_WIDE_INT *);
extern bool contains_bitfld_component_ref_p (const_tree); extern bool contains_bitfld_component_ref_p (const_tree);
extern bool type_in_anonymous_namespace_p (tree); extern bool type_in_anonymous_namespace_p (tree);
extern bool block_may_fallthru (const_tree);
/* In tree-nested.c */ /* In tree-nested.c */
extern tree build_addr (tree, tree); extern tree build_addr (tree, tree);
...@@ -4880,9 +4879,6 @@ is_lang_specific (tree t) ...@@ -4880,9 +4879,6 @@ is_lang_specific (tree t)
return TREE_CODE (t) == LANG_TYPE || TREE_CODE (t) >= NUM_TREE_CODES; return TREE_CODE (t) == LANG_TYPE || TREE_CODE (t) >= NUM_TREE_CODES;
} }
/* In gimple-low.c. */
extern bool block_may_fallthru (const_tree);
/* In vtable-verify.c. */ /* In vtable-verify.c. */
extern void save_vtable_map_decl (tree); extern void save_vtable_map_decl (tree);
......
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