summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-03-09 16:47:10 +0100
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-04-28 23:35:49 +0200
commit4e178ad5cfa6c2e23b81537838458650251d435d (patch)
tree551f0987ac2a9bec72f4a10be06574e4a48dee2b
parentaafa2ae8cef4b41127c5e0e7f4f4940d8037e0c5 (diff)
Propagating escape information to all reachable types
-rw-r--r--gcc/ipa-hello-world.c121
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-12-cast-to-void-ptr-0.c27
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" } } */