summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-03 15:11:58 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-03 16:06:04 +0200
commitbc94282d91826b88863619ef9f0fda932ac73926 (patch)
treed3304f3ea1ad8acd6707f791ed471a3d2f865e79
parent5e26465d33febeac3d019b9213787676a9a31ee2 (diff)
Expr-escaper
-rw-r--r--gcc/expr-escaper.hpp31
-rw-r--r--gcc/ipa-hello-world.c107
-rw-r--r--gcc/type-escaper.hpp6
-rw-r--r--gcc/type-walker.c3
4 files changed, 66 insertions, 81 deletions
diff --git a/gcc/expr-escaper.hpp b/gcc/expr-escaper.hpp
new file mode 100644
index 00000000000..3f4688669b6
--- /dev/null
+++ b/gcc/expr-escaper.hpp
@@ -0,0 +1,31 @@
+#include "ipa-hello-world.h"
+#include "expr-walker.hpp"
+
+class ExprEscaper : public ExprWalker
+{
+public:
+ ExprEscaper() {};
+ void update(const_tree t, Reason r);
+ static TypeEscaper *typeEscaper;
+private:
+ Reason _r;
+ virtual void _walk_pre(const_tree e);
+};
+
+void
+ExprEscaper::update(const_tree t, Reason r)
+{
+ gcc_assert(t);
+ _r = r;
+ walk(t);
+}
+
+void
+ExprEscaper::_walk_pre(const_tree e)
+{
+ const_tree t = TREE_TYPE(e);
+ gcc_assert(t);
+ typeEscaper->update(t, _r);
+}
+
+
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c
index de409a16229..c926473ba8c 100644
--- a/gcc/ipa-hello-world.c
+++ b/gcc/ipa-hello-world.c
@@ -40,6 +40,7 @@
#include <map>
#include <vector>
#include "type-escaper.hpp"
+#include "expr-escaper.hpp"
//#define OPTIMIZED
#define SANITY_CHECKS
@@ -330,67 +331,6 @@ update_escape_info_function_decl(ptrset_t &types, typemap &calc, const_tree expr
update_escape_info(decl_type, types, reason, calc);
}
-static void
-update_escape_info_expr(ptrset_t &types, typemap &calc, const_tree expr, Reason reason)
-{
- gcc_assert(expr);
- const_tree type = TREE_TYPE(expr);
- gcc_assert(type);
- if (!types.in_points_to_record(type)) return;
- update_escape_info(type, types, reason, calc);
-
- const enum tree_code code = TREE_CODE(expr);
- switch (code)
- {
- case SSA_NAME:
- update_escape_info_ssa_name(types, calc, expr, reason);
- break;
- case INTEGER_CST:
- update_escape_info_integer_cst(types, calc, expr, reason);
- break;
- case COMPONENT_REF:
- update_escape_info_component_ref(types, calc, expr, reason);
- break;
- case MEM_REF:
- update_escape_info_mem_ref(types, calc, expr, reason);
- break;
- case FIELD_DECL:
- update_escape_info_field_decl(types, calc, expr, reason);
- break;
- case VAR_DECL:
- update_escape_info_var_decl(types, calc, expr, reason);
- break;
- case ARRAY_REF:
- update_escape_info_array_ref(types, calc, expr, reason);
- break;
- case ADDR_EXPR:
- update_escape_info_addr_expr(types, calc, expr, reason);
- break;
- case CONSTRUCTOR:
- update_escape_info_constructor(types, calc, expr, reason);
- break;
- case REAL_CST:
- update_escape_info_real_cst(types, calc, expr, reason);
- break;
- case STRING_CST:
- update_escape_info_string_cst(types, calc, expr, reason);
- break;
- case PARM_DECL:
- update_escape_info_parm_decl(types, calc, expr, reason);
- break;
- case FUNCTION_DECL:
- update_escape_info_function_decl(types, calc, expr, reason);
- break;
- case BIT_FIELD_REF:
- case RESULT_DECL:
- default:
- {
- log("tree_code: %s\n", get_tree_code_name(code));
- gcc_unreachable();
- }
- break;
- }
-}
static void
calculate_escaping_types_from_cast(ptrset_t &types, typemap &calc, gimple *stmt)
@@ -767,9 +707,9 @@ sanity_check_escape_xor_not(ptrset_t &types)
gcc_assert(type_esc);
const_tree type_non = *j;
gcc_assert(type_non);
- const bool valid_sets = !eq_type_compare(type_esc, type_non);
- if (valid_sets) continue;
- log("comparing %s == %s\n", type_to_string(type_esc).c_str(), type_to_string(type_non).c_str());
+ //const bool valid_sets = !eq_type_compare(type_esc, type_non);
+ //if (valid_sets) continue;
+ //log("comparing %s == %s\n", type_to_string(type_esc).c_str(), type_to_string(type_non).c_str());
//TODO: Remove this comment once we have restricted the "repairing" of sets a bit more.
//gcc_assert(valid_sets);
}
@@ -798,10 +738,10 @@ sanity_check_escape_union_not_equals_ptrset(ptrset_t &types)
const_tree type = *i;
const bool in_union = _union.find(type) != _union.end();
if (in_union) continue;
- log("this type was not found in union %s\n", type_to_string(type).c_str());
+ //log("this type was not found in union %s\n", type_to_string(type).c_str());
//TODO: FIXME: This has to be enabled for the sanity check to work
//But at the moment there's one type which isn't working correctly :(
- //gcc_unreachable();
+ gcc_unreachable();
}
}
@@ -823,17 +763,18 @@ fix_escaping_types_in_set(ptrset_t &types)
gcc_assert(type_non);
// There can be cases where incomplete types are marked as non-escaping
// and complete types counter parts are marked as escaping.
- const bool interesting_case = eq_type_compare(type_esc, type_non);
+ //const bool interesting_case = eq_type_compare(type_esc, type_non);
+ //TODO: We are going to need a different type comparison because this one
+ //fails to take into account the recursion...
+ const bool interesting_case = type_esc == type_non;
if (!interesting_case) continue;
- // TODO: I would really like to constrain this more
- // By making sure that they are equal explicitly because of incompletenes...
- // * type_non must be incomplete
- // * type_non must be pointing to an incomplete type and match the structure of type_esc (those which can be compared)
- log("**NOT** checking for incompleteness %s == %s\n", type_to_string(type_esc).c_str(), type_to_string(type_non).c_str());
+ TypeStringifier stringifier;
+ std::string type_esc_name = stringifier.stringify(type_esc);
+ std::string type_non_name = stringifier.stringify(type_non);
+ log("**NOT** checking for incompleteness %s == %s\n", type_esc_name.c_str(), type_non_name.c_str());
fixed_point_reached = false;
- log("fixing %s == %s\n", type_to_string(type_esc).c_str(), type_to_string(type_non).c_str());
// Add incomplete to escaping
// delete incomplete from non_escaping
// We shouldn't do that inside our iteration loop.
@@ -862,8 +803,9 @@ print_escaping_types_in_set(ptrset_t &types)
const bool is_function = FUNCTION_TYPE == code;
// I just don't want to print out functions.
if (is_function) continue;
-
- log("non_escaping: %s \n", type_to_string(type_non).c_str());
+ TypeStringifier stringifier;
+ std::string name = stringifier.stringify(type_non);
+ log("non_escaping: %s \n", name.c_str());
}
}
@@ -871,12 +813,20 @@ print_escaping_types_in_set(ptrset_t &types)
ptrset_t *TypeEscaper::types = NULL;
typemap TypeEscaper::calc;
-static TypeEscaper typeEscaper;
+static TypeEscaper _typeEscaper;
+static ExprEscaper exprEscaper;
+TypeEscaper *ExprEscaper::typeEscaper = NULL;
static void
update_escape_info( const_tree type, ptrset_t &types, Reason reason, typemap &calc)
{
- typeEscaper.update(type, reason);
+ _typeEscaper.update(type, reason);
+}
+
+static void
+update_escape_info_expr(ptrset_t &types, typemap &calc, const_tree expr, Reason reason)
+{
+ exprEscaper.update(expr, reason);
}
@@ -886,13 +836,14 @@ iphw_execute()
ptrset_t types;
TypeCollector::ptrset = &types;
TypeEscaper::types = &types;
+ ExprEscaper::typeEscaper = &_typeEscaper;
collect_types(types);
typemap eacalc; // Escape Analysis Calculation
// Intermediate results
// Do not read escape analysis results from here
calculate_escaping_types(types, eacalc);
- place_escaping_types_in_set(types, typeEscaper.calc);
+ place_escaping_types_in_set(types, _typeEscaper.calc);
fix_escaping_types_in_set(types);
print_escaping_types_in_set(types);
sanity_check_escape_xor_not(types);
diff --git a/gcc/type-escaper.hpp b/gcc/type-escaper.hpp
index 76a04d2642a..86c9ad6f8b4 100644
--- a/gcc/type-escaper.hpp
+++ b/gcc/type-escaper.hpp
@@ -7,6 +7,9 @@ class TypeEscaper : public TypeWalker
public:
TypeEscaper() : _inside_union(0) {};
void update(const_tree t, Reason r);
+ static ptrset_t *types;
+ static typemap calc;
+private:
virtual void _walk_pointer_pre(const_tree t);
virtual void _walk_reference_pre(const_tree t);
virtual void _walk_array_pre(const_tree t);
@@ -16,9 +19,6 @@ public:
virtual void _walk_method_pre(const_tree t);
virtual void _walk_function_pre(const_tree t);
virtual bool is_memoized(const_tree t);
- static ptrset_t *types;
- static typemap calc;
-private:
unsigned _inside_union;
Reason _reason;
void _update(const_tree t);
diff --git a/gcc/type-walker.c b/gcc/type-walker.c
index 5b5d3520f19..b74db433ee9 100644
--- a/gcc/type-walker.c
+++ b/gcc/type-walker.c
@@ -104,7 +104,10 @@ TypeWalker::_walk(const_tree type, tset_t &tset)
case QUAL_UNION_TYPE:
case LANG_TYPE:
default:
+ {
+ log("missing %s\n", get_tree_code_name(code));
gcc_unreachable();
+ }
break;
}