/* AE program profiling system.
   Definitions for AE measurement code incorporated into gcc.
   Copyright (C) 1989, 1990 by James R. Larus (larus@cs.wisc.edu)

   AE and AEC are 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 1, or (at your option) any
   later version.

   AE and AEC are 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 James R.
   Larus, Computer Sciences Department, University of Wisconsin--Madison,
   1210 West Dayton Street, Madison, WI 53706, USA or to the Free
   Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */


/* $Header: /var/home/larus/AE/AE/RCS/ae.h,v 2.0 90/02/09 17:20:32 larus Exp Locker: larus $ */


/* List datatype. */

typedef
struct list_cell
  {int car;
   struct list_cell *cdr;}
list_cell, *list;

#define CAR(x) x->car

#define CDR(x) x->cdr

list cons ();


#define DOLIST(v, t, lst, body) \
{ \
  list _l_; \
  list cdr_n_free (); \
  for (_l_ = lst; _l_ != NULL; _l_ = cdr_n_free (_l_))\
   { \
     register t v = (t) CAR (_l_); \
     body; \
   } \
}

#ifndef NULL
#define NULL (0)
#endif



/* Iterate over the subexpressions in a INSN, CALL_INSN, or JUMP_INSN. */

#define APPLY_TO_EXP_IN_INSN(insn, val, e_body)			\
{								\
  register char *format_ptr = GET_RTX_FORMAT (GET_CODE (insn));	\
  register int i, j;						\
  register rtx val;						\
  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (insn)); i++)	\
    switch (*format_ptr++)					\
      {								\
      case 'e':							\
	val = XEXP (insn, i);					\
	if (val) {e_body;}					\
	break;							\
      case 'E':							\
	for (j = 0; j < XVECLEN (insn, i); j++)			\
	  {val = XVECEXP (insn, i, j); if (val) {e_body;}}	\
	break;							\
      }								\
}

#define REAL_INSN_P(insn) ((GET_CODE (insn) == INSN		\
			    && GET_CODE (PATTERN (insn)) != USE	\
			    && GET_CODE (PATTERN (insn)) != CLOBBER)\
			   || GET_CODE (insn) == CALL_INSN	\
			   || GET_CODE (insn)== JUMP_INSN)



/* Auxilary information on an instruction. */

typedef struct
{
  short mark;			/* Used to mark instructions in loop */
  short in_block;		/* Number of block containing insn
				   (Only set for 1st insn in block) */
  int flags;			/* Information gleaned about insn */
  list entry_edge;		/* List of (B . L) for edges from insn
				   to block B that enter loop L. */
  list back_edge;		/* Similar list of loop back edges */
  list exit_edge;		/* Similar list of loop exit edges  */
} aux_insn_info;


/* Flags for marking interesting instructions. */

#define FUNCTION_START_FLAG 0x1
#define FUNCTION_END_FLAG 0x2

#define BLOCK_START_FLAG 0x4
#define BLOCK_END_FLAG 0x8

#define CJUMP_TARGET_FLAG 0x10
#define JUMP_TARGET_FLAG 0x20

/* These must increase in value: */
#define EASY_INSN_FLAG 0x40
#define HARD_INSN_FLAG 0x80
#define IMPOSSIBLE_INSN_FLAG 0x100

#define LOOP_HEAD_FLAG 0x200


/* Larger than expected maximum bytes of event produced in a basic block. */

#define CHUNK_SIZE 100
