summaryrefslogtreecommitdiff
path: root/gcc/ipa-type-escape-analysis.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ipa-type-escape-analysis.h')
-rw-r--r--gcc/ipa-type-escape-analysis.h70
1 files changed, 65 insertions, 5 deletions
diff --git a/gcc/ipa-type-escape-analysis.h b/gcc/ipa-type-escape-analysis.h
index 8b9911ace1e..cbd07701199 100644
--- a/gcc/ipa-type-escape-analysis.h
+++ b/gcc/ipa-type-escape-analysis.h
@@ -316,6 +316,8 @@ protected:
*/
bool _deleted;
+ cgraph_node *currently_walking;
+
/* Walk global variables. */
void _walk_globals ();
@@ -323,7 +325,7 @@ protected:
virtual void _walk_global (varpool_node *v);
/* Will walk declarations, locals, ssa names, and basic blocks. */
- void _walk_cnode (cgraph_node *cnode);
+ virtual void _walk_cnode (cgraph_node *cnode);
/* This will walk the CNODE->decl. */
void _walk_decl (cgraph_node *cnode);
@@ -439,6 +441,9 @@ struct type_partitions_s
/* The set of all non escaping types. */
tset_t non_escaping;
+ /* The set of all records. */
+ tset_t records;
+
/* Determine if we have seen this type before. */
bool in_universe (const_tree) const;
@@ -494,8 +499,11 @@ private:
* from PTR.
* This datastructure persists across calls to collect.
*/
+public:
tpartitions_t ptrset;
+private:
+
/* Sanity check determines that the partitions are mutually
* exclusive.
*/
@@ -648,9 +656,9 @@ public:
return typeCollector.get_record_reaching_trees ();
}
-private:
TypeCollector typeCollector;
+private:
/* Catch all callback for all nested expressions E. */
virtual void _walk_pre (const_tree e);
};
@@ -676,9 +684,10 @@ public:
// TODO: I believe this could be made const.
void print_collected ();
-private:
ExprCollector exprCollector;
+private:
+
/* Call back for global variables. */
virtual void _walk_pre_tree (const_tree);
@@ -693,6 +702,53 @@ private:
/* Call back for gcall. */
virtual void _walk_pre_gcall (gcall *s);
+
+ /* Call back for gdebug. */
+ virtual void _walk_pre_gdebug (gdebug *s);
+
+};
+
+class GimpleWhiteLister : GimpleTypeCollector
+{
+public:
+ GimpleWhiteLister()
+ {};
+
+ bool _no_external = true;
+ bool does_not_call_external_functions(cgraph_node *c, std::map<tree, bool> &whitelisted)
+ {
+ gcc_assert(c);
+
+ for (cgraph_edge *edge = c->callees; edge; edge = edge->next_callee)
+ {
+ cgraph_node *callee = edge->callee;
+ if (callee == c) continue;
+ bool in_map = whitelisted.find(callee->decl) != whitelisted.end();
+ if (!in_map) {
+ return false;
+ }
+ bool w = whitelisted[callee->decl];
+ if (!w) {
+ return false;
+ }
+ }
+
+ unsigned int how_many_records = exprCollector.typeCollector.ptrset.records.size();
+ return how_many_records <= 1;
+
+ }
+
+ /* Will walk declarations, locals, ssa names, and basic blocks. */
+ virtual void _walk_cnode (cgraph_node *cnode)
+ {
+ GimpleTypeCollector::_walk_cnode(cnode);
+ }
+
+private:
+ virtual void _walk_pre_gcall (gcall *s)
+ {
+ this->_no_external = false;
+ }
};
// Reason for why a type is escaping
@@ -1004,10 +1060,13 @@ protected:
class GimpleCaster : public GimpleEscaper
{
public:
- GimpleCaster (tpartitions_t &types) : GimpleEscaper (types)
+ GimpleCaster (tpartitions_t &types, std::map<tree, bool> &whitelisted) : GimpleEscaper (types), _whitelisted(whitelisted)
{};
private:
+
+ std::map<tree, bool> &_whitelisted;
+
/* Determine if cast comes from a known function. */
static bool follow_def_to_find_if_really_cast (const_tree);
@@ -1157,7 +1216,7 @@ typedef std::map<const_tree, field_offsets_t> record_field_offset_map_t;
// Partition types into escaping or non escaping sets.
tpartitions_t
-partition_types_into_escaping_nonescaping ();
+partition_types_into_escaping_nonescaping (std::map<tree, bool>&);
// Compute set of not escaping unaccessed fields
record_field_offset_map_t
@@ -1166,5 +1225,6 @@ obtain_nonescaping_unaccessed_fields (tpartitions_t casting,
int warning);
extern bool detected_incompatible_syntax;
+std::map<tree, bool> get_whitelisted_nodes();
#endif /* GCC_IPA_TYPE_ESCAPE_ANALYSIS_H */