From 214ca82d2f5cc412b4605d00d8e5ef714e01d818 Mon Sep 17 00:00:00 2001 From: Erick Ochoa Date: Mon, 22 Jun 2020 11:04:26 +0200 Subject: mcf is working on our pass but fails on another --- gcc/expr-escaper.c | 1 - gcc/expr-rewriter.c | 12 +++++++++++ gcc/gimple-caster.c | 3 +-- gcc/gimple-escaper.c | 4 +++- gcc/gimple-rewriter.c | 25 +++++++++++++++++++++- gcc/gimple-rewriter.hpp | 1 + gcc/gimple-walker.c | 13 +++++++++++ gcc/gimple-walker.hpp | 7 ++++-- gcc/ipa-type-escape-analysis.c | 10 ++++----- .../ipa/ipa-access-counter-04-gimple-cond-0.c | 2 +- gcc/type-escaper.c | 15 ++++++++++++- gcc/type-escaper.hpp | 16 ++++++++------ gcc/type-reconstructor.c | 1 + gcc/type-walker.hpp | 8 +++---- 14 files changed, 93 insertions(+), 25 deletions(-) diff --git a/gcc/expr-escaper.c b/gcc/expr-escaper.c index d2a81d13493..aecb6fc4b40 100644 --- a/gcc/expr-escaper.c +++ b/gcc/expr-escaper.c @@ -51,4 +51,3 @@ ExprEscaper::_walk_pre(const_tree e) typeEscaper.update(t, _r); } - diff --git a/gcc/expr-rewriter.c b/gcc/expr-rewriter.c index 803d4206cb8..142d023cb6e 100644 --- a/gcc/expr-rewriter.c +++ b/gcc/expr-rewriter.c @@ -332,6 +332,17 @@ void ExprTypeRewriter::_walk_COMPONENT_REF_post(const_tree e) { + /* + * Changing the record type will happen later... + const_tree r = TREE_OPERAND(e, 0); + tree record_type = TREE_TYPE(r); + log("changing the record type\n"); + const bool in_map1 = _map.find(record_type) != _map.end(); + log("record in map ? %s\n", in_map1 ? "t" : "f"); + TREE_TYPE((tree)e) = in_map1 ? _map[record_type] : TREE_TYPE((tree)r); + */ + + const_tree f = TREE_OPERAND(e, 1); // So, what we need is a map between this field and the new field const bool in_map = _map2.find(f) != _map2.end(); @@ -355,6 +366,7 @@ ExprTypeRewriter::_walk_COMPONENT_REF_post(const_tree e) // Otherwise, we will just overwrite memory where the previous field was located log("replacing field %s %d with %s %d\n", TypeStringifier::get_field_identifier(f).c_str(), f_offset, TypeStringifier::get_field_identifier(n_f).c_str(), nf_offset); + if (!is_deleted) return; log("deleting field %s %d\n", TypeStringifier::get_field_identifier(f).c_str(), f_offset); diff --git a/gcc/gimple-caster.c b/gcc/gimple-caster.c index 832651cdea5..04283c9237a 100644 --- a/gcc/gimple-caster.c +++ b/gcc/gimple-caster.c @@ -40,8 +40,7 @@ GimpleCaster::_walk_pre(gassign *s) // poor man's goto if (!fn) break; - cgraph_node *node = cgraph_node::get(fn); - bool known_function = GimpleEscaper::filter_known_function(node); + bool known_function = GimpleEscaper::filter_known_function(fn); is_cast = !known_function; is_ssa = false; diff --git a/gcc/gimple-escaper.c b/gcc/gimple-escaper.c index b683a7c4d1b..1829ea9bd07 100644 --- a/gcc/gimple-escaper.c +++ b/gcc/gimple-escaper.c @@ -126,11 +126,13 @@ GimpleEscaper::filter_known_function(const_tree fndecl) const char *_med3 = "arc_compare"; const char *_getArcPosition = "getArcPosition"; const char *_med3_ = "med3.part.0"; + const char *_med3_2 = "med3"; const char* name = IDENTIFIER_POINTER(identifier_node); gcc_assert(name); filter |= strcmp(_specqsort, name) == 0; filter |= strcmp(_med3, name) == 0; filter |= strcmp(_med3_, name) == 0; + filter |= strcmp(_med3_2, name) == 0; filter |= strcmp(_getArcPosition, name) == 0; return filter; } @@ -239,7 +241,7 @@ GimpleEscaper::_walk_pre(gcall *s) { const_tree a = gimple_call_arg(s, i); gcc_assert(a); - exprEscaper.update_single_level(a, arg_reason); + exprEscaper.update(a, arg_reason); } const_tree lhs = gimple_call_lhs(s); diff --git a/gcc/gimple-rewriter.c b/gcc/gimple-rewriter.c index b1e2dc2aa0a..4ba96e2c77f 100644 --- a/gcc/gimple-rewriter.c +++ b/gcc/gimple-rewriter.c @@ -24,6 +24,7 @@ #include "ssa.h" #include "tree-into-ssa.h" #include "gimple-rewriter.hpp" +#include "type-stringifier.hpp" void GimpleTypeRewriter::_walk_pre(const_tree e) @@ -167,6 +168,19 @@ GimpleTypeRewriter::_walk_pre(gassign *s) case POINTER_DIFF_EXPR: handle_pointer_arithmetic(s); break; + case COMPONENT_REF: + { + log("i am missing a component ref\n"); + print_gimple_stmt(dump_file, s, 0); + log("\n"); + + ///TypeStringifier stringifier; + //const_tree type = TREE_TYPE(s); + //std::string name = stringifier.stringify(type); + //log("%s\n", name.c_str()); + } + break; + break; default: log("missing %s\n", get_tree_code_name(e_code)); break; @@ -194,6 +208,15 @@ GimpleTypeRewriter::_rewrite_function_decl() tree decl = DECL_RESULT(fndecl); if (decl) exprTypeRewriter.walk(decl); } +} - +void +GimpleTypeRewriter::_walk_pre(gphi *s) +{ + unsigned n = gimple_phi_num_args (s); + for (unsigned i = 0; i < n; i++) + { + tree a = gimple_phi_arg_def(s, i); + exprTypeRewriter.walk(a); + } } diff --git a/gcc/gimple-rewriter.hpp b/gcc/gimple-rewriter.hpp index 4cc7ac49f65..03d5bfa21ad 100644 --- a/gcc/gimple-rewriter.hpp +++ b/gcc/gimple-rewriter.hpp @@ -12,6 +12,7 @@ public: private: ExprTypeRewriter exprTypeRewriter; void handle_pointer_arithmetic(gimple *s); + virtual void _walk_pre(gphi* ) final; virtual void _walk_pre(const_tree) final; virtual void _walk_pre(gimple*) final; virtual void _walk_pre(gcall *s) final; diff --git a/gcc/gimple-walker.c b/gcc/gimple-walker.c index 3c9c07c13ad..2755dcdab98 100644 --- a/gcc/gimple-walker.c +++ b/gcc/gimple-walker.c @@ -57,12 +57,16 @@ GimpleWalker::walk() { _walk_globals(); + std::set fndecls; cgraph_node *node = NULL; FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) { print_function(node); node->get_untransformed_body(); + const bool already_in_set = fndecls.find(node->decl) != fndecls.end(); + if (already_in_set) continue; _walk_cnode(node); + fndecls.insert(node->decl); } } @@ -116,6 +120,7 @@ GimpleWalker::_walk_cnode(cgraph_node *cnode) _walk_bb(cnode); } + void GimpleWalker::_walk_decl(cgraph_node *cnode) { @@ -194,6 +199,12 @@ GimpleWalker::_walk(basic_block bb) first = false; _deleted = false; } + + for (gimple_stmt_iterator gsi = gsi_start_phis(bb); !gsi_end_p(gsi); gsi_next(&gsi)) + { + gimple *stmt = gsi_stmt(gsi); + walk(stmt); + } } void @@ -224,6 +235,7 @@ GimpleWalker::_walk(gimple *stmt) GimpleWalkerWalk(gcall*); GimpleWalkerWalk(glabel*); GimpleWalkerWalk(gswitch*); + GimpleWalkerWalk(gphi*); const enum gimple_code code = gimple_code (stmt); @@ -258,4 +270,5 @@ GimpleWalkerFuncDef(gcond *) GimpleWalkerFuncDef(gcall *) GimpleWalkerFuncDef(glabel *) GimpleWalkerFuncDef(gswitch *) +GimpleWalkerFuncDef(gphi *) diff --git a/gcc/gimple-walker.hpp b/gcc/gimple-walker.hpp index f601d236224..6c3742afb0b 100644 --- a/gcc/gimple-walker.hpp +++ b/gcc/gimple-walker.hpp @@ -30,6 +30,8 @@ #include "gimple-iterator.h" #include "gimple-ssa.h" +#include + class GimpleWalker { public: @@ -49,10 +51,10 @@ protected: void _walk(basic_block bb); #define GimpleWalkerFuncDecl(type) \ - virtual void _walk_pre(__attribute__((unused)) type stmt) {}; \ + virtual void _walk_pre(type stmt) {}; \ void walk(type stmt); \ void _walk(type stmt); \ - virtual void _walk_post(__attribute__((unused)) type stmt) {} + virtual void _walk_post(type stmt) {} GimpleWalkerFuncDecl(const_tree); GimpleWalkerFuncDecl(gimple*); @@ -62,5 +64,6 @@ protected: GimpleWalkerFuncDecl(gcall*); GimpleWalkerFuncDecl(glabel*); GimpleWalkerFuncDecl(gswitch*); + GimpleWalkerFuncDecl(gphi*); }; diff --git a/gcc/ipa-type-escape-analysis.c b/gcc/ipa-type-escape-analysis.c index 3ce6763558b..681aaa6ec11 100644 --- a/gcc/ipa-type-escape-analysis.c +++ b/gcc/ipa-type-escape-analysis.c @@ -131,7 +131,7 @@ fix_escaping_types_in_set(ptrset_t &types) const bool equal = structuralEquality.equal(type_esc, type_non); if (!equal) continue; - //log("recalulating %s == %s\n", type_esc_name.c_str(), type_non_name.c_str()); + log("recalulating %s == %s\n", type_esc_name.c_str(), type_non_name.c_str()); fixed_point_reached = false; // Add incomplete to escaping // delete incomplete from non_escaping @@ -158,10 +158,10 @@ collect_types() ptrset_t types = collector.get_pointer_set(); // what if we had 2 sets here // points_to_record and not_points_to_record - GimpleEscaper gimpleEscaper(types); - gimpleEscaper.walk(); - if (flag_print_escape_analysis) gimpleEscaper.print_reasons(); - ptrset_t escaping = gimpleEscaper.get_sets(); + //GimpleEscaper gimpleEscaper(types); + //gimpleEscaper.walk(); + //if (flag_print_escape_analysis) gimpleEscaper.print_reasons(); + //ptrset_t escaping = 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-access-counter-04-gimple-cond-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-04-gimple-cond-0.c index 29f0fcfda4d..a80bda39730 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-04-gimple-cond-0.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-04-gimple-cond-0.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-access-analysis " } */ +/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-access-analysis " } */ #include diff --git a/gcc/type-escaper.c b/gcc/type-escaper.c index ef81af37589..870c2453bba 100644 --- a/gcc/type-escaper.c +++ b/gcc/type-escaper.c @@ -115,7 +115,8 @@ TypeEscaper::_update(const_tree t) Reason _is_volatile; _is_volatile.type_is_volatile = is_volatile; Reason _inner = _reason | _is_volatile; - _inner.type_is_casted = _inside_indirect_field ? false : _inner.type_is_casted; + _inner.type_is_casted = _inside_indirect_field > 0 ? false : _inner.type_is_casted; + if (_inside_function > 0) _inner.type_is_casted = false; already_in_typemap ? calc[t] |= _inner : calc[t] = _inner; } @@ -184,8 +185,20 @@ TypeEscaper::_walk_UNION_TYPE_post(const_tree t) void TypeEscaper::_walk_FUNCTION_TYPE_pre(const_tree t) { + _inside_function++; } +void +TypeEscaper::_walk_FUNCTION_TYPE_post(const_tree t) +{ + _inside_function--; +} +void +TypeEscaper::_walk_function_or_method(const_tree t) +{ +} + + void TypeEscaper::_walk_FUNCTION_TYPE(const_tree t) { diff --git a/gcc/type-escaper.hpp b/gcc/type-escaper.hpp index ba4818ff288..3647374f716 100644 --- a/gcc/type-escaper.hpp +++ b/gcc/type-escaper.hpp @@ -8,31 +8,33 @@ class TypeEscaper : public TypeWalker { public: - TypeEscaper(ptrset_t &p) : _ptrset(p), _inside_union(0), _inside_field(0), _inside_indirect_field(0) {}; + TypeEscaper(ptrset_t &p) : _ptrset(p), _inside_union(0), _inside_field(0), _inside_indirect_field(0), _inside_function(0) {}; void update(const_tree t, Reason r); void update_single_level(const_tree t, Reason r); ptrset_t get_sets(); ptrset_t &_ptrset; typemap calc; void print_reasons(); -private: virtual void _walk_POINTER_TYPE_pre(const_tree t) final; virtual void _walk_POINTER_TYPE_post(const_tree t) final; virtual void _walk_REFERENCE_TYPE_pre(const_tree t) final; virtual void _walk_ARRAY_TYPE_pre(const_tree t) final; virtual void _walk_RECORD_TYPE_pre(const_tree t) final; virtual void _walk_UNION_TYPE_pre(const_tree t) final; - virtual void _walk_UNION_TYPE_post(const_tree t) final; - virtual void _walk_METHOD_TYPE_pre(const_tree t) final; - virtual void _walk_FUNCTION_TYPE_pre(const_tree t) final; - virtual void _walk_METHOD_TYPE(const_tree t) final; - virtual void _walk_FUNCTION_TYPE(const_tree t) final; + virtual void _walk_UNION_TYPE_post(const_tree t) override final; + virtual void _walk_METHOD_TYPE_pre(const_tree t) final override; + virtual void _walk_FUNCTION_TYPE_pre(const_tree t) final override; + virtual void _walk_FUNCTION_TYPE_post(const_tree t) final override; + virtual void _walk_METHOD_TYPE(const_tree t) final override; + virtual void _walk_FUNCTION_TYPE(const_tree t) final override; + virtual void _walk_function_or_method(const_tree t) final override; virtual void _walk_field_pre(const_tree t) final; virtual void _walk_field_post(const_tree t) final; virtual bool is_memoized(const_tree t); unsigned _inside_union; unsigned _inside_field; unsigned _inside_indirect_field; + unsigned _inside_function; Reason _reason; void _update(const_tree t); void place_escaping_types_in_set(); diff --git a/gcc/type-reconstructor.c b/gcc/type-reconstructor.c index aeb98e95ee1..769733d33b5 100644 --- a/gcc/type-reconstructor.c +++ b/gcc/type-reconstructor.c @@ -82,6 +82,7 @@ bool TypeReconstructor::is_memoized(const_tree t) { const bool already_changed = _reorg_map.find(t) != _reorg_map.end(); + //mark_all_pointing_here_as_modified(); return already_changed; } diff --git a/gcc/type-walker.hpp b/gcc/type-walker.hpp index c2172dedf80..60c979481ee 100644 --- a/gcc/type-walker.hpp +++ b/gcc/type-walker.hpp @@ -16,14 +16,14 @@ protected: void _walk(const_tree t); void _walk_wrapper(const_tree t); void _walk_record_or_union(const_tree t); - void _walk_function_or_method(const_tree t); + virtual void _walk_function_or_method(const_tree t); virtual bool is_memoized(__attribute__((unused))const_tree t) { return false; }; #define TypeWalkerFuncDecl(code) \ - virtual void _walk_ ## code ## _pre(__attribute__((unused)) const_tree t) {}; \ - void walk_ ## code (const_tree t); \ + virtual void _walk_ ## code ## _pre(const_tree t) {}; \ + virtual void walk_ ## code (const_tree t); \ virtual void _walk_ ## code (const_tree t); \ - virtual void _walk_ ## code ## _post(__attribute__((unused)) const_tree t) {} + virtual void _walk_ ## code ## _post(const_tree t) {} TypeWalkerFuncDecl(VOID_TYPE); TypeWalkerFuncDecl(INTEGER_TYPE); -- cgit v1.2.3