Commit bde351d5 by Richard Biener Committed by Richard Biener

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
parent d2713985
2015-08-12 Richard Biener <rguenther@suse.de> 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): * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
Eliminate edges marked as not executable by SCCVN. Eliminate edges marked as not executable by SCCVN.
* tree-ssa-sccvn.c: Include gimple-iterator.h. * tree-ssa-sccvn.c: Include gimple-iterator.h.
......
...@@ -89,6 +89,10 @@ static const char * const gimple_alloc_kind_names[] = { ...@@ -89,6 +89,10 @@ static const char * const gimple_alloc_kind_names[] = {
"everything else" "everything else"
}; };
/* Static gimple tuple members. */
const enum gimple_code gassign::code_;
/* Gimple tuple constructors. /* Gimple tuple constructors.
Note: Any constructor taking a ``gimple_seq'' as a parameter, can Note: Any constructor taking a ``gimple_seq'' as a parameter, can
be passed a NULL to start with an empty sequence. */ be passed a NULL to start with an empty sequence. */
......
...@@ -37,6 +37,10 @@ enum gimple_code { ...@@ -37,6 +37,10 @@ enum gimple_code {
extern const char *const gimple_code_name[]; extern const char *const gimple_code_name[];
extern const unsigned char gimple_rhs_class_table[]; 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. */ /* Error out if a gimple tuple is addressed incorrectly. */
#if defined ENABLE_GIMPLE_CHECKING #if defined ENABLE_GIMPLE_CHECKING
#define gcc_gimple_checking_assert(EXPR) gcc_assert (EXPR) #define gcc_gimple_checking_assert(EXPR) gcc_assert (EXPR)
...@@ -51,9 +55,59 @@ extern void gimple_check_failed (const_gimple, const char *, int, \ ...@@ -51,9 +55,59 @@ extern void gimple_check_failed (const_gimple, const char *, int, \
gimple_check_failed (__gs, __FILE__, __LINE__, __FUNCTION__, \ gimple_check_failed (__gs, __FILE__, __LINE__, __FUNCTION__, \
(CODE), ERROR_MARK); \ (CODE), ERROR_MARK); \
} while (0) } 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 */ #else /* not ENABLE_GIMPLE_CHECKING */
#define gcc_gimple_checking_assert(EXPR) ((void)(0 && (EXPR))) #define gcc_gimple_checking_assert(EXPR) ((void)(0 && (EXPR)))
#define GIMPLE_CHECK(GS, CODE) (void)0 #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 #endif
/* Class of GIMPLE expressions suitable for the RHS of assignments. See /* Class of GIMPLE expressions suitable for the RHS of assignments. See
...@@ -832,6 +886,7 @@ struct GTY((tag("GSS_WITH_OPS"))) ...@@ -832,6 +886,7 @@ struct GTY((tag("GSS_WITH_OPS")))
struct GTY((tag("GSS_WITH_MEM_OPS"))) struct GTY((tag("GSS_WITH_MEM_OPS")))
gassign : public gimple_statement_with_memory_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. */ /* no additional fields; this uses the layout for GSS_WITH_MEM_OPS. */
}; };
...@@ -864,6 +919,14 @@ is_a_helper <gassign *>::test (gimple gs) ...@@ -864,6 +919,14 @@ is_a_helper <gassign *>::test (gimple gs)
template <> template <>
template <> template <>
inline bool 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) is_a_helper <gbind *>::test (gimple gs)
{ {
return gs->code == GIMPLE_BIND; return gs->code == GIMPLE_BIND;
...@@ -2326,43 +2389,67 @@ get_gimple_rhs_class (enum tree_code code) ...@@ -2326,43 +2389,67 @@ get_gimple_rhs_class (enum tree_code code)
/* Return the LHS of assignment statement GS. */ /* Return the LHS of assignment statement GS. */
static inline tree static inline tree
gimple_assign_lhs (const gassign *gs)
{
return gs->op[0];
}
static inline tree
gimple_assign_lhs (const_gimple gs) gimple_assign_lhs (const_gimple gs)
{ {
GIMPLE_CHECK (gs, GIMPLE_ASSIGN); const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
return gimple_op (gs, 0); return gimple_assign_lhs (ass);
} }
/* Return a pointer to the LHS of assignment statement GS. */ /* Return a pointer to the LHS of assignment statement GS. */
static inline tree * 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_assign_lhs_ptr (const_gimple gs)
{ {
GIMPLE_CHECK (gs, GIMPLE_ASSIGN); const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
return gimple_op_ptr (gs, 0); return gimple_assign_lhs_ptr (ass);
} }
/* Set LHS to be the LHS operand of assignment statement GS. */ /* Set LHS to be the LHS operand of assignment statement GS. */
static inline void static inline void
gimple_assign_set_lhs (gimple gs, tree lhs) gimple_assign_set_lhs (gassign *gs, tree lhs)
{ {
GIMPLE_CHECK (gs, GIMPLE_ASSIGN); gs->op[0] = lhs;
gimple_set_op (gs, 0, lhs);
if (lhs && TREE_CODE (lhs) == SSA_NAME) if (lhs && TREE_CODE (lhs) == SSA_NAME)
SSA_NAME_DEF_STMT (lhs) = gs; 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. */ /* Return the first operand on the RHS of assignment statement GS. */
static inline tree static inline tree
gimple_assign_rhs1 (const gassign *gs)
{
return gs->op[1];
}
static inline tree
gimple_assign_rhs1 (const_gimple gs) gimple_assign_rhs1 (const_gimple gs)
{ {
GIMPLE_CHECK (gs, GIMPLE_ASSIGN); const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
return gimple_op (gs, 1); return gimple_assign_rhs1 (ass);
} }
...@@ -2370,20 +2457,31 @@ gimple_assign_rhs1 (const_gimple gs) ...@@ -2370,20 +2457,31 @@ gimple_assign_rhs1 (const_gimple gs)
statement GS. */ statement GS. */
static inline tree * 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_assign_rhs1_ptr (const_gimple gs)
{ {
GIMPLE_CHECK (gs, GIMPLE_ASSIGN); const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
return gimple_op_ptr (gs, 1); return gimple_assign_rhs1_ptr (ass);
} }
/* Set RHS to be the first operand on the RHS of assignment statement GS. */ /* Set RHS to be the first operand on the RHS of assignment statement GS. */
static inline void 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) ...@@ -2391,73 +2489,104 @@ gimple_assign_set_rhs1 (gimple gs, tree rhs)
If GS does not have two operands, NULL is returned instead. */ If GS does not have two operands, NULL is returned instead. */
static inline tree 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) if (gimple_num_ops (gs) >= 3)
return gimple_op (gs, 2); return gs->op[2];
else else
return NULL_TREE; 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 /* Return a pointer to the second operand on the RHS of assignment
statement GS. */ statement GS. */
static inline tree * 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_assign_rhs2_ptr (const_gimple gs)
{ {
GIMPLE_CHECK (gs, GIMPLE_ASSIGN); const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
return gimple_op_ptr (gs, 2); return gimple_assign_rhs2_ptr (ass);
} }
/* Set RHS to be the second operand on the RHS of assignment statement GS. */ /* Set RHS to be the second operand on the RHS of assignment statement GS. */
static inline void 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. /* Return the third operand on the RHS of assignment statement GS.
If GS does not have two operands, NULL is returned instead. */ If GS does not have two operands, NULL is returned instead. */
static inline tree 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) if (gimple_num_ops (gs) >= 4)
return gimple_op (gs, 3); return gs->op[3];
else else
return NULL_TREE; 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 /* Return a pointer to the third operand on the RHS of assignment
statement GS. */ statement GS. */
static inline tree * static inline tree *
gimple_assign_rhs3_ptr (const_gimple gs) gimple_assign_rhs3_ptr (const_gimple gs)
{ {
GIMPLE_CHECK (gs, GIMPLE_ASSIGN); const gassign *ass = GIMPLE_CHECK2<const gassign *> (gs);
return gimple_op_ptr (gs, 3); 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. */ /* Set RHS to be the third operand on the RHS of assignment statement GS. */
static inline void 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 /* A wrapper around 3 operand gimple_assign_set_rhs_with_ops, for callers
which expect to see only two operands. */ which expect to see only two operands. */
...@@ -2501,21 +2630,25 @@ gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal) ...@@ -2501,21 +2630,25 @@ gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal)
tree code of the object. */ tree code of the object. */
static inline enum tree_code static inline enum tree_code
gimple_assign_rhs_code (const_gimple gs) gimple_assign_rhs_code (const gassign *gs)
{ {
enum tree_code code; enum tree_code code = (enum tree_code) gs->subcode;
GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
code = (enum tree_code) gs->subcode;
/* While we initially set subcode to the TREE_CODE of the rhs for /* 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 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. */ in sync when we rewrite stmts into SSA form or do SSA propagations. */
if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS) if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
code = TREE_CODE (gimple_assign_rhs1 (gs)); code = TREE_CODE (gs->op[1]);
return code; 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 /* Set CODE to be the code for the expression computed on the RHS of
assignment S. */ assignment S. */
......
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