1 /* Interprocedural reference lists. 2 Copyright (C) 2010-2018 Free Software Foundation, Inc. 3 Contributed by Jan Hubicka 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 3, or (at your option) any later 10 version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "target.h" 25 #include "tree.h" 26 #include "cgraph.h" 27 28 /* Remove reference. */ 29 30 void remove_reference()31ipa_ref::remove_reference () 32 { 33 struct ipa_ref_list *list = referred_ref_list (); 34 struct ipa_ref_list *list2 = referring_ref_list (); 35 vec<ipa_ref_t, va_gc> *old_references = list2->references; 36 struct ipa_ref *last; 37 38 gcc_assert (list->referring[referred_index] == this); 39 40 last = list->referring.last (); 41 if (this != last) 42 { 43 if (use == IPA_REF_ALIAS) 44 { 45 /* If deleted item is IPA_REF_ALIAS, we have to move last 46 item of IPA_REF_LIST type to the deleted position. After that 47 we replace last node with deletion slot. */ 48 struct ipa_ref *last_alias = list->last_alias (); 49 50 if (last_alias && referred_index < last_alias->referred_index 51 && last_alias != last) 52 { 53 unsigned last_alias_index = last_alias->referred_index; 54 55 list->referring[referred_index] = last_alias; 56 list->referring[referred_index]->referred_index = referred_index; 57 58 /* New position for replacement is previous index 59 of the last_alias. */ 60 referred_index = last_alias_index; 61 } 62 } 63 64 list->referring[referred_index] = list->referring.last (); 65 list->referring[referred_index]->referred_index= referred_index; 66 } 67 list->referring.pop (); 68 69 last = &list2->references->last (); 70 71 struct ipa_ref *ref = this; 72 73 if (ref != last) 74 { 75 *ref = *last; 76 ref->referred_ref_list ()->referring[referred_index] = ref; 77 } 78 list2->references->pop (); 79 gcc_assert (list2->references == old_references); 80 } 81 82 /* Return true when execution of reference can lead to return from 83 function. */ 84 85 bool cannot_lead_to_return()86ipa_ref::cannot_lead_to_return () 87 { 88 return dyn_cast <cgraph_node *> (referring)->cannot_return_p (); 89 } 90 91 /* Return reference list this reference is in. */ 92 93 struct ipa_ref_list * referring_ref_list(void)94ipa_ref::referring_ref_list (void) 95 { 96 return &referring->ref_list; 97 } 98 99 /* Return reference list this reference is in. */ 100 101 struct ipa_ref_list * referred_ref_list(void)102ipa_ref::referred_ref_list (void) 103 { 104 return &referred->ref_list; 105 } 106