summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/expr-accessor.c82
-rw-r--r--gcc/expr-accessor.hpp27
-rw-r--r--gcc/gimple-accesser.c105
-rw-r--r--gcc/gimple-accesser.hpp24
-rw-r--r--gcc/gimple-caster.c61
-rw-r--r--gcc/gimple-caster.hpp5
-rw-r--r--gcc/gimple-escaper.c3
-rw-r--r--gcc/gimple-escaper.hpp2
-rw-r--r--gcc/gimple-walker.c2
-rw-r--r--gcc/ipa-prototype.h2
-rw-r--r--gcc/ipa-type-escape-analysis.c7
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-access-counter-00-simple-read-0.c7
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-access-counter-01-simple-write-0.c7
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-access-counter-02-pointer-read-0.c7
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-access-counter-03-pointer-write-0.c7
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-access-counter-04-gimple-cond-0.c6
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-16-parameter-cast-0.c20
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-ea-17-malloc-0.c17
-rw-r--r--gcc/type-incomplete-equality.c6
-rw-r--r--gcc/type-walker.c2
22 files changed, 372 insertions, 33 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 1f7a349a4c6..bf0623be999 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1412,6 +1412,8 @@ OBJS = \
type-walker.o \
expr-walker.o \
gimple-walker.o \
+ gimple-accesser.o \
+ expr-accessor.o \
type-collector.o \
expr-collector.o \
gimple-collector.o \
diff --git a/gcc/common.opt b/gcc/common.opt
index ec351e2f96f..ddc872e8c5b 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -3466,4 +3466,8 @@ fprint-cast-analysis
Common Report Var(flag_print_cast_analysis) Optimization
This flag is used to print the escape analysis including type casting.
+fprint-access-analysis
+Common Report Var(flag_print_access_analysis) Optimization
+This flag is used to print the access analysis (if field is read or written to).
+
; This comment is to ensure we retain the blank line above.
diff --git a/gcc/expr-accessor.c b/gcc/expr-accessor.c
new file mode 100644
index 00000000000..594c8d553d6
--- /dev/null
+++ b/gcc/expr-accessor.c
@@ -0,0 +1,82 @@
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple-expr.h"
+#include "predict.h"
+#include "alloc-pool.h"
+#include "tree-pass.h"
+#include "cgraph.h"
+#include "diagnostic.h"
+#include "fold-const.h"
+#include "gimple-fold.h"
+#include "symbol-summary.h"
+#include "tree-vrp.h"
+#include "ipa-prop.h"
+#include "tree-pretty-print.h"
+#include "tree-inline.h"
+#include "ipa-fnsummary.h"
+#include "ipa-utils.h"
+#include "tree-ssa-ccp.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "tree-ssa-alias.h"
+#include "tree-ssanames.h"
+#include "gimple.h"
+#include "cfg.h" // needed for gimple-iterator.h
+#include "gimple-iterator.h"
+#include "gimple-ssa.h"
+#include <stdbool.h>
+
+
+#include "types-inlines.h"
+#include "type-stringifier.hpp"
+#include "expr-accessor.hpp"
+#include "expr-walker.hpp"
+
+void
+ExprAccessor::update(const_tree e, unsigned access)
+{
+ _access = access;
+ walk(e);
+}
+
+void
+ExprAccessor::_walk_COMPONENT_REF_pre(const_tree e)
+{
+ assert_is_type(e, COMPONENT_REF);
+ const_tree op0 = TREE_OPERAND(e, 0);
+ gcc_assert(op0);
+ const_tree op0_t = TREE_TYPE(op0);
+ gcc_assert(op0_t);
+ const_tree op1 = TREE_OPERAND(e, 1);
+ assert_is_type(op1, FIELD_DECL);
+ const bool record_already_in_map = record_field_map.find(op0_t) != record_field_map.end();
+ field_access_map_t field_map;
+ field_map = record_already_in_map ? record_field_map[op0_t] : field_map;
+ const bool field_already_in_map = field_map.find(op1) != field_map.end();
+ unsigned prev_access = field_already_in_map ? field_map[op1] : Empty;
+
+ prev_access |= _access;
+ field_map[op1] = prev_access;
+ record_field_map[op0_t] = field_map;
+}
+
+void
+ExprAccessor::print_accesses()
+{
+ for (auto i = record_field_map.cbegin(), e = record_field_map.cend(); i != e; ++i)
+ {
+ const_tree record = i->first;
+ field_access_map_t field_map = i->second;
+ for (auto j = field_map.cbegin(), f = field_map.cend(); j != f; ++j)
+ {
+ const_tree field = j->first;
+ const std::string name_r = TypeStringifier::get_type_identifier(record);
+ const std::string name_f = TypeStringifier::get_field_identifier(field);
+ unsigned access = j->second;
+ log("%s.%s = 0x%04x\n", name_r.c_str(), name_f.c_str(), access);
+ }
+ }
+}
diff --git a/gcc/expr-accessor.hpp b/gcc/expr-accessor.hpp
new file mode 100644
index 00000000000..c3a0b4ecef7
--- /dev/null
+++ b/gcc/expr-accessor.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "ipa-prototype.h"
+#include "expr-walker.hpp"
+#include "type-escaper.hpp"
+#include "collect-types.h"
+#include <tuple>
+#include <map>
+
+constexpr unsigned Empty = 0x0u;
+constexpr unsigned Read = 0x01u;
+constexpr unsigned Write = 0x02u;
+
+typedef std::map<const_tree, unsigned> field_access_map_t;
+typedef std::map<const_tree, field_access_map_t> record_field_map_t;
+
+class ExprAccessor : public ExprWalker
+{
+public:
+ ExprAccessor() {};
+ void update(const_tree e, unsigned a);
+ void print_accesses();
+private:
+ unsigned _access;
+ record_field_map_t record_field_map;
+ virtual void _walk_COMPONENT_REF_pre(const_tree e);
+};
diff --git a/gcc/gimple-accesser.c b/gcc/gimple-accesser.c
new file mode 100644
index 00000000000..18d74f499c0
--- /dev/null
+++ b/gcc/gimple-accesser.c
@@ -0,0 +1,105 @@
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple-expr.h"
+#include "predict.h"
+#include "alloc-pool.h"
+#include "tree-pass.h"
+#include "cgraph.h"
+#include "diagnostic.h"
+#include "fold-const.h"
+#include "gimple-fold.h"
+#include "symbol-summary.h"
+#include "tree-vrp.h"
+#include "ipa-prop.h"
+#include "tree-pretty-print.h"
+#include "tree-inline.h"
+#include "ipa-fnsummary.h"
+#include "ipa-utils.h"
+#include "tree-ssa-ccp.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "tree-ssa-alias.h"
+#include "tree-ssanames.h"
+#include "gimple.h"
+#include "cfg.h"
+#include "gimple-iterator.h"
+#include "gimple-ssa.h"
+
+#include "types-inlines.h"
+#include "gimple-accesser.hpp"
+
+
+void
+GimpleAccesser::_walk_pre(gassign *s)
+{
+ // There seems to be quite a bit of code duplication here...
+ const enum gimple_rhs_class code = gimple_assign_rhs_class(s);
+ switch (code)
+ {
+ case GIMPLE_TERNARY_RHS:
+ {
+ const_tree rhs3 = gimple_assign_rhs3(s);
+ gcc_assert(rhs3);
+ exprAccessor.update(rhs3, Read);
+ }
+ /* fall-through */
+ case GIMPLE_BINARY_RHS:
+ {
+ const_tree rhs2 = gimple_assign_rhs2(s);
+ gcc_assert(rhs2);
+ exprAccessor.update(rhs2, Read);
+ }
+ /* fall-through */
+ case GIMPLE_UNARY_RHS:
+ case GIMPLE_SINGLE_RHS:
+ {
+ const_tree rhs1 = gimple_assign_rhs1(s);
+ exprAccessor.update(rhs1, Read);
+ const_tree lhs = gimple_assign_lhs(s);
+ if (!lhs) break;
+ exprAccessor.update(lhs, Write);
+ break;
+ }
+ default:
+ gcc_unreachable();
+ break;
+ }
+}
+
+void
+GimpleAccesser::_walk_pre(gcall *s)
+{
+ tree fndecl = gimple_call_fndecl(s);
+ unsigned n = gimple_call_num_args(s);
+ for (unsigned i = 0; i < n; i++)
+ {
+ const_tree a = gimple_call_arg(s, i);
+ gcc_assert(a);
+ exprAccessor.update(a, Read);
+ }
+
+ const_tree lhs = gimple_call_lhs(s);
+ if (!lhs) return;
+ exprAccessor.update(lhs, Write);
+}
+
+void
+GimpleAccesser::_walk_pre(greturn *s)
+{
+ const_tree val = gimple_return_retval(s);
+ if (!val) return;
+ exprAccessor.update(val, Read);
+}
+
+void
+GimpleAccesser::_walk_pre(gcond *s)
+{
+ const_tree lhs = gimple_cond_lhs(s);
+ const_tree rhs = gimple_cond_rhs(s);
+ gcc_assert(lhs && rhs);
+ exprAccessor.update(lhs, Read);
+ exprAccessor.update(rhs, Read);
+}
diff --git a/gcc/gimple-accesser.hpp b/gcc/gimple-accesser.hpp
new file mode 100644
index 00000000000..69bed4839a2
--- /dev/null
+++ b/gcc/gimple-accesser.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "gimple-walker.hpp"
+#include "expr-accessor.hpp"
+
+/*
+ * GimpleAccesser is intended to walk gimple
+ * and update a map that will hold information
+ * on whether a type was casted or not.
+ */
+class GimpleAccesser : public GimpleWalker
+{
+public:
+ GimpleAccesser() : GimpleWalker() {};
+ void print_accesses() { exprAccessor.print_accesses(); };
+private:
+ ExprAccessor exprAccessor;
+ virtual void _walk_pre(gcall *s) final;
+ virtual void _walk_pre(gassign *s) final;
+ virtual void _walk_pre(greturn *s) final;
+ virtual void _walk_pre(gcond *s) final;
+ // Do we need a glabel? I don't think so...
+ // But we might need a gswitch.
+};
diff --git a/gcc/gimple-caster.c b/gcc/gimple-caster.c
index 747d60920aa..299bbf6abfb 100644
--- a/gcc/gimple-caster.c
+++ b/gcc/gimple-caster.c
@@ -22,9 +22,68 @@ GimpleCaster::_walk_pre(gassign *s)
const_tree t_lhs = TREE_TYPE(lhs);
const_tree t_rhs = TREE_TYPE(rhs);
gcc_assert(t_lhs && t_rhs);
- const bool is_cast = equality.equal(t_lhs, t_rhs);
+ const bool is_cast = !equality.equal(t_lhs, t_rhs);
reason.is_escaping = is_cast;
reason.type_is_casted = is_cast;
exprEscaper.update(lhs, reason);
exprEscaper.update(rhs, reason);
+ // TODO:
+ // I think this will re-do the work... But it might be necessary?
+ GimpleEscaper::_walk_pre(s);
+}
+
+void
+GimpleCaster::_walk_pre(gcall *s)
+{
+ GimpleEscaper::_walk_pre(s);
+
+ const_tree fn = gimple_call_fndecl(s);
+ cgraph_node *node = cgraph_node::get(fn);
+ const bool known_function = GimpleEscaper::filter_known_function(node);
+ if (known_function) return;
+
+ const_tree f_t = TREE_TYPE(fn);
+ TypeIncompleteEquality equality;
+ TypeStringifier stringifier;
+
+ unsigned i = 0;
+ unsigned n = gimple_call_num_args(s);
+ for (tree a = TYPE_ARG_TYPES(f_t); NULL_TREE != a; a = TREE_CHAIN(a))
+ {
+ // There seems to be a final VOID_TYPE at the end of the chain
+ if (i == n) break;
+ const_tree formal_t = TREE_VALUE(a);
+ const_tree real = gimple_call_arg(s, i);
+ const_tree real_t = TREE_TYPE(real);
+ const bool is_casted = !equality.equal(formal_t, real_t);
+ const std::string name_r = stringifier.stringify(real_t);
+ const std::string name_f = stringifier.stringify(formal_t);
+ log("looking at casted argument %s == %s ? %s\n", name_r.c_str(), name_f.c_str(), is_casted ? "t" : "f");
+ Reason arg_reason;
+ arg_reason.is_escaping = is_casted;
+ arg_reason.type_is_casted = is_casted;
+ exprEscaper.update(real, arg_reason);
+ i++;
+ }
+
+ /*
+ unsigned n = gimple_call_num_args(s);
+ for (unsigned i = 0; i < n; i++)
+ {
+ const_tree a = gimple_call_arg(s, i);
+ gcc_assert(a);
+ exprEscaper.update(a, reason);
+ }
+ */
+
+ const_tree lhs = gimple_call_lhs(s);
+ if (!lhs) return;
+
+ const_tree r_t = TREE_TYPE(f_t);
+ const_tree l_t TREE_TYPE(lhs);
+ const bool is_casted = !equality.equal(r_t, l_t);
+ Reason ret_reason;
+ ret_reason.is_escaping = is_casted;
+ ret_reason.type_is_casted = is_casted;
+ exprEscaper.update(lhs, ret_reason);
}
diff --git a/gcc/gimple-caster.hpp b/gcc/gimple-caster.hpp
index 2495d537649..74086606862 100644
--- a/gcc/gimple-caster.hpp
+++ b/gcc/gimple-caster.hpp
@@ -12,9 +12,8 @@ class GimpleCaster : public GimpleEscaper
public:
GimpleCaster(ptrset_t &types) : GimpleEscaper(types) {};
private:
- // We don't need this from parent...
- virtual void _walk_pre(gcall *s) final {};
+ virtual void _walk_pre(gcall *s) final;
// Find out which structs are casted.
// Technically we could find this out on parent
- virtual void _walk_pre(gassign *s);
+ virtual void _walk_pre(gassign *s) final;
};
diff --git a/gcc/gimple-escaper.c b/gcc/gimple-escaper.c
index ed879123cc1..3f80d6cd868 100644
--- a/gcc/gimple-escaper.c
+++ b/gcc/gimple-escaper.c
@@ -175,7 +175,7 @@ GimpleEscaper::_walk_pre(gcond *s)
void
GimpleEscaper::_walk_pre(gcall *s)
{
- tree fn = gimple_call_fndecl(s);
+ const_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();
@@ -186,7 +186,6 @@ GimpleEscaper::_walk_pre(gcall *s)
// TODO: Consider this...
//exprEscaper.update(fn, function_type_reason);
-
Reason arg_reason;
arg_reason.is_escaping = _is_escaping;
arg_reason.parameter_is_visible = _is_escaping;
diff --git a/gcc/gimple-escaper.hpp b/gcc/gimple-escaper.hpp
index b6f77111007..d589a3eec01 100644
--- a/gcc/gimple-escaper.hpp
+++ b/gcc/gimple-escaper.hpp
@@ -11,7 +11,7 @@ public:
ExprEscaper exprEscaper;
ptrset_t get_sets() { return exprEscaper.get_sets(); };
void print_reasons() { exprEscaper.print_reasons(); };
-private:
+protected:
typedef std::set<const_tree> undefset;
undefset undefined;
void _init();
diff --git a/gcc/gimple-walker.c b/gcc/gimple-walker.c
index 9259c0d9438..e61b49f0a98 100644
--- a/gcc/gimple-walker.c
+++ b/gcc/gimple-walker.c
@@ -60,7 +60,7 @@ GimpleWalker::walk()
cgraph_node *node = NULL;
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node)
{
- // print_function(node);
+ print_function(node);
node->get_untransformed_body();
_walk_cnode(node);
}
diff --git a/gcc/ipa-prototype.h b/gcc/ipa-prototype.h
index 77413d5c218..a75efaa2e48 100644
--- a/gcc/ipa-prototype.h
+++ b/gcc/ipa-prototype.h
@@ -13,7 +13,7 @@ struct Reason {
Reason operator|(const Reason &);
Reason& operator|=(const Reason &);
void print() const;
- Reason() : is_escaping(0), global_is_visible(0), parameter_is_visible(0), type_is_casted(0), type_is_volatile(0), type_is_in_union(0) {};
+ Reason() : is_escaping(0), global_is_visible(0), parameter_is_visible(0), return_is_visible(0), type_is_casted(0), type_is_volatile(0), type_is_in_union(0) {};
};
diff --git a/gcc/ipa-type-escape-analysis.c b/gcc/ipa-type-escape-analysis.c
index 0f548bf4943..a88602054db 100644
--- a/gcc/ipa-type-escape-analysis.c
+++ b/gcc/ipa-type-escape-analysis.c
@@ -25,6 +25,7 @@
#include "gimple-collector.hpp"
#include "gimple-escaper.hpp"
#include "gimple-caster.hpp"
+#include "gimple-accesser.hpp"
static unsigned int iphw_execute();
@@ -104,8 +105,12 @@ collect_types()
GimpleEscaper gimpleEscaper(types);
gimpleEscaper.walk();
if (flag_print_escape_analysis) gimpleEscaper.print_reasons();
- types = gimpleEscaper.get_sets();
+ ptrset_t escaping = gimpleEscaper.get_sets();
GimpleCaster caster(types);
caster.walk();
if (flag_print_cast_analysis) caster.print_reasons();
+ ptrset_t casting = caster.get_sets();
+ GimpleAccesser accesser;
+ accesser.walk();
+ if (flag_print_access_analysis) accesser.print_accesses();
}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-00-simple-read-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-00-simple-read-0.c
index 88f96ea3be4..390f73a6cc3 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-00-simple-read-0.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-00-simple-read-0.c
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "-flto -fipa-hello-world -fdump-ipa-hello-world" } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-access-analysis " } */
#include <stdio.h>
@@ -14,6 +14,5 @@ main ()
printf("%d\n", astruct.a);
}
-/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "hello-world" } } */
-/* { dg-final { scan-wpa-ipa-dump "astruct_s.a read 1" "hello-world" } } */
-/* { dg-final { scan-wpa-ipa-dump "astruct_s.a read 2" "hello-world" } } */
+// This means a read.
+/* { dg-final { scan-wpa-ipa-dump "astruct_s.a = 0x0001" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-01-simple-write-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-01-simple-write-0.c
index 6e7b3236294..d809ed31df8 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-01-simple-write-0.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-01-simple-write-0.c
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "-flto -fipa-hello-world -fdump-ipa-hello-world" } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-access-analysis " } */
#include <stdio.h>
@@ -14,6 +14,5 @@ main ()
astruct.a = 3;
}
-/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "hello-world" } } */
-/* { dg-final { scan-wpa-ipa-dump "astruct_s.a write 1" "hello-world" } } */
-/* { dg-final { scan-wpa-ipa-dump "astruct_s.a write 2" "hello-world" } } */
+// This means that this is only a write and not a read.
+/* { dg-final { scan-wpa-ipa-dump "astruct_s.a = 0x0003" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-02-pointer-read-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-02-pointer-read-0.c
index 1b6755565ff..59f7707e5af 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-02-pointer-read-0.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-02-pointer-read-0.c
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "-flto -fipa-hello-world -fdump-ipa-hello-world" } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-access-analysis " } */
#include <stdio.h>
@@ -14,6 +14,5 @@ main ()
printf("%d\n", astruct->a);
}
-/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "hello-world" } } */
-/* { dg-final { scan-wpa-ipa-dump "astruct_s.a read 1" "hello-world" } } */
-/* { dg-final { scan-wpa-ipa-dump "astruct_s.a read 2" "hello-world" } } */
+// So, even if we have a pointer COMPONENT_REF counter still works...
+/* { dg-final { scan-wpa-ipa-dump "astruct_s.a = 0x0001" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-03-pointer-write-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-03-pointer-write-0.c
index 68e2f40a12a..17ad02529ee 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-03-pointer-write-0.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-access-counter-03-pointer-write-0.c
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "-flto -fipa-hello-world -fdump-ipa-hello-world" } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-access-analysis " } */
#include <stdio.h>
@@ -14,6 +14,5 @@ main ()
astruct->a = 3;
}
-/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "hello-world" } } */
-/* { dg-final { scan-wpa-ipa-dump "astruct_s.a write 1" "hello-world" } } */
-/* { dg-final { scan-wpa-ipa-dump "astruct_s.a write 2" "hello-world" } } */
+// This says that only writes are happening even if astruct is a pointer
+/* { dg-final { scan-wpa-ipa-dump "astruct_s.a = 0x0003" "type-escape-analysis" } } */
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 0dd152a2783..29f0fcfda4d 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 "-flto -fipa-hello-world -fdump-ipa-hello-world" } */
+/* { dg-options "-fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-access-analysis " } */
#include <stdio.h>
@@ -15,5 +15,5 @@ main ()
}
}
-/* { dg-final { scan-wpa-ipa-dump "collected,astruct_s" "hello-world" } } */
-/* { dg-final { scan-wpa-ipa-dump "astruct_s.a read 1" "hello-world" } } */
+// This says that astruct_s.a is read in a conditional
+/* { dg-final { scan-wpa-ipa-dump "astruct_s.a = 0x0001" "type-escape-analysis" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-ea-16-parameter-cast-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-16-parameter-cast-0.c
new file mode 100644
index 00000000000..623a8c0af00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-16-parameter-cast-0.c
@@ -0,0 +1,20 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-cast-analysis -Wno-incompatible-pointer-types" } */
+
+#include <stddef.h>
+#include <stdio.h>
+
+struct astruct_s { _Bool a; _Bool b; _Bool c; };
+struct bstruct_s { _Bool a; _Bool b; _Bool c; };
+void foo(struct bstruct_s *s) { };
+
+int main(int argc, char** argv)
+{
+ struct astruct_s astruct;
+ foo(&astruct);
+}
+
+// This says that astruct_s is casted
+/* { 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" } } */
+// This says that the pointer is casted
+/* { 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-17-malloc-0.c b/gcc/testsuite/gcc.dg/ipa/ipa-ea-17-malloc-0.c
new file mode 100644
index 00000000000..94e96701f96
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-ea-17-malloc-0.c
@@ -0,0 +1,17 @@
+/* { dg-do link } */
+/* { dg-options "-flto -fipa-type-escape-analysis -fdump-ipa-type-escape-analysis -fprint-cast-analysis -Wno-incompatible-pointer-types" } */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct astruct_s { _Bool a; _Bool b; _Bool c; };
+
+int main(int argc, char** argv)
+{
+ struct astruct_s *a = malloc(sizeof(struct astruct_s));
+}
+
+// This says that astruct_s is not casted
+/* { 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=0 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=0 v=0 u=0" "type-escape-analysis" } } */
diff --git a/gcc/type-incomplete-equality.c b/gcc/type-incomplete-equality.c
index 9ce7eed1413..bf9047a98c7 100644
--- a/gcc/type-incomplete-equality.c
+++ b/gcc/type-incomplete-equality.c
@@ -44,9 +44,9 @@ TypeIncompleteEquality::_equal(const_tree l, const_tree r)
if (!valid_inputs) return l == 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_structurally = incomplete_l && incomplete_r;
+ const bool complete_l = is_complete(l);
+ const bool complete_r = is_complete(r);
+ const bool can_compare_structurally = complete_l && complete_r;
if (can_compare_structurally) return TypeStructuralEquality::_equal(l, r);
const std::string n_l = TypeStringifier::get_type_identifier(l);
diff --git a/gcc/type-walker.c b/gcc/type-walker.c
index 54d547d3fd6..b79daef043d 100644
--- a/gcc/type-walker.c
+++ b/gcc/type-walker.c
@@ -260,7 +260,7 @@ TypeWalker::_walk_args(const_tree t)
{
for (tree arg_node = TYPE_ARG_TYPES(t); NULL_TREE != arg_node; arg_node = TREE_CHAIN(arg_node))
{
- tree arg_node_type = TREE_VALUE(arg_node);
+ const_tree arg_node_type = TREE_VALUE(arg_node);
gcc_assert(arg_node_type);
walk_arg(arg_node_type);
}