static symtab_node lto_symtab_resolve_symbols (symtab_node first) { symtab_node e; symtab_node prevailing = NULL; /* Always set e->node so that edges are updated to reflect decl merging. */ for (e = first; e; e = e->symbol.next_sharing_asm_name) if (lto_symtab_symbol_p (e) && (e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY || e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP || e->symbol.resolution == LDPR_PREVAILING_DEF)) { prevailing = e; break; } /* If the chain is already resolved there is nothing else to do. */ if (prevailing) { /* Assert it's the only one. */ for (e = prevailing->symbol.next_sharing_asm_name; e; e = e->symbol.next_sharing_asm_name) if (lto_symtab_symbol_p (e) && (e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY || e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP || e->symbol.resolution == LDPR_PREVAILING_DEF)) fatal_error ("multiple prevailing defs for %qE", DECL_NAME (prevailing->symbol.decl)); return prevailing; } /* Find the single non-replaceable prevailing symbol and diagnose ODR violations. */ for (e = first; e; e = e->symbol.next_sharing_asm_name) { if (!lto_symtab_resolve_can_prevail_p (e)) continue; /* If we have a non-replaceable definition it prevails. */ if (!lto_symtab_resolve_replaceable_p (e)) { if (prevailing) { error_at (DECL_SOURCE_LOCATION (e->symbol.decl), "%qD has already been defined", e->symbol.decl); inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl), "previously defined here"); } prevailing = e; } } if (prevailing) return prevailing; /* Do a second round choosing one from the replaceable prevailing decls. */ for (e = first; e; e = e->symbol.next_sharing_asm_name) { if (!lto_symtab_resolve_can_prevail_p (e)) continue; /* Choose the first function that can prevail as prevailing. */ if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL) { prevailing = e; break; } /* From variables that can prevail choose the largest one. */ if (!prevailing || tree_int_cst_lt (DECL_SIZE (prevailing->symbol.decl), DECL_SIZE (e->symbol.decl)) /* When variables are equivalent try to chose one that has useful DECL_INITIAL. This makes sense for keyed vtables that are DECL_EXTERNAL but initialized. In units that do not need them we replace the initializer by error_mark_node to conserve memory. We know that the vtable is keyed outside the LTO unit - otherwise the keyed instance would prevail. We still can preserve useful info in the initializer. */ || (DECL_SIZE (prevailing->symbol.decl) == DECL_SIZE (e->symbol.decl) && (DECL_INITIAL (e->symbol.decl) && DECL_INITIAL (e->symbol.decl) != error_mark_node) && (!DECL_INITIAL (prevailing->symbol.decl) || DECL_INITIAL (prevailing->symbol.decl) == error_mark_node))) prevailing = e; } return prevailing; }
static void lto_symtab_resolve_symbols (void **slot) { lto_symtab_entry_t e; lto_symtab_entry_t prevailing = NULL; /* Always set e->node so that edges are updated to reflect decl merging. */ for (e = (lto_symtab_entry_t) *slot; e; e = e->next) { if (TREE_CODE (e->decl) == FUNCTION_DECL) e->node = cgraph_get_node (e->decl); else if (TREE_CODE (e->decl) == VAR_DECL) e->vnode = varpool_get_node (e->decl); if (e->resolution == LDPR_PREVAILING_DEF_IRONLY || e->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP || e->resolution == LDPR_PREVAILING_DEF) prevailing = e; } /* If the chain is already resolved there is nothing else to do. */ if (prevailing) return; /* Find the single non-replaceable prevailing symbol and diagnose ODR violations. */ for (e = (lto_symtab_entry_t) *slot; e; e = e->next) { if (!lto_symtab_resolve_can_prevail_p (e)) { e->resolution = LDPR_RESOLVED_IR; e->guessed = true; continue; } /* Set a default resolution - the final prevailing one will get adjusted later. */ e->resolution = LDPR_PREEMPTED_IR; e->guessed = true; if (!lto_symtab_resolve_replaceable_p (e)) { if (prevailing) { error_at (DECL_SOURCE_LOCATION (e->decl), "%qD has already been defined", e->decl); inform (DECL_SOURCE_LOCATION (prevailing->decl), "previously defined here"); } prevailing = e; } } if (prevailing) goto found; /* Do a second round choosing one from the replaceable prevailing decls. */ for (e = (lto_symtab_entry_t) *slot; e; e = e->next) { if (e->resolution != LDPR_PREEMPTED_IR) continue; /* Choose the first function that can prevail as prevailing. */ if (TREE_CODE (e->decl) == FUNCTION_DECL) { prevailing = e; break; } /* From variables that can prevail choose the largest one. */ if (!prevailing || tree_int_cst_lt (DECL_SIZE (prevailing->decl), DECL_SIZE (e->decl))) prevailing = e; } if (!prevailing) return; found: /* If current lto files represent the whole program, it is correct to use LDPR_PREVALING_DEF_IRONLY. If current lto files are part of whole program, internal resolver doesn't know if it is LDPR_PREVAILING_DEF or LDPR_PREVAILING_DEF_IRONLY. Use IRONLY conforms to using -fwhole-program. Otherwise, it doesn't matter using either LDPR_PREVAILING_DEF or LDPR_PREVAILING_DEF_IRONLY FIXME: above workaround due to gold plugin makes some variables IRONLY, which are indeed PREVAILING_DEF in resolution file. These variables still need manual externally_visible attribute. */ prevailing->resolution = LDPR_PREVAILING_DEF_IRONLY; prevailing->guessed = true; }