diff options
author | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-09 11:24:45 +0200 |
---|---|---|
committer | Erick Ochoa <erick.ochoa@theobroma-systems.com> | 2020-06-09 12:59:52 +0200 |
commit | 7e87749b70a6955808682689962112b33ebb422b (patch) | |
tree | 2d7115b0411de72806458f7156ca71aacc4249a3 | |
parent | 8417ba15c91443e5bfca945c3cf412523d2c1e0c (diff) |
Fixes escape analysis tests
23 files changed, 165 insertions, 94 deletions
diff --git a/gcc/common.opt b/gcc/common.opt index cdbaecf86ac..ec351e2f96f 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -3458,4 +3458,12 @@ fipa-type-escape-analysis Common Report Var(flag_ipa_type_escape_analysis) Optimization This flag is only used for debugging the type escape analysis +fprint-escape-analysis +Common Report Var(flag_print_escape_analysis) Optimization +This flag is used to print the escape analysis proper. It does not include type casting. + +fprint-cast-analysis +Common Report Var(flag_print_cast_analysis) Optimization +This flag is used to print the escape analysis including type casting. + ; This comment is to ensure we retain the blank line above. diff --git a/gcc/gimple-caster.c b/gcc/gimple-caster.c index ce96a78d7dc..747d60920aa 100644 --- a/gcc/gimple-caster.c +++ b/gcc/gimple-caster.c @@ -2,11 +2,11 @@ #include "gimple-pretty-print.h" #include "type-incomplete-equality.hpp" +#include "type-stringifier.hpp" void GimpleCaster::_walk_pre(gassign *s) { - print_gimple_stmt(dump_file, s, TDF_NONE); const enum gimple_rhs_class code = gimple_assign_rhs_class(s); const bool valid_input = GIMPLE_SINGLE_RHS == code; if (!valid_input) return; diff --git a/gcc/gimple-escaper.c b/gcc/gimple-escaper.c index 4c1cedd7412..ed879123cc1 100644 --- a/gcc/gimple-escaper.c +++ b/gcc/gimple-escaper.c @@ -30,6 +30,8 @@ #include <stdbool.h> #include "gimple-escaper.hpp" +#include "type-stringifier.hpp" +#include "type-incomplete-equality.hpp" void @@ -67,6 +69,26 @@ GimpleEscaper::is_function_escaping(cgraph_node *cnode) return cnode->externally_visible; } +bool +GimpleEscaper::is_variable_escaping(varpool_node *vnode) +{ + gcc_assert(vnode); + return vnode->externally_visible; +} + +void +GimpleEscaper::_walk_global(varpool_node *vnode) +{ + gcc_assert(vnode); + const_tree var_decl = vnode->decl; + Reason reason {} ; + const bool is_escaping = is_variable_escaping(vnode); + reason.is_escaping = is_escaping; + reason.global_is_visible = is_escaping; + exprEscaper.update(var_decl, reason); + GimpleWalker::_walk_global(vnode); +} + bool GimpleEscaper::filter_known_function(cgraph_node *node) { @@ -88,7 +110,7 @@ GimpleEscaper::filter_known_function(cgraph_node *node) } void -GimpleEscaper::_walk_pre(__attribute__((unused)) const_tree t) +GimpleEscaper::_walk_pre(const_tree t) { // Is any global variable escaping? Reason reason; @@ -96,7 +118,7 @@ GimpleEscaper::_walk_pre(__attribute__((unused)) const_tree t) } void -GimpleEscaper::_walk_pre(__attribute__((unused)) gassign *s) +GimpleEscaper::_walk_pre(gassign *s) { Reason reason; const enum gimple_rhs_class code = gimple_assign_rhs_class(s); @@ -131,7 +153,7 @@ GimpleEscaper::_walk_pre(__attribute__((unused)) gassign *s) } void -GimpleEscaper::_walk_pre(__attribute__((unused)) greturn *s) +GimpleEscaper::_walk_pre(greturn *s) { Reason reason; const_tree val = gimple_return_retval(s); @@ -140,7 +162,7 @@ GimpleEscaper::_walk_pre(__attribute__((unused)) greturn *s) } void -GimpleEscaper::_walk_pre(__attribute__((unused)) gcond *s) +GimpleEscaper::_walk_pre(gcond *s) { Reason reason; const_tree lhs = gimple_cond_lhs(s); @@ -154,11 +176,20 @@ void GimpleEscaper::_walk_pre(gcall *s) { tree fn = gimple_call_fndecl(s); + cgraph_node *node = cgraph_node::get(fn); + const bool _is_function_escaping = is_function_escaping(node); const bool is_undefined = undefined.find(fn) != undefined.end(); + const bool _is_escaping = is_undefined || _is_function_escaping; + Reason function_type_reason; + function_type_reason.is_escaping = _is_escaping; + function_type_reason.global_is_visible = _is_escaping; + // TODO: Consider this... + //exprEscaper.update(fn, function_type_reason); + Reason arg_reason; - arg_reason.is_escaping = is_undefined; - arg_reason.parameter_is_visible = is_undefined; + arg_reason.is_escaping = _is_escaping; + arg_reason.parameter_is_visible = _is_escaping; unsigned n = gimple_call_num_args(s); for (unsigned i = 0; i < n; i++) { @@ -171,7 +202,7 @@ GimpleEscaper::_walk_pre(gcall *s) if (!lhs) return; Reason return_reason; - return_reason.is_escaping = is_undefined; - return_reason.return_is_visible = is_undefined; + return_reason.is_escaping = _is_escaping; + return_reason.return_is_visible = _is_escaping; exprEscaper.update(lhs, return_reason); } diff --git a/gcc/gimple-escaper.hpp b/gcc/gimple-escaper.hpp index 9c439fffe38..b6f77111007 100644 --- a/gcc/gimple-escaper.hpp +++ b/gcc/gimple-escaper.hpp @@ -17,6 +17,9 @@ private: void _init(); static bool filter_known_function(cgraph_node *); static bool is_function_escaping(cgraph_node *); + static bool is_variable_escaping(varpool_node *); + static bool _is_assignment_casted(gassign *s); + virtual void _walk_global(varpool_node *); virtual void _walk_pre(gassign *s) ; virtual void _walk_pre(greturn *s) ; virtual void _walk_pre(gcond *s) ; diff --git a/gcc/gimple-walker.c b/gcc/gimple-walker.c index eb15db85a01..9259c0d9438 100644 --- a/gcc/gimple-walker.c +++ b/gcc/gimple-walker.c @@ -60,6 +60,7 @@ GimpleWalker::walk() cgraph_node *node = NULL; FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) { + // print_function(node); node->get_untransformed_body(); _walk_cnode(node); } @@ -71,13 +72,19 @@ GimpleWalker::_walk_globals() varpool_node *vnode = NULL; FOR_EACH_VARIABLE(vnode) { - gcc_assert(vnode); - struct ipa_ref *ref = NULL; - for (unsigned i = 0; vnode->iterate_referring(i, ref); i++) - { - tree var_decl = vnode->decl; - walk(var_decl); - } + _walk_global(vnode); + } +} + +void +GimpleWalker::_walk_global(varpool_node *vnode) +{ + gcc_assert(vnode); + struct ipa_ref *ref = NULL; + for (unsigned i = 0; vnode->iterate_referring(i, ref); i++) + { + tree var_decl = vnode->decl; + walk(var_decl); } } diff --git a/gcc/gimple-walker.hpp b/gcc/gimple-walker.hpp index cc1ece64f05..bfd5d5afb6e 100644 --- a/gcc/gimple-walker.hpp +++ b/gcc/gimple-walker.hpp @@ -36,8 +36,9 @@ public: GimpleWalker() {}; void walk(); -private: +protected: + virtual void _walk_global(varpool_node*); void _walk_globals(); void _walk_ssa_names(cgraph_node *cnode); void _walk_cnode(cgraph_node *cnode); diff --git a/gcc/ipa-prototype.c b/gcc/ipa-prototype.c index c718e5bb57e..f8cf7aa9067 100644 --- a/gcc/ipa-prototype.c +++ b/gcc/ipa-prototype.c @@ -53,8 +53,6 @@ typedef std::set<const_tree> undefset; void Reason::print() const { - if (!this->is_escaping) return; - log("g=%d p=%d r=%d c=%d v=%d u=%d\n", this->global_is_visible, this->parameter_is_visible, this->return_is_visible, this->type_is_casted, this->type_is_volatile, this->type_is_in_union); } @@ -78,6 +76,7 @@ Reason::operator|=(const Reason &other) this->is_escaping |= other.is_escaping; this->global_is_visible |= other.global_is_visible; this->parameter_is_visible |= other.parameter_is_visible; + this->return_is_visible |= other.return_is_visible; this->type_is_casted |= other.type_is_casted; this->type_is_volatile |= other.type_is_volatile; this->type_is_in_union |= other.type_is_in_union; diff --git a/gcc/ipa-type-escape-analysis.c b/gcc/ipa-type-escape-analysis.c index be5f00f93de..0f548bf4943 100644 --- a/gcc/ipa-type-escape-analysis.c +++ b/gcc/ipa-type-escape-analysis.c @@ -23,6 +23,8 @@ #include "attribs.h" #include "gimple-collector.hpp" +#include "gimple-escaper.hpp" +#include "gimple-caster.hpp" static unsigned int iphw_execute(); @@ -98,4 +100,12 @@ collect_types() GimpleTypeCollector collector; collector.walk(); collector.print_collected(); + ptrset_t types = collector.get_pointer_set(); + GimpleEscaper gimpleEscaper(types); + gimpleEscaper.walk(); + if (flag_print_escape_analysis) gimpleEscaper.print_reasons(); + types = gimpleEscaper.get_sets(); + GimpleCaster caster(types); + caster.walk(); + if (flag_print_cast_analysis) caster.print_reasons(); } diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-00-collect-global-record-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-00-collect-global-record-0.c index 9d096b3747f..b7f1b3c051f 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-00-collect-global-record-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-00-collect-global-record-0.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-escape-analysis" } */ struct astruct_s { _Bool a; _Bool b; _Bool c;}; struct astruct_s astruct; diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-01-collect-global-pointers-to-record-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-01-collect-global-pointers-to-record-0.c index 94cd66d8ef7..511543307ce 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-01-collect-global-pointers-to-record-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-01-collect-global-pointers-to-record-0.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-escape-analysis" } */ #include <stddef.h> diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-02-collect-global-array-to-record-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-02-collect-global-array-to-record-0.c index 3cacc4a3838..c2cfeb313c9 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-02-collect-global-array-to-record-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-02-collect-global-array-to-record-0.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-escape-analysis" } */ #include <stddef.h> diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-03-collect-nested-record-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-03-collect-nested-record-0.c index 2feb88a1a60..652f8576ecd 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-03-collect-nested-record-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-03-collect-nested-record-0.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-escape-analysis" } */ #include <stddef.h> diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-04-collect-parameters-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-04-collect-parameters-0.c index 7b40c7701bf..5f952afe739 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-04-collect-parameters-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-04-collect-parameters-0.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-escape-analysis" } */ #include <stddef.h> @@ -15,6 +15,17 @@ main () { } -/* { dg-final { scan-ipa-dump "collected,astruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-ipa-dump "collected,astruct_s*" "type-escape-analysis" } } */ -/* { dg-final { scan-ipa-dump "collected,astruct_s[]" "type-escape-analysis" } } */ +// We have a complete type, probably from record_parameter +/* { dg-final { scan-wpa-ipa-dump "collected: record astruct_s .boolean_type a.boolean_type b.boolean_type c.." "type-escape-analysis" } } */ +// Now we have an incomplete struct +/* { dg-final { scan-wpa-ipa-dump "collected: record astruct_s .." "type-escape-analysis" } } */ +// This is the pointer... +/* { dg-final { scan-wpa-ipa-dump "collected: record astruct_s ..." "type-escape-analysis" } } */ +// We are missing the array parameter +// But it seems that the array parameter is passed as a pointer, which makes sense... +// array_parameter (struct astruct_s * a) +// { +// <bb 2> : +// return; +// +// } diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-05-global-escapes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-05-global-escapes-0.c index 32a77195322..29071ccce29 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-05-global-escapes-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-05-global-escapes-0.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-escape-analysis" } */ /* { dg-require-effective-target lto } */ @@ -17,7 +17,10 @@ int main() } -/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "variable bstruct is escaping false" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "collected,bstruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "variable astruct is escaping true" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump "collected: record astruct_s .boolean_type a;boolean_type b;boolean_type c;." "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump "collected: record bstruct_s .boolean_type a;boolean_type b;boolean_type c;." "type-escape-analysis" } } */ +// Do we find the externally visible struct? +// This says that record astruct_s is escaping because the reason g (global is visible) is set to true... +/* { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a.boolean_type b.boolean_type c.. reason: g=1 p=0 r=0 c=0 v=0 u=0" "type-escape-analysis" } } */ +// This says that record bstruct_s is not escaping +/* { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a.boolean_type b.boolean_type c.. reason: g=0 p=0 r=0 c=0 v=0 u=0" "type-escape-analysis" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-06-global-type-escapes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-06-global-type-escapes-0.c index 2e7024ab907..56344f78faf 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-06-global-type-escapes-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-06-global-type-escapes-0.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-escape-analysis" } */ #include <stddef.h> @@ -14,8 +14,16 @@ int main() bstruct.b = 0; } +// This test is pretty much the same as the previous one. +// The reason for this is because initially the previous +// test tested the escaping of variables and this one of +// types. Since, we are now not checking variables escaping +// these two tests have merged. -/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "type astruct_s is escaping true" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "collected,bstruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "type bstruct_s is escaping false" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump "collected: record astruct_s .boolean_type a;boolean_type b;boolean_type c;." "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump "collected: record bstruct_s .boolean_type a;boolean_type b;boolean_type c;." "type-escape-analysis" } } */ +// Do we find the externally visible struct? +// This says that record astruct_s is escaping because the reason g (global is visible) is set to true... +/* { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a.boolean_type b.boolean_type c.. reason: g=1 p=0 r=0 c=0 v=0 u=0" "type-escape-analysis" } } */ +// This says that record bstruct_s is not escaping +/* { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a.boolean_type b.boolean_type c.. reason: g=0 p=0 r=0 c=0 v=0 u=0" "type-escape-analysis" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-08-parameter-escapes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-08-parameter-escapes-0.c index d1842987735..5c0443c217c 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-08-parameter-escapes-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-08-parameter-escapes-0.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-escape-analysis" } */ /* { dg-require-effective-target lto } */ @@ -15,13 +15,10 @@ void non_escaping(struct bstruct_s dstruct) {} int main() { - astruct.a = 0; - bstruct.b = 0; + escaping(astruct); + non_escaping(bstruct); } -/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "hello-world" } } */ -/* { dg-final { scan-wpa-ipa-dump "variable bstruct is escaping false" "hello-world" } } */ -/* { dg-final { scan-wpa-ipa-dump "collected,bstruct_s" "hello-world" } } */ -/* { dg-final { scan-wpa-ipa-dump "parameter type astruct_s is escaping true" "hello-world" } } */ -/* { dg-final { scan-wpa-ipa-dump "parameter type bstruct_s is escaping false" "hello-world" } } */ +/* { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: g=0 p=1 r=0 c=0 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: g=0 p=0 r=0 c=0 v=0 u=0" "type-escape-analysis" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-09-parameter-type-escapes-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-09-parameter-type-escapes-0.c deleted file mode 100644 index 79809249942..00000000000 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-09-parameter-type-escapes-0.c +++ /dev/null @@ -1,24 +0,0 @@ -/* { dg-do link } */ -/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ - -#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)) void escaping(struct astruct_s cstruct) {} -void non_escaping(struct bstruct_s dstruct) {} - -int main() -{ - astruct.a = 0; - bstruct.b = 0; -} - - -/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "collected,bstruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "type bstruct_s is escaping false" "type-escape-analysis" } } */ 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 index f2c5f307f01..e1be6c2bfbd 100644 --- 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 @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-escape-analysis" } */ #include <stddef.h> @@ -9,16 +9,17 @@ 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) {} +struct astruct_s __attribute__((externally_visible)) escaping() { struct astruct_s a; return a; } +struct bstruct_s non_escaping() {} int main() { - astruct.a = 0; - bstruct.b = 0; + astruct = escaping(); + bstruct = non_escaping(); } -/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "collected,bstruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "type bstruct_s is escaping false" "type-escape-analysis" } } */ +// This says that astruct_s escapes because it is returning from an externally visible function +/* { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: g=0 p=0 r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ +// This says that bstruct_s does not escape +/* { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: g=0 p=0 r=0 c=0 v=0 u=0" "type-escape-analysis" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c index 596f220a72c..d79b1574ce4 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-11-cast-to-void-ptr-0.c @@ -20,4 +20,13 @@ int main() } -/* { dg-final { scan-wpa-ipa-dump "record" "structure-reorg" } } */ +// The type +/* { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: g=0 p=0 r=0 c=1 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: g=0 p=0 r=0 c=1 v=0 u=0" "type-escape-analysis" } } */ +// The pointer +/* { dg-final { scan-wpa-ipa-dump " record bstruct_s .boolean_type a;boolean_type b;boolean_type c;.. reason: g=0 p=0 r=0 c=1 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;.. reason: g=0 p=0 r=0 c=1 v=0 u=0" "type-escape-analysis" } } */ + +// But there are incomplete types... should does be marked as escaping as well here? +// No, because at the moment, how we compute it is with the fixed point and at that moment, we get rid of reasons. +// So, at the moment, it is sufficient to say that only a fraction of equivalent types escape. 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 index 1f298b1415b..5a9be3021e0 100644 --- 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 @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-cast-analysis" } */ #include <stddef.h> @@ -20,8 +20,8 @@ int main() } -/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "type astruct_s\\\* is escaping true" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "type astruct_s is escaping true" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "collected,bstruct_s" "type-escape-analysis" } } */ -/* { dg-final { scan-wpa-ipa-dump "type bstruct_s is escaping false" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump "void_type. reason: g=0 p=0 r=0 c=1 v=0 u=0" "type-escape-analysis" } } */ +// base type +/* { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;. reason: g=0 p=0 r=0 c=1 v=0 u=0" "type-escape-analysis" } } */ +// pointer +/* { dg-final { scan-wpa-ipa-dump " record astruct_s .boolean_type a;boolean_type b;boolean_type c;.. reason: g=0 p=0 r=0 c=1 v=0 u=0" "type-escape-analysis" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-13-calling-printf-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-13-calling-printf-0.c index aa3e97b5444..fb3e0e9d17d 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-ea-13-calling-printf-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-13-calling-printf-0.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis" } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-escape-analysis" } */ #include <stddef.h> #include <stdio.h> @@ -7,9 +7,21 @@ int main(int argc, char** argv) { char *filename = "helloworld.txt"; - FILE* f = fopen(filename); + FILE* f = fopen(filename, "r"); fclose(f); } -/* { dg-final { scan-wpa-ipa-dump "type FILE is escaping true" "type-escape-analysis" } } */ +// This is the incomplete type p=0 because it is memoized and it is an optimization. +// However, I will also match a 1 +/* { dg-final { scan-wpa-ipa-dump " record _IO_FILE .. reason: g=0 p=. r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump " record _IO_FILE ... reason: g=0 p=. r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump " record _IO_wide_data .. reason: g=0 p=. r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump " record _IO_wide_data ... reason: g=0 p=. r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump " record _IO_codecvt .. reason: g=0 p=. r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump " record _IO_codecvt ... reason: g=0 p=. r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump "void_type. reason: g=0 p=. r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump " record _IO_marker .. reason: g=0 p=. r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ +/* { dg-final { scan-wpa-ipa-dump " record _IO_marker ... reason: g=0 p=. r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ +// This is the complete type... but I have condensed it to match .* +/* { dg-final { scan-wpa-ipa-dump " record FILE .* reason: g=0 p=. r=1 c=0 v=0 u=0" "type-escape-analysis" } } */ diff --git a/gcc/type-escaper.c b/gcc/type-escaper.c index 466f13a77cc..65ff8d6f0d0 100644 --- a/gcc/type-escaper.c +++ b/gcc/type-escaper.c @@ -167,12 +167,7 @@ TypeEscaper::print_reasons() const_tree t = i->first; std::string name = stringifier.stringify(t); const bool in_universe = _ptrset.in_universe(t); - if (!in_universe) continue; - Reason r = i->second; - const bool is_escaping = r.is_escaping; - if (!is_escaping) continue; - log("%s reason: ", name.c_str()); r.print(); } diff --git a/gcc/type-incomplete-equality.c b/gcc/type-incomplete-equality.c index ed0a27154b4..9ce7eed1413 100644 --- a/gcc/type-incomplete-equality.c +++ b/gcc/type-incomplete-equality.c @@ -46,8 +46,8 @@ TypeIncompleteEquality::_equal(const_tree l, const_tree r) // if any of these are incomplete, then we can only compare using identifiers... const bool incomplete_l = is_incomplete(l); const bool incomplete_r = is_incomplete(r); - const bool can_compare_incompletely = incomplete_l || incomplete_r; - if (!can_compare_incompletely) return TypeCanonicalEquality::_equal(l, r); + const bool can_compare_structurally = incomplete_l && incomplete_r; + if (can_compare_structurally) return TypeStructuralEquality::_equal(l, r); const std::string n_l = TypeStringifier::get_type_identifier(l); const std::string n_r = TypeStringifier::get_type_identifier(r); |