+/* FIXME: inappropriate dependency of cgraph on IPA. */
+#include "ipa-ref-inline.h"
+
+/* Return node that alias N is aliasing. */
+
+static inline struct cgraph_node *
+cgraph_alias_aliased_node (struct cgraph_node *n)
+{
+ struct ipa_ref *ref;
+
+ ipa_ref_list_reference_iterate (&n->ref_list, 0, ref);
+ gcc_checking_assert (ref->use == IPA_REF_ALIAS);
+ if (ref->refered_type == IPA_REF_CGRAPH)
+ return ipa_ref_node (ref);
+ return NULL;
+}
+
+/* Return node that alias N is aliasing. */
+
+static inline struct varpool_node *
+varpool_alias_aliased_node (struct varpool_node *n)
+{
+ struct ipa_ref *ref;
+
+ ipa_ref_list_reference_iterate (&n->ref_list, 0, ref);
+ gcc_checking_assert (ref->use == IPA_REF_ALIAS);
+ if (ref->refered_type == IPA_REF_VARPOOL)
+ return ipa_ref_varpool_node (ref);
+ return NULL;
+}
+
+/* Given NODE, walk the alias chain to return the function NODE is alias of.
+ Walk through thunk, too.
+ When AVAILABILITY is non-NULL, get minimal availablity in the chain. */
+
+static inline struct cgraph_node *
+cgraph_function_node (struct cgraph_node *node, enum availability *availability)
+{
+ if (availability)
+ *availability = cgraph_function_body_availability (node);
+ while (node)
+ {
+ if (node->alias && node->analyzed)
+ node = cgraph_alias_aliased_node (node);
+ else if (node->thunk.thunk_p)
+ node = node->callees->callee;
+ else
+ return node;
+ if (node && availability)
+ {
+ enum availability a;
+ a = cgraph_function_body_availability (node);
+ if (a < *availability)
+ *availability = a;
+ }
+ }
+ if (availability)
+ *availability = AVAIL_NOT_AVAILABLE;
+ return NULL;
+}
+
+/* Given NODE, walk the alias chain to return the function NODE is alias of.
+ Do not walk through thunks.
+ When AVAILABILITY is non-NULL, get minimal availablity in the chain. */
+
+static inline struct cgraph_node *
+cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *availability)
+{
+ if (availability)
+ *availability = cgraph_function_body_availability (node);
+ while (node)
+ {
+ if (node->alias && node->analyzed)
+ node = cgraph_alias_aliased_node (node);
+ else
+ return node;
+ if (node && availability)
+ {
+ enum availability a;
+ a = cgraph_function_body_availability (node);
+ if (a < *availability)
+ *availability = a;
+ }
+ }
+ if (availability)
+ *availability = AVAIL_NOT_AVAILABLE;
+ return NULL;
+}
+
+/* Given NODE, walk the alias chain to return the function NODE is alias of.
+ Do not walk through thunks.
+ When AVAILABILITY is non-NULL, get minimal availablity in the chain. */
+
+static inline struct varpool_node *
+varpool_variable_node (struct varpool_node *node, enum availability *availability)
+{
+ if (availability)
+ *availability = cgraph_variable_initializer_availability (node);
+ while (node)
+ {
+ if (node->alias && node->analyzed)
+ node = varpool_alias_aliased_node (node);
+ else
+ return node;
+ if (node && availability)
+ {
+ enum availability a;
+ a = cgraph_variable_initializer_availability (node);
+ if (a < *availability)
+ *availability = a;
+ }
+ }
+ if (availability)
+ *availability = AVAIL_NOT_AVAILABLE;
+ return NULL;
+}
+
+/* Return true when the edge E represents a direct recursion. */
+static inline bool
+cgraph_edge_recursive_p (struct cgraph_edge *e)
+{
+ struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL);
+ if (e->caller->global.inlined_to)
+ return e->caller->global.inlined_to->decl == callee->decl;
+ else
+ return e->caller->decl == callee->decl;
+}
+
+/* Return true if the TM_CLONE bit is set for a given FNDECL. */
+static inline bool
+decl_is_tm_clone (const_tree fndecl)
+{
+ struct cgraph_node *n = cgraph_get_node (fndecl);
+ if (n)
+ return n->tm_clone;
+ return false;
+}