aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-param-manipulation.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ipa-param-manipulation.cc')
-rw-r--r--gcc/ipa-param-manipulation.cc37
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;
}