summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Oblock <gary@amperecomputing.com>2020-06-08 20:46:26 -0700
committerGary Oblock <gary@amperecomputing.com>2020-06-10 10:22:50 -0700
commit0e3acbe69c82973e886682c25531ecc05a29e71f (patch)
tree95062c44b309a92e1ef5ba723fa0f406f6c35159
parent809717bc09868292c63fd82c15ea0925f2eae780 (diff)
Trasnsformations stub in place and malloc in development.
-rw-r--r--gcc/ipa-str-reorg-instance-interleave.c610
-rw-r--r--gcc/ipa-structure-reorg.c59
-rw-r--r--gcc/ipa-structure-reorg.h4
3 files changed, 344 insertions, 329 deletions
diff --git a/gcc/ipa-str-reorg-instance-interleave.c b/gcc/ipa-str-reorg-instance-interleave.c
index fd87336152d..d2eaa0fa4c7 100644
--- a/gcc/ipa-str-reorg-instance-interleave.c
+++ b/gcc/ipa-str-reorg-instance-interleave.c
@@ -40,6 +40,9 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "stor-layout.h"
#include "diagnostic-core.h"
+#include "ssa.h"
+#include "tree-ssanames.h"
+#include "cfghooks.h"
static void str_reorg_instance_interleave_qual_part ( Info *);
static void str_reorg_instance_interleave_type_part ( Info *);
@@ -100,7 +103,7 @@ str_reorg_instance_interleave_trans ( Info *info)
if ( ri != NULL )
{
enum ReorgTransformation trans =
- reorg_recognize ( stmt, info);
+ reorg_recognize ( stmt, node, info);
// print out trans and stmt if dumping
if ( info->show_transforms )
{
@@ -288,306 +291,329 @@ str_reorg_instance_interleave_trans ( Info *info)
// Not needed for single pool.
break;
case ReorgT_Malloc:
- DEBUG_L("ReorgT_Malloc\n");
- /*
- // Note, unlike other simpler transformations,
- // this must build new basic blocks to add new
- // gimple to and use a phi for the final result.
- // See appendix on malloc transformation for
- // each comment starting with "FROM."
- ReorgType_t *ri = contains_a_reorgtype( stmt, info);
- // FROM len = val/size
- tree arg = gimple_call_arg( stmt, 0);
- len is new SSA
- tree val = gimple_call_lhs( stmt);
- gcc_assert( TREE_CODE( TREE_TYPE(val)) == INDIRECT_REF);
- tree size = TYPE_SIZE_UNIT( TREE_TYPE( TREE_TYPE( val)));
- // FROM len = val/size (insert before stmt)
- gimple_stmt_iterator *gsi = gsi_for_stmt( stmt);
- gimple *glen =
- gimple_build_assign(
- len,
- TRUNC_DIV_EXPR,
- val,
- size,
- NULL_TREE, NULL_TREE);
- gsi_insert_before( gsi, glen, GSI_SAME_STMT);
- // Note in other places in this doc this would
- // be "insert glen before stmt" instead of this but
- // here we need to create new basic blocks.
- // FROM edge = split this block after stmt
- edge new_edge = split_edge( bb, stmt);
- // FROM before_bb = edge->src // same as this bb
- before_bb = edge->src;
- // FROM after_bb = edge->dest
- after_bb = edge->dest;
- // FROM delete edge
- remove_edge( e);
- // FROM prev_bb = before_bb
- prev_bb = before_bb;
- // FROM prev_ok_field is new label
- tree prev_ok_field_L =
- create_artificial_label( UNKNOWN_LOCATION);
- // FROM after_label is new label
- tree after_label_L =
- create_artificial_label( UNKNOWN_LOCATION);
- // FROM add goto for prev_ok_field to end of before_bb
- gimple *goto_pof = gimple_build_goto( prev_ok_field_L);
- gsi_insert_before( gsi, *goto_pof, GSI_SAME_STMT);
- // FROM failure_bb = create_empty_block(prev_bb)
- basic_block failure_bb = create_empty_block( prev_bb);
- // FROM make_edge( failure_bb, after_bb, EDGE_FALLTHRU);
- edge failure_edge = make_edge( failure_bb,
- after_bb, EDGE_FALLTHRU);
- // FROM bad_field is new label
- tree bad_field_L =
- create_artificial_label( UNKNOWN_LOCATION);
- // FROM delete stmt
- gsi_remove( gsi, true);
-
- // code in failure_bb
- //
- // FROM fail_val is new SSA
- tree return_type = TREE_TYPE( arg);
- tree fail_val =
- make_temp_ssa_name( return_type, NULL, "fail_val")
- // FROM gsi = gsi_start_bb( failure_bb)
- gsi = gsi_start_bb( failure_bb);
- // FROM gsi_insert_after( &gsi, "goto after_label")
- gimple *goto_al = gimple_build_goto( after_label_L);
- gsi_insert_after( &gsi, goto_al);
- // (per field) {
- tree field;
- tree reorg_type = ri->gcc_type;
- tree fndecl_free = builtin_decl_explicit( BUILT_IN_FREE);
- tree base = ri->clone;
- for( field = TYPE_FIELDS( reorg_type);
- field;
- field = DECL_CHAIN( field)) {
- // FROM gsi_insert_after( &gsi, "base.field = 0")
- tree lhs_ass =
- build3( COMPONENT_REF, ptr_type_node, base, field, NULL_TREE);
- gimple *gzero = gimple_build_assign( lhs_ass, null_pointer_node);
- gsi_insert_after( &gsi, gzero);
-
- // FROM gsi_insert_after( &gsi, "free(field)")
- tree to_free =
- make_temp_ssa_name( type, NULL, "to_free")
- gcall *free_call = gimple_build_call( fndecl_free, 1, to_free);
- gsi_insert_after( &gsi, free_call);
- tree rhs_ass =
- build3( COMPONENT_REF, ptr_type_node, base, field, NULL_TREE);
- gimple *gaddr2free = gimple_build_assign( to_free, rhs_ass);
- gsi_insert_after( &gsi, gaddr2free);
- }
- // FROM gsi_insert_after( &gsi, "fail_val = minint")
- gimple *gretnull =
- gimple_build_assign( fail_val,
- build_int_cst(
- TYPE_MIN_VALUE( TREE_TYPE(fail_val))));
- gsi_insert_after( &gsi, gretnull);
- // FROM gsi_insert_after( &gsi, bad_field )
- gimple gbad_field = gimple_build_label( bad_field_L);
- gsi_insert_after( &gsi, gbad_field );
-
- // loop setup trickery for gimple idioms
- //
- // FROM prev_order = failure_bb
- prev_order = failure_bb;
- // FROM prev_bb = before_bb
- prev_bb = before_bb;
+ #if 0
+ DEBUG_L("Transform ReorgT_Malloc\n");
+ INDENT(2);
+ // Note, unlike other simpler transformations,
+ // this must build new basic blocks to add new
+ // gimple to and use a phi for the final result.
+ // See appendix on malloc transformation for
+ // each comment starting with "FROM."
+ ReorgType_t *ri = contains_a_reorgtype( stmt, info);
+ // FROM len = val/size
+ tree arg = gimple_call_arg( stmt, 0);
+ // TBD: len is new SSA
+ tree val = gimple_call_lhs( stmt);
+ gcc_assert( TREE_CODE( TREE_TYPE(val)) == INDIRECT_REF);
+ tree size = TYPE_SIZE_UNIT( TREE_TYPE( TREE_TYPE( val)));
+ // FROM len = val/size (insert before stmt) <== maybe arg/size
+ tree len =
+ make_temp_ssa_name( sizetype, NULL, "fail_val");
+ gimple_stmt_iterator gsi = gsi_for_stmt( stmt);
+ //gimple *glen =
+ // gimple_build_assign ( len, TRUNC_DIV_EXPR, val, size);
+ gimple *glen =
+ gimple_build_assign ( len, TRUNC_DIV_EXPR, arg, size);
+ gsi_insert_before( &gsi, glen, GSI_SAME_STMT);
+ // Note in other places in this doc this would
+ // be "insert glen before stmt" instead of this but
+ // here we need to create new basic blocks.
+ // FROM edge = split this block after stmt
+ edge new_edge = split_block ( bb, stmt);
+ // FROM before_bb = edge->src // same as this bb
+ basic_block before_bb = new_edge->src; //
+ // FROM after_bb = edge->dest
+ basic_block after_bb = new_edge->dest;
+ // FROM delete edge
+ remove_edge ( new_edge);
+ // FROM prev_bb = before_bb
+ basic_block prev_bb = before_bb;
+ // FROM prev_ok_field is new label
+ tree prev_ok_field_L =
+ create_artificial_label ( UNKNOWN_LOCATION);
+ // FROM after_label is new label
+ tree after_label_L =
+ create_artificial_label ( UNKNOWN_LOCATION);
+ // FROM add goto for prev_ok_field to end of before_bb
+ gimple *goto_pof = gimple_build_goto ( prev_ok_field_L);
+ gsi_insert_before ( &gsi, goto_pof, GSI_SAME_STMT); // TBD insert after???
+ // FROM failure_bb = create_empty_block(prev_bb)
+ basic_block failure_bb = create_empty_bb ( prev_bb);
+ // FROM make_edge( failure_bb, after_bb, EDGE_FALLTHRU);
+ edge failure_edge = make_edge ( failure_bb,
+ after_bb, EDGE_FALLTHRU);
+ // FROM bad_field is new label
+ tree bad_field_L =
+ create_artificial_label ( UNKNOWN_LOCATION);
+ // FROM delete stmt
+ gsi_remove ( &gsi, true);
- // Generate all the real allocation code
- tree fndecl_malloc = builtin_decl_explicit( BUILT_IN_MALLOC);
- tree base = ri->clone;
- // FROM (for fields) {
- for( field = TYPE_FIELDS( reorg_type);
- field;
- field = DECL_CHAIN( field)) {
- // FROM res is new SSA
- // Note, alternative code would substitute ptr_type_node
- // for null_pointer_node.
- tree res =
- make_temp_ssa_name( null_pointer_node, NULL, "res")
- // FROM new_bb = create_empty_block(prev_order);
- basic_block new_bb = create_empty_block( prev_order);
- // FROM gsi = gsi_start_bb( new_bb)
- gimple_stmt_iterator gsi = gsi_start_bb( new_bb);
- // FROM set imm dom new_bb as prev_bb
- set_immediate_dominator( CDI_DOMINATORS, new_bb, prev_bb);
- // FROM make_edge( prev_bb, new_bb, EDGE_TRUE_VALUE);
- make_edge( prev_bb, new_bb, EDGE_TRUE_VALUE);
- // FROM make_edge( new_bb, failure_bb, EDGE_FALSE_VALUE);
- make_edge( new_bb, failure_bb, EDGE_FALSE_VALUE);
- // FROM new_ok_field is new label
- tree new_ok_field_L =
- create_artificial_label( UNKNOWN_LOCATION);
- // FROM gsi_insert_after( &gsi, "if( res NE NULL )
- // goto new_ok_field;
- // goto bad_field")
- tree res =
- make_temp_ssa_name( pointer_type_node, NULL, "res")
- gimple *gcond =
- gimple_build_cond( NE_EXPR, res, null_pointer_node,
- new_ok_field_L, bad_field_L);
- gsi_insert_after( &gsi, gcond);
- // FROM gsi_insert_after( &gsi, "base.field = res")
- tree lhs_ass =
- build3( COMPONENT_REF, ptr_type_node, base, field, NULL_TREE);
- gimple *gset_field = gimple_build_assign( lhs_ass, res);
- gsi_insert_after( &gsi, gset_field);
+ // code in failure_bb
+ //
+ // FROM fail_val is new SSA
+ tree return_type = TREE_TYPE ( arg);
+ tree fail_val =
+ make_temp_ssa_name ( return_type, NULL, "fail_val");
+ // FROM gsi = gsi_start_bb ( failure_bb)
+ gsi = gsi_start_bb ( failure_bb);
+ // FROM gsi_insert_after ( &gsi, "goto after_label")
+ gimple *goto_al = gimple_build_goto ( after_label_L);
+ gsi_insert_after ( &gsi, goto_al, GSI_SAME_STMT);
+ // (per field) {
+ tree field;
+ tree reorg_type = ri->gcc_type; // is this useful here?
+ tree reorg_pointer_type = ri->pointer_rep;
+ tree fndecl_free = builtin_decl_explicit( BUILT_IN_FREE);
+ tree base = ri->clone;
+ for( field = TYPE_FIELDS( reorg_type);
+ field;
+ field = DECL_CHAIN( field)) {
+ // FROM gsi_insert_after( &gsi, "base.field = 0")
+ tree lhs_ass =
+ build3( COMPONENT_REF, ptr_type_node, base, field, NULL_TREE);
+ gimple *gzero = gimple_build_assign( lhs_ass, null_pointer_node);
+ gsi_insert_after( &gsi, gzero, GSI_SAME_STMT);
- // FROM gsi_insert_after( &gsi, "res = malloc( mem_size)")
- // The alternative to sizetype are long_integer_type_node
- // and integer_type_node.
- tree mem_size =
- make_temp_ssa_name( sizetype, NULL, "mem_size");
- gcall *malloc_call = gimple_build_call( fndecl_malloc, 1, mem_size);
- gimple_call_set_lhs( malloc_call, res);
- gsi_insert_after( &gsi, malloc_call);
- // FROM gsi_insert_after( &gsi, "mem_size = len * field_size")
- gimple *gsize =
- gimple_build_assign( mem_size, MULT_EXPR, TYPE_SIZE(field),
- len, NULL_TREE, NULL_TREE);
- gsi_insert_after( &gsi, gsize);
- // FROM gsi_insert_after( &gsi, prev_ok_field)
- gimple gprev_ok_field = gimple_build_label( prev_ok_field_L);
- gsi_insert_after( &gsi, gprev_ok_field_L );
- // FROM prev_bb = new_bb
- prev_bb = new_bb;
- // FROM prev_order = new_bb
- prev_order = new_bb;
- // FROM prev_ok_field = new_ok_field
- prev_ok_field_L = new_ok_field_L;
- }
-
- // create basic block for success
- //
- // FROM success_bb = create_empty_block(prev_bb_order);
- success_bb = create_empty_block(prev_bb_order);
- // FROM set imm dom success_bb as prev_bb
- set_immediate_dominator( CDI_DOMINATORS, success_bb, prev_bb);
- // FROM make_edge( prev_bb, success_bb, EDGE_TRUE_VALUE);
- make_edge( prev_bb, success_bb, EDGE_TRUE_VALUE);
- // FROM make_edge( success_bb, after_bb, EDGE_TRUE_VALUE);
- edge success_edge = make_edge( success_bb, after_bb, EDGE_TRUE_VALUE);
+ // FROM gsi_insert_after( &gsi, "free(field)")
+ // TBD -- I'm
+ tree to_free =
+ make_temp_ssa_name( reorg_pointer_type, NULL, "to_free");
+ gcall *free_call = gimple_build_call( fndecl_free, 1, to_free);
+ gsi_insert_after( &gsi, free_call, GSI_SAME_STMT);
+ tree rhs_ass =
+ build3( COMPONENT_REF, ptr_type_node, base, field, NULL_TREE);
+ gimple *gaddr2free = gimple_build_assign( to_free, rhs_ass);
+ gsi_insert_after( &gsi, gaddr2free, GSI_SAME_STMT);
+ }
+ // FROM gsi_insert_after( &gsi, "fail_val = minint")
+ gimple *gretnull =
+ gimple_build_assign ( fail_val,
+ build_int_cst ( size_type_node,
+ TYPE_MIN_VALUE ( TREE_TYPE ( fail_val))));
+ gsi_insert_after( &gsi, gretnull, GSI_SAME_STMT);
+ // FROM gsi_insert_after( &gsi, bad_field )
+ gimple *gbad_field = gimple_build_label( bad_field_L);
+ gsi_insert_after( &gsi, gbad_field, GSI_SAME_STMT);
+
+ // loop setup trickery for gimple idioms
+ //
+ // FROM prev_order = failure_bb
+ basic_block prev_order = failure_bb;
+ // FROM prev_bb = before_bb
+ prev_bb = before_bb;
+
+ // Generate all the real allocation code
+ tree fndecl_malloc = builtin_decl_explicit( BUILT_IN_MALLOC);
+ // This, after the following loop, will hold the start of the
+ // field related code.
+ tree new_ok_field_L;
- // code in success_bb
- //
- // FROM success_val is new SSA
- tree success_val =
- make_temp_ssa_name( int_ptrsize_type, NULL, "success_val");
- // FROM gsi = gsi_start_bb( failure_bb)
- gimple_stmt_iterator gsi = gsi_start_bb( failure_bb);
- // FROM gsi_insert_after( &gsi, "goto after_label")
- gimple *goto_al = gimple_build_goto( after_label_L);
- gsi_insert_after( &gsi, goto_al);
- // FROM gsi_insert_after( &gsi, "success_val = 0")
- gimple *set_succ =
- gimple_build_assign( success_val, build_int_cst( 0));
- gsi_insert_after( &gsi, set_succ);
- // FROM gsi_insert_after( &gsi, new_ok_field )
- gimple gnew_ok_field = gimple_build_label( new_ok_field_L);
- gsi_insert_after( &gsi, gnew_ok_field );
+ // FROM (for fields) {
+ for( field = TYPE_FIELDS( reorg_type);
+ field;
+ field = DECL_CHAIN( field))
+ {
+ // FROM res is new SSA
+ // Note, alternative code would substitute ptr_type_node
+ // for null_pointer_node.
+ // This is probably a duplicate of the def of res below.
+ //tree res =
+ // make_temp_ssa_name( null_pointer_node, NULL, "res");
+ // FROM new_bb = create_empty_block(prev_order);
+ basic_block new_bb = create_empty_bb ( prev_order);
+ // FROM gsi = gsi_start_bb( new_bb)
+ gimple_stmt_iterator gsi = gsi_start_bb ( new_bb);
+ // FROM set imm dom new_bb as prev_bb
+ set_immediate_dominator ( CDI_DOMINATORS, new_bb, prev_bb);
+ // FROM make_edge( prev_bb, new_bb, EDGE_TRUE_VALUE);
+ make_edge ( prev_bb, new_bb, EDGE_TRUE_VALUE);
+ // FROM make_edge( new_bb, failure_bb, EDGE_FALSE_VALUE);
+ make_edge ( new_bb, failure_bb, EDGE_FALSE_VALUE);
+ // FROM new_ok_field is new label
+ new_ok_field_L =
+ create_artificial_label ( UNKNOWN_LOCATION);
+ // FROM gsi_insert_after( &gsi, "if( res NE NULL )
+ // goto new_ok_field;
+ // goto bad_field")
+ tree res =
+ make_temp_ssa_name ( ptr_type_node, NULL, "res");
+ gimple *gcond =
+ gimple_build_cond ( NE_EXPR, res, null_pointer_node,
+ new_ok_field_L, bad_field_L);
+ gsi_insert_after ( &gsi, gcond, GSI_SAME_STMT);
+ // FROM gsi_insert_after( &gsi, "base.field = res")
+ tree lhs_ass =
+ build3( COMPONENT_REF, ptr_type_node, base, field, NULL_TREE);
+ gimple *gset_field = gimple_build_assign( lhs_ass, res);
+ gsi_insert_after( &gsi, gset_field, GSI_SAME_STMT);
+
+ // FROM gsi_insert_after( &gsi, "res = malloc( mem_size)")
+ // The alternative to sizetype are long_integer_type_node
+ // and integer_type_node.
+ tree mem_size =
+ make_temp_ssa_name( sizetype, NULL, "mem_size");
+ gcall *malloc_call = gimple_build_call( fndecl_malloc, 1, mem_size);
+ gimple_call_set_lhs( malloc_call, res);
+ gsi_insert_after( &gsi, malloc_call, GSI_SAME_STMT);
+ // FROM gsi_insert_after( &gsi, "mem_size = len * field_size")
+ //gimple *gsize =
+ // gimple_build_assign ( mem_size, MULT_EXPR, TYPE_SIZE(field),
+ // len, NULL_TREE, NULL_TREE);
+ gimple *gsize =
+ gimple_build_assign ( mem_size,
+ MULT_EXPR,
+ TYPE_SIZE ( field),
+ len);
+ gsi_insert_after( &gsi, gsize, GSI_SAME_STMT);
+ // FROM gsi_insert_after( &gsi, prev_ok_field)
+ gimple *gprev_ok_field = gimple_build_label ( prev_ok_field_L);
+ gsi_insert_after ( &gsi, gprev_ok_field, GSI_SAME_STMT);
+ // FROM prev_bb = new_bb
+ prev_bb = new_bb;
+ // FROM prev_order = new_bb
+ prev_order = new_bb;
+ // FROM prev_ok_field = new_ok_field
+ prev_ok_field_L = new_ok_field_L;
+ }
- // add code to after_bb
- //
- // FROM gsi = gsi_start_bb( after_bb)
- gimple_stmt_iterator gsi = gsi_start_bb( after_bb);
- // FROM gsi_insert_after( &gsi, "lhs = "phi(success_val, fail_val)
- gphi *der_phi = create_phi_node( lhs, after_bb);
- add_phi_arg( der_phi, success_val, success_edge, UNKNOWN_LOCATION);
- add_phi_arg( der_phi, fail_val, failure_edge, UNKNOWN_LOCATION);
-
- // FROM gsi_insert_after( &gsi, after_label)
- gimple gafter_label = gimple_build_label( after_L);
- gsi_insert_after( &gsi, gafter_label );
- */
+ // create basic block for success
+ //
+ // FROM success_bb = create_empty_block(prev_bb_order);
+ basic_block success_bb = create_empty_bb ( prev_bb);
+ // FROM set imm dom success_bb as prev_bb
+ set_immediate_dominator ( CDI_DOMINATORS, success_bb, prev_bb);
+ // FROM make_edge( prev_bb, success_bb, EDGE_TRUE_VALUE);
+ make_edge ( prev_bb, success_bb, EDGE_TRUE_VALUE);
+ // FROM make_edge( success_bb, after_bb, EDGE_TRUE_VALUE);
+ edge success_edge = make_edge ( success_bb, after_bb, EDGE_TRUE_VALUE);
+
+ // code in success_bb
+ //
+ // FROM success_val is new SSA
+ tree success_val =
+ make_temp_ssa_name( reorg_pointer_type, NULL, "success_val");
+ // FROM gsi = gsi_start_bb( failure_bb)
+ // Reuse the same gsi??? Or create a new one???
+ //gimple_stmt_iterator gsi = gsi_start_bb ( failure_bb);
+ gsi = gsi_start_bb ( failure_bb);
+ // FROM gsi_insert_after( &gsi, "goto after_label")
+ // Reuse goto_al
+ //gimple *goto_al = gimple_build_goto( after_label_L);
+ goto_al = gimple_build_goto( after_label_L);
+ gsi_insert_after( &gsi, goto_al, GSI_SAME_STMT);
+ // FROM gsi_insert_after( &gsi, "success_val = 0")
+ gimple *set_succ =
+ gimple_build_assign ( success_val,
+ build_int_cst ( reorg_pointer_type, 0));
+ gsi_insert_after( &gsi, set_succ, GSI_SAME_STMT);
+ // FROM gsi_insert_after( &gsi, new_ok_field )
+ gimple *gnew_ok_field = gimple_build_label ( new_ok_field_L);
+ gsi_insert_after ( &gsi, gnew_ok_field, GSI_SAME_STMT);
+
+ // add code to after_bb
+ //
+ // FROM gsi = gsi_start_bb( after_bb)
+ // Reuse gsi
+ //gimple_stmt_iterator gsi = gsi_start_bb( after_bb);
+ gsi = gsi_start_bb( after_bb);
+ // FROM gsi_insert_after( &gsi, "lhs = "phi(success_val, fail_val)
+ gphi *der_phi = create_phi_node( lhs, after_bb);
+ add_phi_arg( der_phi, success_val, success_edge, UNKNOWN_LOCATION);
+ add_phi_arg( der_phi, fail_val, failure_edge, UNKNOWN_LOCATION);
+
+ // FROM gsi_insert_after( &gsi, after_label)
+ gimple gafter_label = gimple_build_label( after_L);
+ gsi_insert_after( &gsi, gafter_label, GSI_SAME_STMT);
+ #endif
+ INDENT(-2);
break;
case ReorgT_Calloc:
DEBUG_L("ReorgT_Calloc\n");
/*
- // This used to be almost a clone of the old version of
- // the malloc code above and needs to transformed just like
- // what was done above to malloc.
- tree arg = gimple_call_arg( stmt, 0);
- len is new SSA
- tree val = gimple_call_lhs( stmt);
- gcc_assert( TREE_CODE( TREE_TYPE(val)) == INDIRECT_REF);
- tree size = TYPE_SIZE_UNIT( TREE_TYPE( TREE_TYPE( val)));
- gimple *glen =
- gimple_build_assign(
- len,
- TRUNC_DIV_EXPR,
- val,
- size,
- NULL_TREE, NULL_TREE);
- insert glen before stmt
- tree lfial = create_artificial_label( UNKNOWN_LOCATION);
- gimple *gfail = gimple_build_label( lfail);
- tree lnotfial = create_artificial_label( UNKNOWN_LOCATION);
- gimple *gnotfail = gimple_build_label( lnotfail);
- tree base = ri->clone;
- for each element of base {
- // call malloc
- tree lok = create_artificial_label( UNKNOWN_LOCATION);
- gimple *glok = gimple_build_label( lok);
- tree *fndecl = builtin_decl_explicit( BUILT_IN_MALLOC);
- mem_size is new SSA
- gimple *gsize =
- gimple_build_assign(
- mem_size,
- MULT_EXPR,
- TYPE_SIZE(element),
- len,
- NULL_TREE, NULL_TREE);
- insert gsize before stmt
- gcall *call = gimple_build_call( fndecl, 1, mem_size);
- mres is new SSA
- gimple_call_set_lhs( call, mres)
- insert call before stmt
- // Set element to return value of malloc.
- // Note, the devil is in the details here.
- gen concat( REORG_SP_PREFIX,
- type_name( lhs) ).element <- mres
- and insert before stmt
- // gen test of return
- gimple *gcond =
- gimple_build_cond( EQ_EXPR, mres,
- null_pointer_node, lfail, lok);
- insert gcond before stmt
- insert glok before stmt
- // call memset
- fndecl = builtin_decl_explicit( BUILT_IN_MEMSET);
- call =
- gimple_build_call( fndecl, 3, mres, int_node_zero, mem_size);
- insert call before stmt
- }
+ // This used to be almost a clone of the old version of
+ // the malloc code above and needs to transformed just like
+ // what was done above to malloc.
+ tree arg = gimple_call_arg( stmt, 0);
+ len is new SSA
+ tree val = gimple_call_lhs( stmt);
+ gcc_assert( TREE_CODE( TREE_TYPE(val)) == INDIRECT_REF);
+ tree size = TYPE_SIZE_UNIT( TREE_TYPE( TREE_TYPE( val)));
+ gimple *glen =
+ gimple_build_assign(
+ len,
+ TRUNC_DIV_EXPR,
+ val,
+ size,
+ NULL_TREE, NULL_TREE);
+ //insert glen before stmt
+ gimple_stmt_iterator stmt_gsi = gsi_for_stmt ( stmt);
+ gsi_link_before( stmt_gsi, glen, GSI_SAME_STMT);
+ tree lfial = create_artificial_label( UNKNOWN_LOCATION);
+ gimple *gfail = gimple_build_label( lfail);
+ tree lnotfial = create_artificial_label( UNKNOWN_LOCATION);
+ gimple *gnotfail = gimple_build_label( lnotfail);
+ tree base = ri->clone;
+ for (each element of base) // TBD <==
+ {
+ // call malloc
+ tree lok = create_artificial_label( UNKNOWN_LOCATION);
+ gimple *glok = gimple_build_label( lok);
+ tree *fndecl = builtin_decl_explicit( BUILT_IN_MALLOC);
+ mem_size is new SSA
+ gimple *gsize =
+ gimple_build_assign(
+ mem_size,
+ MULT_EXPR,
+ TYPE_SIZE(element),
+ len,
+ NULL_TREE, NULL_TREE);
+ insert gsize before stmt
+ gcall *call = gimple_build_call( fndecl, 1, mem_size);
+ mres is new SSA
+ gimple_call_set_lhs( call, mres)
+ insert call before stmt
+ // Set element to return value of malloc.
+ // Note, the devil is in the details here.
+ gen concat( REORG_SP_PREFIX,
+ type_name( lhs) ).element <- mres
+ and insert before stmt
+ // gen test of return
+ gimple *gcond =
+ gimple_build_cond( EQ_EXPR, mres,
+ null_pointer_node, lfail, lok);
+ insert gcond before stmt
+ insert glok before stmt
+ // call memset
+ fndecl = builtin_decl_explicit( BUILT_IN_MEMSET);
+ call =
+ gimple_build_call( fndecl, 3, mres, int_node_zero, mem_size);
+ insert call before stmt
+ }
- // fake return value of zero
- gimple *gretzero =
- gimple_build_assign( lhs,
- build_int_cst(
- TYPE_MIN_VALUE( TREE_TYPE(lhs)), 0));
- insert gretzero before stmt
- gimple *ggoto = gimple_build_goto( lnotfail);
- insert ggoto before stmt
- insert glab1 before stmt
- 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
- set element to null
- }
- // fake return value of null
- gimple *gretnull =
- gimple_build_assign( lhs,
- build_int_cst(
- TYPE_MIN_VALUE( TREE_TYPE(lhs))));
- insert gretnull before stmt
- insert gnotfail before stmt
- delete stmt
- */
+ // fake return value of zero
+ gimple *gretzero =
+ gimple_build_assign( lhs,
+ build_int_cst(
+ TYPE_MIN_VALUE( TREE_TYPE(lhs)), 0));
+ insert gretzero before stmt
+ gimple *ggoto = gimple_build_goto( lnotfail);
+ insert ggoto before stmt
+ insert glab1 before stmt
+ 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
+ set element to null
+ }
+ // fake return value of null
+ gimple *gretnull =
+ gimple_build_assign( lhs,
+ build_int_cst(
+ TYPE_MIN_VALUE( TREE_TYPE(lhs))));
+ insert gretnull before stmt
+ insert gnotfail before stmt
+ delete stmt
+ */
break;
case ReorgT_Realloc:
DEBUG_L("ReorgT_Realloc\n");
diff --git a/gcc/ipa-structure-reorg.c b/gcc/ipa-structure-reorg.c
index 58e7578a8c8..68865afbb19 100644
--- a/gcc/ipa-structure-reorg.c
+++ b/gcc/ipa-structure-reorg.c
@@ -76,7 +76,7 @@ static void reorg_forbidden ( gimple *, Info *);
//static ReorgTransformation reorg_recognize ( gimple *, Info *);
//static bool is_reorg_type ( tree, Info *);
//static tree base_type_of ( tree);
-static bool is_user_function ( gimple *, Info *);
+static bool is_user_function ( gimple *, cgraph_node *, Info *);
static bool is_reorg_alloc_trigger ( gimple *);
static ReorgType_t *find_struct_type_ptr_to_struct ( tree, Info *);
//static ReorgType_t *get_reorgtype_info ( tree, Info *);
@@ -917,7 +917,7 @@ transformation_legality ( Info *info)
int num = num_reorgtypes ( stmt, info);
if ( num != 0 )
{
- if ( reorg_recognize( stmt, info) == Not_Supported )
+ if ( reorg_recognize( stmt, node, info) == Not_Supported )
{
int i;
for ( i = 0; i < num; i++ )
@@ -1034,7 +1034,7 @@ undelete_reorgtype ( ReorgType_t *rt, Info *info )
}
ReorgTransformation
-reorg_recognize ( gimple *stmt, Info *info )
+reorg_recognize ( gimple *stmt, cgraph_node* node, Info_t *info )
{
DEBUG_L ( "ReorgTransformation reorg_recognize for: ");
DEBUG_F ( print_gimple_stmt, stderr, stmt, 0);
@@ -1115,6 +1115,7 @@ reorg_recognize ( gimple *stmt, Info *info )
INDENT(-4);
switch ( recognize_op( rhs, info) )
{
+ case ReorgOpT_Scalar: // "z"
case ReorgOpT_Temp: // "t"
case ReorgOpT_Indirect: // "a->f"
case ReorgOpT_AryDir: // "x[i].f"
@@ -1190,13 +1191,15 @@ reorg_recognize ( gimple *stmt, Info *info )
{
DEBUG_L("GIMPLE_COND:\n");
INDENT(-2);
- tree op1 = gimple_assign_rhs1 ( stmt);
- tree op2 = gimple_assign_rhs2( stmt);
+ //tree op1 = gimple_assign_rhs1 ( stmt);
+ //tree op2 = gimple_assign_rhs2( stmt);
+ tree op1 = gimple_cond_lhs ( stmt);
+ tree op2 = gimple_cond_rhs ( stmt);
enum tree_code cond_code = gimple_cond_code (stmt);
- // TBD The parenthesis where a disaster here in the HL Design so
+ // TBD The parenthesis were a disaster here in the HL Design so
// double check this!
bool zero_case =
- ( POINTER_TYPE_P ( TREE_TYPE ( op1)) && integer_zerop ( op2))
+ ( POINTER_TYPE_P ( TREE_TYPE ( op1)) && integer_zerop ( op2))
|| ( POINTER_TYPE_P ( TREE_TYPE ( op2)) && integer_zerop ( op1));
switch ( cond_code )
{
@@ -1219,6 +1222,10 @@ reorg_recognize ( gimple *stmt, Info *info )
case GIMPLE_CALL:
{
DEBUG_L("GIMPLE_CALL:\n");
+ struct cgraph_edge *edge = node->get_edge ( stmt);
+ gcc_assert( edge);
+ DEBUG_L("called function %s gimple_body\n",
+ edge->callee->has_gimple_body_p() ? "has a" : "has no");
INDENT(-2);
if ( gimple_call_builtin_p( stmt, BUILT_IN_CALLOC ) ) return ReorgT_Calloc;
if ( gimple_call_builtin_p( stmt, BUILT_IN_MALLOC ) ) return ReorgT_Malloc;
@@ -1230,7 +1237,7 @@ reorg_recognize ( gimple *stmt, Info *info )
// transformation is meaningless but the type still needs to be
// adjusted (does transform really do this?)
- if ( is_user_function ( stmt, info) )
+ if ( is_user_function ( stmt, node, info) )
{
return ReorgT_UserFunc;
}
@@ -1253,35 +1260,15 @@ reorg_recognize ( gimple *stmt, Info *info )
}
static bool
-is_user_function ( gimple *call_stmt, Info *info)
+is_user_function ( gimple *call_stmt, cgraph_node* node, Info *info)
{
- tree fndecl = gimple_call_fndecl ( call_stmt);
-
- DEBUG_L("is_user_function: decl in: %p,", fndecl);
- DEBUG_F( print_generic_decl, stderr, fndecl, (dump_flags_t)-1);
- DEBUG("\n");
- INDENT(2);
-
- gcc_assert ( fndecl);
-
- cgraph_node* node;
- bool ret_val = false;
- FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
- {
- DEBUG_L("decl %p,", node->decl);
- DEBUG_F( print_generic_decl, stderr, node->decl, (dump_flags_t)-1);
- DEBUG("\n");
-
- if ( node->decl == fndecl )
- {
- ret_val = true;
- break;
- }
- }
-
- INDENT(-2);
- return true; // <==== Evil work around!!!!!!
- return ret_val;
+ // I'm not 100% sure this is a great idea but it means that
+ // if we know nothing about the contents of a function
+ // then it shouldn't be considered a user written function
+ // that is part of our program.
+ struct cgraph_edge *ce;
+ ce = node->get_edge ( call_stmt);
+ return ce->callee->has_gimple_body_p();
}
void
diff --git a/gcc/ipa-structure-reorg.h b/gcc/ipa-structure-reorg.h
index 6864caf27a3..509597ca85f 100644
--- a/gcc/ipa-structure-reorg.h
+++ b/gcc/ipa-structure-reorg.h
@@ -212,7 +212,9 @@ extern void clear_deleted_types( Info *);
extern void restore_deleted_types ( Info *);
extern void remove_deleted_types ( Info *, ReorgFn);
extern enum ReorgOpTrans recognize_op ( tree, Info_t *);
-extern ReorgTransformation reorg_recognize ( gimple *, Info_t *);
+extern ReorgTransformation reorg_recognize ( gimple *,
+ cgraph_node *,
+ Info_t *);
extern ReorgType_t *get_reorgtype_info ( tree, Info_t *);
extern ReorgType_t *contains_a_reorgtype ( gimple *, Info *);
extern bool is_reorg_type ( tree, Info_t *);