/* Dummy data flow analysis for GNU compiler in nonoptimizing mode.
   Copyright (C) 1987, 91, 94, 95, 96, 1997 Free Software Foundation, Inc.

This file is part of GNU CC.

GNU CC 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.

GNU CC 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 GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */


/* This file performs stupid register allocation, which is used
   when cc1 gets the -noreg switch (which is when cc does not get -O).

   Stupid register allocation goes in place of the flow_analysis,
   local_alloc and global_alloc passes.  combine_instructions cannot
   be done with stupid allocation because the data flow info that it needs
   is not computed here.

   In stupid allocation, the only user-defined variables that can
   go in registers are those declared "register".  They are assumed
   to have a life span equal to their scope.  Other user variables
   are given stack slots in the rtl-generation pass and are not
   represented as pseudo regs.  A compiler-generated temporary
   is assumed to live from its first mention to its last mention.

   Since each pseudo-reg's life span is just an interval, it can be
   represented as a pair of numbers, each of which identifies an insn by
   its position in the function (number of insns before it).  The first
   thing done for stupid allocation is to compute such a number for each
   insn.  It is called the suid.  Then the life-interval of each
   pseudo reg is computed.  Then the pseudo regs are ordered by priority
   and assigned hard regs in priority order.  */

#include "config.h"
#include "system.h"

#include "rtl.h"
#include "hard-reg-set.h"
#include "regs.h"
#include "flags.h"
#include "toplev.h"

/* Vector mapping INSN_UIDs to suids.
   The suids are like uids but increase monotonically always.
   We use them to see whether a subroutine call came
   between a variable's birth and its death.  */

static int *uid_suid;

/* Get the suid of an insn.  */

#define INSN_SUID(INSN) (uid_suid[INSN_UID (INSN)])

/* Record the suid of the last CALL_INSN
   so we can tell whether a pseudo reg crosses any calls.  */

static int last_call_suid;

/* Record the suid of the last NOTE_INSN_SETJMP
   so we can tell whether a pseudo reg crosses any setjmp.  */

static int last_setjmp_suid;

/* Element N is suid of insn where life span of pseudo reg N ends.
   Element is  0 if register N has not been seen yet on backward scan.  */

static int *reg_where_dead;

/* Element N is suid of insn where life span of pseudo reg N begins.  */

static int *reg_where_born;

/* Numbers of pseudo-regs to be allocated, highest priority first.  */

static int *reg_order;

/* Indexed by reg number (hard or pseudo), nonzero if register is live
   at the current point in the instruction stream.  */

static char *regs_live;

/* Indexed by reg number, nonzero if reg was used in a SUBREG that changes
   its size.  */

static char *regs_change_size;

/* Indexed by reg number, nonzero if reg crosses a setjmp.  */

static char *regs_crosses_setjmp;

/* Indexed by insn's suid, the set of hard regs live after that insn.  */

static HARD_REG_SET *after_insn_hard_regs;

/* Record that hard reg REGNO is live after insn INSN.  */

#define MARK_LIVE_AFTER(INSN,REGNO)  \
  SET_HARD_REG_BIT (after_insn_hard_regs[INSN_SUID (INSN)], (REGNO))

static int stupid_reg_compare	PROTO((const GENERIC_PTR,const GENERIC_PTR));
static int stupid_find_reg	PROTO((int, enum reg_class, enum machine_mode,
				       int, int, int));
static void stupid_mark_refs	PROTO((rtx, rtx));

/* Stupid life analysis is for the case where only variables declared
   `register' go in registers.  For this case, we mark all
   pseudo-registers that belong to register variables as
   dying in the last instruction of the function, and all other
   pseudo registers as dying in the last place they are referenced.
   Hard registers are marked as dying in the last reference before
   the end or before each store into them.  */

void
stupid_life_analysis (f, nregs, file)
     rtx f;
     int nregs;
     FILE *file;
{
  register int i;
  register rtx last, insn;
  int max_uid, max_suid;

  current_function_has_computed_jump = 0;

  bzero (regs_ever_live, sizeof regs_ever_live);

  regs_live = (char *) alloca (nregs);

  /* First find the last real insn, and count the number of insns,
     and assign insns their suids.  */

  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
    if (INSN_UID (insn) > i)
      i = INSN_UID (insn);

  max_uid = i + 1;
  uid_suid = (int *) alloca ((i + 1) * sizeof (int));

  /* Compute the mapping from uids to suids.
     Suids are numbers assigned to insns, like uids,
     except that suids increase monotonically through the code.  */

  last = 0;			/* In case of empty function body */
  for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
    {
      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
	last = insn;

      INSN_SUID (insn) = ++i;
    }

  last_call_suid = i + 1;
  last_setjmp_suid = i + 1;
  max_suid = i + 1;

  max_regno = nregs;

  /* Allocate tables to record info about regs.  */

  reg_where_dead = (int *) alloca (nregs * sizeof (int));
  bzero ((char *) reg_where_dead, nregs * sizeof (int));

  reg_where_born = (int *) alloca (nregs * sizeof (int));
  bzero ((char *) reg_where_born, nregs * sizeof (int));

  reg_order = (int *) alloca (nregs * sizeof (int));
  bzero ((char *) reg_order, nregs * sizeof (int));

  regs_change_size = (char *) alloca (nregs * sizeof (char));
  bzero ((char *) regs_change_size, nregs * sizeof (char));

  regs_crosses_setjmp = (char *) alloca (nregs * sizeof (char));
  bzero ((char *) regs_crosses_setjmp, nregs * sizeof (char));

  /* Allocate the reg_renumber array */
  allocate_reg_info (max_regno, FALSE, TRUE);
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    reg_renumber[i] = i;

  after_insn_hard_regs
    = (HARD_REG_SET *) alloca (max_suid * sizeof (HARD_REG_SET));

  bzero ((char *) after_insn_hard_regs, max_suid * sizeof (HARD_REG_SET));

  /* Allocate and zero out many data structures
     that will record the data from lifetime analysis.  */

  allocate_for_life_analysis ();

  for (i = 0; i < max_regno; i++)
    REG_N_DEATHS (i) = 1;

  bzero (regs_live, nregs);

  /* Find where each pseudo register is born and dies,
     by scanning all insns from the end to the start
     and noting all mentions of the registers.

     Also find where each hard register is live
     and record that info in after_insn_hard_regs.
     regs_live[I] is 1 if hard reg I is live
     at the current point in the scan.  */

  for (insn = last; insn; insn = PREV_INSN (insn))
    {
      register HARD_REG_SET *p = after_insn_hard_regs + INSN_SUID (insn);

      /* Copy the info in regs_live into the element of after_insn_hard_regs
	 for the current position in the rtl code.  */

      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (regs_live[i])
	  SET_HARD_REG_BIT (*p, i);

      /* Update which hard regs are currently live
	 and also the birth and death suids of pseudo regs
	 based on the pattern of this insn.  */

      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
	stupid_mark_refs (PATTERN (insn), insn);

      if (GET_CODE (insn) == NOTE
	  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
	last_setjmp_suid = INSN_SUID (insn);

      /* Mark all call-clobbered regs as dead after each call insn so that
	 a pseudo whose life span includes this insn will not go in one of
	 them.  If the function contains a non-local goto, mark all hard
	 registers dead (except for stack related bits).

	 Then mark those regs as all dead for the continuing scan
	 of the insns before the call.  */

      if (GET_CODE (insn) == CALL_INSN)
	{
	  last_call_suid = INSN_SUID (insn);

	  if (current_function_has_nonlocal_label)
	    {
	      IOR_COMPL_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
				      fixed_reg_set);
	      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
		if (! fixed_regs[i])
	          regs_live[i] = 0;
	    }
	  else
	    {
	      IOR_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
				call_used_reg_set);
	      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	        if (call_used_regs[i])
	          regs_live[i] = 0;
	    }

	  /* It is important that this be done after processing the insn's
	     pattern because we want the function result register to still
	     be live if it's also used to pass arguments.  */
	  stupid_mark_refs (CALL_INSN_FUNCTION_USAGE (insn), insn);
	}
      if (GET_CODE (insn) == JUMP_INSN && computed_jump_p (insn))
	current_function_has_computed_jump = 1;
    }

  /* Now decide the order in which to allocate the pseudo registers.  */

  for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
    reg_order[i] = i;

  qsort (&reg_order[LAST_VIRTUAL_REGISTER + 1],
	 max_regno - LAST_VIRTUAL_REGISTER - 1, sizeof (int),
	 stupid_reg_compare);

  /* Now, in that order, try to find hard registers for those pseudo regs.  */

  for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
    {
      register int r = reg_order[i];

      /* Some regnos disappear from the rtl.  Ignore them to avoid crash. 
	 Also don't allocate registers that cross a setjmp, or live across
	 a call if this function receives a nonlocal goto.  */
      if (regno_reg_rtx[r] == 0 || regs_crosses_setjmp[r]
	  || (REG_N_CALLS_CROSSED (r) > 0 
	      && current_function_has_nonlocal_label))
	continue;

      /* Now find the best hard-register class for this pseudo register */
      if (N_REG_CLASSES > 1)
	reg_renumber[r] = stupid_find_reg (REG_N_CALLS_CROSSED (r), 
					   reg_preferred_class (r),
					   PSEUDO_REGNO_MODE (r),
					   reg_where_born[r],
					   reg_where_dead[r],
					   regs_change_size[r]);

      /* If no reg available in that class, try alternate class.  */
      if (reg_renumber[r] == -1 && reg_alternate_class (r) != NO_REGS)
	reg_renumber[r] = stupid_find_reg (REG_N_CALLS_CROSSED (r),
					   reg_alternate_class (r),
					   PSEUDO_REGNO_MODE (r),
					   reg_where_born[r],
					   reg_where_dead[r],
					   regs_change_size[r]);
    }

  if (file)
    dump_flow_info (file);
}

/* Comparison function for qsort.
   Returns -1 (1) if register *R1P is higher priority than *R2P.  */

static int
stupid_reg_compare (r1p, r2p)
     const GENERIC_PTR r1p;
     const GENERIC_PTR r2p;
{
  register int r1 = *(int *)r1p, r2 = *(int *)r2p;
  register int len1 = reg_where_dead[r1] - reg_where_born[r1];
  register int len2 = reg_where_dead[r2] - reg_where_born[r2];
  int tem;

  tem = len2 - len1;
  if (tem != 0)
    return tem;

  tem = REG_N_REFS (r1) - REG_N_REFS (r2);
  if (tem != 0)
    return tem;

  /* If regs are equally good, sort by regno,
     so that the results of qsort leave nothing to chance.  */
  return r1 - r2;
}

/* Find a block of SIZE words of hard registers in reg_class CLASS
   that can hold a value of machine-mode MODE
     (but actually we test only the first of the block for holding MODE)
   currently free from after insn whose suid is BORN_INSN
   through the insn whose suid is DEAD_INSN,
   and return the number of the first of them.
   Return -1 if such a block cannot be found.

   If CALL_PRESERVED is nonzero, insist on registers preserved
   over subroutine calls, and return -1 if cannot find such.

   If CHANGES_SIZE is nonzero, it means this register was used as the
   operand of a SUBREG that changes its size.  */

static int
stupid_find_reg (call_preserved, class, mode,
		 born_insn, dead_insn, changes_size)
     int call_preserved;
     enum reg_class class;
     enum machine_mode mode;
     int born_insn, dead_insn;
     int changes_size;
{
  register int i, ins;
#ifdef HARD_REG_SET
  register		/* Declare them register if they are scalars.  */
#endif
    HARD_REG_SET used, this_reg;
#ifdef ELIMINABLE_REGS
  static struct {int from, to; } eliminables[] = ELIMINABLE_REGS;
#endif

  /* If this register's life is more than 5,000 insns, we probably
     can't allocate it, so don't waste the time trying.  This avoids
     quadratic behavior on programs that have regularly-occurring
     SAVE_EXPRs.  */
  if (dead_insn > born_insn + 5000)
    return -1;

  COPY_HARD_REG_SET (used,
		     call_preserved ? call_used_reg_set : fixed_reg_set);

#ifdef ELIMINABLE_REGS
  for (i = 0; i < sizeof eliminables / sizeof eliminables[0]; i++)
    SET_HARD_REG_BIT (used, eliminables[i].from);
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
  SET_HARD_REG_BIT (used, HARD_FRAME_POINTER_REGNUM);
#endif
#else
  SET_HARD_REG_BIT (used, FRAME_POINTER_REGNUM);
#endif

  for (ins = born_insn; ins < dead_insn; ins++)
    IOR_HARD_REG_SET (used, after_insn_hard_regs[ins]);

#ifdef STACK_REGS
  if (current_function_has_computed_jump)
    for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
      SET_HARD_REG_BIT (used, i);
#endif
  
  IOR_COMPL_HARD_REG_SET (used, reg_class_contents[(int) class]);

#ifdef CLASS_CANNOT_CHANGE_SIZE
  if (changes_size)
    IOR_HARD_REG_SET (used,
		      reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE]);
#endif

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
#ifdef REG_ALLOC_ORDER
      int regno = reg_alloc_order[i];
#else
      int regno = i;
#endif

      /* If a register has screwy overlap problems,
	 don't use it at all if not optimizing.
	 Actually this is only for the 387 stack register,
	 and it's because subsequent code won't work.  */
#ifdef OVERLAPPING_REGNO_P
      if (OVERLAPPING_REGNO_P (regno))
	continue;
#endif

      if (! TEST_HARD_REG_BIT (used, regno)
	  && HARD_REGNO_MODE_OK (regno, mode))
	{
	  register int j;
	  register int size1 = HARD_REGNO_NREGS (regno, mode);
	  for (j = 1; j < size1 && ! TEST_HARD_REG_BIT (used, regno + j); j++);
	  if (j == size1)
	    {
	      CLEAR_HARD_REG_SET (this_reg);
	      while (--j >= 0)
		SET_HARD_REG_BIT (this_reg, regno + j);
	      for (ins = born_insn; ins < dead_insn; ins++)
		{
		  IOR_HARD_REG_SET (after_insn_hard_regs[ins], this_reg);
		}
	      return regno;
	    }
#ifndef REG_ALLOC_ORDER
	  i += j;		/* Skip starting points we know will lose */
#endif
	}
    }

  return -1;
}

/* Walk X, noting all assignments and references to registers
   and recording what they imply about life spans.
   INSN is the current insn, supplied so we can find its suid.  */

static void
stupid_mark_refs (x, insn)
     rtx x, insn;
{
  register RTX_CODE code;
  register char *fmt;
  register int regno, i;

  if (x == 0)
    return;

  code = GET_CODE (x);

  if (code == SET || code == CLOBBER)
    {
      if (SET_DEST (x) != 0
	  && (GET_CODE (SET_DEST (x)) == REG
	      || (GET_CODE (SET_DEST (x)) == SUBREG
		  && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
		  && (REGNO (SUBREG_REG (SET_DEST (x)))
		      >= FIRST_PSEUDO_REGISTER))))
	{
	  /* Register is being assigned.  */
	  /* If setting a SUBREG, we treat the entire reg as being set.  */
	  if (GET_CODE (SET_DEST (x)) == SUBREG)
	    regno = REGNO (SUBREG_REG (SET_DEST (x)));
	  else
	    regno = REGNO (SET_DEST (x));

	  /* For hard regs, update the where-live info.  */
	  if (regno < FIRST_PSEUDO_REGISTER)
	    {
	      register int j
		= HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (x)));

	      while (--j >= 0)
		{
		  regs_ever_live[regno+j] = 1;
		  regs_live[regno+j] = 0;

		  /* The following line is for unused outputs;
		     they do get stored even though never used again.  */
		  MARK_LIVE_AFTER (insn, regno+j);

		  /* When a hard reg is clobbered, mark it in use
		     just before this insn, so it is live all through.  */
		  if (code == CLOBBER && INSN_SUID (insn) > 0)
		    SET_HARD_REG_BIT (after_insn_hard_regs[INSN_SUID (insn) - 1],
				      regno+j);
		}
	    }
	  /* For pseudo regs, record where born, where dead, number of
	     times used, and whether live across a call.  */
	  else
	    {
	      /* Update the life-interval bounds of this pseudo reg.  */

	      /* When a pseudo-reg is CLOBBERed, it is born just before
		 the clobbering insn.  When setting, just after.  */
	      int where_born = INSN_SUID (insn) - (code == CLOBBER);

	      reg_where_born[regno] = where_born;

	      /* The reg must live at least one insn even
		 in it is never again used--because it has to go
		 in SOME hard reg.  Mark it as dying after the current
		 insn so that it will conflict with any other outputs of
		 this insn.  */
	      if (reg_where_dead[regno] < where_born + 2)
		{
		  reg_where_dead[regno] = where_born + 2;
		  regs_live[regno] = 1;
		}

	      /* Count the refs of this reg.  */
	      REG_N_REFS (regno)++;

	      if (last_call_suid < reg_where_dead[regno])
		REG_N_CALLS_CROSSED (regno) += 1;

	      if (last_setjmp_suid < reg_where_dead[regno])
		regs_crosses_setjmp[regno] = 1;

	      /* If this register is only used in this insn and is only
		 set, mark it unused.  We have to do this even when not 
		 optimizing so that MD patterns which count on this
		 behavior (e.g., it not causing an output reload on
		 an insn setting CC) will operate correctly.  */
	      if (GET_CODE (SET_DEST (x)) == REG
		  && REGNO_FIRST_UID (regno) == INSN_UID (insn)
		  && REGNO_LAST_UID (regno) == INSN_UID (insn)
		  && (code == CLOBBER || ! reg_mentioned_p (SET_DEST (x),
							    SET_SRC (x))))
		REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_UNUSED,
						      SET_DEST (x),
						      REG_NOTES (insn));
	    }
	}

      /* Record references from the value being set,
	 or from addresses in the place being set if that's not a reg.
	 If setting a SUBREG, we treat the entire reg as *used*.  */
      if (code == SET)
	{
	  stupid_mark_refs (SET_SRC (x), insn);
	  if (GET_CODE (SET_DEST (x)) != REG)
	    stupid_mark_refs (SET_DEST (x), insn);
	}
      return;
    }

  else if (code == SUBREG
	   && GET_CODE (SUBREG_REG (x)) == REG
	   && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER
	   && (GET_MODE_SIZE (GET_MODE (x))
	       != GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
	   && (INTEGRAL_MODE_P (GET_MODE (x))
	       || INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (x)))))
    regs_change_size[REGNO (SUBREG_REG (x))] = 1;

  /* Register value being used, not set.  */

  else if (code == REG)
    {
      regno = REGNO (x);
      if (regno < FIRST_PSEUDO_REGISTER)
	{
	  /* Hard reg: mark it live for continuing scan of previous insns.  */
	  register int j = HARD_REGNO_NREGS (regno, GET_MODE (x));
	  while (--j >= 0)
	    {
	      regs_ever_live[regno+j] = 1;
	      regs_live[regno+j] = 1;
	    }
	}
      else
	{
	  /* Pseudo reg: record first use, last use and number of uses.  */

	  reg_where_born[regno] = INSN_SUID (insn);
	  REG_N_REFS (regno)++;
	  if (regs_live[regno] == 0)
	    {
	      regs_live[regno] = 1;
	      reg_where_dead[regno] = INSN_SUID (insn);
	    }
	}
      return;
    }

  /* Recursive scan of all other rtx's.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	stupid_mark_refs (XEXP (x, i), insn);
      if (fmt[i] == 'E')
	{
	  register int j;
	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    stupid_mark_refs (XVECEXP (x, i, j), insn);
	}
    }
}
