commit 55e576c7ca01679551404dac9f6302443c2a6bae Author: Kyrylo Tkachov Date: Thu May 14 12:00:07 2015 +0100 [AArch64][9/N] Implement TARGET_CAN_INLINE_P diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 0a6ed70..34cd986 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -8486,6 +8486,113 @@ aarch64_option_valid_attribute_p (tree fndecl, tree, tree args, int) return ret; } +/* Helper for aarch64_can_inline_p. In the case where CALLER and CALLEE are + tri-bool options (yes, no, don't care) and the default value is + DEF, determine whether to reject inlining. */ + +static bool +aarch64_reject_inlining (int caller, int callee, int dont_care, int def) +{ + /* If both caller and callee care about the value then reject inlining + if they don't match up. */ + if (caller != dont_care && callee != dont_care && caller != callee) + return true; + + /* If caller doesn't care then make sure that the default agrees + with the callee. */ + if (caller == dont_care && callee != dont_care && callee != def) + return true; + + return false; +} + +/* Implement TARGET_CAN_INLINE_P. Decide whether it is valid + to inline CALLE into CALLER based on target-specific info. + Make sure that the caller and callee have compatible architectural + features. Then go through the other possible target attributes + and. Try not to reject always_inline callees unless they are + incompatible architecturally. */ + +static bool +aarch64_can_inline_p (tree caller, tree callee) +{ + bool ret = false; + tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller); + tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee); + + /* If callee has no option attributes, then it is ok to inline. */ + if (!callee_tree) + ret = true; + else + { + struct cl_target_option *caller_opts + = TREE_TARGET_OPTION (caller_tree ? caller_tree + : target_option_default_node); + struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree); + + + /* Callee's ISA flags should be a subset of the caller's. */ + if ((caller_opts->x_aarch64_isa_flags & callee_opts->x_aarch64_isa_flags) + == callee_opts->x_aarch64_isa_flags) + ret = true; + + /* Allow non-strict aligned functions inlining into strict + aligned ones. */ + if ((TARGET_STRICT_ALIGN_P (caller_opts->x_target_flags) + != TARGET_STRICT_ALIGN_P (callee_opts->x_target_flags)) + && !(!TARGET_STRICT_ALIGN_P (callee_opts->x_target_flags) + && TARGET_STRICT_ALIGN_P (caller_opts->x_target_flags))) + ret = false; + + bool always_inline = lookup_attribute ("always_inline", + DECL_ATTRIBUTES (callee)); + + /* If the architectural features match up and the callee is always_inline + then the other attributes don't matter. */ + if (always_inline) + return ret; + + if (caller_opts->x_aarch64_cmodel_var + != callee_opts->x_aarch64_cmodel_var) + ret = false; + + if (caller_opts->x_aarch64_tls_dialect + != callee_opts->x_aarch64_tls_dialect) + ret = false; + + + /* Honour explicit requests to workaround errata. */ + if (aarch64_reject_inlining (caller_opts->x_aarch64_fix_a53_err835769, + callee_opts->x_aarch64_fix_a53_err835769, + 2, TARGET_FIX_ERR_A53_835769_DEFAULT)) + ret = false; + + /* If the user explicitly specified -momit-leaf-frame-pointer for the + caller and calle and they don't match up, reject inlining. */ + if (aarch64_reject_inlining (caller_opts->x_flag_omit_leaf_frame_pointer, + callee_opts->x_flag_omit_leaf_frame_pointer, + 2, 1)) + ret = false; + + /* If the callee has specific tuning overrides, respect them. */ + if (callee_opts->x_aarch64_override_tune_string != NULL + && caller_opts->x_aarch64_override_tune_string == NULL) + ret = false; + + /* If the user specified tuning override strings for the + caller and callee and they don't match up, reject inlining. + We just do a string compare here, we don't analyze the meaning + of the string, as it would be too costly for little gain. */ + if (callee_opts->x_aarch64_override_tune_string + && caller_opts->x_aarch64_override_tune_string + && (strcmp (callee_opts->x_aarch64_override_tune_string, + caller_opts->x_aarch64_override_tune_string) != 0)) + ret = false; + } + + return ret; +} + /* Return true if SYMBOL_REF X binds locally. */ static bool @@ -12963,6 +13070,9 @@ aarch64_unspec_may_trap_p (const_rtx x, unsigned flags) #undef TARGET_OPTION_VALID_ATTRIBUTE_P #define TARGET_OPTION_VALID_ATTRIBUTE_P aarch64_option_valid_attribute_p +#undef TARGET_CAN_INLINE_P +#define TARGET_CAN_INLINE_P aarch64_can_inline_p + #undef TARGET_PASS_BY_REFERENCE #define TARGET_PASS_BY_REFERENCE aarch64_pass_by_reference