diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-03-09 16:47:10 +0100 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-04-28 23:35:49 +0200 |
commit | 4e178ad5cfa6c2e23b81537838458650251d435d (patch) | |
tree | 551f0987ac2a9bec72f4a10be06574e4a48dee2b | |
parent | aafa2ae8cef4b41127c5e0e7f4f4940d8037e0c5 (diff) |
Propagating escape information to all reachable types
-rw-r--r-- | gcc/ipa-hello-world.c | 121 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipa-ea-12-cast-to-void-ptr-0.c | 27 |
2 files changed, 127 insertions, 21 deletions
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c index df08d76ceeb..8289728f9bc 100644 --- a/gcc/ipa-hello-world.c +++ b/gcc/ipa-hello-world.c @@ -48,6 +48,90 @@ typedef struct escaping_info_s escaping_info; typedef hash_map<const_tree, escaping_info> type_map; static bool filter_type (type_map &escape_map, const_tree type); +void update_escape_info (const_tree type, type_map &escape_map, bool is_escaping); + +void +update_escape_info_pointer (const_tree pointer_type, type_map &escape_map, bool is_escaping) +{ + gcc_assert(pointer_type); + enum tree_code tree_code_pointer_type = TREE_CODE(pointer_type); + bool is_pointer_type = POINTER_TYPE == tree_code_pointer_type; + gcc_assert(is_pointer_type); + + escaping_info *info = escape_map.get(pointer_type); + if (!info) return; + + info->is_escaping |= is_escaping; + tree tree_type_pointer_type = TREE_TYPE(pointer_type); + gcc_assert(tree_type_pointer_type); + update_escape_info (tree_type_pointer_type, escape_map, info->is_escaping); +} + +void +update_escape_info_array (const_tree array_type, type_map &escape_map, bool is_escaping) +{ + gcc_assert(array_type); + enum tree_code tree_code_array_type = TREE_CODE(array_type); + bool is_array_type = ARRAY_TYPE == tree_code_array_type; + gcc_assert(is_array_type); + + escaping_info *info = escape_map.get(array_type); + if (!info) return; + + info->is_escaping |= is_escaping; + tree tree_type_array_type = TREE_TYPE(array_type); + gcc_assert(tree_type_array_type); + update_escape_info (tree_type_array_type, escape_map, info->is_escaping); +} + +void +update_escape_info_record (const_tree record_type, type_map &escape_map, bool is_escaping) +{ + gcc_assert(record_type); + enum tree_code tree_code_record_type = TREE_CODE(record_type); + bool is_record_type = RECORD_TYPE == tree_code_record_type; + gcc_assert(is_record_type); + + escaping_info *info = escape_map.get(record_type); + // we are collecting records, therefore, we **must** have + // it in the escaping info + gcc_assert(info); + info->is_escaping |= is_escaping; + + + for (tree field = TYPE_FIELDS (record_type); field; field = DECL_CHAIN (field)) + { + gcc_assert(field); + tree tree_type_field = TREE_TYPE(field); + gcc_assert(tree_type_field); + update_escape_info (tree_type_field, escape_map, info->is_escaping); + } +} + +void +update_escape_info (const_tree type, type_map &escape_map, bool is_escaping) +{ + // INFO: This is an optimization. + if (!is_escaping) return; + + gcc_assert(type); + enum tree_code tree_code_type = TREE_CODE(type); + switch (tree_code_type) + { + case ARRAY_TYPE: + update_escape_info_array(type, escape_map, is_escaping); + break; + case POINTER_TYPE: + update_escape_info_pointer(type, escape_map, is_escaping); + break; + case RECORD_TYPE: + update_escape_info_record(type, escape_map, is_escaping); + break; + default: + break; + } +} + static bool filter_pointer (type_map &escape_map, const_tree pointer) { @@ -370,9 +454,8 @@ calculate_escaping_parameters(cgraph_node *cnode, type_map &escape_map) gcc_assert(identifier); tree tree_type = TREE_TYPE(parm); gcc_assert(tree_type); - escaping_info *info = escape_map.get(tree_type); - if (!info) continue; - info->is_escaping |= is_escaping; + // void update_escaping_info (const_tree type, type_map &escape_map, bool is_escaping); + update_escape_info(tree_type, escape_map, is_escaping); log("variable %s is escaping %s\n", identifier, is_escaping ? "true" : "false"); } } @@ -394,10 +477,12 @@ is_return_type_escaping(cgraph_node *cnode, type_map &escape_map) gcc_assert(return_type); log("return type %s\n", get_type_name(return_type)); - escaping_info *info = escape_map.get(return_type); + // void update_escaping_info (const_tree type, type_map &escape_map, bool is_escaping); + update_escape_info(return_type, escape_map, is_escaping); + //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; + //if (!info) return; + //info->is_escaping |= is_escaping; } void @@ -428,9 +513,11 @@ is_any_variable_escaping(type_map &escape_map) gcc_assert(decl); tree type = TREE_TYPE(decl); gcc_assert(type); - escaping_info *info = escape_map.get(type); - if (!info) return; - info->is_escaping |= is_escaping; + // void update_escaping_info (const_tree type, type_map &escape_map, bool is_escaping); + update_escape_info (type, escape_map, is_escaping); + //escaping_info *info = escape_map.get(type); + //if (!info) return; + //info->is_escaping |= is_escaping; } } @@ -466,19 +553,11 @@ cast_to_void_in_assign(const_tree lhs, const_tree rhs, type_map &escape_map) log("is casting stmt ? %s\n", is_casting_stmt ? "true" : "false"); if (!is_casting_stmt) return; - escaping_info *info_lhs = escape_map.get(tree_type_lhs); - if (info_lhs) - { - log("escaping lhs %s\n", type_name_lhs); - info_lhs->is_escaping = true; - } + log("escaping lhs %s\n", type_name_lhs); + update_escape_info(tree_type_lhs, escape_map, true); - escaping_info *info_rhs = escape_map.get(tree_type_rhs); - if (info_rhs) - { - log("escaping rhs %s\n", type_name_rhs); - info_rhs->is_escaping = true; - } + log("escaping rhs %s\n", type_name_rhs); + update_escape_info(tree_type_rhs, escape_map, true); } static void diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-12-cast-to-void-ptr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-12-cast-to-void-ptr-0.c new file mode 100644 index 00000000000..7218e5d54e4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-12-cast-to-void-ptr-0.c @@ -0,0 +1,27 @@ +/* { 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 + +void casting_to_void (struct astruct_s *s) +{ + void *nullify_non_escape = s; +} + +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 "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" } } */ |