[PATCH] Force rtl templates to be inlined
Andi Kleen
andi@firstfloor.org
Tue Sep 2 07:05:00 GMT 2014
From: Andi Kleen <ak@linux.intel.com>
I noticed that with the trunk compiler a range of the new rtl
inlines show up as hot in a profiler during stage1. I think
that happens because stage1 is not using optimization
and does not inline plain "inline". And these rtl inlines
are very frequently called.
Mark them all with __attribute__((always_inline)) which forces
inlining even with -O0.
Passes bootstrap and testing on x86_64-linux.
Cc: dmalcolm@redhat.com
include/:
2014-09-01 Andi Kleen <ak@linux.intel.com>
* ansidecl.h (ALWAYS_INLINE): Add.
gcc/:
2014-09-01 Andi Kleen <ak@linux.intel.com>
* rtl.h (is_a_helper): Change inline to ALWAYS_INLINE.
(rhs_regno): Dito.
(init_costs_to_max): Dito.
(init_costs_to_zero): Dito.
(costs_lt_p): Dito.
(costs_add_n_insns): Dito.
(wi::int_traits ::get_precision): Dito.
(wi::shwi): Dito.
(wi::min_value): Dito.
(wi::max_value): Dito.
(set_rtx_cost): Dito.
(get_full_set_rtx_cost): Dito.
(set_src_cost): Dito.
(get_full_set_src_cost): Dito.
(get_mem_attrs): Dito.
---
gcc/rtl.h | 111 +++++++++++++++++++++++++++--------------------------
include/ansidecl.h | 6 +++
2 files changed, 62 insertions(+), 55 deletions(-)
diff --git a/gcc/rtl.h b/gcc/rtl.h
index beeed2f..d711e43 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_RTL_H
#include <utility>
+#include "ansidecl.h"
#include "statistics.h"
#include "machmode.h"
#include "input.h"
@@ -418,7 +419,7 @@ public:
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_expr_list *>::test (rtx rt)
{
return rt->code == EXPR_LIST;
@@ -447,7 +448,7 @@ public:
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_insn_list *>::test (rtx rt)
{
return rt->code == INSN_LIST;
@@ -474,7 +475,7 @@ public:
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_sequence *>::test (rtx rt)
{
return rt->code == SEQUENCE;
@@ -482,7 +483,7 @@ is_a_helper <rtx_sequence *>::test (rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <const rtx_sequence *>::test (const_rtx rt)
{
return rt->code == SEQUENCE;
@@ -778,7 +779,7 @@ struct GTY(()) rtvec_def {
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_insn *>::test (rtx rt)
{
return (INSN_P (rt)
@@ -790,7 +791,7 @@ is_a_helper <rtx_insn *>::test (rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <const rtx_insn *>::test (const_rtx rt)
{
return (INSN_P (rt)
@@ -802,7 +803,7 @@ is_a_helper <const rtx_insn *>::test (const_rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_debug_insn *>::test (rtx rt)
{
return DEBUG_INSN_P (rt);
@@ -810,7 +811,7 @@ is_a_helper <rtx_debug_insn *>::test (rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_nonjump_insn *>::test (rtx rt)
{
return NONJUMP_INSN_P (rt);
@@ -818,7 +819,7 @@ is_a_helper <rtx_nonjump_insn *>::test (rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_jump_insn *>::test (rtx rt)
{
return JUMP_P (rt);
@@ -826,7 +827,7 @@ is_a_helper <rtx_jump_insn *>::test (rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_call_insn *>::test (rtx rt)
{
return CALL_P (rt);
@@ -834,7 +835,7 @@ is_a_helper <rtx_call_insn *>::test (rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_call_insn *>::test (rtx_insn *insn)
{
return CALL_P (insn);
@@ -842,7 +843,7 @@ is_a_helper <rtx_call_insn *>::test (rtx_insn *insn)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_jump_table_data *>::test (rtx rt)
{
return JUMP_TABLE_DATA_P (rt);
@@ -850,7 +851,7 @@ is_a_helper <rtx_jump_table_data *>::test (rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_jump_table_data *>::test (rtx_insn *insn)
{
return JUMP_TABLE_DATA_P (insn);
@@ -858,7 +859,7 @@ is_a_helper <rtx_jump_table_data *>::test (rtx_insn *insn)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_barrier *>::test (rtx rt)
{
return BARRIER_P (rt);
@@ -866,7 +867,7 @@ is_a_helper <rtx_barrier *>::test (rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_code_label *>::test (rtx rt)
{
return LABEL_P (rt);
@@ -874,7 +875,7 @@ is_a_helper <rtx_code_label *>::test (rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_code_label *>::test (rtx_insn *insn)
{
return LABEL_P (insn);
@@ -882,7 +883,7 @@ is_a_helper <rtx_code_label *>::test (rtx_insn *insn)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_note *>::test (rtx rt)
{
return NOTE_P (rt);
@@ -890,7 +891,7 @@ is_a_helper <rtx_note *>::test (rtx rt)
template <>
template <>
-inline bool
+ALWAYS_INLINE bool
is_a_helper <rtx_note *>::test (rtx_insn *insn)
{
return NOTE_P (insn);
@@ -1257,26 +1258,26 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
/* Methods of rtx_expr_list. */
-inline rtx_expr_list *rtx_expr_list::next () const
+ALWAYS_INLINE rtx_expr_list *rtx_expr_list::next () const
{
rtx tmp = XEXP (this, 1);
return safe_as_a <rtx_expr_list *> (tmp);
}
-inline rtx rtx_expr_list::element () const
+ALWAYS_INLINE rtx rtx_expr_list::element () const
{
return XEXP (this, 0);
}
/* Methods of rtx_insn_list. */
-inline rtx_insn_list *rtx_insn_list::next () const
+ALWAYS_INLINE rtx_insn_list *rtx_insn_list::next () const
{
rtx tmp = XEXP (this, 1);
return safe_as_a <rtx_insn_list *> (tmp);
}
-inline rtx_insn *rtx_insn_list::insn () const
+ALWAYS_INLINE rtx_insn *rtx_insn_list::insn () const
{
rtx tmp = XEXP (this, 0);
return safe_as_a <rtx_insn *> (tmp);
@@ -1284,17 +1285,17 @@ inline rtx_insn *rtx_insn_list::insn () const
/* Methods of rtx_sequence. */
-inline int rtx_sequence::len () const
+ALWAYS_INLINE int rtx_sequence::len () const
{
return XVECLEN (this, 0);
}
-inline rtx rtx_sequence::element (int index) const
+ALWAYS_INLINE rtx rtx_sequence::element (int index) const
{
return XVECEXP (this, 0, index);
}
-inline rtx_insn *rtx_sequence::insn (int index) const
+ALWAYS_INLINE rtx_insn *rtx_sequence::insn (int index) const
{
return as_a <rtx_insn *> (XVECEXP (this, 0, index));
}
@@ -1303,12 +1304,12 @@ inline rtx_insn *rtx_sequence::insn (int index) const
/* Holds a unique number for each insn.
These are not necessarily sequentially increasing. */
-inline int INSN_UID (const_rtx insn)
+ALWAYS_INLINE int INSN_UID (const_rtx insn)
{
return RTL_INSN_CHAIN_FLAG_CHECK ("INSN_UID",
(insn))->u2.insn_uid;
}
-inline int& INSN_UID (rtx insn)
+ALWAYS_INLINE int& INSN_UID (rtx insn)
{
return RTL_INSN_CHAIN_FLAG_CHECK ("INSN_UID",
(insn))->u2.insn_uid;
@@ -1321,60 +1322,60 @@ inline int& INSN_UID (rtx insn)
and an lvalue form:
SET_NEXT_INSN/SET_PREV_INSN. */
-inline rtx_insn *PREV_INSN (const rtx_insn *insn)
+ALWAYS_INLINE rtx_insn *PREV_INSN (const rtx_insn *insn)
{
rtx prev = XEXP (insn, 0);
return safe_as_a <rtx_insn *> (prev);
}
-inline rtx& SET_PREV_INSN (rtx_insn *insn)
+ALWAYS_INLINE rtx& SET_PREV_INSN (rtx_insn *insn)
{
return XEXP (insn, 0);
}
-inline rtx_insn *NEXT_INSN (const rtx_insn *insn)
+ALWAYS_INLINE rtx_insn *NEXT_INSN (const rtx_insn *insn)
{
rtx next = XEXP (insn, 1);
return safe_as_a <rtx_insn *> (next);
}
-inline rtx& SET_NEXT_INSN (rtx_insn *insn)
+ALWAYS_INLINE rtx& SET_NEXT_INSN (rtx_insn *insn)
{
return XEXP (insn, 1);
}
-inline basic_block BLOCK_FOR_INSN (const_rtx insn)
+ALWAYS_INLINE basic_block BLOCK_FOR_INSN (const_rtx insn)
{
return XBBDEF (insn, 2);
}
-inline basic_block& BLOCK_FOR_INSN (rtx insn)
+ALWAYS_INLINE basic_block& BLOCK_FOR_INSN (rtx insn)
{
return XBBDEF (insn, 2);
}
/* The body of an insn. */
-inline rtx PATTERN (const_rtx insn)
+ALWAYS_INLINE rtx PATTERN (const_rtx insn)
{
return XEXP (insn, 3);
}
-inline rtx& PATTERN (rtx insn)
+ALWAYS_INLINE rtx& PATTERN (rtx insn)
{
return XEXP (insn, 3);
}
-inline unsigned int INSN_LOCATION (const_rtx insn)
+ALWAYS_INLINE unsigned int INSN_LOCATION (const_rtx insn)
{
return XUINT (insn, 4);
}
-inline unsigned int& INSN_LOCATION (rtx insn)
+ALWAYS_INLINE unsigned int& INSN_LOCATION (rtx insn)
{
return XUINT (insn, 4);
}
-inline bool INSN_HAS_LOCATION (const rtx_insn *insn)
+ALWAYS_INLINE bool INSN_HAS_LOCATION (const rtx_insn *insn)
{
return LOCATION_LOCUS (INSN_LOCATION (insn)) != UNKNOWN_LOCATION;
}
@@ -1387,7 +1388,7 @@ inline bool INSN_HAS_LOCATION (const rtx_insn *insn)
-1 means this instruction has not been recognized yet. */
#define INSN_CODE(INSN) XINT (INSN, 5)
-inline rtvec rtx_jump_table_data::get_labels () const
+ALWAYS_INLINE rtvec rtx_jump_table_data::get_labels () const
{
rtx pat = PATTERN (this);
if (GET_CODE (pat) == ADDR_VEC)
@@ -1658,7 +1659,7 @@ enum label_kind
be decremented and possibly the label can be deleted. */
#define JUMP_LABEL(INSN) XCEXP (INSN, 7, JUMP_INSN)
-inline rtx_insn *JUMP_LABEL_AS_INSN (const rtx_insn *insn)
+ALWAYS_INLINE rtx_insn *JUMP_LABEL_AS_INSN (const rtx_insn *insn)
{
return safe_as_a <rtx_insn *> (JUMP_LABEL (insn));
}
@@ -1682,7 +1683,7 @@ inline rtx_insn *JUMP_LABEL_AS_INSN (const rtx_insn *insn)
(RTL_FLAG_CHECK1 ("ORIGINAL_REGNO", (RTX), REG)->u2.original_regno)
/* Force the REGNO macro to only be used on the lhs. */
-static inline unsigned int
+static ALWAYS_INLINE unsigned int
rhs_regno (const_rtx x)
{
return XCUINT (x, 0, REG);
@@ -1774,7 +1775,7 @@ struct full_rtx_costs
};
/* Initialize a full_rtx_costs structure C to the maximum cost. */
-static inline void
+static ALWAYS_INLINE void
init_costs_to_max (struct full_rtx_costs *c)
{
c->speed = MAX_COST;
@@ -1782,7 +1783,7 @@ init_costs_to_max (struct full_rtx_costs *c)
}
/* Initialize a full_rtx_costs structure C to zero cost. */
-static inline void
+static ALWAYS_INLINE void
init_costs_to_zero (struct full_rtx_costs *c)
{
c->speed = 0;
@@ -1791,7 +1792,7 @@ init_costs_to_zero (struct full_rtx_costs *c)
/* Compare two full_rtx_costs structures A and B, returning true
if A < B when optimizing for speed. */
-static inline bool
+static ALWAYS_INLINE bool
costs_lt_p (struct full_rtx_costs *a, struct full_rtx_costs *b,
bool speed)
{
@@ -1805,7 +1806,7 @@ costs_lt_p (struct full_rtx_costs *a, struct full_rtx_costs *b,
/* Increase both members of the full_rtx_costs structure C by the
cost of N insns. */
-static inline void
+static ALWAYS_INLINE void
costs_add_n_insns (struct full_rtx_costs *c, int n)
{
c->speed += COSTS_N_INSNS (n);
@@ -1904,13 +1905,13 @@ namespace wi
};
}
-inline unsigned int
+ALWAYS_INLINE unsigned int
wi::int_traits <rtx_mode_t>::get_precision (const rtx_mode_t &x)
{
return GET_MODE_PRECISION (x.second);
}
-inline wi::storage_ref
+ALWAYS_INLINE wi::storage_ref
wi::int_traits <rtx_mode_t>::decompose (HOST_WIDE_INT *,
unsigned int precision,
const rtx_mode_t &x)
@@ -1949,7 +1950,7 @@ namespace wi
wide_int max_value (enum machine_mode, signop);
}
-inline wi::hwi_with_prec
+ALWAYS_INLINE wi::hwi_with_prec
wi::shwi (HOST_WIDE_INT val, enum machine_mode mode)
{
return shwi (val, GET_MODE_PRECISION (mode));
@@ -1957,7 +1958,7 @@ wi::shwi (HOST_WIDE_INT val, enum machine_mode mode)
/* Produce the smallest number that is represented in MODE. The precision
is taken from MODE and the sign from SGN. */
-inline wide_int
+ALWAYS_INLINE wide_int
wi::min_value (enum machine_mode mode, signop sgn)
{
return min_value (GET_MODE_PRECISION (mode), sgn);
@@ -1965,7 +1966,7 @@ wi::min_value (enum machine_mode mode, signop sgn)
/* Produce the largest number that is represented in MODE. The precision
is taken from MODE and the sign from SGN. */
-inline wide_int
+ALWAYS_INLINE wide_int
wi::max_value (enum machine_mode mode, signop sgn)
{
return max_value (GET_MODE_PRECISION (mode), sgn);
@@ -2007,7 +2008,7 @@ extern enum rtx_code get_index_code (const struct address_info *);
/* Return the cost of SET X. SPEED_P is true if optimizing for speed
rather than size. */
-static inline int
+static ALWAYS_INLINE int
set_rtx_cost (rtx x, bool speed_p)
{
return rtx_cost (x, INSN, 4, speed_p);
@@ -2015,7 +2016,7 @@ set_rtx_cost (rtx x, bool speed_p)
/* Like set_rtx_cost, but return both the speed and size costs in C. */
-static inline void
+static ALWAYS_INLINE void
get_full_set_rtx_cost (rtx x, struct full_rtx_costs *c)
{
get_full_rtx_cost (x, INSN, 4, c);
@@ -2025,7 +2026,7 @@ get_full_set_rtx_cost (rtx x, struct full_rtx_costs *c)
of a register move. SPEED_P is true if optimizing for speed rather
than size. */
-static inline int
+static ALWAYS_INLINE int
set_src_cost (rtx x, bool speed_p)
{
return rtx_cost (x, SET, 1, speed_p);
@@ -2033,7 +2034,7 @@ set_src_cost (rtx x, bool speed_p)
/* Like set_src_cost, but return both the speed and size costs in C. */
-static inline void
+static ALWAYS_INLINE void
get_full_set_src_cost (rtx x, struct full_rtx_costs *c)
{
get_full_rtx_cost (x, SET, 1, c);
@@ -3055,7 +3056,7 @@ extern struct target_rtl *this_target_rtl;
#ifndef GENERATOR_FILE
/* Return the attributes of a MEM rtx. */
-static inline struct mem_attrs *
+static ALWAYS_INLINE struct mem_attrs *
get_mem_attrs (const_rtx x)
{
struct mem_attrs *attrs;
diff --git a/include/ansidecl.h b/include/ansidecl.h
index 0fb23bb..9132ee0 100644
--- a/include/ansidecl.h
+++ b/include/ansidecl.h
@@ -306,6 +306,12 @@ So instead we use the macro below and test it against specific values. */
#define ENUM_BITFIELD(TYPE) unsigned int
#endif
+#ifdef __GNUC__
+#define ALWAYS_INLINE __attribute__ ((always_inline)) inline
+#else
+#define ALWAYS_INLINE inline
+#endif
+
#ifdef __cplusplus
}
#endif
--
2.1.0
More information about the Gcc-patches
mailing list