summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Oblock <gary@amperecomputing.com>2020-10-27 11:20:38 -0700
committerGary Oblock <gary@amperecomputing.com>2020-10-27 11:20:38 -0700
commit6bd040ada3dc6323960906ad86e3baa7c601000f (patch)
treeccef4571cbf04ed31b938b516c5a7d2c593d755d
parentaac167add8a1252eee3119dad61baa73a39c8030 (diff)
The free transformation.
-rw-r--r--gcc/ipa-str-reorg-instance-interleave.c85
1 files changed, 74 insertions, 11 deletions
diff --git a/gcc/ipa-str-reorg-instance-interleave.c b/gcc/ipa-str-reorg-instance-interleave.c
index b5ecf789cf6..d98f9eadabb 100644
--- a/gcc/ipa-str-reorg-instance-interleave.c
+++ b/gcc/ipa-str-reorg-instance-interleave.c
@@ -1293,17 +1293,80 @@ str_reorg_instance_interleave_trans ( Info *info)
*/
break;
case ReorgT_Free:
- // TBD
- DEBUG_L("ReorgT_Free\n");
- // We won't free the base because it a global.
- /*
- for each element of base {
- tree fndecl = builtin_decl_explicit( BUILT_IN_FREE);
- gcall *call = gimple_build_call( fndecl, 1, element);
- insert call before stmt
- }
- delete stmt
- */
+ {
+ DEBUG_L("ReorgT_Free\n");
+ // We won't free the base because it a global.
+ /*
+ for each element of base {
+ tree fndecl = builtin_decl_explicit( BUILT_IN_FREE);
+ gcall *call = gimple_build_call( fndecl, 1, element);
+ insert call before stmt
+ }
+ delete stmt
+ */
+ gimple_stmt_iterator gsi = gsi_for_stmt( stmt);
+
+ //tree fndecl_free = gimple_call_fndecl ( stmt);
+ tree fndecl_free = builtin_decl_implicit ( BUILT_IN_FREE);
+ tree field;
+ tree base = ri->instance_interleave.base;
+ tree reorg_type = ri->gcc_type;
+
+ cgraph_edge *edge = node->get_edge ( stmt); // expt
+
+ for( field = TYPE_FIELDS( reorg_type);
+ field;
+ field = DECL_CHAIN( field))
+ {
+
+ tree base_field =
+ find_coresponding_field ( base, field);
+ tree base_field_type = TREE_TYPE( base_field);
+
+ gcc_assert ( base_field_type);
+ tree to_free =
+ make_temp_ssa_name( base_field_type, NULL, "to_free");
+
+ tree rhs_ass = build3( COMPONENT_REF,
+ base_field_type,
+ base,
+ base_field, NULL_TREE);
+
+ gimple *gaddr2free = gimple_build_assign( to_free, rhs_ass);
+ SSA_NAME_DEF_STMT ( to_free) = gaddr2free;
+
+ gsi_insert_before( &gsi, gaddr2free, GSI_SAME_STMT);
+
+ gcc_assert ( ptr_type_node);
+ tree m_cast2free =
+ make_temp_ssa_name( ptr_type_node, NULL, "m_cast2free");
+
+ gimple *gm_cast2free =
+ gimple_build_assign( m_cast2free, CONVERT_EXPR, to_free);
+ SSA_NAME_DEF_STMT ( m_cast2free) = gm_cast2free;
+
+ gsi_insert_before( &gsi, gm_cast2free, GSI_SAME_STMT);
+
+ gcall *free_call = gimple_build_call( fndecl_free, 1, m_cast2free);
+ gsi_insert_before( &gsi, free_call, GSI_SAME_STMT);
+
+ if ( edge )
+ {
+ // We steal the existing edge to a free
+ cgraph_edge::set_call_stmt ( edge, free_call);
+ edge = NULL;
+ }
+ else
+ {
+ cgraph_node::get ( cfun->decl)->
+ create_edge ( cgraph_node::get_create ( fndecl_free),
+ free_call,
+ bb->count
+ );
+ }
+ }
+ gsi_remove ( &gsi, true);
+ }
break;
case ReorgT_UserFunc:
{