summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-08 15:23:31 +0200
committerErick Ochoa <erick.ochoa@theobroma-systems.com>2020-06-08 15:23:31 +0200
commite17befe197116a35e07f8e466a199569491ac861 (patch)
treeae0e9cf31bd383c8596fc9ace4f9b72b022ecef9
parent140efef10e83422f31b8773dd0ffbf72d2fb0741 (diff)
Deletes and comments previous API
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/common.opt8
-rw-r--r--gcc/ipa-hello-world.c569
-rw-r--r--gcc/ipa-hello-world.h18
-rw-r--r--gcc/ipa-str-reorg-dead-field-eliminate.c19
-rw-r--r--gcc/ipa-type-escape-analysis.c962
-rw-r--r--gcc/ipa-type-escape-analysis.h21
-rw-r--r--gcc/passes.def2
-rw-r--r--gcc/tree-pass.h2
9 files changed, 8 insertions, 1595 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 74afacd6128..75f1086c74b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1407,8 +1407,6 @@ OBJS = \
incpath.o \
init-regs.o \
internal-fn.o \
- ipa-type-escape-analysis.o \
- ipa-hello-world.o \
ipa-prototype.o \
type-walker.o \
expr-walker.o \
diff --git a/gcc/common.opt b/gcc/common.opt
index 7313513d08a..19b0b255bdc 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -3444,14 +3444,6 @@ fipa-typelist-field=
Common Joined Report Var(flag_ipa_typelist_field) Init(0)
-fipa-typelist-field=<string> Name of struct of interest
-fipa-type-escape-analysis
-Common Report Var(flag_ipa_type_escape_analysis) Optimization
-Type escape analysis
-
-fipa-hello-world
-Common Report Var(flag_ipa_hello_world) Optimization
-Hello world
-
ftp-types-compared=
Common Joined Report Var(flag_tp_types_compared) Init(0)
diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c
deleted file mode 100644
index 20c122f3a16..00000000000
--- a/gcc/ipa-hello-world.c
+++ /dev/null
@@ -1,569 +0,0 @@
-#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-cfg.h"
-#include "gimple.h"
-#include "cfg.h" // needed for gimple-iterator.h
-#include "gimple-iterator.h"
-
-#include <map>
-#include <set>
-
-#include "ipa-type-escape-analysis.h"
-#include "ipa-str-reorg-utils.h"
-#include "ipa-hello-world.h"
-
-
-//TODO: place in header file
-inline static void
-print_function (cgraph_node *cnode)
-{
- if (!dump_file)
- return;
- gcc_assert (cnode);
- cnode->get_untransformed_body ();
- dump_function_to_file (cnode->decl, dump_file, TDF_NONE);
-}
-
-//TODO: do not use pair.
-//This names are unintelligible
-typedef std::pair<unsigned /* reads */, unsigned /* writes */> accesses;
-struct field_comparator
-{
- bool operator()(const fields &left, const fields &right) const
- {
- const_tree left_record = left.first;
- gcc_assert(left_record);
- const_tree right_record = right.first;
- gcc_assert(right_record);
- // Make sure that we are only comparing valid types...
- const enum tree_code tree_code_left_record = TREE_CODE(left_record);
- const enum tree_code tree_code_right_record = TREE_CODE(right_record);
- const bool is_left_record_type = RECORD_TYPE == tree_code_left_record;
- const bool is_right_record_type = RECORD_TYPE == tree_code_right_record;
- gcc_assert(is_left_record_type);
- gcc_assert(is_right_record_type);
- const bool are_left_and_right_valid = is_left_record_type && is_right_record_type;
- gcc_assert(are_left_and_right_valid);
-
- // Handle typedefs:
- // Get the main variants of the main types
- const_tree main_variant_left = TYPE_MAIN_VARIANT(left_record);
- gcc_assert(main_variant_left);
- const_tree main_variant_right = TYPE_MAIN_VARIANT(right_record);
- gcc_assert(main_variant_right);
- // If they are not equal, we can do a comparison of the types here...
- const bool are_main_variants_equal = main_variant_left == main_variant_right;
- const bool left_type_less_than_right_type = main_variant_left < main_variant_right;
- if (!are_main_variants_equal) return left_type_less_than_right_type;
-
- // If they are equal, that means that we are comparing fields defined in the same record
- const_tree left_field = left.second;
- gcc_assert(left_field);
- const_tree right_field = right.second;
- gcc_assert(right_field);
- // Make sure that they are valid
- const enum tree_code tree_code_left_field = TREE_CODE(left_field);
- const enum tree_code tree_code_right_field = TREE_CODE(right_field);
- const bool is_left_field_field_decl = FIELD_DECL == tree_code_left_field;
- const bool is_right_field_field_decl = FIELD_DECL == tree_code_right_field;
- const bool are_left_and_right_field_decls = is_left_field_field_decl && is_right_field_field_decl;
- gcc_assert(are_left_and_right_field_decls);
-
- // Compare on the field offset.
- const_tree left_constant = byte_position(left_field);
- gcc_assert(left_constant);
- const_tree right_constant = byte_position(right_field);
- gcc_assert(right_constant);
- unsigned left_offset = tree_to_uhwi(left_constant);
- unsigned right_offset = tree_to_uhwi(right_constant);
- const bool left_offset_less_than_right_offset = left_offset < right_offset;
- return left_offset_less_than_right_offset;
- }
-};
-
-typedef std::map<fields, accesses, field_comparator> field_access_counter;
-typedef std::set<const_tree> record_set;
-
-enum access_code { READ_ACCESS, WRITE_ACCESS };
-
-void count_access_for_types_in_expr(const_tree expr, const record_set &non_escaping_records, field_access_counter &counter, const enum access_code access);
-
-void
-count_access_for_type_in_component_ref(const_tree component_ref, const record_set &non_escaping_records, field_access_counter &counter, const enum access_code access)
-{
- log("types in component_ref\n");
- gcc_assert(component_ref);
- enum tree_code tree_code_component_ref = TREE_CODE(component_ref);
- const bool is_component_ref = COMPONENT_REF == tree_code_component_ref;
- gcc_assert(is_component_ref);
-
- const_tree _struct = TREE_OPERAND(component_ref, 0);
- gcc_assert(_struct);
-
- log ("going in recursion\n");
- count_access_for_types_in_expr(_struct, non_escaping_records, counter, READ_ACCESS);
- const_tree tree_type_struct = TREE_TYPE(_struct);
- gcc_assert(tree_type_struct);
- enum tree_code tree_type_struct_code = TREE_CODE(tree_type_struct);
- const bool is_record_type = RECORD_TYPE == tree_type_struct_code;
- //TODO: Also write something for UNION_TYPE
- switch (tree_type_struct_code)
- {
- case UNION_TYPE: return; break;
- case RECORD_TYPE: break;
- default: gcc_unreachable(); break;
- }
- gcc_assert(is_record_type);
-
- //FIXME: Future proofing or making things more difficult to read?
- bool in_set =
-#if __cplusplus > 201703L
- non_escaping_records.contains(tree_type_struct)
-#else
- non_escaping_records.find(tree_type_struct) != non_escaping_records.end()
-#endif
- ;
-
- in_set |=
-#if __cplusplus > 201703L
- non_escaping_records.contains(TYPE_MAIN_VARIANT(tree_type_struct))
-#else
- non_escaping_records.find(TYPE_MAIN_VARIANT(tree_type_struct)) != non_escaping_records.end()
-#endif
- ;
-
-
- log("%s is in non_escaping_records ? %s\n", get_type_name(tree_type_struct), in_set ? "true" : "false");
- log("access is %s\n", access == READ_ACCESS ? "read_access" : "write_access");
- log("%s is escaping %s\n", get_type_name(tree_type_struct), in_set ? "true" : "false");
- if (!in_set) return;
-
- const_tree field = TREE_OPERAND(component_ref, 1);
- gcc_assert(field);
- enum tree_code tree_code_field = TREE_CODE(field);
- const bool is_field_decl = FIELD_DECL == tree_code_field;
- gcc_assert(is_field_decl);
-
- const std::pair<const_tree, const_tree> struct_field_pair = std::make_pair(tree_type_struct, field);
- accesses &access_counter = counter[struct_field_pair];
-
- switch (access)
- {
- case READ_ACCESS:
- //TODO: do not use pair.
- //This names are unintelligible
- access_counter.first++;
- log("%s.%s read %d\n", get_type_name(tree_type_struct), get_field_name(field), access_counter.first);
- break;
- case WRITE_ACCESS:
- //TODO: do not use pair.
- //This names are unintelligible
- access_counter.second++;
- log("%s.%s write %d\n", get_type_name(tree_type_struct), get_field_name(field), access_counter.second);
- break;
- default:
- gcc_unreachable();
- break;
- }
-}
-
-static inline void
-is_addr_expr_p(const_tree expr)
-{
- gcc_assert(expr);
- const enum tree_code code = TREE_CODE(expr);
- const bool is_addr_expr = ADDR_EXPR == code;
- gcc_assert(is_addr_expr);
-}
-
-
-void
-count_access_for_type_in_addr_expr(const_tree expr, const record_set &non_escaping_records, field_access_counter &counter, const enum access_code access)
-{
- is_addr_expr_p(expr);
- const_tree op0 = TREE_OPERAND(expr, 0);
- count_access_for_types_in_expr(op0, non_escaping_records, counter, access);
-}
-
-static inline void
-is_array_expr_p(const_tree expr)
-{
- gcc_assert(expr);
- const enum tree_code code = TREE_CODE(expr);
- const bool is_addr_expr = ARRAY_REF == code;
- gcc_assert(is_addr_expr);
-}
-
-void
-count_access_for_type_in_array_expr(const_tree expr, const record_set &non_escaping_records, field_access_counter &counter, const enum access_code access)
-{
- is_array_expr_p(expr);
- const_tree op0 = TREE_OPERAND(expr, 0);
- const_tree op1 = TREE_OPERAND(expr, 1);
- count_access_for_types_in_expr(op0, non_escaping_records, counter, READ_ACCESS);
- count_access_for_types_in_expr(op1, non_escaping_records, counter, READ_ACCESS);
-}
-
-void
-count_access_for_types_in_expr(const_tree expr, const record_set &non_escaping_records, field_access_counter &counter, const enum access_code access)
-{
- log("types in expr\n");
- gcc_assert(expr);
- enum tree_code tree_code_expr = TREE_CODE(expr);
- switch (tree_code_expr)
- {
- case COMPONENT_REF: count_access_for_type_in_component_ref(expr, non_escaping_records, counter, access); break;
- case ADDR_EXPR: count_access_for_type_in_addr_expr(expr, non_escaping_records, counter, access); break;
- case ARRAY_REF : count_access_for_type_in_array_expr(expr, non_escaping_records, counter, access); break;
- default: break;
- }
-}
-
-void
-count_access_for_types_in_lhs(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter)
-{
- gcc_assert(stmt);
- const enum gimple_code gimple_code_stmt = gimple_code(stmt);
- const bool is_assign = GIMPLE_ASSIGN == gimple_code_stmt;
- const bool is_call = GIMPLE_CALL == gimple_code_stmt;
- const bool is_valid = is_assign || is_call;
- gcc_assert(is_valid);
-
-
- const_tree lhs = is_assign ? gimple_assign_lhs (stmt) : gimple_call_lhs (stmt);
- /* GIMPLE_CALL might have a lhs null.
- * E.g.
- * foo()
- */
- if (!lhs) return;
-
- count_access_for_types_in_expr(lhs, non_escaping_records, counter, WRITE_ACCESS);
-}
-
-void
-count_access_for_types_in_rhs(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter)
-{
- gcc_assert(stmt);
- const enum gimple_code gimple_code_stmt = gimple_code(stmt);
- const bool is_assign = GIMPLE_ASSIGN == gimple_code_stmt;
- gcc_assert(is_assign);
-
- log("types in rhs\n");
- const enum gimple_rhs_class gimple_rhs_class_stmt = gimple_assign_rhs_class(stmt);
- switch (gimple_rhs_class_stmt)
- {
- case GIMPLE_TERNARY_RHS:
- {
- log("gimple_ternary_rhs\n");
- }
- /* fall through */
- case GIMPLE_BINARY_RHS:
- {
- log("gimple_binary_rhs\n");
- }
- /* fall through */
- case GIMPLE_SINGLE_RHS:
- case GIMPLE_UNARY_RHS:
- {
- const_tree rhs1 = gimple_assign_rhs1(stmt);
- gcc_assert(rhs1);
- count_access_for_types_in_expr(rhs1, non_escaping_records, counter, READ_ACCESS);
- log("gimple_single_rhs\n");
- }
- break;
- default:
- gcc_unreachable();
- break;
- }
-}
-
-inline static void
-is_gimple_assign_p(gimple *stmt)
-{
- gcc_assert(stmt);
- const enum gimple_code code = gimple_code(stmt);
- const bool is_assign = GIMPLE_ASSIGN == code;
- gcc_assert(is_assign);
-}
-
-inline static void
-is_gimple_call_p(gimple *stmt)
-{
- gcc_assert(stmt);
- const enum gimple_code code = gimple_code(stmt);
- const bool is_call = GIMPLE_CALL == code;
- gcc_assert(is_call);
-
-}
-
-void
-count_access_for_types_in_assign(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter)
-{
- is_gimple_assign_p(stmt);
-
- count_access_for_types_in_rhs(stmt, non_escaping_records, counter);
- count_access_for_types_in_lhs(stmt, non_escaping_records, counter);
-}
-
-static void
-count_access_for_types_in_call_rhs(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter)
-{
- is_gimple_call_p(stmt);
- unsigned args = gimple_call_num_args (stmt);
-
-
-
- for (unsigned i = 0; i < args; i++)
- {
- const_tree arg = gimple_call_arg (stmt, i);
- count_access_for_types_in_expr(arg, non_escaping_records, counter, READ_ACCESS);
- }
-
-}
-
-void
-count_access_for_types_in_call(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter)
-{
- is_gimple_call_p(stmt);
- count_access_for_types_in_lhs(stmt, non_escaping_records, counter);
-
- /* TODO: We need to iterate over each argument and find out if it is a read */
- count_access_for_types_in_call_rhs(stmt, non_escaping_records, counter);
-}
-
-void
-count_access_for_types_in_stmt(gimple *stmt, const record_set &non_escaping_records, field_access_counter &counter)
-{
- gcc_assert(stmt);
- const enum gimple_code gimple_code_stmt = gimple_code(stmt);
- switch(gimple_code_stmt)
- {
- case GIMPLE_ASSIGN:
- count_access_for_types_in_assign(stmt, non_escaping_records, counter);
- break;
- case GIMPLE_CALL:
- count_access_for_types_in_call(stmt, non_escaping_records, counter);
- break;
- default:
- break;
- }
-}
-
-void
-count_access_for_types_in_bb(basic_block bb, const record_set &non_escaping_records, field_access_counter &counter)
-{
- gcc_assert(bb);
- for (gimple_stmt_iterator gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi))
- {
- gimple *stmt = gsi_stmt(gsi);
- count_access_for_types_in_stmt(stmt, non_escaping_records, counter);
- }
-}
-
-void
-count_access_for_types_in_function(cgraph_node *cnode, const record_set &non_escaping_records, field_access_counter &counter)
-{
- gcc_assert(cnode);
- tree decl = cnode->decl;
- gcc_assert(decl);
- function *func = DECL_STRUCT_FUNCTION (decl);
- gcc_assert(func);
- push_cfun(func);
- basic_block bb = NULL;
- FOR_EACH_BB_FN (bb, func)
- {
- gcc_assert(bb);
- count_access_for_types_in_bb(bb, non_escaping_records, counter);
- }
- pop_cfun();
-}
-
-void
-init_field_access_counter(field_access_counter &counter, const record_set &non_escaping_records)
-{
- for (auto it = non_escaping_records.cbegin(); it != non_escaping_records.cend(); ++it)
- {
- const_tree record = *it;
- gcc_assert(record);
- enum tree_code tree_code_record_type = TREE_CODE(record);
- const bool is_record_type = RECORD_TYPE == tree_code_record_type;
- gcc_assert(is_record_type);
-
- for (tree field = TYPE_FIELDS (record); field; field = DECL_CHAIN (field))
- {
- gcc_assert(field);
- const std::pair<const_tree, const_tree> struct_field_pair = std::make_pair(record, field);
- counter[struct_field_pair] = { 0, 0 };
- }
- }
-}
-
-/* INFO:
- * Yes, I know we are returning a std::map.
- * Bad pattern? Maybe, but this will only be called once
- * and I rather pass by value because that allows
- * me to have a pure function and not worry about
- * garbage collection
- *
- * TODO: I'd like to change type_map for a std::map
- * TODO: I'd like to make this a template that can work
- * for std::map and std::set
- */
-field_access_counter
-count_access_for_types_in_linking_unit(const record_set &non_escaping_records)
-{
- field_access_counter counter;
- init_field_access_counter(counter, non_escaping_records);
- cgraph_node *cnode = NULL;
- FOR_EACH_DEFINED_FUNCTION(cnode)
- {
- gcc_assert(cnode);
- log("printing a defined function\n");
- print_function(cnode);
- count_access_for_types_in_function(cnode, non_escaping_records, counter);
- }
- return counter;
-}
-
-bool
-_calculate_non_escaping_records(const_tree const &type, escaping_info *info, record_set *non_escaping_records)
-{
-
- gcc_assert(info);
- log("NOW: %s is escaping %s\n", get_type_name(type), info->is_escaping ? "true" : "false");
- if (info->is_escaping) return true;
- gcc_assert(non_escaping_records);
-
- enum tree_code tree_code_type = TREE_CODE(type);
- const bool is_record_type = RECORD_TYPE == tree_code_type;
- log("NOW: %s is record %s\n", get_type_name(type), is_record_type ? "true" : "false");
- if (!is_record_type) return true;
-
- non_escaping_records->insert(type);
- return true;
-}
-
-/*
- * Yes, again, we are passing a std::set
- * as a value. I don\t care too much since
- * this is only called once...
- */
-static record_set
-calculate_non_escaping_records(type_map &escaping_type_info)
-{
- // We are going to have to traverse the type_map...
- // This is why I don't really like hash_set...
- record_set non_escaping_records;
- escaping_type_info.traverse<record_set*, _calculate_non_escaping_records>(&non_escaping_records);
- return non_escaping_records;
-}
-
-static field_access_counter
-count_field_accesses()
-{
-
- type_map escaping_types;
- calculate_escaping_types(escaping_types);
- const record_set non_escaping_records = calculate_non_escaping_records(escaping_types);
- field_access_counter counter = count_access_for_types_in_linking_unit(non_escaping_records);
- return counter;
-}
-
-record_field_set
-get_fields_to_reorg()
-{
- const field_access_counter counter = count_field_accesses();
- record_field_set records_and_fields_to_reorg;
- for (auto it = counter.cbegin(); it != counter.cend(); ++it)
- {
- fields record_field_pair = it->first;
- accesses counter = it->second;
- const_tree record = record_field_pair.first;
- const_tree field = record_field_pair.second;
- // We are interested in reads == 0;
- unsigned reads = counter.first;
- log("final count for %s.%s = %d\n", get_type_name(record), get_field_name(field), reads);
- if (0 != reads) continue;
-
- records_and_fields_to_reorg.insert(record_field_pair);
- }
-
- return records_and_fields_to_reorg;
-}
-
-static void
-print_record_field_set(const record_field_set &to_reorg)
-{
- log("I am about to print\n");
- for (auto it = to_reorg.cbegin(); it != to_reorg.cend(); ++it)
- {
- fields record_field_pair = *it;
- const_tree record = record_field_pair.first;
- const_tree field = record_field_pair.second;
- // TODO: Some fields / records might be anonymous
- log("will eliminate %s.%s\n", get_type_name(record), get_field_name(field));
- }
-}
-
-
-static unsigned int
-iphw_execute()
-{
- const record_field_set to_reorg = get_fields_to_reorg();
- log("I am about to enter print function\n");
- print_record_field_set(to_reorg);
- return 0;
-}
-
-namespace {
-const pass_data pass_data_ipa_hello_world =
-{
- SIMPLE_IPA_PASS,
- "hello-world",
- OPTGROUP_NONE,
- TV_NONE,
- (PROP_cfg | PROP_ssa),
- 0,
- 0,
- 0,
- 0,
-};
-
-class pass_ipa_hello_world : public simple_ipa_opt_pass
-{
-public:
- pass_ipa_hello_world (gcc::context *ctx)
- : simple_ipa_opt_pass(pass_data_ipa_hello_world, ctx)
- {}
-
- virtual bool gate(function*) { return flag_ipa_hello_world; }
- virtual unsigned execute (function*) { return iphw_execute(); }
-};
-} // anon namespace
-
-simple_ipa_opt_pass*
-make_pass_ipa_hello_world (gcc::context *ctx)
-{
- return new pass_ipa_hello_world (ctx);
-}
diff --git a/gcc/ipa-hello-world.h b/gcc/ipa-hello-world.h
deleted file mode 100644
index e001ac17041..00000000000
--- a/gcc/ipa-hello-world.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef GCC_IPA_HELLO_WORLD_H
-#define GCC_IPA_HELLO_WORLD_H
-#pragma once
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tree.h"
-
-#include <set>
-
-//TODO: do not use pair.
-//This names are unintelligible
-typedef std::pair<const_tree /* record */, const_tree /* field */> fields;
-typedef std::set<fields> record_field_set;
-record_field_set get_fields_to_reorg();
-
-#endif
diff --git a/gcc/ipa-str-reorg-dead-field-eliminate.c b/gcc/ipa-str-reorg-dead-field-eliminate.c
index 2e192328ad8..f918974f719 100644
--- a/gcc/ipa-str-reorg-dead-field-eliminate.c
+++ b/gcc/ipa-str-reorg-dead-field-eliminate.c
@@ -50,7 +50,6 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-structure-reorg.h"
#include "ipa-utils.h"
#include "ipa-str-reorg-utils.h"
-#include "ipa-hello-world.h"
#include "gimple-caster.hpp"
@@ -67,6 +66,7 @@ along with GCC; see the file COPYING3. If not see
}
+/*
static void
log_expr_prologue (const int indent, const char *debug_str, tree expr)
{
@@ -609,6 +609,7 @@ is_interesting_struct_escape_analysis(const_tree record)
if (is_blacklisted) return false;
}
+ */
/*
bool is_whitelisted = false;
for (int i = 0; i < 4; i++)
@@ -618,6 +619,7 @@ is_interesting_struct_escape_analysis(const_tree record)
if (!is_whitelisted) return false;
*/
+ /*
bool in_set =
#if __cplusplus > 201703L
@@ -739,6 +741,7 @@ is_interesting_field_escape_analysis(const_tree field)
is_field_decl_p(field);
const char* field_name = get_field_name(field);
+ */
/*
const char* whitelist [2] = { "nextin", "nextout" };
@@ -750,6 +753,7 @@ is_interesting_field_escape_analysis(const_tree field)
if (!is_whitelisted) return false;
*/
+ /*
const bool in_set =
#if __cplusplus > 201703L
interesting_fields.contains(field_name);
@@ -1058,7 +1062,7 @@ collect_global_declaration (varpool_node *vnode,
int i;
struct ipa_ref *ref;
- /* Only IPA_REF_STORE and IPA_REF_LOAD left. */
+
for (i = 0; vnode->iterate_referring (i, ref); i++)
{
bool filter_out = (*filter) (vnode->decl, decl_map);
@@ -1144,12 +1148,6 @@ make_new_record_based_on_typedef (const_tree _typedef, t_map *mod_type_map)
return new_type;
}
-/*
- * This method will copy the parameter
- * and delete the field named "delete_me"
- * int the copy. The offsets will be adjusted
- * to account for the deleted parameter
- */
static const_tree
make_new_record_based_on_old (const_tree old,
t_map *mod_type_map)
@@ -2205,13 +2203,11 @@ rewrite_assign_rhs (gimple *stmt, gimple_stmt_iterator &gsi,
tree rhs3 = gimple_assign_rhs3 (stmt);
is_stmt_rewritten |= rewrite_expr (rhs3, type_map, 0);
}
- /* fall through */
case GIMPLE_BINARY_RHS:
{
tree rhs2 = gimple_assign_rhs2 (stmt);
is_stmt_rewritten |= rewrite_expr (rhs2, type_map, 0);
}
- /* fall through */
case GIMPLE_SINGLE_RHS:
case GIMPLE_UNARY_RHS:
{
@@ -2596,7 +2592,6 @@ rewrite_global_decl (varpool_node *vnode,
int i;
struct ipa_ref *ref;
- /* Only IPA_REF_STORE and IPA_REF_LOAD left. */
for (i = 0; vnode->iterate_referring (i, ref); i++)
{
test_log ("rewriting global declaration", 0);
@@ -2763,6 +2758,8 @@ str_reorg_dead_field_eliminate (__attribute__((unused)) Info *info)
return iphw_execute ();
}
+*/
+
#if USE_NEW_INTERFACE
int
str_reorg_dead_field_eliminate_qual (Info *info)
diff --git a/gcc/ipa-type-escape-analysis.c b/gcc/ipa-type-escape-analysis.c
deleted file mode 100644
index dfaf859ae71..00000000000
--- a/gcc/ipa-type-escape-analysis.c
+++ /dev/null
@@ -1,962 +0,0 @@
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "backend.h"
-#include "options.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-cfg.h"
-#include "gimple-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 "gimple.h"
-#include "cfg.h" // needed for gimple-iterator.h
-#include "gimple-iterator.h"
-#include <stdbool.h>
-
-#include "ipa-str-reorg-utils.h"
-#include "ipa-type-escape-analysis.h"
-
-
-// First we need to collect all types
-
-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, escaping_reason reason);
-
-static const escaping_reason null_reason = { 0, 0, 0, 0 };
-inline escaping_reason
-new_escaping_reason()
-{
- return null_reason;
-}
-
-//TODO:
-// Should we be using C++?
-escaping_reason
-union_op(const escaping_reason &left, const escaping_reason &right)
-{
- escaping_reason retval;
- retval.global_is_visible = left.global_is_visible | right.global_is_visible;
- retval.parameter_is_visible = left.parameter_is_visible | right.parameter_is_visible;
- retval.return_is_visible = left.return_is_visible | right.return_is_visible;;
- retval.type_is_casted = left.type_is_casted | right.type_is_casted;;
- return retval;
-}
-
-void
-explain_print(escaping_reason reason)
-{
- if (reason.global_is_visible) log("global is visible");
- if (reason.parameter_is_visible) log(", parameter is visible");
- if (reason.return_is_visible) log(", return is visible");
- if (reason.type_is_casted) log(", type is casted");
- log("\n");
-}
-
-void
-update_escape_info_pointer (const_tree pointer_type, type_map &escape_map, bool is_escaping, escaping_reason reason)
-{
- 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) { log("no info\n"); return;}
-
- info->is_escaping |= is_escaping;
- info->reason = union_op(info->reason, reason);
- 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, info->reason);
-}
-
-void
-update_escape_info_array (const_tree array_type, type_map &escape_map, bool is_escaping, escaping_reason reason)
-{
- 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) { log("no info\n"); return;}
-
- info->is_escaping |= is_escaping;
- info->reason = union_op(info->reason, reason);
- 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, info->reason);
-}
-
-void
-update_escape_info_record (const_tree record_type, type_map &escape_map, bool is_escaping, escaping_reason reason)
-{
- 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
- //FIXME: Is this true? According to creduce bug, no.
- gcc_assert(info);
- info->is_escaping |= is_escaping;
- info->reason = union_op(info->reason, reason);
-
-
- 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, info->reason);
- }
-}
-
-void
-update_escape_info (const_tree type, type_map &escape_map, bool is_escaping, escaping_reason reason)
-{
- // INFO: This is an optimization.
- if (!is_escaping) { log("is not escaping\n"); return; }
-
- gcc_assert(type);
- enum tree_code tree_code_type = TREE_CODE(type);
- // We need to make sure that we are only dealing with
- // the main type and not typedefs...
- switch (tree_code_type)
- {
- case ARRAY_TYPE:
- update_escape_info_array(type, escape_map, is_escaping, reason);
- break;
- case POINTER_TYPE:
- update_escape_info_pointer(type, escape_map, is_escaping, reason);
- break;
- case RECORD_TYPE:
- update_escape_info_record(type, escape_map, is_escaping, reason);
- break;
- default:
- break;
- }
-}
-
-static bool
-filter_pointer (type_map &escape_map, const_tree pointer)
-{
- enum tree_code code = TREE_CODE (pointer);
- gcc_assert(POINTER_TYPE == code);
- const_tree base_type = TREE_TYPE(pointer);
- return filter_type (escape_map, base_type);
-}
-
-static bool
-filter_array (type_map &escape_map, const_tree array)
-{
- enum tree_code code = TREE_CODE (array);
- gcc_assert(ARRAY_TYPE == code);
- const_tree base_type = TREE_TYPE(array);
- return filter_type (escape_map, base_type);
-}
-
-static bool
-filter_record (type_map &escape_map, const_tree record)
-{
- log("filtering record %s\n", get_type_name(record));
- gcc_assert(record);
- enum tree_code code = TREE_CODE(record);
- gcc_assert(RECORD_TYPE == code);
-
- for (tree field = TYPE_FIELDS (record); field; field = DECL_CHAIN (field))
- {
- tree field_type = TREE_TYPE(field);
- gcc_assert(field_type);
- filter_type(escape_map, field_type);
- }
-
- return false;
-}
-
-static bool
-filter_type (type_map &escape_map, const_tree type)
-{
- log("inside filter_type\n");
-
- if (!type) return true;
-
- bool retval = true;
- enum tree_code code = TREE_CODE(type);
- switch (code)
- {
- case ARRAY_TYPE: retval = filter_array(escape_map, type); break;
- case POINTER_TYPE: retval = filter_pointer(escape_map, type); break;
- case RECORD_TYPE: retval = filter_record(escape_map, type); break;
- default: break;
- }
-
-
- log("filter_type %s boring ? %s\n", get_type_name(type), retval ? "true" : "false");
- if (retval) return retval;
- escaping_reason reason = new_escaping_reason();
- escaping_info info = { type , false , reason};
- escape_map.put(type, info);
- return retval;
-}
-
-static bool
-filter_var_decl (type_map &escape_map, const_tree var_decl)
-{
- log("filtering var_decl\n");
- gcc_assert(var_decl);
- enum tree_code code = TREE_CODE(var_decl);
- gcc_assert(code == VAR_DECL);
- tree type = TREE_TYPE (var_decl);
- gcc_assert(type);
- return filter_type(escape_map, type);
-}
-
-static bool
-filter_parm_declarations (const_tree parm_decl, type_map &escape_map)
-{
- gcc_assert(parm_decl);
- enum tree_code code = TREE_CODE(parm_decl);
- gcc_assert(PARM_DECL == code);
- tree type = TREE_TYPE (parm_decl);
- gcc_assert(type);
- return filter_type(escape_map, type);
-}
-
-static void
-collect_global(type_map &escape_map, varpool_node *vnode)
-{
- log("collect_global\n");
- gcc_assert(vnode);
-
- struct ipa_ref *ref = NULL;
- for (int i = 0; vnode->iterate_referring (i, ref); i++)
- {
- log("inside vnode loop\n");
- tree decl = vnode->decl;
- gcc_assert(decl);
- enum tree_code code = TREE_CODE(decl);
- gcc_assert(VAR_DECL == code);
- bool filter_out = filter_var_decl(escape_map, decl);
- if (filter_out) continue;
-
- tree type = TREE_TYPE(decl);
- gcc_assert(type);
- log("collecting global type escape analysis %s\n", get_type_name(type));
- escaping_reason reason = new_escaping_reason();
- escaping_info info = { type, false, reason };
- escape_map.put (type, info);
- //escape_map.put (TYPE_MAIN_VARIANT(type), info);
- }
-}
-
-static void
-collect_globals(type_map &escape_map)
-{
- varpool_node *vnode;
- FOR_EACH_VARIABLE (vnode)
- {
- collect_global(escape_map, vnode);
- }
-}
-
-static void
-collect_parm_declarations (cgraph_node *cnode, type_map &escape_map)
-{
- gcc_assert(cnode);
- log("does function %s have parameters?\n", cnode->name());
- for (tree parm = DECL_ARGUMENTS (cnode->decl); parm; parm = DECL_CHAIN (parm))
- {
- tree type = TREE_TYPE(parm);
- log("about to enter parameter type %s\n", get_type_name(type));
- bool filter_out = filter_parm_declarations (parm, escape_map);
- if (filter_out) continue;
-
- log("putting parameter type %s\n", get_type_name(type));
- gcc_assert(type);
-
- escaping_reason reason = new_escaping_reason();
- escaping_info info = { type, false, reason };
- escape_map.put(type, info);
- }
-}
-
-static void
-collect_local_declarations (cgraph_node *cnode, type_map &escape_map)
-{
- gcc_assert(cnode);
- int i = 0;
- function *func = DECL_STRUCT_FUNCTION (cnode->decl);
- cnode->get_untransformed_body ();
- tree var_decl = NULL;
- FOR_EACH_LOCAL_DECL (func, i, var_decl)
- {
- gcc_assert(var_decl);
- bool filter_out = filter_var_decl(escape_map, var_decl);
- if (filter_out) continue;
-
- tree tree_type = TREE_TYPE(var_decl);
- gcc_assert(tree_type);
- escaping_reason reason = new_escaping_reason();
- escaping_info info = { tree_type, false, reason};
- escape_map.put(tree_type, info);
- }
-}
-
-static void collect_expr (const_tree expr, type_map &escape_map);
-
-static void
-collect_expr_in_component_ref(const_tree cref, type_map &escape_map)
-{
- gcc_assert(cref);
- const enum tree_code code = TREE_CODE(cref);
- const bool is_cref = COMPONENT_REF == code;
- gcc_assert(is_cref);
-
- const_tree _struct = TREE_OPERAND(cref, 0);
- gcc_assert(_struct);
-
- const_tree _struct_type = TREE_TYPE(_struct);
- log("we are in collect_expr_in_component_ref %s\n", get_type_name(_struct_type));
- escaping_reason reason = new_escaping_reason();
- escaping_info info = { _struct_type, false , reason};
- escape_map.put(_struct_type, info);
-
- collect_expr(_struct, escape_map);
-
-}
-
-static void
-collect_expr (const_tree expr, type_map &escape_map)
-{
- gcc_assert(expr);
- enum tree_code tree_code_expr = TREE_CODE(expr);
- switch (tree_code_expr)
- {
- case COMPONENT_REF:
- collect_expr_in_component_ref(expr, escape_map);
- break;
- default:
- break;
- }
-}
-
-static void
-collect_pointer_plus (tree lhs, tree rhs1, tree rhs2, type_map &escape_map)
-{
- log("collect_pointer_plus\n");
- const_tree lhs_type = lhs ? TREE_TYPE(lhs) : NULL;
- bool is_lhs_boring = lhs_type ? filter_type(escape_map, lhs_type) : true;
- const_tree rhs1_type = rhs1 ? TREE_TYPE(rhs1) : NULL;
- bool is_rhs1_boring = rhs1_type ? filter_type(escape_map, rhs1_type) : true;
- const_tree rhs2_type = rhs2 ? TREE_TYPE(rhs2) : NULL;
- bool is_rhs2_boring = rhs2_type ? filter_type(escape_map, rhs2_type) : true;
-
- if (!is_lhs_boring)
- {
- escaping_reason reason = new_escaping_reason();
- escaping_info info = { lhs_type , false, reason };
- escape_map.put(lhs_type, info);
- }
- if (!is_rhs1_boring)
- {
- collect_expr(rhs1, escape_map);
- }
- if (!is_rhs2_boring)
- {
- collect_expr(rhs2, escape_map);
- }
-}
-
-static void
-collect_assign_rhs (gimple *stmt, type_map &escape_map)
-{
- enum tree_code code = gimple_expr_code (stmt);
- switch (code)
- {
- case POINTER_PLUS_EXPR:
- case POINTER_DIFF_EXPR:
- case COMPONENT_REF:
- {
- tree rhs2 = gimple_assign_rhs2(stmt);
- tree rhs1 = gimple_assign_rhs1(stmt);
- tree lhs = gimple_assign_lhs (stmt);
- collect_pointer_plus (lhs, rhs1, rhs2, escape_map);
- break;
- }
- default:
- break;
- }
-}
-
-static void
-collect_assign (gimple *stmt, type_map &escape_map)
-{
- gcc_assert(stmt);
- collect_assign_rhs (stmt, escape_map);
-}
-
-static void
-collect_stmt (gimple *stmt, type_map &escape_map)
-{
- gcc_assert (stmt);
- const enum gimple_code code = gimple_code (stmt);
- switch (code)
- {
- case GIMPLE_ASSIGN:
- collect_assign(stmt, escape_map);
- break;
- default:
- break;
- }
-
- return;
-}
-
-static void
-collect_basic_block (basic_block bb, type_map &escape_map)
-{
- gcc_assert(bb);
- for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next(&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- collect_stmt (stmt, escape_map);
- }
-}
-
-static void
-collect_function_body (cgraph_node *cnode, type_map &escape_map)
-{
- gcc_assert (cnode);
- cnode->get_untransformed_body();
- basic_block bb = NULL;
- tree decl = cnode->decl;
- gcc_assert(decl);
- function *func = DECL_STRUCT_FUNCTION (decl);
- gcc_assert(func);
- push_cfun(func);
- FOR_EACH_BB_FN (bb, func)
- {
- gcc_assert(bb);
- collect_basic_block (bb, escape_map);
- }
- pop_cfun();
-}
-
-static void
-collect_return_type (cgraph_node *cnode, type_map &escape_map)
-{
- gcc_assert(cnode);
-
- const_tree decl = cnode->decl;
- const enum tree_code code = TREE_CODE(decl);
- const bool is_function_decl = FUNCTION_DECL == code;
- gcc_assert (is_function_decl);
-
- const_tree fn_type = TREE_TYPE (decl);
- const enum tree_code fn_type_code = TREE_CODE(fn_type);
- const bool is_fn_type = FUNCTION_TYPE == fn_type_code;
- gcc_assert (is_fn_type);
-
- const_tree ret_type = TREE_TYPE(fn_type);
- gcc_assert (ret_type);
-
- const bool is_boring = filter_type(escape_map, ret_type);
- if (is_boring) return;
-
- escaping_reason reason = new_escaping_reason();
- escaping_info info = {ret_type, false, reason};
- escape_map.put(ret_type, info);
- return;
-}
-
-static void
-collect_types(type_map &escape_map)
-{
- collect_globals(escape_map);
-
- cgraph_node *cnode = NULL;
- FOR_EACH_DEFINED_FUNCTION (cnode)
- {
- collect_function_body (cnode, escape_map);
- collect_local_declarations (cnode, escape_map);
- collect_parm_declarations (cnode, escape_map);
- collect_return_type (cnode, escape_map);
- }
-}
-
-bool
-_print_types( const_tree const &type, escaping_info *info, __attribute__((unused)) void*)
-{
- log("collected,%s\n", get_type_name(type));
- bool is_escaping = info->is_escaping;
- log("type %s is escaping %s : ", get_type_name(type), is_escaping ? "true" : "false");
- explain_print(info->reason);
- return true;
-}
-
-static void
-print_types(type_map &escape_map)
-{
- log("printing_types\n");
- escape_map.traverse<void*, _print_types> (NULL);
-}
-
-static bool
-is_variable_escaping(varpool_node *vnode)
-{
- gcc_assert(vnode);
- return vnode->externally_visible;
-}
-
-static bool
-is_function_escaping(const cgraph_node *cnode)
-{
- gcc_assert(cnode);
- return cnode->externally_visible; /* TODO: How are FOR_EACH_FUNCTION and FOR_EACH_DEFINED_FUNCTION different */ // || !cnode->definition;
-}
-
-void calculate_escaping_parameters(const cgraph_node *cnode, type_map &escape_map, bool override = false);
-
-void
-calculate_escaping_parameters(const cgraph_node *cnode, type_map &escape_map, bool override)
-{
- gcc_assert(cnode);
- tree function = cnode->decl;
- gcc_assert(function);
- enum tree_code code = TREE_CODE (function);
- bool is_function_decl = FUNCTION_DECL == code;
- gcc_assert (is_function_decl);
-
- bool is_escaping = is_function_escaping(cnode) || override;
- function_args_iterator iter;
- tree arg;
- const_tree function_type = TREE_TYPE(function);
- FOREACH_FUNCTION_ARGS (function_type, arg, iter)
- {
- //const_tree main_type = TYPE_MAIN_VARIANT(arg);
- log("parameter type %s is escaping %s\n", get_type_name(arg), is_escaping ? "true" : "false");
- escaping_reason reason = new_escaping_reason();
- reason.parameter_is_visible = is_escaping;
- update_escape_info(arg, escape_map, is_escaping, reason);
- }
-}
-void is_return_type_escaping(const cgraph_node *cnode, type_map &escape_map, bool override = false);
-
-void
-is_return_type_escaping(const cgraph_node *cnode, type_map &escape_map, bool override)
-{
- gcc_assert(cnode);
- bool is_escaping = is_function_escaping(cnode) || override;
- tree function = cnode->decl;
- gcc_assert(function);
- enum tree_code code = TREE_CODE(function);
- bool is_function = FUNCTION_DECL == code;
- gcc_assert(is_function);
-
- tree tree_type = TREE_TYPE(function);
- gcc_assert(tree_type);
- tree return_type = TREE_TYPE(tree_type);
- gcc_assert(return_type);
- log("return type %s\n", get_type_name(return_type));
-
- // void update_escaping_info (const_tree type, type_map &escape_map, bool is_escaping);
-/*struct escaping_reason_s {
- unsigned global_is_visible : 1;
- unsigned function_is_visible : 1;
-};
-*/
- escaping_reason reason = new_escaping_reason();
- reason.return_is_visible = is_escaping;
- update_escape_info(return_type, escape_map, is_escaping, reason);
- //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;
-}
-
-
-bool
-calculate_escaping_types_from_function_signatures (
- cgraph_node * const &cnode, type_map *escape_map)
-{
-
- gcc_assert(escape_map);
- gcc_assert(cnode);
- bool is_escaping = is_function_escaping(cnode);
- log("function %s is escaping %s\n", cnode->name(), is_escaping ? "true" : "false");
- calculate_escaping_parameters(cnode, *escape_map, is_escaping);
- is_return_type_escaping(cnode, *escape_map, is_escaping);
- return true;
-}
-
-void
-find_calls_to_undefined_functions_from_call(gimple *stmt, hash_set<tree> &set, type_map &escape_map)
-{
- gcc_assert(stmt);
- const enum gimple_code code = gimple_code(stmt);
- const bool is_gimple_call = GIMPLE_CALL == code;
- gcc_assert(is_gimple_call);
-
- gcall *call = dyn_cast<gcall *>(stmt);
- tree fn = gimple_call_fndecl(stmt);
-
- // Function pointer?
- if (!fn) return;
-
- // if fn is in set... then it means that it is undefined.
- if (!set.contains(fn)) return;
-
- unsigned num_arguments = gimple_call_num_args(call);
- for (unsigned i = 0; i < num_arguments; i++)
- {
- tree argument = gimple_call_arg(stmt, i);
- /*
- // TODO: Why is this the case?
- gimple *def_for_arg = SSA_NAME_DEF_STMT(argument);
- gcc_assert(def_for_arg);
- const enum gimple_code code2 = gimple_code(def_for_arg);
- const bool is_gimple_call2 = GIMPLE_CALL == code2;
- const bool is_gimple_assign = GIMPLE_ASSIGN == code2;
- const bool is_assignable = is_gimple_call2 ^ is_gimple_assign;
- gcc_assert(is_assignable);
-
- tree arg_var = is_gimple_assign ? gimple_assign_lhs(def_for_arg) : gimple_call_lhs(def_for_arg);
- gcc_assert(arg_var);
- */
- tree arg_type = TREE_TYPE(argument);
- gcc_assert(arg_type);
-
- bool is_escaping = true;
- escaping_reason reason = new_escaping_reason();
- reason.parameter_is_visible = is_escaping;
- update_escape_info(arg_type, escape_map, is_escaping, reason);
- }
-}
-
-void
-find_calls_to_undefined_functions_from_stmt(gimple *stmt, hash_set<tree> &set, type_map &escape_map)
-{
- gcc_assert(stmt);
- const enum gimple_code code = gimple_code (stmt);
- const bool is_gimple_call = GIMPLE_CALL == code;
- if (!is_gimple_call) return;
-
- find_calls_to_undefined_functions_from_call(stmt, set, escape_map);
-}
-
-
-void
-find_calls_to_undefined_functions_from_bb(basic_block bb, hash_set<tree> &set, type_map &escape_map)
-{
- gcc_assert(bb);
- for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- find_calls_to_undefined_functions_from_stmt(stmt, set, escape_map);
- }
-}
-
-void
-find_calls_to_undefined_functions_from_function(cgraph_node *cnode, hash_set<tree> &set, type_map &escape_map)
-{
- gcc_assert(cnode);
- cnode->get_untransformed_body ();
- function *func = DECL_STRUCT_FUNCTION(cnode->decl);
- basic_block bb = NULL;
- push_cfun(func);
- FOR_EACH_BB_FN(bb, func)
- {
- find_calls_to_undefined_functions_from_bb(bb, set, escape_map);
- }
- pop_cfun();
-}
-
-void
-is_any_function_escaping(type_map &escape_map)
-{
- cgraph_node *cnode = NULL;
- hash_set<tree> not_defined_functions;
-
- FOR_EACH_FUNCTION (cnode)
- {
- gcc_assert(cnode);
- const char* _free = "free";
- //const char* _memset = "memset";
- const char* _malloc = "malloc";
- const char* _realloc = "realloc";
- const char* _calloc= "calloc";
- const char* ob_name = cnode->name();
- if (strcmp(ob_name, _free) == 0) continue;
- //if (strcmp(ob_name, _memset) == 0) continue;
- if (strcmp(ob_name, _malloc) == 0) continue;
- if (strcmp(ob_name, _realloc) == 0) continue;
- if (strcmp(ob_name, _calloc) == 0) continue;
-
- not_defined_functions.add(cnode->decl);
- }
-
-
- FOR_EACH_DEFINED_FUNCTION(cnode)
- {
- gcc_assert(cnode);
- cnode->get_untransformed_body();
- not_defined_functions.remove(cnode->decl);
- calculate_escaping_types_from_function_signatures (cnode, &escape_map);
- }
-
- // not_defined_functions.traverse<type_map *, calculate_escaping_types_from_function_signatures> (&escape_map);
- //TODO: Walk gimple code and identify GIMPLE_CALL to see if function is not defined...
- FOR_EACH_DEFINED_FUNCTION(cnode)
- {
- find_calls_to_undefined_functions_from_function(cnode, not_defined_functions, escape_map);
- }
-}
-
-void
-is_any_variable_escaping(type_map &escape_map)
-{
- varpool_node *vnode = NULL;
- // Global variables
- FOR_EACH_VARIABLE(vnode)
- {
- bool is_escaping = is_variable_escaping(vnode);
- log("variable %s is escaping %s\n", vnode->name(), is_escaping ? "true" : "false");
- tree decl = vnode->decl;
- gcc_assert(decl);
- tree type = TREE_TYPE(decl);
- gcc_assert(type);
- // void update_escaping_info (const_tree type, type_map &escape_map, bool is_escaping);
- escaping_reason reason = new_escaping_reason();
- reason.global_is_visible = is_escaping;
- update_escape_info (type, escape_map, is_escaping, reason);
- //escaping_info *info = escape_map.get(type);
- //if (!info) return;
- //info->is_escaping |= is_escaping;
- }
-}
-
-//TODO: place in header file
-inline static void
-print_function (cgraph_node *cnode)
-{
- if (!dump_file)
- return;
- gcc_assert (cnode);
- cnode->get_untransformed_body ();
- dump_function_to_file (cnode->decl, dump_file, TDF_NONE);
-}
-
-static bool
-cast_to_void_in_assign(const_tree lhs, const_tree rhs, type_map &escape_map)
-{
- gcc_assert(lhs);
- gcc_assert(rhs);
- const_tree tree_type_lhs = TREE_TYPE(lhs);
- gcc_assert(tree_type_lhs);
- const_tree tree_type_rhs = TREE_TYPE(rhs);
- gcc_assert(tree_type_rhs);
- const char* const type_name_lhs = get_type_name(tree_type_lhs);
- const char* const type_name_rhs = get_type_name(tree_type_rhs);
- enum tree_code tree_code_rhs = TREE_CODE(rhs);
- bool is_ssa_name = SSA_NAME == tree_code_rhs;
- bool is_var_decl = VAR_DECL == tree_code_rhs;
- bool is_var_decl_or_ssa_name = is_ssa_name || is_var_decl;
- log("lhs = %s, rhs = %s\n", type_name_lhs, type_name_rhs);
- if (!is_var_decl_or_ssa_name) return false;
-
- // We need to find out the base...
- const_tree base_type_lhs = get_base_type(tree_type_lhs);
- gcc_assert(base_type_lhs);
- const_tree base_type_rhs = get_base_type(tree_type_rhs);
- gcc_assert(base_type_rhs);
- // TODO: FIXME:
- // Is this always correct? I think this can only happen
- // if we are mallocing and friends...
- enum tree_code tree_code_base_type_rhs = TREE_CODE(base_type_rhs);
- if (tree_code_base_type_rhs == VOID_TYPE) return false;
-
- bool is_casting_stmt = TYPE_MAIN_VARIANT(base_type_lhs) != TYPE_MAIN_VARIANT(base_type_rhs);
- log("is casting stmt ? %s\n", is_casting_stmt ? "true" : "false");
- if (!is_casting_stmt) return false;
-
- log("escaping lhs %s\n", type_name_lhs);
- escaping_reason reason = new_escaping_reason();
- reason.type_is_casted = is_casting_stmt;
- update_escape_info(tree_type_lhs, escape_map, is_casting_stmt, reason);
-
- log("escaping rhs %s\n", type_name_rhs);
- update_escape_info(tree_type_rhs, escape_map, is_casting_stmt, reason);
- return true;
-}
-
-static void
-cast_to_void_in_assign (gimple *stmt, type_map &escape_map)
-{
- enum gimple_code gcode = gimple_code (stmt);
- const char* const gcode_str = gimple_code_name[gcode];
- gcc_assert(gcode_str);
-
- switch (gimple_assign_rhs_class (stmt))
- {
- case GIMPLE_SINGLE_RHS:
- case GIMPLE_UNARY_RHS:
- {
- tree lhs = gimple_assign_lhs(stmt);
- tree rhs = gimple_assign_rhs1(stmt);
- bool retval = cast_to_void_in_assign(lhs, rhs, escape_map);
- if (!retval) break;
-
- tree tree_type_lhs = TYPE_MAIN_VARIANT(TREE_TYPE(lhs));
- tree tree_type_rhs = TYPE_MAIN_VARIANT(TREE_TYPE(rhs));
- const char* const type_name_lhs = get_type_name(tree_type_lhs);
- const char* const type_name_rhs = get_type_name(tree_type_rhs);
- log("type casting %s != %s ", type_name_lhs, type_name_rhs);
- if (dump_file) print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
- log("\n");
- }
- default:
- break;
- }
-}
-
-static void
-cast_to_void_in_stmt (gimple *stmt, type_map &escape_map)
-{
- gcc_assert (stmt);
- const enum gimple_code code = gimple_code (stmt);
- switch (code)
- {
- case GIMPLE_ASSIGN:
- cast_to_void_in_assign(stmt, escape_map);
- break;
- default:
- break;
- }
-
- return;
-}
-
-static void
-cast_to_void_in_bb(basic_block bb, type_map &escape_map)
-{
- gcc_assert(bb);
- for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next(&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- cast_to_void_in_stmt (stmt, escape_map);
- }
-}
-
-static void
-cast_to_void_in_function(cgraph_node *cnode, type_map &escape_map)
-{
- gcc_assert (cnode);
- print_function (cnode);
- basic_block bb = NULL;
- tree decl = cnode->decl;
- gcc_assert(decl);
- function *func = DECL_STRUCT_FUNCTION (decl);
- gcc_assert(func);
- push_cfun(func);
- FOR_EACH_BB_FN (bb, func)
- {
- gcc_assert(bb);
- cast_to_void_in_bb(bb, escape_map);
- }
- pop_cfun();
-}
-
-static void
-cast_to_void_in_program(type_map &escape_map)
-{
- cgraph_node *cnode = NULL;
- FOR_EACH_DEFINED_FUNCTION (cnode)
- {
- gcc_assert(cnode);
- cnode->get_untransformed_body();
- cast_to_void_in_function(cnode, escape_map);
- }
-}
-
-/* INFO:
- * Yes, I know we are returning a std::map.
- * Bad pattern? Maybe, but this will only be called once
- * and I rather pass by value because that allows
- * me to have a pure function and not worry about
- * garbage collection
- *
- * TODO: I'd like to change type_map for a std::map
- * TODO: I'd like to make this a template that can work
- * for std::map and std::set
- */
-void
-calculate_escaping_types(type_map &escape_map)
-{
- collect_types(escape_map);
- is_any_variable_escaping(escape_map);
- is_any_function_escaping(escape_map);
- cast_to_void_in_program(escape_map);
- print_types(escape_map);
-}
-
-static unsigned int
-iphw_execute()
-{
- // We can ignore the return value here...
- type_map escape_map;
- calculate_escaping_types(escape_map);
- return 0;
-}
-
-
-namespace {
-const pass_data pass_data_ipa_type_escape_analysis =
-{
- SIMPLE_IPA_PASS,
- "type-escape-analysis",
- OPTGROUP_NONE,
- TV_NONE,
- (PROP_cfg | PROP_ssa),
- 0,
- 0,
- 0,
- 0,
-};
-
-class pass_ipa_type_escape_analysis : public simple_ipa_opt_pass
-{
-public:
- pass_ipa_type_escape_analysis (gcc::context *ctx)
- : simple_ipa_opt_pass(pass_data_ipa_type_escape_analysis, ctx)
- {}
-
- virtual bool gate(function*) { return in_lto_p && flag_ipa_type_escape_analysis; }
- virtual unsigned execute (function*) { return iphw_execute(); }
-};
-} // anon namespace
-
-simple_ipa_opt_pass*
-make_pass_ipa_type_escape_analysis (gcc::context *ctx)
-{
- return new pass_ipa_type_escape_analysis (ctx);
-}
diff --git a/gcc/ipa-type-escape-analysis.h b/gcc/ipa-type-escape-analysis.h
deleted file mode 100644
index 7dcda948189..00000000000
--- a/gcc/ipa-type-escape-analysis.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef GCC_IPA_TYPE_ESCAPE_ANALYSIS_H
-#define GCC_IPA_TYPE_ESCAPE_ANALYSIS_H
-#pragma once
-
-struct escaping_reason_s {
- unsigned global_is_visible : 1;
- unsigned parameter_is_visible : 1;
- unsigned return_is_visible : 1;
- unsigned type_is_casted : 1;
-};
-typedef struct escaping_reason_s escaping_reason;
-
-struct escaping_info_s { const_tree type; bool is_escaping; escaping_reason reason; };
-typedef struct escaping_info_s escaping_info;
-//TODO: Maybe change this to a std::map?
-//Can we get an idea of what conventions gcc want?
-//Maybe I should ask...
-typedef hash_map<const_tree, escaping_info> type_map;
-void calculate_escaping_types(type_map&);
-
-#endif
diff --git a/gcc/passes.def b/gcc/passes.def
index b4c0fa0d3c1..4c8391281f2 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -149,8 +149,6 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_ipa_profile);
NEXT_PASS (pass_ipa_icf);
NEXT_PASS (pass_ipa_devirt);
- NEXT_PASS (pass_ipa_type_escape_analysis);
- NEXT_PASS (pass_ipa_hello_world);
NEXT_PASS (pass_ipa_cp);
NEXT_PASS (pass_ipa_sra);
NEXT_PASS (pass_ipa_cdtor_merge);
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 25fccb80f31..ddf1edb9c90 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -502,8 +502,6 @@ extern ipa_opt_pass_d *make_pass_ipa_fn_summary (gcc::context *ctxt);
extern ipa_opt_pass_d *make_pass_ipa_inline (gcc::context *ctxt);
extern simple_ipa_opt_pass *make_pass_ipa_free_lang_data (gcc::context *ctxt);
extern simple_ipa_opt_pass *make_pass_ipa_free_fn_summary (gcc::context *ctxt);
-extern simple_ipa_opt_pass *make_pass_ipa_type_escape_analysis (gcc::context *ctxt);
-extern simple_ipa_opt_pass *make_pass_ipa_hello_world (gcc::context *ctxt);
extern simple_ipa_opt_pass *make_pass_ipa_prototype (gcc::context *ctxt);
extern ipa_opt_pass_d *make_pass_ipa_cp (gcc::context *ctxt);
extern ipa_opt_pass_d *make_pass_ipa_sra (gcc::context *ctxt);