示例#1
0
static void
test_conversion_to_ssa ()
{
  /* As above, construct a trivial function, gimplify it, and build a CFG: */
  tree fndecl = build_trivial_high_gimple_function ();
  function *fun = DECL_STRUCT_FUNCTION (fndecl);
  ASSERT_TRUE (fun != NULL);
  build_cfg (fndecl);

  convert_to_ssa (fndecl);

  verify_three_block_gimple_cfg (fun);

  /* For out trivial test function we should now have something like
     this:
       test_fn ()
       {
	 <bb 2>:
	 _1 = 42;
	 return _1;
       }
  */
  basic_block bb2 = get_real_block (fun);
  gimple *stmt_a = gimple_seq_first_stmt (bb_seq (bb2));
  ASSERT_EQ (GIMPLE_ASSIGN, gimple_code (stmt_a));

  gimple *stmt_b = stmt_a->next;
  ASSERT_EQ (GIMPLE_RETURN, gimple_code (stmt_b));
  ASSERT_EQ (NULL, stmt_b->next);

  greturn *return_stmt = as_a <greturn *> (stmt_b);
  ASSERT_EQ (SSA_NAME, TREE_CODE (gimple_return_retval (return_stmt)));
}
示例#2
0
static void
verify_three_block_gimple_cfg (function *fun)
{
  verify_three_block_cfg (fun);

  /* The "fake" basic blocks should be flagged as gimple, but with have no
     statements.  */
  basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (fun);
  ASSERT_TRUE (entry != NULL);
  ASSERT_EQ (0, entry->flags & BB_RTL);
  ASSERT_EQ (NULL, bb_seq (entry));

  basic_block exit = EXIT_BLOCK_PTR_FOR_FN (fun);
  ASSERT_TRUE (exit != NULL);
  ASSERT_EQ (0, entry->flags & BB_RTL);
  ASSERT_EQ (NULL, bb_seq (exit));

  /* The "real" basic block should be flagged as gimple, and have one
     or more statements.  */
  basic_block bb2 = get_real_block (fun);
  ASSERT_TRUE (bb2 != NULL);
  ASSERT_EQ (0, entry->flags & BB_RTL);
  ASSERT_TRUE (bb_seq (bb2) != NULL);
}
示例#3
0
static void
test_building_cfg ()
{
  /* Construct a trivial function, and gimplify it: */
  tree fndecl = build_trivial_high_gimple_function ();
  function *fun = DECL_STRUCT_FUNCTION (fndecl);
  ASSERT_TRUE (fun != NULL);

  /* Build a CFG.  */
  build_cfg (fndecl);

  /* The CFG-building code constructs a 4-block cfg (with
     ENTRY and EXIT):
       test_fn ()
       {
         <bb 2>:
	 D.65 = 42;

	 <bb 3>:
	 return D.65;
       }
     and then ought to merge blocks 2 and 3 in cleanup_tree_cfg.

     Hence we should end up with a simple 3-block cfg, the two "fake" ones,
     and a "real" one:
       [ENTRY] -> [block2] -> [EXIT]
     with code like this:
	 test_fn ()
	 {
	   <bb 2>:
	   D.56 = 42;
	   return D.56;
	 }
  */
  verify_three_block_gimple_cfg (fun);

  /* Verify the statements within the "real" block.  */
  basic_block bb2 = get_real_block (fun);
  gimple *stmt_a = gimple_seq_first_stmt (bb_seq (bb2));
  ASSERT_EQ (GIMPLE_ASSIGN, gimple_code (stmt_a));
  gimple *stmt_b = stmt_a->next;
  ASSERT_EQ (GIMPLE_RETURN, gimple_code (stmt_b));
  ASSERT_EQ (NULL, stmt_b->next);
}
示例#4
0
static void
adjust_return_value (basic_block bb, tree m, tree a)
{
  tree retval;
  gimple ret_stmt = gimple_seq_last_stmt (bb_seq (bb));
  gimple_stmt_iterator gsi = gsi_last_bb (bb);

  gcc_assert (gimple_code (ret_stmt) == GIMPLE_RETURN);

  retval = gimple_return_retval (ret_stmt);
  if (!retval || retval == error_mark_node)
    return;

  if (m)
    retval = adjust_return_value_with_ops (MULT_EXPR, "mul_tmp", m_acc, retval,
					   gsi);
  if (a)
    retval = adjust_return_value_with_ops (PLUS_EXPR, "acc_tmp", a_acc, retval,
					   gsi);
  gimple_return_set_retval (ret_stmt, retval);
  update_stmt (ret_stmt);
}