Ejemplo n.º 1
0
void
reserve_phi_args_for_new_edge (basic_block bb)
{
  size_t len = EDGE_COUNT (bb->preds);
  size_t cap = ideal_phi_node_len (len + 4);
  gimple_stmt_iterator gsi;

  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gimple *loc = gsi_stmt_ptr (&gsi);

      if (len > gimple_phi_capacity (*loc))
	{
	  gimple old_phi = *loc;

	  resize_phi_node (loc, cap);

	  /* The result of the PHI is defined by this PHI node.  */
	  SSA_NAME_DEF_STMT (gimple_phi_result (*loc)) = *loc;

	  release_phi_node (old_phi);
	}

      /* We represent a "missing PHI argument" by placing NULL_TREE in
	 the corresponding slot.  If PHI arguments were added
	 immediately after an edge is created, this zeroing would not
	 be necessary, but unfortunately this is not the case.  For
	 example, the loop optimizer duplicates several basic blocks,
	 redirects edges, and then fixes up PHI arguments later in
	 batch.  */
      SET_PHI_ARG_DEF (*loc, len - 1, NULL_TREE);

      (*loc)->gimple_phi.nargs++;
    }
}
Ejemplo n.º 2
0
static tree
make_phi_node (tree var, int len)
{
  tree phi;
  int capacity, i;

  capacity = ideal_phi_node_len (len);

  phi = allocate_phi_node (capacity);

  /* We need to clear the entire PHI node, including the argument
     portion, because we represent a "missing PHI argument" by placing
     NULL_TREE in PHI_ARG_DEF.  */
  memset (phi, 0, (sizeof (struct tree_phi_node) - sizeof (struct phi_arg_d)
		   + sizeof (struct phi_arg_d) * len));
  TREE_SET_CODE (phi, PHI_NODE);
  PHI_NUM_ARGS (phi) = len;
  PHI_ARG_CAPACITY (phi) = capacity;
  TREE_TYPE (phi) = TREE_TYPE (var);
  if (TREE_CODE (var) == SSA_NAME)
    SET_PHI_RESULT (phi, var);
  else
    SET_PHI_RESULT (phi, make_ssa_name (var, phi));

  for (i = 0; i < capacity; i++)
    {
      use_operand_p  imm;
      imm = &(PHI_ARG_IMM_USE_NODE (phi, i));
      imm->use = &(PHI_ARG_DEF_TREE (phi, i));
      imm->prev = NULL;
      imm->next = NULL;
      imm->stmt = phi;
    }
  return phi;
}
Ejemplo n.º 3
0
void
reserve_phi_args_for_new_edge (basic_block bb)
{
  tree *loc;
  int len = EDGE_COUNT (bb->preds);
  int cap = ideal_phi_node_len (len + 4);

  for (loc = &(bb->phi_nodes);
       *loc;
       loc = &PHI_CHAIN (*loc))
    {
      if (len > PHI_ARG_CAPACITY (*loc))
	{
	  tree old_phi = *loc;

	  resize_phi_node (loc, cap);

	  /* The result of the phi is defined by this phi node.  */
	  SSA_NAME_DEF_STMT (PHI_RESULT (*loc)) = *loc;

	  release_phi_node (old_phi);
	}

      /* We represent a "missing PHI argument" by placing NULL_TREE in
	 the corresponding slot.  If PHI arguments were added
	 immediately after an edge is created, this zeroing would not
	 be necessary, but unfortunately this is not the case.  For
	 example, the loop optimizer duplicates several basic blocks,
	 redirects edges, and then fixes up PHI arguments later in
	 batch.  */
      SET_PHI_ARG_DEF (*loc, len - 1, NULL_TREE);

      PHI_NUM_ARGS (*loc)++;
    }
}
Ejemplo n.º 4
0
static gimple
make_phi_node (tree var, int len)
{
  gimple phi;
  int capacity, i;

  capacity = ideal_phi_node_len (len);

  phi = allocate_phi_node (capacity);

  /* We need to clear the entire PHI node, including the argument
     portion, because we represent a "missing PHI argument" by placing
     NULL_TREE in PHI_ARG_DEF.  */
  memset (phi, 0, (sizeof (struct gimple_statement_phi)
		   - sizeof (struct phi_arg_d)
		   + sizeof (struct phi_arg_d) * len));
  phi->gsbase.code = GIMPLE_PHI;
  gimple_init_singleton (phi);
  phi->gimple_phi.nargs = len;
  phi->gimple_phi.capacity = capacity;
  if (!var)
    ;
  else if (TREE_CODE (var) == SSA_NAME)
    gimple_phi_set_result (phi, var);
  else
    gimple_phi_set_result (phi, make_ssa_name (var, phi));

  for (i = 0; i < capacity; i++)
    {
      use_operand_p  imm;

      gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION);
      imm = gimple_phi_arg_imm_use_ptr (phi, i);
      imm->use = gimple_phi_arg_def_ptr (phi, i);
      imm->prev = NULL;
      imm->next = NULL;
      imm->loc.stmt = phi;
    }

  return phi;
}