summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/dumpfile.c2
-rw-r--r--gcc/dwarf2out.c1
-rw-r--r--gcc/gimple-low.c126
-rw-r--r--gcc/gimple-low.h29
-rw-r--r--gcc/sese.c1
-rw-r--r--gcc/tree-cfgcleanup.h28
-rw-r--r--gcc/tree-chrec.c1
-rw-r--r--gcc/tree-data-ref.c1
-rw-r--r--gcc/tree-dfa.h184
-rw-r--r--gcc/tree-flow-inline.h191
-rw-r--r--gcc/tree-flow.h64
-rw-r--r--gcc/tree-into-ssa.c22
-rw-r--r--gcc/tree-into-ssa.h50
-rw-r--r--gcc/tree-pretty-print.h20
-rw-r--r--gcc/tree-scalar-evolution.c1
-rw-r--r--gcc/tree.c122
-rw-r--r--gcc/tree.h6
17 files changed, 438 insertions, 411 deletions
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
index 435d22dc8eb..4a19b6d4648 100644
--- a/gcc/dumpfile.c
+++ b/gcc/dumpfile.c
@@ -22,8 +22,8 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "diagnostic-core.h"
#include "dumpfile.h"
-#include "gimple-pretty-print.h"
#include "tree.h"
+#include "gimple-pretty-print.h"
/* If non-NULL, return one past-the-end of the matching SUBPART of
the WHOLE string. */
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 8d865d38d0e..723317b8e6a 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -92,6 +92,7 @@ along with GCC; see the file COPYING3. If not see
#include "lra.h"
#include "dumpfile.h"
#include "opts.h"
+#include "tree-dfa.h"
static void dwarf2out_source_line (unsigned int, const char *, int, bool);
static rtx last_var_location_insn;
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index cf6bac2b35e..8e083aeb4d7 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -598,56 +598,9 @@ lower_try_catch (gimple_stmt_iterator *gsi, struct lower_data *data)
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:
- /* 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;
- }
-}
-
-
-/* Same as above, but for a GIMPLE_TRY_CATCH. */
+/* Try to determine whether a TRY_CATCH expression can fall through.
+ This is a subroutine of gimple_stmt_may_fallthru. */
static bool
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
immediately following STMT. This guess need not be 100% accurate;
simply be conservative and return true if we don't know. This is
diff --git a/gcc/gimple-low.h b/gcc/gimple-low.h
new file mode 100644
index 00000000000..b66de2ef2c2
--- /dev/null
+++ b/gcc/gimple-low.h
@@ -0,0 +1,29 @@
+/* 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 */
diff --git a/gcc/sese.c b/gcc/sese.c
index d5ffa25bbb9..c861b23d937 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "hash-table.h"
+#include "tree.h"
#include "tree-pretty-print.h"
#include "tree-ssa.h"
#include "cfgloop.h"
diff --git a/gcc/tree-cfgcleanup.h b/gcc/tree-cfgcleanup.h
new file mode 100644
index 00000000000..6bd3c3940ec
--- /dev/null
+++ b/gcc/tree-cfgcleanup.h
@@ -0,0 +1,28 @@
+/* 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 */
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index 16df51bbbef..64f2dcb13bf 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "tree.h"
#include "tree-pretty-print.h"
#include "cfgloop.h"
#include "tree-ssa.h"
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 530f00d82d0..9133df4a2b7 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -76,6 +76,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "tree.h"
#include "gimple-pretty-print.h"
#include "tree-ssa.h"
#include "cfgloop.h"
diff --git a/gcc/tree-dfa.h b/gcc/tree-dfa.h
new file mode 100644
index 00000000000..7d0a47009f6
--- /dev/null
+++ b/gcc/tree-dfa.h
@@ -0,0 +1,184 @@
+/* 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 */
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index b3a6d4b45c1..164df957315 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -42,52 +42,6 @@ gimple_vop (const struct function *fun)
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. */
static inline unsigned int
gimple_stmt_max_uid (struct function *fn)
@@ -240,149 +194,4 @@ gimple_ssa_operands (const struct function *fun)
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 */
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 46082e29856..d3a4e33b921 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -30,7 +30,11 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "ipa-reference.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,
or list of labels to represent transaction restart. */
@@ -92,21 +96,6 @@ struct GTY(()) gimple_df {
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);
/*---------------------------------------------------------------------------
@@ -255,48 +244,6 @@ extern basic_block move_sese_region_to_fn (struct function *, basic_block,
void remove_edge_and_dominated_blocks (edge);
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 */
tree fold_const_aggregate_ref (tree);
tree gimple_fold_stmt_to_constant (gimple, tree (*)(tree));
@@ -539,7 +486,6 @@ void get_address_description (tree, struct mem_address *);
tree maybe_fold_tmr (tree);
unsigned int execute_fixup_cfg (void);
-bool fixup_noreturn_call (gimple stmt);
/* In ipa-pure-const.c */
void warn_function_noreturn (tree);
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index c1da5e4fcbb..2f5ac69251e 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "domwalk.h"
#include "params.h"
#include "diagnostic-core.h"
+#include "tree-into-ssa.h"
/* This file builds the SSA form for a function as described in:
@@ -253,27 +254,6 @@ enum rewrite_mode {
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. */
static bitmap symbols_to_rename_set;
static vec<tree> symbols_to_rename;
diff --git a/gcc/tree-into-ssa.h b/gcc/tree-into-ssa.h
new file mode 100644
index 00000000000..0c44f046697
--- /dev/null
+++ b/gcc/tree-into-ssa.h
@@ -0,0 +1,50 @@
+/* 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 */
diff --git a/gcc/tree-pretty-print.h b/gcc/tree-pretty-print.h
index ec421fa938f..f70556db03d 100644
--- a/gcc/tree-pretty-print.h
+++ b/gcc/tree-pretty-print.h
@@ -31,24 +31,24 @@ along with GCC; see the file COPYING3. If not see
#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 print_declaration (pretty_printer *, tree, int, int);
-extern int dump_generic_node (pretty_printer *, tree, int, int, bool);
+extern void debug_generic_expr (tree);
+extern void debug_generic_stmt (tree);
+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_indented (FILE *, tree, int, 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 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 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 pp_tree_identifier (pretty_printer *, tree);
extern void dump_function_header (FILE *, tree, int);
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 */
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 06379024450..f85353c22bd 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -256,6 +256,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "tree.h"
#include "hash-table.h"
#include "gimple-pretty-print.h"
#include "tree-ssa.h"
diff --git a/gcc/tree.c b/gcc/tree.c
index ebee116f0c5..705332f878c 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -12125,4 +12125,126 @@ contains_bitfld_component_ref_p (const_tree ref)
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"
diff --git a/gcc/tree.h b/gcc/tree.h
index 4cd7e9e9f65..a71cd96414f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4528,10 +4528,9 @@ extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
extern bool virtual_method_call_p (tree);
extern tree obj_type_ref_class (tree ref);
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 type_in_anonymous_namespace_p (tree);
+extern bool block_may_fallthru (const_tree);
/* In tree-nested.c */
extern tree build_addr (tree, tree);
@@ -4880,9 +4879,6 @@ is_lang_specific (tree t)
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. */
extern void save_vtable_map_decl (tree);