Beispiel #1
0
static inline tree *
gimple_ops (gimple gs)
{
  size_t off;
  off = gimple_ops_offset_[gimple_statement_structure (gs)];
  return (tree *) ((char *) gs + off);
}
Beispiel #2
0
tree
walk_gimple_op (gimple *stmt, walk_tree_fn callback_op,
		struct walk_stmt_info *wi)
{
  hash_set<tree> *pset = (wi) ? wi->pset : NULL;
  unsigned i;
  tree ret = NULL_TREE;

  switch (gimple_code (stmt))
    {
    case GIMPLE_ASSIGN:
      /* Walk the RHS operands.  If the LHS is of a non-renamable type or
         is a register variable, we may use a COMPONENT_REF on the RHS.  */
      if (wi)
	{
	  tree lhs = gimple_assign_lhs (stmt);
	  wi->val_only
	    = (is_gimple_reg_type (TREE_TYPE (lhs)) && !is_gimple_reg (lhs))
	      || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
	}

      for (i = 1; i < gimple_num_ops (stmt); i++)
	{
	  ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi,
			   pset);
	  if (ret)
	    return ret;
	}

      /* Walk the LHS.  If the RHS is appropriate for a memory, we
	 may use a COMPONENT_REF on the LHS.  */
      if (wi)
	{
          /* If the RHS is of a non-renamable type or is a register variable,
	     we may use a COMPONENT_REF on the LHS.  */
	  tree rhs1 = gimple_assign_rhs1 (stmt);
	  wi->val_only
	    = (is_gimple_reg_type (TREE_TYPE (rhs1)) && !is_gimple_reg (rhs1))
	      || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
	  wi->is_lhs = true;
	}

      ret = walk_tree (gimple_op_ptr (stmt, 0), callback_op, wi, pset);
      if (ret)
	return ret;

      if (wi)
	{
	  wi->val_only = true;
	  wi->is_lhs = false;
	}
      break;

    case GIMPLE_CALL:
      if (wi)
	{
	  wi->is_lhs = false;
	  wi->val_only = true;
	}

      ret = walk_tree (gimple_call_chain_ptr (as_a <gcall *> (stmt)),
		       callback_op, wi, pset);
      if (ret)
        return ret;

      ret = walk_tree (gimple_call_fn_ptr (stmt), callback_op, wi, pset);
      if (ret)
        return ret;

      for (i = 0; i < gimple_call_num_args (stmt); i++)
	{
	  if (wi)
	    wi->val_only
	      = is_gimple_reg_type (TREE_TYPE (gimple_call_arg (stmt, i)));
	  ret = walk_tree (gimple_call_arg_ptr (stmt, i), callback_op, wi,
			   pset);
	  if (ret)
	    return ret;
	}

      if (gimple_call_lhs (stmt))
	{
	  if (wi)
	    {
	      wi->is_lhs = true;
	      wi->val_only
		= is_gimple_reg_type (TREE_TYPE (gimple_call_lhs (stmt)));
	    }

	  ret = walk_tree (gimple_call_lhs_ptr (stmt), callback_op, wi, pset);
	  if (ret)
	    return ret;
	}

      if (wi)
	{
	  wi->is_lhs = false;
	  wi->val_only = true;
	}
      break;

    case GIMPLE_CATCH:
      ret = walk_tree (gimple_catch_types_ptr (as_a <gcatch *> (stmt)),
		       callback_op, wi, pset);
      if (ret)
	return ret;
      break;

    case GIMPLE_EH_FILTER:
      ret = walk_tree (gimple_eh_filter_types_ptr (stmt), callback_op, wi,
		       pset);
      if (ret)
	return ret;
      break;

    case GIMPLE_ASM:
      ret = walk_gimple_asm (as_a <gasm *> (stmt), callback_op, wi);
      if (ret)
	return ret;
      break;

    case GIMPLE_OMP_CONTINUE:
      {
	gomp_continue *cont_stmt = as_a <gomp_continue *> (stmt);
	ret = walk_tree (gimple_omp_continue_control_def_ptr (cont_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;

	ret = walk_tree (gimple_omp_continue_control_use_ptr (cont_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
      }
      break;

    case GIMPLE_OMP_CRITICAL:
      {
	gomp_critical *omp_stmt = as_a <gomp_critical *> (stmt);
	ret = walk_tree (gimple_omp_critical_name_ptr (omp_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
	ret = walk_tree (gimple_omp_critical_clauses_ptr (omp_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
      }
      break;

    case GIMPLE_OMP_ORDERED:
      {
	gomp_ordered *omp_stmt = as_a <gomp_ordered *> (stmt);
	ret = walk_tree (gimple_omp_ordered_clauses_ptr (omp_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
      }
      break;

    case GIMPLE_OMP_FOR:
      ret = walk_tree (gimple_omp_for_clauses_ptr (stmt), callback_op, wi,
		       pset);
      if (ret)
	return ret;
      for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
	{
	  ret = walk_tree (gimple_omp_for_index_ptr (stmt, i), callback_op,
			   wi, pset);
	  if (ret)
	    return ret;
	  ret = walk_tree (gimple_omp_for_initial_ptr (stmt, i), callback_op,
			   wi, pset);
	  if (ret)
	    return ret;
	  ret = walk_tree (gimple_omp_for_final_ptr (stmt, i), callback_op,
			   wi, pset);
	  if (ret)
	    return ret;
	  ret = walk_tree (gimple_omp_for_incr_ptr (stmt, i), callback_op,
			   wi, pset);
	  if (ret)
	    return ret;
	}
      break;

    case GIMPLE_OMP_PARALLEL:
      {
	gomp_parallel *omp_par_stmt = as_a <gomp_parallel *> (stmt);
	ret = walk_tree (gimple_omp_parallel_clauses_ptr (omp_par_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
	ret = walk_tree (gimple_omp_parallel_child_fn_ptr (omp_par_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
	ret = walk_tree (gimple_omp_parallel_data_arg_ptr (omp_par_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
      }
      break;

    case GIMPLE_OMP_TASK:
      ret = walk_tree (gimple_omp_task_clauses_ptr (stmt), callback_op,
		       wi, pset);
      if (ret)
	return ret;
      ret = walk_tree (gimple_omp_task_child_fn_ptr (stmt), callback_op,
		       wi, pset);
      if (ret)
	return ret;
      ret = walk_tree (gimple_omp_task_data_arg_ptr (stmt), callback_op,
		       wi, pset);
      if (ret)
	return ret;
      ret = walk_tree (gimple_omp_task_copy_fn_ptr (stmt), callback_op,
		       wi, pset);
      if (ret)
	return ret;
      ret = walk_tree (gimple_omp_task_arg_size_ptr (stmt), callback_op,
		       wi, pset);
      if (ret)
	return ret;
      ret = walk_tree (gimple_omp_task_arg_align_ptr (stmt), callback_op,
		       wi, pset);
      if (ret)
	return ret;
      break;

    case GIMPLE_OMP_SECTIONS:
      ret = walk_tree (gimple_omp_sections_clauses_ptr (stmt), callback_op,
		       wi, pset);
      if (ret)
	return ret;
      ret = walk_tree (gimple_omp_sections_control_ptr (stmt), callback_op,
		       wi, pset);
      if (ret)
	return ret;

      break;

    case GIMPLE_OMP_SINGLE:
      ret = walk_tree (gimple_omp_single_clauses_ptr (stmt), callback_op, wi,
		       pset);
      if (ret)
	return ret;
      break;

    case GIMPLE_OMP_TARGET:
      {
	gomp_target *omp_stmt = as_a <gomp_target *> (stmt);
	ret = walk_tree (gimple_omp_target_clauses_ptr (omp_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
	ret = walk_tree (gimple_omp_target_child_fn_ptr (omp_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
	ret = walk_tree (gimple_omp_target_data_arg_ptr (omp_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
      }
      break;

    case GIMPLE_OMP_TEAMS:
      ret = walk_tree (gimple_omp_teams_clauses_ptr (stmt), callback_op, wi,
		       pset);
      if (ret)
	return ret;
      break;

    case GIMPLE_OMP_ATOMIC_LOAD:
      {
	gomp_atomic_load *omp_stmt = as_a <gomp_atomic_load *> (stmt);
	ret = walk_tree (gimple_omp_atomic_load_lhs_ptr (omp_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
	ret = walk_tree (gimple_omp_atomic_load_rhs_ptr (omp_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
      }
      break;

    case GIMPLE_OMP_ATOMIC_STORE:
      {
	gomp_atomic_store *omp_stmt = as_a <gomp_atomic_store *> (stmt);
	ret = walk_tree (gimple_omp_atomic_store_val_ptr (omp_stmt),
			 callback_op, wi, pset);
	if (ret)
	  return ret;
      }
      break;

    case GIMPLE_TRANSACTION:
      ret = walk_tree (gimple_transaction_label_ptr (
			 as_a <gtransaction *> (stmt)),
		       callback_op, wi, pset);
      if (ret)
	return ret;
      break;

    case GIMPLE_OMP_RETURN:
      ret = walk_tree (gimple_omp_return_lhs_ptr (stmt), callback_op, wi,
		       pset);
      if (ret)
	return ret;
      break;

      /* Tuples that do not have operands.  */
    case GIMPLE_NOP:
    case GIMPLE_RESX:
    case GIMPLE_PREDICT:
      break;

    default:
      {
	enum gimple_statement_structure_enum gss;
	gss = gimple_statement_structure (stmt);
	if (gss == GSS_WITH_OPS || gss == GSS_WITH_MEM_OPS)
	  for (i = 0; i < gimple_num_ops (stmt); i++)
	    {
	      ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, pset);
	      if (ret)
		return ret;
	    }
      }
      break;
    }

  return NULL_TREE;
}