/* APPLE LOCAL file loops-to-memset */
/*  Loops to memset.
    Copyright (C) 2004 Free Software Foundation, Inc.
    Contributed by Andrew Pinski <apinski@apple.com>.
  
    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, 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
#include "diagnostic.h"
#include "tree-flow.h"
#include "tree-dump.h"
#include "timevar.h"
#include "cfgloop.h"
#include "domwalk.h"
#include "params.h"
#include "tree-pass.h"
#include "flags.h"
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
#include "tree-chrec.h"
#include "tree-vectorizer.h"

/* MERGE FIXME 4709514 */
#if 0
static bool memset_debug_stats (struct loop *loop);
static bool memset_debug_details (struct loop *loop);

/* Function memset_analyze_data_refs.

   Find all the data references in the loop.

   Handle INDIRECT_REFs and one dimensional ARRAY_REFs 
   which base is really an array (not a pointer).

   This is different from vect_analyze_data_refs in tree-vectorizer.c as
   we handle unaligned data stores and we only handle data stores.  */

static bool
memset_analyze_data_refs (loop_vec_info loop_vinfo)
{
  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
  basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
  int nbbs = loop->num_nodes;
  block_stmt_iterator si;
  int j;
  struct data_reference *dr;
  
  if (memset_debug_details (NULL))
    fprintf (dump_file, "\n<<memset_analyze_data_refs>>\n");
  
  for (j = 0; j < nbbs; j++)
    {
      basic_block bb = bbs[j];
      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
	{
	  tree stmt = bsi_stmt (si);
	  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
	  v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
	  v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
	  vuse_optype vuses = STMT_VUSE_OPS (stmt);
	  varray_type *datarefs = NULL;
	  int nvuses, nv_may_defs, nv_must_defs;
	  tree memref = NULL;
	  tree array_base;
	  tree symbl;
	  
	  /* Assumption: there exists a data-ref in stmt, if and only if 
	     it has vuses/vdefs.  */
	  
	  if (!vuses && !v_may_defs && !v_must_defs)
	    continue;
	  
	  nvuses = NUM_VUSES (vuses);
	  nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
	  nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
	  
	  if (nvuses && (nv_may_defs || nv_must_defs))
	    {
	      if (memset_debug_details (NULL))
		{
		  fprintf (dump_file, "unexpected vdefs and vuses in stmt: ");
		  print_generic_expr (dump_file, stmt, TDF_SLIM);
		}
	      return false;
	    }
	  
	  if (TREE_CODE (stmt) != MODIFY_EXPR)
	    {
	      if (memset_debug_details (NULL))
		{
		  fprintf (dump_file, "unexpected vops in stmt: ");
		  print_generic_expr (dump_file, stmt, TDF_SLIM);
		}
	      return false;
	    }
	  
	  if (vuses)
	    {
	      if (memset_debug_details (NULL))
		{
		  fprintf (dump_file, "Memory access in the loop: ");
		  print_generic_expr (dump_file, stmt, TDF_SLIM);
		}
	      return false;
	    } 
	  else /* vdefs */
	    {
	      memref = TREE_OPERAND (stmt, 0);
	      datarefs = &(LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
	    }
	  
	  if (TREE_CODE (memref) == INDIRECT_REF)
            {
	      /* MERGE FIXME 4709514 */
	      abort ();
	      /* dr = vect_analyze_pointer_ref_access (memref, stmt, false); */
	      if (! dr)
		return false; 
	      symbl = DR_BASE_NAME (dr);	
            }
	  else if (TREE_CODE (memref) == ARRAY_REF)
	    {
	      tree base;		
	      array_base = TREE_OPERAND (memref, 0);
	      
	      if (TREE_CODE (array_base) == ARRAY_REF)
                {
		  if (memset_debug_stats (loop) || memset_debug_details (loop))
		    {
		      fprintf (dump_file, 
			       "not vectorized: multi-dimensional array.");
		      print_generic_expr (dump_file, stmt, TDF_SLIM);
		    }
		  return false;
                }
	      
	      dr = analyze_array (stmt, memref, false);
	      
	      /* Find the relevant symbol for aliasing purposes.  */	
	      base = DR_BASE_NAME (dr);
	      switch (TREE_CODE (base))	
		{
		case VAR_DECL:
		  symbl = base;
		  break;
		default:
		  if (memset_debug_stats (loop) 
		      || memset_debug_details (loop))
		    {
		      fprintf (dump_file,
			       "not transformed: unhandled struct/class field access ");
		      print_generic_expr (dump_file, stmt, TDF_SLIM);
		    }
		  return false;
		} /* switch */
	    }
	  else
	    {
	      if (memset_debug_stats (loop) || memset_debug_details (loop))
		{
		  fprintf (dump_file, "not transformed: unhandled data ref: ");
		  print_generic_expr (dump_file, stmt, TDF_SLIM);
		}
	      return false;
	    }
		
	  /* Find and record the memtag assigned to this data-ref.  */
	  if (TREE_CODE (symbl) == VAR_DECL 
	      || (TREE_CODE (symbl) == COMPONENT_REF 
		  && TREE_CODE (TREE_OPERAND (symbl, 0)) == VAR_DECL))
	    STMT_VINFO_MEMTAG (stmt_info) = symbl;
	  else if (TREE_CODE (symbl) == SSA_NAME)
	    {
	      tree tag;
	      symbl = SSA_NAME_VAR (symbl);
	      tag = get_var_ann (symbl)->type_mem_tag;
	      if (!tag)
		{
		  tree ptr = TREE_OPERAND (memref, 0);
		  if (TREE_CODE (ptr) == SSA_NAME)
		    tag = get_var_ann (SSA_NAME_VAR (ptr))->type_mem_tag;
		}
	      if (!tag)
		{
		  if (memset_debug_stats (loop) || memset_debug_details (loop))
		    fprintf (dump_file, "not vectorized: no memtag for ref.");
		  return false;
		}
	      STMT_VINFO_MEMTAG (stmt_info) = tag;
	    }
	  else
	    {
	      if (memset_debug_stats (loop) || memset_debug_details (loop))
		{
		  fprintf (dump_file, "not vectorized: unsupported data-ref: ");
		  print_generic_expr (dump_file, memref, TDF_SLIM);
		}
	      return false;
	    }
	  
	  VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
	  STMT_VINFO_DATA_REF (stmt_info) = dr;
	}
    }
  
  return true;
}

/* Function memset_analyze_loop_with_symbolic_num_of_iters.

   In case the number of iterations that LOOP iterates in unknown at compile 
   time, an epilog loop will be generated, and the loop induction variables 
   (IVs) will be "advanced" to the value they are supposed to take just before 
   the epilog loop. Here we check that the access function of the loop IVs
   and the expression that represents the loop bound are simple enough.
   These restrictions will be relxed in the future.  */

static bool 
memset_analyze_loop_with_symbolic_num_of_iters (tree niters, 
					        struct loop *loop)
{
  basic_block bb = loop->header;
  tree phi;

  if (memset_debug_details (NULL))
    fprintf (dump_file, 
	     "\n<<memset_analyze_loop_with_symbolic_num_of_iters>>\n");
  
  if (chrec_contains_undetermined (niters))
    {
      if (memset_debug_details (NULL))
        fprintf (dump_file, "Infinite number of iterations.");
      return false;
    }

  if (!niters)
    {
      if (memset_debug_details (NULL))
        fprintf (dump_file, "niters is NULL pointer.");
      return false;
    }

  if (memset_debug_details (NULL))
    {
      fprintf (dump_file, "Symbolic number of iterations is ");
      print_generic_expr (dump_file, niters, TDF_DETAILS);
    }
   
  /* Analyze phi functions of the loop header.  */

  for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
    {
      tree access_fn = NULL;
      tree evolution_part;

      if (memset_debug_details (NULL))
	{
          fprintf (dump_file, "Analyze phi: ");
          print_generic_expr (dump_file, phi, TDF_SLIM);
	}

      /* Skip virtual phi's. The data dependences that are associated with
         virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */

      if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
	{
	  if (memset_debug_details (NULL))
	    fprintf (dump_file, "virtual phi. skip.");
	  continue;
	}

      /* Analyze the evolution function.  */

      access_fn = instantiate_parameters
	(loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));

      if (!access_fn)
	{
	  if (memset_debug_details (NULL))
	    fprintf (dump_file, "No Access function.");
	  return false;
	}

      if (memset_debug_details (NULL))
        {
	  fprintf (dump_file, "Access function of PHI: ");
	  print_generic_expr (dump_file, access_fn, TDF_SLIM);
        }

      evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
      
      if (evolution_part == NULL_TREE)
	return false;
  
      /* FORNOW: We do not transform initial conditions of IVs 
	 which evolution functions are a polynomial of degree >= 2.  */

      if (tree_is_chrec (evolution_part))
	return false;  
    }

  return  true;
}


/* Function debug_loop_details.

   For memset debug dumps.  */

static bool
memset_debug_details (struct loop *loop)
{
   basic_block bb;
   block_stmt_iterator si;
   tree node = NULL_TREE;

  if (!dump_file || !(dump_flags & TDF_DETAILS))
    return false;

  if (!loop)
    {
      fprintf (dump_file, "\n");
      return true;
    }

  if (!loop->header)
    return false;

  bb = loop->header;

  for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
    {
      node = bsi_stmt (si);
      if (node && EXPR_P (node) && EXPR_LOCUS (node))
	break;
    }

  if (node && EXPR_P (node) && EXPR_LOCUS (node)
      && EXPR_FILENAME (node) && EXPR_LINENO (node))
    {
      fprintf (dump_file, "\nloop at %s:%d: ", 
               EXPR_FILENAME (node), EXPR_LINENO (node));
      return true;
    }

  return false;
}

/* Function debug_loop_stats.

   For vectorization statistics dumps.  */

static bool
memset_debug_stats (struct loop *loop)
{
  basic_block bb;
  block_stmt_iterator si;
  tree node = NULL_TREE;

  if (!dump_file || !(dump_flags & TDF_STATS))
    return false;

  if (!loop)
    {
      fprintf (dump_file, "\n");
      return true;
    }

  if (!loop->header)
    return false;

  bb = loop->header;

  for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
    {
      node = bsi_stmt (si);
      if (node && EXPR_P (node) && EXPR_LOCUS (node))
        break;
    }

  if (node && EXPR_P (node) && EXPR_LOCUS (node) 
      && EXPR_FILENAME (node) && EXPR_LINENO (node))
    {
      fprintf (dump_file, "\nloop at %s:%d: ", 
	EXPR_FILENAME (node), EXPR_LINENO (node));
      return true;
    }

  return false;
}

/* Function memset_analyze_loop_form.

   Verify the following restrictions:
   - it's an inner-most loop
   - number of BBs = 2 (which are the loop header and the latch)
   - the loop has a pre-header
   - the loop has a single entry and exit
   - the loop exit condition is simple enough, and the number of iterations
     can be analyzed (a countable loop).

   This differs from vect_analyze_loop_form by we handle non constant
   interations.  */

static loop_vec_info
memset_analyze_loop_form (struct loop *loop)
{
  loop_vec_info loop_vinfo;
  tree loop_cond;
  tree number_of_iterations = NULL_TREE;

  if (memset_debug_details (loop))
    fprintf (dump_file, "\n<<memset_analyze_loop_form>>\n");

  if (loop->level > 1		/* FORNOW: inner-most loop  */
      || loop->num_exits > 1 || loop->num_entries > 1 || loop->num_nodes != 2
      || !loop->pre_header || !loop->header || !loop->latch)
    {
      if (memset_debug_stats (loop) || memset_debug_details (loop))	
	{
	  fprintf (dump_file, "not vectorized: bad loop form.\n");
	  if (loop->level > 1)
	    fprintf (dump_file, "nested loop.\n");
	  else if (loop->num_exits > 1 || loop->num_entries > 1)
	    fprintf (dump_file, "multiple entries or exits.\n");
	  else if (loop->num_nodes != 2 || !loop->header || !loop->latch)
	    fprintf (dump_file, "too many BBs in loop.\n");
	  else if (!loop->pre_header)
	    fprintf (dump_file, "no pre-header BB for loop.\n");
	}
      
      return NULL;
    }

  /* We assume that the loop exit condition is at the end of the loop. i.e,
     that the loop is represented as a do-while (with a proper if-guard
     before the loop if needed), where the loop header contains all the
     executable statements, and the latch is empty.  */
  if (!empty_block_p (loop->latch))
    {
      if (memset_debug_stats (loop) || memset_debug_details (loop))     
        fprintf (dump_file, "not vectorized: unexpectd loop form.");
      return NULL;
    }

  if (empty_block_p (loop->header))
    {
      if (memset_debug_stats (loop) || memset_debug_details (loop))     
        fprintf (dump_file, "not transformed: empty loop.");
      return NULL;
    }

  loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
  if (!loop_cond)
    {
      if (memset_debug_stats (loop) || memset_debug_details (loop))
	fprintf (dump_file, "not vectorized: complicated exit condition.\n");
      return NULL;
    }
    
  if (!number_of_iterations) 
    {
      if (memset_debug_stats (loop) || memset_debug_details (loop))
	fprintf (dump_file, 
		 "not vectorized: number of iterations cannot be computed.");
      return NULL;
    }

  loop_vinfo = new_loop_vec_info (loop);
  LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
  
  if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
    {
      if (memset_debug_details (NULL))
	fprintf (dump_file, "loop bound unknown.");

      /* Unknown loop bound.  */
      if (!memset_analyze_loop_with_symbolic_num_of_iters (number_of_iterations,
							   loop))
	{
          if (memset_debug_stats (loop) || memset_debug_details (loop))
	    fprintf (dump_file, "not transformed: can't determine loop bound.\n");
	  return NULL;
	}
      else
	{
	  /* We need only one loop entry for unknown loop bound support.  */
	  if (loop->num_entries != 1 || !loop->pre_header)
	    {	      
	      if (memset_debug_stats (loop) || memset_debug_details (loop))
		fprintf (dump_file, 
			 "not transformed: more than one loop entry.");
	      return NULL;
	    }
	}
    }
  else if (LOOP_VINFO_INT_NITERS (loop_vinfo) == 0)
    {
      if (memset_debug_stats (loop) || memset_debug_details (loop))
	fprintf (dump_file, "not transformed: number of iterations = 0.\n");
      return NULL;
    }

  LOOP_VINFO_EXIT_COND (loop_vinfo) = loop_cond;

  return loop_vinfo;
}

/* Mark all the variables in V_MAY_DEF or V_MUST_DEF operands for STMT for
   renaming. This becomes necessary when we modify all of a non-scalar.  */

static void
mark_all_v_defs (tree stmt)
{
  tree sym;
  ssa_op_iter iter;

  get_stmt_operands (stmt);

  FOR_EACH_SSA_TREE_OPERAND (sym, stmt, iter, SSA_OP_VIRTUAL_DEFS)
    { 
      if (TREE_CODE (sym) == SSA_NAME) 
	sym = SSA_NAME_VAR (sym);
      bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
    }
}
/* MERGE FIXME 4709514 */
#endif

/* This is the main entry point for the transformation.  */
void
tree_ssa_memset (struct loops *ARG_UNUSED (loops))
{
  /* MERGE FIXME 4709514 */
#if 0
  unsigned i;
  
  for (i = 1; i < loops->num; i++)
    {
      struct loop *loop = loops->parray[i];
      loop_vec_info vectorizer_info;
      varray_type writes;
      struct data_reference *drw;
      tree access_chrec;
      tree noi;
      
      if (!loop)
        continue;
      
      flow_loop_scan (loop, LOOP_ALL);
      vectorizer_info = memset_analyze_loop_form (loop);
      if (!vectorizer_info)
        continue;
      
      if (!memset_analyze_data_refs (vectorizer_info))
	{
	  if (memset_debug_details (loop))
	    fprintf (dump_file, "bad data references.");
	  destroy_loop_vec_info (vectorizer_info);
	  continue;
	}
      
      writes = LOOP_VINFO_DATAREF_WRITES (vectorizer_info);
      
      /* TODO: handle more than data write.  */
      if (VARRAY_ACTIVE_SIZE (writes) != 1)
	{
	  if (memset_debug_details (loop))
	    fprintf (dump_file, "no or more than one store.");
	  destroy_loop_vec_info (vectorizer_info);
	  continue;
	}
      
      drw = VARRAY_GENERIC_PTR (writes, 0);
      
      /* TODO: handle multi-dimension arrays.  */
      if (DR_NUM_DIMENSIONS (drw) != 1)
	{
	  if (memset_debug_details (loop))
	    fprintf (dump_file, "cannot handle multiple dimension array.");
	  destroy_loop_vec_info (vectorizer_info);
	  continue;
	}
      
      if (TREE_CODE (TREE_OPERAND (DR_STMT (drw), 1)) != INTEGER_CST)
	{
	  if (memset_debug_details (loop))
	    fprintf (dump_file, "non constant store value.");
	  destroy_loop_vec_info (vectorizer_info);
	  continue;
	}
      
      /* TODO: handle other than zero values in types
         where the unit size is greater than one. */
      if (!integer_zerop (TREE_OPERAND (DR_STMT (drw), 1))
	  && !integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drw)))))
	{
	  if (memset_debug_details (loop))
	    fprintf (dump_file, "cannot handle other zero value for types of other than char (for now).");
	  destroy_loop_vec_info (vectorizer_info);
	  continue;
	}
      
      access_chrec = DR_ACCESS_FN (drw, 0);
      
      noi = LOOP_VINFO_NITERS (vectorizer_info);      
      
      /* Build the memset call.  */
      {
        tree array = DR_BASE_NAME (drw);
	tree value = TREE_OPERAND (DR_STMT (drw), 1);
	tree function = implicit_built_in_decls[BUILT_IN_MEMSET];
	tree args = NULL_TREE;
	block_stmt_iterator bsi = bsi_last (loop->pre_header);
	tree array_1 = make_rename_temp (ptr_type_node, NULL);
	tree temp, stmt, var;
	tree ni_name;
	
	stmt = DR_STMT (drw);
	
	/* Remove the array access stmt. */
	{
	  block_stmt_iterator access_bsi;
	  /* Mark the MAY_DEF as needed to be renamed. */
	  mark_all_v_defs (stmt);
	  access_bsi = bsi_for_stmt (stmt);
	  bsi_remove (&access_bsi);
	}
	
	if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
	  {
	    tree type = TREE_TYPE (TREE_TYPE (array));
	    tree base = array;
	    
	    while (TREE_CODE (base) == REALPART_EXPR
		   || TREE_CODE (base) == IMAGPART_EXPR
		   || handled_component_p (base))
	      base = TREE_OPERAND (base, 0);
	    
	    if (DECL_P (base))
	      TREE_ADDRESSABLE (base) = 1;
	    
	    array = build4 (ARRAY_REF, type, array, size_zero_node,
	                    NULL_TREE, NULL_TREE);
	    array = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (array)),
	                    array);
	  }
	
	{
	  tree start = CHREC_LEFT (access_chrec);
	  tree size_mult;
	  tree array_var;
	  start = fold_convert (TREE_TYPE (array), start);
	  size_mult = fold_convert (TREE_TYPE (array),
			            TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array))));
	  array = fold (build2 (PLUS_EXPR, 
				TREE_TYPE (array),
				array, 
				fold (build2 (MULT_EXPR, 
					      TREE_TYPE (array), 
					      start, 
					      size_mult))));
	  array_var = create_tmp_var (TREE_TYPE (array), "tmp");
	  add_referenced_tmp_var (array_var);
	  array = force_gimple_operand (array, &stmt, false, array_var);

	  if (stmt)
	    bsi_insert_after (&bsi, stmt, BSI_CONTINUE_LINKING);
	}
	
	var = create_tmp_var (size_type_node, "tmp");
	add_referenced_tmp_var (var);
	
	noi = fold (build2 (MULT_EXPR, TREE_TYPE (noi), noi,
	                    fold_convert (TREE_TYPE (noi),
			                  TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array))))));

	stmt = NULL_TREE;
	ni_name = force_gimple_operand (noi, &stmt, false, var);

	if (stmt)
	  bsi_insert_after (&bsi, stmt, BSI_CONTINUE_LINKING);
      
	temp = build2 (MODIFY_EXPR, void_type_node, array_1,
		       array);
	
	bsi_insert_after (&bsi, temp, BSI_CONTINUE_LINKING);
	
	args = tree_cons (NULL, ni_name, args);
	args = tree_cons (NULL, fold_convert (integer_type_node, value), args);
	args = tree_cons (NULL, array_1, args);
	
	temp = build_function_call_expr (function, args);
	
	bsi_insert_after (&bsi, temp, BSI_CONTINUE_LINKING);
      }
      
      destroy_loop_vec_info (vectorizer_info);
      
    }
  
  rewrite_into_ssa (false);
  if (!bitmap_empty_p (vars_to_rename))
    {
      /* The rewrite of ssa names may cause violation of loop closed ssa
         form invariants.  TODO -- avoid these rewrites completely.
         Information in virtual phi nodes is sufficient for it.  */
      rewrite_into_loop_closed_ssa (); 
    }
  bitmap_clear (vars_to_rename);
/* MERGE FIXME 4709514 */
#endif
}
