aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-08-12 07:42:31 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-08-12 07:42:31 +0000
commitbde351d539b33d5723a60835cf4b663afdcd821d (patch)
treefd22296b386f2d75e390a2b202de287caaa900c6
parentd27139850b789dbfc7c9c5604432c5d16114528d (diff)
downloadgcc-bde351d539b33d5723a60835cf4b663afdcd821d.zip
gcc-bde351d539b33d5723a60835cf4b663afdcd821d.tar.gz
gcc-bde351d539b33d5723a60835cf4b663afdcd821d.tar.bz2
gimple.h (remove_pointer): New trait.
2015-08-12 Richard Biener <rguenther@suse.de> * gimple.h (remove_pointer): New trait. (GIMPLE_CHECK2): New inline template function. (gassign::code_): New constant static member. (is_a_helper<const gassign *>): Add. (gimple_assign_lhs): Use GIMPLE_CHECK2 in the gimple overload and forward to a new gassign overload with less checking and a cheaper way to access the operand. (gimple_assign_lhs_ptr): Likewise. (gimple_assign_set_lhs): Likewise. (gimple_assign_rhs1, gimple_assign_rhs1_ptr, gimple_assign_set_rhs1): Likewise. (gimple_assign_rhs2, gimple_assign_rhs2_ptr, gimple_assign_set_rhs2): Likewise. (gimple_assign_rhs3, gimple_assign_rhs3_ptr, gimple_assign_set_rhs3): Likewise. (gimple_assign_rhs_code): Likewise. * gimple.c (gassign::code_): Define. From-SVN: r226802
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/gimple.c4
-rw-r--r--gcc/gimple.h209
3 files changed, 195 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 206dc3a..62b3827 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,25 @@
2015-08-12 Richard Biener <rguenther@suse.de>
+ * gimple.h (remove_pointer): New trait.
+ (GIMPLE_CHECK2): New inline template function.
+ (gassign::code_): New constant static member.
+ (is_a_helper<const gassign *>): Add.
+ (gimple_assign_lhs): Use GIMPLE_CHECK2 in the gimple overload
+ and forward to a new gassign overload with less checking and a
+ cheaper way to access the operand.
+ (gimple_assign_lhs_ptr): Likewise.
+ (gimple_assign_set_lhs): Likewise.
+ (gimple_assign_rhs1, gimple_assign_rhs1_ptr, gimple_assign_set_rhs1):
+ Likewise.
+ (gimple_assign_rhs2, gimple_assign_rhs2_ptr, gimple_assign_set_rhs2):
+ Likewise.
+ (gimple_assign_rhs3, gimple_assign_rhs3_ptr, gimple_assign_set_rhs3):
+ Likewise.
+ (gimple_assign_rhs_code): Likewise.
+ * gimple.c (gassign::code_): Define.
+
+2015-08-12 Richard Biener <rguenther@suse.de>
+
* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
Eliminate edges marked as not executable by SCCVN.
* tree-ssa-sccvn.c: Include gimple-iterator.h.
diff --git a/gcc/gimple.c b/gcc/gimple.c
index e31a273..e4866ac 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -89,6 +89,10 @@ static const char * const gimple_alloc_kind_names[] = {
"everything else"
};
+/* Static gimple tuple members. */
+const enum gimple_code gassign::code_;
+
+
/* Gimple tuple constructors.
Note: Any constructor taking a ``gimple_seq'' as a parameter, can
be passed a NULL to start with an empty sequence. */
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 2004188..9e9be4a 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -37,6 +37,10 @@ enum gimple_code {
extern const char *const gimple_code_name[];
extern const unsigned char gimple_rhs_class_table[];
+/* Strip the outermost pointer, from tr1/type_traits. */
+template<typename T> struct remove_pointer { typedef T type; };
+template<typename T> struct remove_pointer<T *> { typedef T type; };
+
/* Error out if a gimple tuple is addressed incorrectly. */
#if defined ENABLE_GIMPLE_CHECKING
#define gcc_gimple_checking_assert(EXPR) gcc_assert (EXPR)
@@ -51,9 +55,59 @@ extern void gimple_check_failed (const_gimple, const char *, int, \
gimple_check_failed (__gs, __FILE__, __LINE__, __FUNCTION__, \
(CODE), ERROR_MARK); \
} while (0)
+template <typename T>
+static inline T
+GIMPLE_CHECK2(const_gimple gs,
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ const char *file = __builtin_FILE (),
+ int line = __builtin_LINE (),
+ const char *fun = __builtin_FUNCTION ())
+#else
+ const char *file = __FILE__,
+ int line = __LINE__,
+ const char *fun = NULL)
+#endif
+{
+ T ret = dyn_cast <T> (gs);
+ if (!ret)
+ gimple_check_failed (gs, file, line, fun,
+ remove_pointer<T>::type::code_, ERROR_MARK);
+ return ret;
+}
+template <typename T>
+static inline T
+GIMPLE_CHECK2(gimple gs,
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ const char *file = __builtin_FILE (),
+ int line = __builtin_LINE (),
+ const char *fun = __builtin_FUNCTION ())
+#else
+ const char *file = __FILE__,
+ int line = __LINE__,
+ const char *fun = NULL)
+#endif
+{
+ T ret = dyn_cast <T> (gs);
+ if (!ret)
+ gimple_check_failed (gs, file, line, fun,
+ remove_pointer<T>::type::code_, ERROR_MARK);
+ return ret;
+}
#else /* not ENABLE_GIMPLE_CHECKING */
#define gcc_gimple_checking_assert(EXPR) ((void)(0 && (EXPR)))
#define GIMPLE_CHECK(GS, CODE) (void)0
+template <typename T>
+static inline T
+GIMPLE_CHECK2(gimple gs)
+{
+ return as_a <T> (gs);
+}
+template <typename T>
+static inline T
+GIMPLE_CHECK2(const_gimple gs)
+{
+ return as_a <T> (gs);
+}
#endif
/* Class of GIMPLE expressions suitable for the RHS of assignments. See
@@ -832,6 +886,7 @@ struct GTY((tag("GSS_WITH_OPS")))
struct GTY((tag("GSS_WITH_MEM_OPS")))
gassign : public gimple_statement_with_memory_ops
{
+ static const enum gimple_code code_ = GIMPLE_ASSIGN;
/* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */
};
@@ -864,6 +919,14 @@ is_a_helper <gassign *>::test (gimple gs)
template <>
template <>
inline bool
+is_a_helper <const gassign *>::test (const_gimple gs)
+{
+ return gs->code == GIMPLE_ASSIGN;
+}
+
+template <>
+template <>
+inline bool
is_a_helper <gbind *>::test (gimple gs)
{
return gs->code == GIMPLE_BIND;
@@ -2326,43 +2389,67 @@ get_gimple_rhs_class (enum tree_code code)
/* Return the LHS of assignment statement GS. */
static inline tree
+gimple_assign_lhs (const gassign *gs)
+{
+ return gs->op[0];
+}
+
+static inline tree
gimple_assign_lhs (const_gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
- return gimple_op (gs, 0);
+ const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
+ return gimple_assign_lhs (ass);
}
/* Return a pointer to the LHS of assignment statement GS. */
static inline tree *
+gimple_assign_lhs_ptr (const gassign *gs)
+{
+ return const_cast<tree *> (&gs->op[0]);
+}
+
+static inline tree *
gimple_assign_lhs_ptr (const_gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
- return gimple_op_ptr (gs, 0);
+ const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
+ return gimple_assign_lhs_ptr (ass);
}
/* Set LHS to be the LHS operand of assignment statement GS. */
static inline void
-gimple_assign_set_lhs (gimple gs, tree lhs)
+gimple_assign_set_lhs (gassign *gs, tree lhs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
- gimple_set_op (gs, 0, lhs);
+ gs->op[0] = lhs;
if (lhs && TREE_CODE (lhs) == SSA_NAME)
SSA_NAME_DEF_STMT (lhs) = gs;
}
+static inline void
+gimple_assign_set_lhs (gimple gs, tree lhs)
+{
+ gassign *ass = GIMPLE_CHECK2<gassign *> (gs);
+ gimple_assign_set_lhs (ass, lhs);
+}
+
/* Return the first operand on the RHS of assignment statement GS. */
static inline tree
+gimple_assign_rhs1 (const gassign *gs)
+{
+ return gs->op[1];
+}
+
+static inline tree
gimple_assign_rhs1 (const_gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
- return gimple_op (gs, 1);
+ const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
+ return gimple_assign_rhs1 (ass);
}
@@ -2370,20 +2457,31 @@ gimple_assign_rhs1 (const_gimple gs)
statement GS. */
static inline tree *
+gimple_assign_rhs1_ptr (const gassign *gs)
+{
+ return const_cast<tree *> (&gs->op[1]);
+}
+
+static inline tree *
gimple_assign_rhs1_ptr (const_gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
- return gimple_op_ptr (gs, 1);
+ const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
+ return gimple_assign_rhs1_ptr (ass);
}
/* Set RHS to be the first operand on the RHS of assignment statement GS. */
static inline void
-gimple_assign_set_rhs1 (gimple gs, tree rhs)
+gimple_assign_set_rhs1 (gassign *gs, tree rhs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ gs->op[1] = rhs;
+}
- gimple_set_op (gs, 1, rhs);
+static inline void
+gimple_assign_set_rhs1 (gimple gs, tree rhs)
+{
+ gassign *ass = GIMPLE_CHECK2<gassign *> (gs);
+ gimple_assign_set_rhs1 (ass, rhs);
}
@@ -2391,73 +2489,104 @@ gimple_assign_set_rhs1 (gimple gs, tree rhs)
If GS does not have two operands, NULL is returned instead. */
static inline tree
-gimple_assign_rhs2 (const_gimple gs)
+gimple_assign_rhs2 (const gassign *gs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
-
if (gimple_num_ops (gs) >= 3)
- return gimple_op (gs, 2);
+ return gs->op[2];
else
return NULL_TREE;
}
+static inline tree
+gimple_assign_rhs2 (const_gimple gs)
+{
+ const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
+ return gimple_assign_rhs2 (ass);
+}
+
/* Return a pointer to the second operand on the RHS of assignment
statement GS. */
static inline tree *
+gimple_assign_rhs2_ptr (const gassign *gs)
+{
+ gcc_gimple_checking_assert (gimple_num_ops (gs) >= 3);
+ return const_cast<tree *> (&gs->op[2]);
+}
+
+static inline tree *
gimple_assign_rhs2_ptr (const_gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
- return gimple_op_ptr (gs, 2);
+ const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
+ return gimple_assign_rhs2_ptr (ass);
}
/* Set RHS to be the second operand on the RHS of assignment statement GS. */
static inline void
-gimple_assign_set_rhs2 (gimple gs, tree rhs)
+gimple_assign_set_rhs2 (gassign *gs, tree rhs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ gcc_gimple_checking_assert (gimple_num_ops (gs) >= 3);
+ gs->op[2] = rhs;
+}
- gimple_set_op (gs, 2, rhs);
+static inline void
+gimple_assign_set_rhs2 (gimple gs, tree rhs)
+{
+ gassign *ass = GIMPLE_CHECK2<gassign *> (gs);
+ return gimple_assign_set_rhs2 (ass, rhs);
}
/* Return the third operand on the RHS of assignment statement GS.
If GS does not have two operands, NULL is returned instead. */
static inline tree
-gimple_assign_rhs3 (const_gimple gs)
+gimple_assign_rhs3 (const gassign *gs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
-
if (gimple_num_ops (gs) >= 4)
- return gimple_op (gs, 3);
+ return gs->op[3];
else
return NULL_TREE;
}
+static inline tree
+gimple_assign_rhs3 (const_gimple gs)
+{
+ const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
+ return gimple_assign_rhs3 (ass);
+}
+
/* Return a pointer to the third operand on the RHS of assignment
statement GS. */
static inline tree *
gimple_assign_rhs3_ptr (const_gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
- return gimple_op_ptr (gs, 3);
+ const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
+ gcc_gimple_checking_assert (gimple_num_ops (gs) >= 4);
+ return const_cast<tree *> (&ass->op[3]);
}
/* Set RHS to be the third operand on the RHS of assignment statement GS. */
static inline void
-gimple_assign_set_rhs3 (gimple gs, tree rhs)
+gimple_assign_set_rhs3 (gassign *gs, tree rhs)
{
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ gcc_gimple_checking_assert (gimple_num_ops (gs) >= 4);
+ gs->op[3] = rhs;
+}
- gimple_set_op (gs, 3, rhs);
+static inline void
+gimple_assign_set_rhs3 (gimple gs, tree rhs)
+{
+ gassign *ass = GIMPLE_CHECK2<gassign *> (gs);
+ gimple_assign_set_rhs3 (ass, rhs);
}
+
/* A wrapper around 3 operand gimple_assign_set_rhs_with_ops, for callers
which expect to see only two operands. */
@@ -2501,21 +2630,25 @@ gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal)
tree code of the object. */
static inline enum tree_code
-gimple_assign_rhs_code (const_gimple gs)
+gimple_assign_rhs_code (const gassign *gs)
{
- enum tree_code code;
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
-
- code = (enum tree_code) gs->subcode;
+ enum tree_code code = (enum tree_code) gs->subcode;
/* While we initially set subcode to the TREE_CODE of the rhs for
GIMPLE_SINGLE_RHS assigns we do not update that subcode to stay
in sync when we rewrite stmts into SSA form or do SSA propagations. */
if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
- code = TREE_CODE (gimple_assign_rhs1 (gs));
+ code = TREE_CODE (gs->op[1]);
return code;
}
+static inline enum tree_code
+gimple_assign_rhs_code (const_gimple gs)
+{
+ const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
+ return gimple_assign_rhs_code (ass);
+}
+
/* Set CODE to be the code for the expression computed on the RHS of
assignment S. */