diff options
Diffstat (limited to 'gcc/ipa-param-manipulation.cc')
-rw-r--r-- | gcc/ipa-param-manipulation.cc | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc index 4878867..11f843c 100644 --- a/gcc/ipa-param-manipulation.cc +++ b/gcc/ipa-param-manipulation.cc @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "sreal.h" #include "ipa-cp.h" #include "ipa-prop.h" +#include "attr-callback.h" /* Actual prefixes of different newly synthetized parameters. Keep in sync with IPA_PARAM_PREFIX_* defines. */ @@ -308,6 +309,16 @@ drop_type_attribute_if_params_changed_p (tree name) return false; } +/* Return TRUE if the attribute should be dropped in the decl it is sitting on + changes. Primarily affects attributes working with the decls arguments. */ +static bool +drop_decl_attribute_if_params_changed_p (tree name) +{ + if (is_attribute_p (CALLBACK_ATTR_IDENT, name)) + return true; + return false; +} + /* Build and return a function type just like ORIG_TYPE but with parameter types given in NEW_PARAM_TYPES - which can be NULL if, but only if, ORIG_TYPE itself has NULL TREE_ARG_TYPEs. If METHOD2FUNC is true, also make @@ -488,11 +499,12 @@ ipa_param_adjustments::method2func_p (tree orig_type) performing all atored modifications. TYPE_ORIGINAL_P should be true when OLD_TYPE refers to the type before any IPA transformations, as opposed to a type that can be an intermediate one in between various IPA - transformations. */ + transformations. Set pointee of ARGS_MODIFIED (if provided) to TRUE if the + type's arguments were changed. */ tree -ipa_param_adjustments::build_new_function_type (tree old_type, - bool type_original_p) +ipa_param_adjustments::build_new_function_type ( + tree old_type, bool type_original_p, bool *args_modified /* = NULL */) { auto_vec<tree,16> new_param_types, *new_param_types_p; if (prototype_p (old_type)) @@ -518,6 +530,8 @@ ipa_param_adjustments::build_new_function_type (tree old_type, || get_original_index (index) != (int)index) modified = true; + if (args_modified) + *args_modified = modified; return build_adjusted_function_type (old_type, new_param_types_p, method2func_p (old_type), m_skip_return, @@ -536,10 +550,11 @@ ipa_param_adjustments::adjust_decl (tree orig_decl) { tree new_decl = copy_node (orig_decl); tree orig_type = TREE_TYPE (orig_decl); + bool args_modified = false; if (prototype_p (orig_type) || (m_skip_return && !VOID_TYPE_P (TREE_TYPE (orig_type)))) { - tree new_type = build_new_function_type (orig_type, false); + tree new_type = build_new_function_type (orig_type, false, &args_modified); TREE_TYPE (new_decl) = new_type; } if (method2func_p (orig_type)) @@ -556,6 +571,20 @@ ipa_param_adjustments::adjust_decl (tree orig_decl) if (m_skip_return) DECL_IS_MALLOC (new_decl) = 0; + /* If the decl's arguments changed, we might need to drop some attributes. */ + if (args_modified && DECL_ATTRIBUTES (new_decl)) + { + tree t = DECL_ATTRIBUTES (new_decl); + tree *last = &DECL_ATTRIBUTES (new_decl); + DECL_ATTRIBUTES (new_decl) = NULL; + for (; t; t = TREE_CHAIN (t)) + if (!drop_decl_attribute_if_params_changed_p (get_attribute_name (t))) + { + *last = copy_node (t); + TREE_CHAIN (*last) = NULL; + last = &TREE_CHAIN (*last); + } + } return new_decl; } |