/* Miscellaneous SSA utility functions.
   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "rtl.h"
#include "tm_p.h"
#include "ggc.h"
#include "langhooks.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
#include "bitmap.h"
#include "pointer-set.h"
#include "tree-flow.h"
#include "tree-gimple.h"
#include "tree-inline.h"
#include "varray.h"
#include "timevar.h"
#include "hashtab.h"
#include "tree-dump.h"
#include "tree-pass.h"
#include "toplev.h"

/* Remove the corresponding arguments from the PHI nodes in E's
   destination block and redirect it to DEST.  Return redirected edge.
   The list of removed arguments is stored in PENDING_STMT (e).  */

edge
ssa_redirect_edge (edge e, basic_block dest)
{
  tree phi;
  tree list = NULL, *last = &list;
  tree src, dst, node;

  /* Remove the appropriate PHI arguments in E's destination block.  */
  for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
    {
      if (PHI_ARG_DEF (phi, e->dest_idx) == NULL_TREE)
	continue;

      src = PHI_ARG_DEF (phi, e->dest_idx);
      dst = PHI_RESULT (phi);
      node = build_tree_list (dst, src);
      *last = node;
      last = &TREE_CHAIN (node);
    }

  e = redirect_edge_succ_nodup (e, dest);
  PENDING_STMT (e) = list;

  return e;
}

/* Add PHI arguments queued in PENDINT_STMT list on edge E to edge
   E->dest.  */

void
flush_pending_stmts (edge e)
{
  tree phi, arg;

  if (!PENDING_STMT (e))
    return;

  for (phi = phi_nodes (e->dest), arg = PENDING_STMT (e);
       phi;
       phi = PHI_CHAIN (phi), arg = TREE_CHAIN (arg))
    {
      tree def = TREE_VALUE (arg);
      add_phi_arg (phi, def, e);
    }

  PENDING_STMT (e) = NULL;
}

/* Return true if SSA_NAME is malformed and mark it visited.

   IS_VIRTUAL is true if this SSA_NAME was found inside a virtual
      operand.  */

static bool
verify_ssa_name (tree ssa_name, bool is_virtual)
{
  if (TREE_CODE (ssa_name) != SSA_NAME)
    {
      error ("expected an SSA_NAME object");
      return true;
    }

  if (TREE_TYPE (ssa_name) != TREE_TYPE (SSA_NAME_VAR (ssa_name)))
    {
      error ("type mismatch between an SSA_NAME and its symbol");
      return true;
    }

  if (SSA_NAME_IN_FREE_LIST (ssa_name))
    {
      error ("found an SSA_NAME that had been released into the free pool");
      return true;
    }

  if (is_virtual && is_gimple_reg (ssa_name))
    {
      error ("found a virtual definition for a GIMPLE register");
      return true;
    }

  if (!is_virtual && !is_gimple_reg (ssa_name))
    {
      error ("found a real definition for a non-register");
      return true;
    }

  if (is_virtual && var_ann (SSA_NAME_VAR (ssa_name)) 
      && get_subvars_for_var (SSA_NAME_VAR (ssa_name)) != NULL)
    {
      error ("found real variable when subvariables should have appeared");
      return true;
    }

  return false;
}


/* Return true if the definition of SSA_NAME at block BB is malformed.

   STMT is the statement where SSA_NAME is created.

   DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
      version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
      it means that the block in that array slot contains the
      definition of SSA_NAME.

   IS_VIRTUAL is true if SSA_NAME is created by a V_MAY_DEF or a
      V_MUST_DEF.  */

static bool
verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
	    tree stmt, bool is_virtual)
{
  if (verify_ssa_name (ssa_name, is_virtual))
    goto err;

  if (definition_block[SSA_NAME_VERSION (ssa_name)])
    {
      error ("SSA_NAME created in two different blocks %i and %i",
	     definition_block[SSA_NAME_VERSION (ssa_name)]->index, bb->index);
      goto err;
    }

  definition_block[SSA_NAME_VERSION (ssa_name)] = bb;

  if (SSA_NAME_DEF_STMT (ssa_name) != stmt)
    {
      error ("SSA_NAME_DEF_STMT is wrong");
      fprintf (stderr, "Expected definition statement:\n");
      print_generic_stmt (stderr, SSA_NAME_DEF_STMT (ssa_name), TDF_VOPS);
      fprintf (stderr, "\nActual definition statement:\n");
      print_generic_stmt (stderr, stmt, TDF_VOPS);
      goto err;
    }

  return false;

err:
  fprintf (stderr, "while verifying SSA_NAME ");
  print_generic_expr (stderr, ssa_name, 0);
  fprintf (stderr, " in statement\n");
  print_generic_stmt (stderr, stmt, TDF_VOPS);

  return true;
}


/* Return true if the use of SSA_NAME at statement STMT in block BB is
   malformed.

   DEF_BB is the block where SSA_NAME was found to be created.

   IDOM contains immediate dominator information for the flowgraph.

   CHECK_ABNORMAL is true if the caller wants to check whether this use
      is flowing through an abnormal edge (only used when checking PHI
      arguments).

   IS_VIRTUAL is true if SSA_NAME is created by a V_MAY_DEF or a
      V_MUST_DEF.
   
   If NAMES_DEFINED_IN_BB is not NULL, it contains a bitmap of ssa names
     that are defined before STMT in basic block BB.  */

static bool
verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
	    tree stmt, bool check_abnormal, bool is_virtual,
	    bitmap names_defined_in_bb)
{
  bool err = false;
  tree ssa_name = USE_FROM_PTR (use_p);

  err = verify_ssa_name (ssa_name, is_virtual);

  if (!TREE_VISITED (ssa_name))
    if (verify_imm_links (stderr, ssa_name))
      err = true;

  TREE_VISITED (ssa_name) = 1;

  if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (ssa_name))
      && default_def (SSA_NAME_VAR (ssa_name)) == ssa_name)
    ; /* Default definitions have empty statements.  Nothing to do.  */
  else if (!def_bb)
    {
      error ("missing definition");
      err = true;
    }
  else if (bb != def_bb
	   && !dominated_by_p (CDI_DOMINATORS, bb, def_bb))
    {
      error ("definition in block %i does not dominate use in block %i",
	     def_bb->index, bb->index);
      err = true;
    }
  else if (bb == def_bb
	   && names_defined_in_bb != NULL
	   && !bitmap_bit_p (names_defined_in_bb, SSA_NAME_VERSION (ssa_name)))
    {
      error ("definition in block %i follows the use", def_bb->index);
      err = true;
    }

  if (check_abnormal
      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
    {
      error ("SSA_NAME_OCCURS_IN_ABNORMAL_PHI should be set");
      err = true;
    }

  /* Make sure the use is in an appropriate list by checking the previous 
     element to make sure it's the same.  */
  if (use_p->prev == NULL)
    {
      error ("no immediate_use list");
      err = true;
    }
  else
    {
      tree listvar ;
      if (use_p->prev->use == NULL)
	listvar = use_p->prev->stmt;
      else
	listvar = USE_FROM_PTR (use_p->prev);
      if (listvar != ssa_name)
        {
	  error ("wrong immediate use list");
	  err = true;
	}
    }

  if (err)
    {
      fprintf (stderr, "for SSA_NAME: ");
      print_generic_expr (stderr, ssa_name, TDF_VOPS);
      fprintf (stderr, " in statement:\n");
      print_generic_stmt (stderr, stmt, TDF_VOPS);
    }

  return err;
}


/* Return true if any of the arguments for PHI node PHI at block BB is
   malformed.

   DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME version
      numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set, it means that the
      block in that array slot contains the definition of SSA_NAME.  */

static bool
verify_phi_args (tree phi, basic_block bb, basic_block *definition_block)
{
  edge e;
  bool err = false;
  unsigned i, phi_num_args = PHI_NUM_ARGS (phi);

  if (EDGE_COUNT (bb->preds) != phi_num_args)
    {
      error ("incoming edge count does not match number of PHI arguments");
      err = true;
      goto error;
    }

  for (i = 0; i < phi_num_args; i++)
    {
      use_operand_p op_p = PHI_ARG_DEF_PTR (phi, i);
      tree op = USE_FROM_PTR (op_p);


      e = EDGE_PRED (bb, i);

      if (op == NULL_TREE)
	{
	  error ("PHI argument is missing for edge %d->%d",
	         e->src->index,
		 e->dest->index);
	  err = true;
	  goto error;
	}

      if (TREE_CODE (op) != SSA_NAME && !is_gimple_min_invariant (op))
	{
	  error ("PHI argument is not SSA_NAME, or invariant");
	  err = true;
	}

      if (TREE_CODE (op) == SSA_NAME)
	err = verify_use (e->src, definition_block[SSA_NAME_VERSION (op)], op_p,
			  phi, e->flags & EDGE_ABNORMAL,
			  !is_gimple_reg (PHI_RESULT (phi)),
			  NULL);

      if (e->dest != bb)
	{
	  error ("wrong edge %d->%d for PHI argument",
	         e->src->index, e->dest->index);
	  err = true;
	}

      if (err)
	{
	  fprintf (stderr, "PHI argument\n");
	  print_generic_stmt (stderr, op, TDF_VOPS);
	  goto error;
	}
    }

error:
  if (err)
    {
      fprintf (stderr, "for PHI node\n");
      print_generic_stmt (stderr, phi, TDF_VOPS);
    }


  return err;
}


static void
verify_flow_insensitive_alias_info (void)
{
  tree var;
  bitmap visited = BITMAP_ALLOC (NULL);
  referenced_var_iterator rvi;

  FOR_EACH_REFERENCED_VAR (var, rvi)
    {
      size_t j;
      var_ann_t ann;
      VEC(tree,gc) *may_aliases;
      tree alias;

      ann = var_ann (var);
      may_aliases = ann->may_aliases;

      for (j = 0; VEC_iterate (tree, may_aliases, j, alias); j++)
	{
	  bitmap_set_bit (visited, DECL_UID (alias));

	  if (!may_be_aliased (alias))
	    {
	      error ("non-addressable variable inside an alias set");
	      debug_variable (alias);
	      goto err;
	    }
	}
    }

  FOR_EACH_REFERENCED_VAR (var, rvi)
    {
      var_ann_t ann;
      ann = var_ann (var);

      if (!MTAG_P (var)
	  && ann->is_aliased
	  && !bitmap_bit_p (visited, DECL_UID (var)))
	{
	  error ("addressable variable that is aliased but is not in any alias set");
	  goto err;
	}
    }

  BITMAP_FREE (visited);
  return;

err:
  debug_variable (var);
  internal_error ("verify_flow_insensitive_alias_info failed");
}


static void
verify_flow_sensitive_alias_info (void)
{
  size_t i;
  tree ptr;

  for (i = 1; i < num_ssa_names; i++)
    {
      tree var;
      var_ann_t ann;
      struct ptr_info_def *pi;
 

      ptr = ssa_name (i);
      if (!ptr)
	continue;

      /* We only care for pointers that are actually referenced in the
	 program.  */
      if (!POINTER_TYPE_P (TREE_TYPE (ptr)) || !TREE_VISITED (ptr))
	continue;

      /* RESULT_DECL is special.  If it's a GIMPLE register, then it
	 is only written-to only once in the return statement.
	 Otherwise, aggregate RESULT_DECLs may be written-to more than
	 once in virtual operands.  */
      var = SSA_NAME_VAR (ptr);
      if (TREE_CODE (var) == RESULT_DECL
	  && is_gimple_reg (ptr))
	continue;

      pi = SSA_NAME_PTR_INFO (ptr);
      if (pi == NULL)
	continue;

      ann = var_ann (var);
      if (pi->is_dereferenced && !pi->name_mem_tag && !ann->symbol_mem_tag)
	{
	  error ("dereferenced pointers should have a name or a symbol tag");
	  goto err;
	}

      if (pi->name_mem_tag
	  && (pi->pt_vars == NULL || bitmap_empty_p (pi->pt_vars)))
	{
	  error ("pointers with a memory tag, should have points-to sets");
	  goto err;
	}

      if (pi->value_escapes_p
	  && pi->name_mem_tag
	  && !is_call_clobbered (pi->name_mem_tag))
	{
	  error ("pointer escapes but its name tag is not call-clobbered");
	  goto err;
	}
    }

  return;

err:
  debug_variable (ptr);
  internal_error ("verify_flow_sensitive_alias_info failed");
}

DEF_VEC_P (bitmap);
DEF_VEC_ALLOC_P (bitmap,heap);

/* Verify that all name tags have different points to sets.
   This algorithm takes advantage of the fact that every variable with the
   same name tag must have the same points-to set. 
   So we check a single variable for each name tag, and verify that its
   points-to set is different from every other points-to set for other name
   tags.

   Additionally, given a pointer P_i with name tag NMT and symbol tag
   SMT, this function verified the alias set of SMT is a superset of
   the alias set of NMT.  */

static void
verify_name_tags (void)
{
  size_t i;  
  size_t j;
  bitmap first, second;  
  VEC(tree,heap) *name_tag_reps = NULL;
  VEC(bitmap,heap) *pt_vars_for_reps = NULL;
  bitmap type_aliases = BITMAP_ALLOC (NULL);

  /* First we compute the name tag representatives and their points-to sets.  */
  for (i = 0; i < num_ssa_names; i++)
    {
      struct ptr_info_def *pi;
      tree smt, ptr = ssa_name (i);

      if (ptr == NULL_TREE)
	continue;
      
      pi = SSA_NAME_PTR_INFO (ptr);

      if (!TREE_VISITED (ptr) 
	  || !POINTER_TYPE_P (TREE_TYPE (ptr)) 
	  || !pi
	  || !pi->name_mem_tag 
	  || TREE_VISITED (pi->name_mem_tag))
	continue;

      TREE_VISITED (pi->name_mem_tag) = 1;

      if (pi->pt_vars == NULL)
	continue;

      VEC_safe_push (tree, heap, name_tag_reps, ptr);
      VEC_safe_push (bitmap, heap, pt_vars_for_reps, pi->pt_vars);

      /* Verify that alias set of PTR's symbol tag is a superset of the
	 alias set of PTR's name tag.  */
      smt = var_ann (SSA_NAME_VAR (ptr))->symbol_mem_tag;
      if (smt)
	{
	  size_t i;
	  VEC(tree,gc) *aliases = var_ann (smt)->may_aliases;
	  tree alias;

	  bitmap_clear (type_aliases);
	  for (i = 0; VEC_iterate (tree, aliases, i, alias); i++)
	    bitmap_set_bit (type_aliases, DECL_UID (alias));

	  /* When grouping, we may have added PTR's symbol tag into the
	     alias set of PTR's name tag.  To prevent a false
	     positive, pretend that SMT is in its own alias set.  */
	  bitmap_set_bit (type_aliases, DECL_UID (smt));

	  if (bitmap_equal_p (type_aliases, pi->pt_vars))
	    continue;

	  if (!bitmap_intersect_compl_p (type_aliases, pi->pt_vars))
	    {
	      error ("alias set of a pointer's symbol tag should be a superset of the corresponding name tag");
	      debug_variable (smt);
	      debug_variable (pi->name_mem_tag);
	      goto err;
	    }
	}
    }
  
  /* Now compare all the representative bitmaps with all other representative
     bitmaps, to verify that they are all different.  */
  for (i = 0; VEC_iterate (bitmap, pt_vars_for_reps, i, first); i++)
    {
       for (j = i + 1; VEC_iterate (bitmap, pt_vars_for_reps, j, second); j++)
	 { 
	   if (bitmap_equal_p (first, second))
	     {
	       error ("two different pointers with identical points-to sets but different name tags");
	       debug_variable (VEC_index (tree, name_tag_reps, j));
	       goto err;
	     }
	 }
    }

  /* Lastly, clear out the visited flags.  */
  for (i = 0; i < num_ssa_names; i++)
    {
      if (ssa_name (i))
	{
	  tree ptr = ssa_name (i);
	  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
	  if (!TREE_VISITED (ptr) 
	      || !POINTER_TYPE_P (TREE_TYPE (ptr)) 
	      || !pi
	      || !pi->name_mem_tag)
	    continue;
	  TREE_VISITED (pi->name_mem_tag) = 0;
	}
    } 

  /* We do not have to free the bitmaps or trees in the vectors, as
     they are not owned by us.  */
  VEC_free (bitmap, heap, pt_vars_for_reps);
  VEC_free (tree, heap, name_tag_reps);
  BITMAP_FREE (type_aliases);
  return;
  
err:
  debug_variable (VEC_index (tree, name_tag_reps, i));
  internal_error ("verify_name_tags failed");
}


/* Verify the consistency of call clobbering information.  */
static void
verify_call_clobbering (void)
{
  unsigned int i;
  bitmap_iterator bi;
  tree var;
  referenced_var_iterator rvi;

  /* At all times, the result of the DECL_CALL_CLOBBERED flag should
     match the result of the call_clobbered_vars bitmap.  Verify both
     that everything in call_clobbered_vars is marked
     DECL_CALL_CLOBBERED, and that everything marked
     DECL_CALL_CLOBBERED is in call_clobbered_vars.  */
  EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
    {
      var = referenced_var (i);
      if (!MTAG_P (var) && !DECL_CALL_CLOBBERED (var))
	{
	  error ("variable in call_clobbered_vars but not marked DECL_CALL_CLOBBERED");
	  debug_variable (var);
	  goto err;
	}
    }
  FOR_EACH_REFERENCED_VAR (var, rvi)
    {
      if (!MTAG_P (var) && DECL_CALL_CLOBBERED (var)
	  && !bitmap_bit_p (call_clobbered_vars, DECL_UID (var)))
	{
	  error ("variable marked DECL_CALL_CLOBBERED but not in call_clobbered_vars bitmap.");
	  debug_variable (var);
	  goto err;
	}
    }
  return;

 err:
    internal_error ("verify_call_clobbering failed");
}

/* Verify the consistency of aliasing information.  */

static void
verify_alias_info (void)
{
  verify_flow_sensitive_alias_info ();
  verify_name_tags ();
  verify_call_clobbering ();
  verify_flow_insensitive_alias_info ();
}


/* Verify common invariants in the SSA web.
   TODO: verify the variable annotations.  */

void
verify_ssa (bool check_modified_stmt)
{
  size_t i;
  basic_block bb;
  basic_block *definition_block = XCNEWVEC (basic_block, num_ssa_names);
  ssa_op_iter iter;
  tree op;
  enum dom_state orig_dom_state = dom_computed[CDI_DOMINATORS];
  bitmap names_defined_in_bb = BITMAP_ALLOC (NULL);

  gcc_assert (!need_ssa_update_p ());

  verify_stmts ();

  timevar_push (TV_TREE_SSA_VERIFY);

  /* Keep track of SSA names present in the IL.  */
  for (i = 1; i < num_ssa_names; i++)
    {
      tree name = ssa_name (i);
      if (name)
	{
	  tree stmt;
	  TREE_VISITED (name) = 0;

	  stmt = SSA_NAME_DEF_STMT (name);
	  if (!IS_EMPTY_STMT (stmt))
	    {
	      basic_block bb = bb_for_stmt (stmt);
	      verify_def (bb, definition_block,
			  name, stmt, !is_gimple_reg (name));

	    }
	}
    }

  calculate_dominance_info (CDI_DOMINATORS);

  /* Now verify all the uses and make sure they agree with the definitions
     found in the previous pass.  */
  FOR_EACH_BB (bb)
    {
      edge e;
      tree phi;
      edge_iterator ei;
      block_stmt_iterator bsi;

      /* Make sure that all edges have a clear 'aux' field.  */
      FOR_EACH_EDGE (e, ei, bb->preds)
	{
	  if (e->aux)
	    {
	      error ("AUX pointer initialized for edge %d->%d", e->src->index,
		      e->dest->index);
	      goto err;
	    }
	}

      /* Verify the arguments for every PHI node in the block.  */
      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
	{
	  if (verify_phi_args (phi, bb, definition_block))
	    goto err;
	  bitmap_set_bit (names_defined_in_bb,
			  SSA_NAME_VERSION (PHI_RESULT (phi)));
	}

      /* Now verify all the uses and vuses in every statement of the block.  */
      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
	{
	  tree stmt = bsi_stmt (bsi);
	  use_operand_p use_p;

	  if (check_modified_stmt && stmt_modified_p (stmt))
	    {
	      error ("stmt (%p) marked modified after optimization pass : ",
		     (void *)stmt);
	      print_generic_stmt (stderr, stmt, TDF_VOPS);
	      goto err;
	    }

	  if (TREE_CODE (stmt) == MODIFY_EXPR
	      && TREE_CODE (TREE_OPERAND (stmt, 0)) != SSA_NAME)
	    {
	      tree lhs, base_address;

	      lhs = TREE_OPERAND (stmt, 0);
	      base_address = get_base_address (lhs);

	      if (base_address
		  && SSA_VAR_P (base_address)
		  && ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF|SSA_OP_VMUSTDEF))
		{
		  error ("statement makes a memory store, but has no "
			 "V_MAY_DEFS nor V_MUST_DEFS");
		  print_generic_stmt (stderr, stmt, TDF_VOPS);
		  goto err;
		}
	    }

	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
	                            SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
	    {
	      op = USE_FROM_PTR (use_p);
	      if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
			      use_p, stmt, false, !is_gimple_reg (op),
			      names_defined_in_bb))
		goto err;
	    }

	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
	    bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
	}

      bitmap_clear (names_defined_in_bb);
    }

  /* Finally, verify alias information.  */
  verify_alias_info ();

  free (definition_block);

  /* Restore the dominance information to its prior known state, so
     that we do not perturb the compiler's subsequent behavior.  */
  if (orig_dom_state == DOM_NONE)
    free_dominance_info (CDI_DOMINATORS);
  else
    dom_computed[CDI_DOMINATORS] = orig_dom_state;
  
  BITMAP_FREE (names_defined_in_bb);
  timevar_pop (TV_TREE_SSA_VERIFY);
  return;

err:
  internal_error ("verify_ssa failed");
}

/* Return true if the uid in both int tree maps are equal.  */

int
int_tree_map_eq (const void *va, const void *vb)
{
  const struct int_tree_map *a = (const struct int_tree_map *) va;
  const struct int_tree_map *b = (const struct int_tree_map *) vb;
  return (a->uid == b->uid);
}

/* Hash a UID in a int_tree_map.  */

unsigned int
int_tree_map_hash (const void *item)
{
  return ((const struct int_tree_map *)item)->uid;
}


/* Initialize global DFA and SSA structures.  */

void
init_tree_ssa (void)
{
  referenced_vars = htab_create_ggc (20, int_tree_map_hash, 
				     int_tree_map_eq, NULL);
  default_defs = htab_create_ggc (20, int_tree_map_hash, int_tree_map_eq, NULL);
  call_clobbered_vars = BITMAP_ALLOC (NULL);
  addressable_vars = BITMAP_ALLOC (NULL);
  init_alias_heapvars ();
  init_ssanames ();
  init_phinodes ();
  global_var = NULL_TREE;
  aliases_computed_p = false;
}


/* Deallocate memory associated with SSA data structures for FNDECL.  */

void
delete_tree_ssa (void)
{
  size_t i;
  basic_block bb;
  block_stmt_iterator bsi;
  referenced_var_iterator rvi;
  tree var;

  /* Release any ssa_names still in use.  */
  for (i = 0; i < num_ssa_names; i++)
    {
      tree var = ssa_name (i);
      if (var && TREE_CODE (var) == SSA_NAME)
        {
	  SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var));
	  SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var));
	}
      release_ssa_name (var);
    }

  /* Remove annotations from every tree in the function.  */
  FOR_EACH_BB (bb)
    {
      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
	{
	  tree stmt = bsi_stmt (bsi);
	  stmt_ann_t ann = get_stmt_ann (stmt);

	  free_ssa_operands (&ann->operands);
	  ann->addresses_taken = 0;
	  mark_stmt_modified (stmt);
	}
      set_phi_nodes (bb, NULL);
    }

  /* Remove annotations from every referenced variable.  */
  FOR_EACH_REFERENCED_VAR (var, rvi)
    {
      ggc_free (var->common.ann);
      var->common.ann = NULL;
    }
  htab_delete (referenced_vars);
  referenced_vars = NULL;

  fini_ssanames ();
  fini_phinodes ();

  global_var = NULL_TREE;
  
  htab_delete (default_defs);
  BITMAP_FREE (call_clobbered_vars);
  call_clobbered_vars = NULL;
  BITMAP_FREE (addressable_vars);
  addressable_vars = NULL;
  modified_noreturn_calls = NULL;
  aliases_computed_p = false;
  delete_alias_heapvars ();
  gcc_assert (!need_ssa_update_p ());
}


/* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a
   useless type conversion, otherwise return false.  */

bool
tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
{
  if (inner_type == outer_type)
    return true;

  /* Changes in machine mode are never useless conversions.  */
  if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type))
    return false;

  /* If the inner and outer types are effectively the same, then
     strip the type conversion and enter the equivalence into
     the table.  */
  if (lang_hooks.types_compatible_p (inner_type, outer_type))
    return true;

  /* If both types are pointers and the outer type is a (void *), then
     the conversion is not necessary.  The opposite is not true since
     that conversion would result in a loss of information if the
     equivalence was used.  Consider an indirect function call where
     we need to know the exact type of the function to correctly
     implement the ABI.  */
  else if (POINTER_TYPE_P (inner_type)
           && POINTER_TYPE_P (outer_type)
	   && TYPE_REF_CAN_ALIAS_ALL (inner_type)
	      == TYPE_REF_CAN_ALIAS_ALL (outer_type)
	   && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
    return true;

  /* Don't lose casts between pointers to volatile and non-volatile
     qualified types.  Doing so would result in changing the semantics
     of later accesses.  */
  else if (POINTER_TYPE_P (inner_type)
           && POINTER_TYPE_P (outer_type)
	   && TYPE_VOLATILE (TREE_TYPE (outer_type))
	      != TYPE_VOLATILE (TREE_TYPE (inner_type)))
    return false;

  /* APPLE LOCAL begin mainline */
  /* Do not lose casts from const qualified to non-const                                 
     qualified.  */
  else if (POINTER_TYPE_P (inner_type)
           && POINTER_TYPE_P (outer_type)
	   && (TYPE_READONLY (TREE_TYPE (outer_type))
	       != TYPE_READONLY (TREE_TYPE (inner_type)))
	   && TYPE_READONLY (TREE_TYPE (inner_type)))
    return false;
  /* APPLE LOCAL end mainline */

  /* Pointers/references are equivalent if their pointed to types
     are effectively the same.  This allows to strip conversions between
     pointer types with different type qualifiers.  */
  else if (POINTER_TYPE_P (inner_type)
           && POINTER_TYPE_P (outer_type)
	   && TYPE_REF_CAN_ALIAS_ALL (inner_type)
	      == TYPE_REF_CAN_ALIAS_ALL (outer_type)
           && lang_hooks.types_compatible_p (TREE_TYPE (inner_type),
					     TREE_TYPE (outer_type)))
    return true;

  /* If both the inner and outer types are integral types, then the
     conversion is not necessary if they have the same mode and
     signedness and precision, and both or neither are boolean.  Some
     code assumes an invariant that boolean types stay boolean and do
     not become 1-bit bit-field types.  Note that types with precision
     not using all bits of the mode (such as bit-field types in C)
     mean that testing of precision is necessary.  */
  else if (INTEGRAL_TYPE_P (inner_type)
           && INTEGRAL_TYPE_P (outer_type)
	   && TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
	   && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type)
	   && simple_cst_equal (TYPE_MAX_VALUE (inner_type), TYPE_MAX_VALUE (outer_type))
	   && simple_cst_equal (TYPE_MIN_VALUE (inner_type), TYPE_MIN_VALUE (outer_type)))
    {
      bool first_boolean = (TREE_CODE (inner_type) == BOOLEAN_TYPE);
      bool second_boolean = (TREE_CODE (outer_type) == BOOLEAN_TYPE);
      if (first_boolean == second_boolean)
	return true;
    }

  /* Recurse for complex types.  */
  else if (TREE_CODE (inner_type) == COMPLEX_TYPE
	   && TREE_CODE (outer_type) == COMPLEX_TYPE
	   && tree_ssa_useless_type_conversion_1 (TREE_TYPE (outer_type),
						  TREE_TYPE (inner_type)))
    return true;

  return false;
}

/* Return true if EXPR is a useless type conversion, otherwise return
   false.  */

bool
tree_ssa_useless_type_conversion (tree expr)
{
  /* If we have an assignment that merely uses a NOP_EXPR to change
     the top of the RHS to the type of the LHS and the type conversion
     is "safe", then strip away the type conversion so that we can
     enter LHS = RHS into the const_and_copies table.  */
  if (TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR
      || TREE_CODE (expr) == VIEW_CONVERT_EXPR
      || TREE_CODE (expr) == NON_LVALUE_EXPR)
    return tree_ssa_useless_type_conversion_1 (TREE_TYPE (expr),
					       TREE_TYPE (TREE_OPERAND (expr,
									0)));


  return false;
}

/* Returns true if statement STMT may read memory.  */

bool
stmt_references_memory_p (tree stmt)
{
  stmt_ann_t ann = stmt_ann (stmt);

  if (ann->has_volatile_ops)
    return true;

  return (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS));
}

/* Internal helper for walk_use_def_chains.  VAR, FN and DATA are as
   described in walk_use_def_chains.
   
   VISITED is a pointer set used to mark visited SSA_NAMEs to avoid
      infinite loops.  We used to have a bitmap for this to just mark
      SSA versions we had visited.  But non-sparse bitmaps are way too
      expensive, while sparse bitmaps may cause quadratic behavior.

   IS_DFS is true if the caller wants to perform a depth-first search
      when visiting PHI nodes.  A DFS will visit each PHI argument and
      call FN after each one.  Otherwise, all the arguments are
      visited first and then FN is called with each of the visited
      arguments in a separate pass.  */

static bool
walk_use_def_chains_1 (tree var, walk_use_def_chains_fn fn, void *data,
		       struct pointer_set_t *visited, bool is_dfs)
{
  tree def_stmt;

  if (pointer_set_insert (visited, var))
    return false;

  def_stmt = SSA_NAME_DEF_STMT (var);

  if (TREE_CODE (def_stmt) != PHI_NODE)
    {
      /* If we reached the end of the use-def chain, call FN.  */
      return fn (var, def_stmt, data);
    }
  else
    {
      int i;

      /* When doing a breadth-first search, call FN before following the
	 use-def links for each argument.  */
      if (!is_dfs)
	for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
	  if (fn (PHI_ARG_DEF (def_stmt, i), def_stmt, data))
	    return true;

      /* Follow use-def links out of each PHI argument.  */
      for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
	{
	  tree arg = PHI_ARG_DEF (def_stmt, i);
	  if (TREE_CODE (arg) == SSA_NAME
	      && walk_use_def_chains_1 (arg, fn, data, visited, is_dfs))
	    return true;
	}

      /* When doing a depth-first search, call FN after following the
	 use-def links for each argument.  */
      if (is_dfs)
	for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
	  if (fn (PHI_ARG_DEF (def_stmt, i), def_stmt, data))
	    return true;
    }
  
  return false;
}
  


/* Walk use-def chains starting at the SSA variable VAR.  Call
   function FN at each reaching definition found.  FN takes three
   arguments: VAR, its defining statement (DEF_STMT) and a generic
   pointer to whatever state information that FN may want to maintain
   (DATA).  FN is able to stop the walk by returning true, otherwise
   in order to continue the walk, FN should return false.  

   Note, that if DEF_STMT is a PHI node, the semantics are slightly
   different.  The first argument to FN is no longer the original
   variable VAR, but the PHI argument currently being examined.  If FN
   wants to get at VAR, it should call PHI_RESULT (PHI).

   If IS_DFS is true, this function will:

	1- walk the use-def chains for all the PHI arguments, and,
	2- call (*FN) (ARG, PHI, DATA) on all the PHI arguments.

   If IS_DFS is false, the two steps above are done in reverse order
   (i.e., a breadth-first search).  */


void
walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data,
                     bool is_dfs)
{
  tree def_stmt;

  gcc_assert (TREE_CODE (var) == SSA_NAME);

  def_stmt = SSA_NAME_DEF_STMT (var);

  /* We only need to recurse if the reaching definition comes from a PHI
     node.  */
  if (TREE_CODE (def_stmt) != PHI_NODE)
    (*fn) (var, def_stmt, data);
  else
    {
      struct pointer_set_t *visited = pointer_set_create ();
      walk_use_def_chains_1 (var, fn, data, visited, is_dfs);
      pointer_set_destroy (visited);
    }
}


/* Emit warnings for uninitialized variables.  This is done in two passes.

   The first pass notices real uses of SSA names with default definitions.
   Such uses are unconditionally uninitialized, and we can be certain that
   such a use is a mistake.  This pass is run before most optimizations,
   so that we catch as many as we can.

   The second pass follows PHI nodes to find uses that are potentially
   uninitialized.  In this case we can't necessarily prove that the use
   is really uninitialized.  This pass is run after most optimizations,
   so that we thread as many jumps and possible, and delete as much dead
   code as possible, in order to reduce false positives.  We also look
   again for plain uninitialized variables, since optimization may have
   changed conditionally uninitialized to unconditionally uninitialized.  */

/* Emit a warning for T, an SSA_NAME, being uninitialized.  The exact
   warning text is in MSGID and LOCUS may contain a location or be null.  */

static void
warn_uninit (tree t, const char *gmsgid, void *data)
{
  tree var = SSA_NAME_VAR (t);
  tree def = SSA_NAME_DEF_STMT (t);
  tree context = (tree) data;
  location_t *locus, *fun_locus;

  /* Default uses (indicated by an empty definition statement),
     are uninitialized.  */
  if (!IS_EMPTY_STMT (def))
    return;

  /* Except for PARMs of course, which are always initialized.  */
  if (TREE_CODE (var) == PARM_DECL)
    return;

  /* Hard register variables get their initial value from the ether.  */
  if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
    return;

  /* TREE_NO_WARNING either means we already warned, or the front end
     wishes to suppress the warning.  */
  if (TREE_NO_WARNING (var))
    return;

  locus = (context != NULL && EXPR_HAS_LOCATION (context)
	   ? EXPR_LOCUS (context)
	   : &DECL_SOURCE_LOCATION (var));
  warning (0, gmsgid, locus, var);
  fun_locus = &DECL_SOURCE_LOCATION (cfun->decl);
  if (locus->file != fun_locus->file
      || locus->line < fun_locus->line
      || locus->line > cfun->function_end_locus.line)
    inform ("%J%qD was declared here", var, var);

  TREE_NO_WARNING (var) = 1;
}
   
/* Called via walk_tree, look for SSA_NAMEs that have empty definitions
   and warn about them.  */

static tree
warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data)
{
  tree t = *tp;

  switch (TREE_CODE (t))
    {
    case SSA_NAME:
      /* We only do data flow with SSA_NAMEs, so that's all we
	 can warn about.  */
      warn_uninit (t, "%H%qD is used uninitialized in this function", data);
      *walk_subtrees = 0;
      break;

    case REALPART_EXPR:
    case IMAGPART_EXPR:
      /* The total store transformation performed during gimplification
	 creates uninitialized variable uses.  If all is well, these will
	 be optimized away, so don't warn now.  */
      if (TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
	*walk_subtrees = 0;
      break;

    default:
      if (IS_TYPE_OR_DECL_P (t))
	*walk_subtrees = 0;
      break;
    }

  return NULL_TREE;
}

/* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
   and warn about them.  */

static void
warn_uninitialized_phi (tree phi)
{
  int i, n = PHI_NUM_ARGS (phi);

  /* Don't look at memory tags.  */
  if (!is_gimple_reg (PHI_RESULT (phi)))
    return;

  for (i = 0; i < n; ++i)
    {
      tree op = PHI_ARG_DEF (phi, i);
      if (TREE_CODE (op) == SSA_NAME)
	warn_uninit (op, "%H%qD may be used uninitialized in this function",
		     NULL);
    }
}

static unsigned int
execute_early_warn_uninitialized (void)
{
  block_stmt_iterator bsi;
  basic_block bb;

  FOR_EACH_BB (bb)
    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
      {
	tree context = bsi_stmt (bsi);
	walk_tree (bsi_stmt_ptr (bsi), warn_uninitialized_var,
		   context, NULL);
      }
  return 0;
}

static unsigned int
execute_late_warn_uninitialized (void)
{
  basic_block bb;
  tree phi;

  /* Re-do the plain uninitialized variable check, as optimization may have
     straightened control flow.  Do this first so that we don't accidentally
     get a "may be" warning when we'd have seen an "is" warning later.  */
  execute_early_warn_uninitialized ();

  FOR_EACH_BB (bb)
    for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
      warn_uninitialized_phi (phi);
  return 0;
}

static bool
gate_warn_uninitialized (void)
{
  return warn_uninitialized != 0;
}

struct tree_opt_pass pass_early_warn_uninitialized =
{
  NULL,					/* name */
  gate_warn_uninitialized,		/* gate */
  execute_early_warn_uninitialized,	/* execute */
  NULL,					/* sub */
  NULL,					/* next */
  0,					/* static_pass_number */
  0,					/* tv_id */
  PROP_ssa,				/* properties_required */
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  0,                                    /* todo_flags_finish */
  0				        /* letter */
};

struct tree_opt_pass pass_late_warn_uninitialized =
{
  NULL,					/* name */
  gate_warn_uninitialized,		/* gate */
  execute_late_warn_uninitialized,	/* execute */
  NULL,					/* sub */
  NULL,					/* next */
  0,					/* static_pass_number */
  0,					/* tv_id */
  PROP_ssa,				/* properties_required */
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  0,                                    /* todo_flags_finish */
  0				        /* letter */
};
	  
