diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-03-09 14:33:44 +0100 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-04-28 23:35:48 +0200 |
commit | b084c84c358b7632e0896473de598bcd3f756339 (patch) | |
tree | a317187dd5c5d325aae71b9a58ba433c35acc218 | |
parent | 83ecbc042ff3a1cd788abe84fd16fa0e507714b2 (diff) |
Find if return type escapes
-rw-r--r-- | gcc/ipa-hello-world.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipa-ea-10-return-type-escapes-0.c | 25 |
2 files changed, 52 insertions, 2 deletions
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c index cbe293d2df0..738e385396d 100644 --- a/gcc/ipa-hello-world.c +++ b/gcc/ipa-hello-world.c @@ -220,6 +220,7 @@ is_function_escaping(cgraph_node *cnode) void calculate_escaping_parameters(cgraph_node *cnode, type_map &escape_map) { + gcc_assert(cnode); tree function = cnode->decl; gcc_assert(function); enum tree_code code = TREE_CODE (function); @@ -236,13 +237,36 @@ calculate_escaping_parameters(cgraph_node *cnode, type_map &escape_map) tree tree_type = TREE_TYPE(parm); gcc_assert(tree_type); escaping_info *info = escape_map.get(tree_type); - gcc_assert(info); + if (!info) continue; info->is_escaping |= is_escaping; log("variable %s is escaping %s\n", identifier, is_escaping ? "true" : "false"); } } void +is_return_type_escaping(cgraph_node *cnode, type_map &escape_map) +{ + gcc_assert(cnode); + bool is_escaping = is_function_escaping(cnode); + tree function = cnode->decl; + gcc_assert(function); + enum tree_code code = TREE_CODE(function); + bool is_function = FUNCTION_DECL == code; + gcc_assert(is_function); + + tree tree_type = TREE_TYPE(function); + gcc_assert(tree_type); + tree return_type = TREE_TYPE(tree_type); + gcc_assert(return_type); + log("return type %s\n", get_type_name(return_type)); + + escaping_info *info = escape_map.get(return_type); + // If there's no info it means it is not interesting... + if (!info) return; + info->is_escaping |= is_escaping; +} + +void is_any_function_escaping(type_map &escape_map) { cgraph_node *cnode = NULL; @@ -253,6 +277,7 @@ is_any_function_escaping(type_map &escape_map) bool is_escaping = is_function_escaping(cnode); log("function %s is escaping %s\n", cnode->name(), is_escaping ? "true" : "false"); calculate_escaping_parameters(cnode, escape_map); + is_return_type_escaping(cnode, escape_map); } } @@ -270,7 +295,7 @@ is_any_variable_escaping(type_map &escape_map) tree type = TREE_TYPE(decl); gcc_assert(type); escaping_info *info = escape_map.get(type); - gcc_assert(info); + if (!info) return; info->is_escaping |= is_escaping; } } diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-10-return-type-escapes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-10-return-type-escapes-0.c new file mode 100644 index 00000000000..1a6de797477 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-10-return-type-escapes-0.c @@ -0,0 +1,25 @@ +/* { dg-do link } */ +/* { dg-options "-flto -fipa-hello-world -fdump-ipa-hello-world" } */ + +#include <stddef.h> + +struct astruct_s { _Bool a; _Bool b; _Bool c;}; +struct astruct_s astruct; // This should not escape +struct bstruct_s { _Bool a; _Bool b; _Bool c;}; +struct bstruct_s bstruct; // This should not escape + +// This will make astruct_s escape +__attribute__((externally_visible)) struct astruct_s escaping() { struct astruct_s a; return a; } +void non_escaping(struct bstruct_s dstruct) {} + +int main() +{ + astruct.a = 0; + bstruct.b = 0; +} + + +/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "hello-world" } } */ +/* { dg-final { scan-wpa-ipa-dump "type astruct_s is escaping true" "hello-world" } } */ +/* { dg-final { scan-wpa-ipa-dump "collected,bstruct_s" "hello-world" } } */ +/* { dg-final { scan-wpa-ipa-dump "type bstruct_s is escaping false" "hello-world" } } */ |