+ {
+ do
+ {
+ i = i->outer;
+ if (i == NULL)
+ return;
+ }
+ while (i->next_peer == NULL);
+ i = i->next_peer;
+ }
+ }
+}
+
+/* Computes the frequency of the call statement so that it can be stored in
+ cgraph_edge. BB is the basic block of the call statement. */
+int
+compute_call_stmt_bb_frequency (tree decl, basic_block bb)
+{
+ int entry_freq = ENTRY_BLOCK_PTR_FOR_FUNCTION
+ (DECL_STRUCT_FUNCTION (decl))->frequency;
+ int freq = bb->frequency;
+
+ if (profile_status_for_function (DECL_STRUCT_FUNCTION (decl)) == PROFILE_ABSENT)
+ return CGRAPH_FREQ_BASE;
+
+ if (!entry_freq)
+ entry_freq = 1, freq++;
+
+ freq = freq * CGRAPH_FREQ_BASE / entry_freq;
+ if (freq > CGRAPH_FREQ_MAX)
+ freq = CGRAPH_FREQ_MAX;
+
+ return freq;
+}
+
+/* Mark address taken in STMT. */
+
+static bool
+mark_address (gimple stmt, tree addr, void *data)
+{
+ addr = get_base_address (addr);
+ if (TREE_CODE (addr) == FUNCTION_DECL)
+ {
+ struct cgraph_node *node = cgraph_get_create_node (addr);
+ cgraph_mark_address_taken_node (node);
+ ipa_record_reference ((symtab_node)data,
+ (symtab_node)node,
+ IPA_REF_ADDR, stmt);
+ }
+ else if (addr && TREE_CODE (addr) == VAR_DECL
+ && (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
+ {
+ struct varpool_node *vnode = varpool_node_for_decl (addr);
+
+ ipa_record_reference ((symtab_node)data,
+ (symtab_node)vnode,
+ IPA_REF_ADDR, stmt);
+ }
+
+ return false;
+}
+
+/* Mark load of T. */
+
+static bool
+mark_load (gimple stmt, tree t, void *data)
+{
+ t = get_base_address (t);
+ if (t && TREE_CODE (t) == FUNCTION_DECL)
+ {
+ /* ??? This can happen on platforms with descriptors when these are
+ directly manipulated in the code. Pretend that it's an address. */
+ struct cgraph_node *node = cgraph_get_create_node (t);
+ cgraph_mark_address_taken_node (node);
+ ipa_record_reference ((symtab_node)data,
+ (symtab_node)node,
+ IPA_REF_ADDR, stmt);
+ }
+ else if (t && TREE_CODE (t) == VAR_DECL
+ && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
+ {
+ struct varpool_node *vnode = varpool_node_for_decl (t);
+
+ ipa_record_reference ((symtab_node)data,
+ (symtab_node)vnode,
+ IPA_REF_LOAD, stmt);