/* 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"

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 */
	      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);
    }
}


/* This is the main entry point for the transformation.  */
void
tree_ssa_memset (struct loops *loops)
{
  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);
}
