OSDN Git Service

g++.dg/lookup/exception1.C: New test.
[pf3gnuchains/gcc-fork.git] / gcc / rtl.h
index 3842426..3cab166 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -62,6 +62,8 @@ extern const char * const rtx_format[NUM_RTX_CODE];
 
 extern const char rtx_class[NUM_RTX_CODE];
 #define GET_RTX_CLASS(CODE)            (rtx_class[(int) (CODE)])
+
+extern const unsigned char rtx_next[NUM_RTX_CODE];
 \f
 /* The flags and bitfields of an ADDR_DIFF_VEC.  BASE is the base label
    relative to which the offsets are calculated, as explained in rtl.def.  */
@@ -89,6 +91,9 @@ typedef struct
    so MEMs that the same attributes share a data structure.  This means
    they cannot be modified in place.  If any element is nonzero, it means
    the value of the corresponding attribute is unknown.  */
+/* ALIGN and SIZE are the alignment and size of the MEM itself,
+   while EXPR can describe a larger underlying object, which might have a
+   stricter alignment; OFFSET is the offset of the MEM within that object.  */
 typedef struct mem_attrs GTY(())
 {
   HOST_WIDE_INT alias;         /* Memory alias set.  */
@@ -100,7 +105,7 @@ typedef struct mem_attrs GTY(())
 
 /* Common union for an element of an rtx.  */
 
-typedef union rtunion_def
+union rtunion_def
 {
   HOST_WIDE_INT rtwint;
   int rtint;
@@ -115,11 +120,13 @@ typedef union rtunion_def
   tree rttree;
   struct basic_block_def *bb;
   mem_attrs *rtmem;
-} rtunion;
+};
+typedef union rtunion_def rtunion;
 
 /* RTL expression ("rtx").  */
 
-struct rtx_def
+struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"), 
+                   chain_prev ("RTX_PREV (&%h)")))
 {
   /* The kind of expression this is.  */
   ENUM_BITFIELD(rtx_code) code: 16;
@@ -130,9 +137,10 @@ struct rtx_def
   /* 1 in a MEM if we should keep the alias set for this mem unchanged
      when we access a component.
      1 in a CALL_INSN if it is a sibling call.
-     1 in a SET that is for a return.  */
+     1 in a SET that is for a return.
+     In a CODE_LABEL, part of the two-bit alternate entry field.  */
   unsigned int jump : 1;
-  /* This flag is currently unused.  */
+  /* In a CODE_LABEL, part of the two-bit alternate entry field.  */
   unsigned int call : 1;
   /* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere.
      1 in a SUBREG if it references an unsigned object whose mode has been
@@ -161,14 +169,14 @@ struct rtx_def
      and must not be deleted even if its count is zero.
      1 in a LABEL_REF if this is a reference to a label outside the
      current loop.
-     1 in an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER, or NOTE if
-     this insn must be scheduled together with the preceding insn.  Valid
-     only within sched.
+     1 in an INSN, JUMP_INSN or CALL_INSN if this insn must be scheduled
+     together with the preceding insn.  Valid only within sched.
      1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and
      from the target of a branch.  Valid from reorg until end of compilation;
      cleared before used.
-     1 in an INSN or related rtx if this insn is dead code.  Valid only during
-     dead-code elimination phase; cleared before use.  */
+     1 in an INSN, JUMP_INSN or CALL_INSN or related rtx if this insn is
+     dead code.  Valid only during dead-code elimination phase; cleared
+     before use.  */
   unsigned int in_struct : 1;
   /* At the end of RTL generation, 1 if this rtx is used.  This is used for
      copying shared structure.  See `unshare_all_rtl'.
@@ -178,7 +186,7 @@ struct rtx_def
      has used it as the function.  */
   unsigned int used : 1;
   /* Nonzero if this rtx came from procedure integration.
-     1 in a REG means this reg refers to the return value
+     1 in a REG or PARALLEL means this rtx refers to the return value
      of the current function.
      1 in a SYMBOL_REF if the symbol is weak.  */
   unsigned integrated : 1;
@@ -195,11 +203,29 @@ struct rtx_def
   /* The first element of the operands of this rtx.
      The number of operands and their types are controlled
      by the `code' field, according to rtl.def.  */
-  rtunion fld[1];
+  rtunion GTY ((special ("rtx_def"),
+               desc ("GET_CODE (&%0)"))) fld[1];
 };
 
 #define NULL_RTX (rtx) 0
 
+/* The "next" and "previous" RTX, relative to this one.  */
+
+#define RTX_NEXT(X) (rtx_next[GET_CODE (X)] == 0 ? NULL                        \
+                    : *(rtx *)(((char *)X) + rtx_next[GET_CODE (X)]))
+
+/* FIXME: the "NEXT_INSN (PREV_INSN (X)) == X" condition shouldn't be needed.
+ */
+#define RTX_PREV(X) ((GET_CODE (X) == INSN              \
+                      || GET_CODE (X) == CALL_INSN      \
+                      || GET_CODE (X) == JUMP_INSN      \
+                      || GET_CODE (X) == NOTE           \
+                      || GET_CODE (X) == BARRIER        \
+                      || GET_CODE (X) == CODE_LABEL)    \
+                     && PREV_INSN (X) != NULL           \
+                     && NEXT_INSN (PREV_INSN (X)) == X  \
+                     ? PREV_INSN (X) : NULL)
+
 /* Define macros to access the `code' field of the rtx.  */
 
 #define GET_CODE(RTX)      ((enum rtx_code) (RTX)->code)
@@ -553,7 +579,7 @@ do {                                \
 /* 1 if RTX is an insn that is dead code.  Valid only for dead-code
    elimination phase.  */
 #define INSN_DEAD_CODE_P(RTX)                                          \
-  (RTL_FLAG_CHECK1("INSN_DEAD_CODE_P", (RTX), INSN)->in_struct)
+  (RTL_FLAG_CHECK3("INSN_DEAD_CODE_P", (RTX), INSN, CALL_INSN, JUMP_INSN)->in_struct)
 
 /* 1 if RTX is an insn in a delay slot and is from the target of the branch.
    If the branch insn has INSN_ANNULLED_BRANCH_P set, this insn should only be
@@ -762,6 +788,7 @@ extern const char * const reg_note_name[];
 #define NOTE_BASIC_BLOCK(INSN) XCBBDEF (INSN, 4, NOTE)
 #define NOTE_EXPECTED_VALUE(INSN) XCEXP (INSN, 4, NOTE)
 #define NOTE_PREDICTION(INSN)   XCINT (INSN, 4, NOTE)
+#define NOTE_PRECONDITIONED(INSN)   XCINT (INSN, 4, NOTE)
 
 /* In a NOTE that is a line number, this is the line number.
    Other kinds of NOTEs are identified by negative numbers here.  */
@@ -857,7 +884,7 @@ enum insn_note
      NOTE_EXPECTED_VALUE; stored as (eq (reg) (const_int)).  */
   NOTE_INSN_EXPECTED_VALUE,
 
-  /* Record a prediction.  Uses NOTE_PREDICTION. */
+  /* Record a prediction.  Uses NOTE_PREDICTION.  */
   NOTE_INSN_PREDICTION,
 
   NOTE_INSN_MAX
@@ -877,8 +904,55 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
    of LABEL_REFs that point at it, so unused labels can be deleted.  */
 #define LABEL_NUSES(RTX) XCINT (RTX, 4, CODE_LABEL)
 
-/* Associate a name with a CODE_LABEL.  */
-#define LABEL_ALTERNATE_NAME(RTX) XCSTR (RTX, 8, CODE_LABEL)
+/* Labels carry a two-bit field composed of the ->jump and ->call
+   bits.  This field indicates whether the label is an alternate
+   entry point, and if so, what kind.  */
+enum label_kind
+{
+  LABEL_NORMAL = 0,    /* ordinary label */
+  LABEL_STATIC_ENTRY,  /* alternate entry point, not exported */
+  LABEL_GLOBAL_ENTRY,  /* alternate entry point, exported */
+  LABEL_WEAK_ENTRY     /* alternate entry point, exported as weak symbol */
+};
+
+#if defined ENABLE_RTL_FLAG_CHECKING && (GCC_VERSION > 2007)
+
+/* Retrieve the kind of LABEL.  */
+#define LABEL_KIND(LABEL) __extension__                                        \
+({ rtx const _label = (LABEL);                                         \
+   if (GET_CODE (_label) != CODE_LABEL)                                        \
+     rtl_check_failed_flag ("LABEL_KIND", _label, __FILE__, __LINE__,  \
+                           __FUNCTION__);                              \
+   (enum label_kind) ((_label->jump << 1) | _label->call); })
+
+/* Set the kind of LABEL.  */
+#define SET_LABEL_KIND(LABEL, KIND) do {                               \
+   rtx _label = (LABEL);                                               \
+   unsigned int _kind = (KIND);                                                \
+   if (GET_CODE (_label) != CODE_LABEL)                                        \
+     rtl_check_failed_flag ("SET_LABEL_KIND", _label, __FILE__, __LINE__, \
+                           __FUNCTION__);                              \
+   _label->jump = ((_kind >> 1) & 1);                                  \
+   _label->call = (_kind & 1);                                         \
+} while (0)
+
+#else
+
+/* Retrieve the kind of LABEL.  */
+#define LABEL_KIND(LABEL) \
+   ((enum label_kind) (((LABEL)->jump << 1) | (LABEL)->call))
+
+/* Set the kind of LABEL.  */
+#define SET_LABEL_KIND(LABEL, KIND) do {                               \
+   rtx _label = (LABEL);                                               \
+   unsigned int _kind = (KIND);                                                \
+   _label->jump = ((_kind >> 1) & 1);                                  \
+   _label->call = (_kind & 1);                                         \
+} while (0)
+
+#endif /* rtl flag checking */
+
+#define LABEL_ALT_ENTRY_P(LABEL) (LABEL_KIND (LABEL) != LABEL_NORMAL)
 
 /* The original regno this ADDRESSOF was built for.  */
 #define ADDRESSOF_REGNO(RTX) XCUINT (RTX, 1, ADDRESSOF)
@@ -915,9 +989,10 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
 #define REGNO(RTX) XCUINT (RTX, 0, REG)
 #define ORIGINAL_REGNO(RTX) X0UINT (RTX, 1)
 
-/* 1 if RTX is a reg that is the current function's return value.  */
+/* 1 if RTX is a reg or parallel that is the current function's return
+   value.  */
 #define REG_FUNCTION_VALUE_P(RTX)                                      \
-  (RTL_FLAG_CHECK1("REG_FUNCTION_VALUE_P", (RTX), REG)->integrated)
+  (RTL_FLAG_CHECK2("REG_FUNCTION_VALUE_P", (RTX), REG, PARALLEL)->integrated)
 
 /* 1 if RTX is a reg that corresponds to a variable declared by the user.  */
 #define REG_USERVAR_P(RTX)                                             \
@@ -938,14 +1013,13 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
 #define INTVAL(RTX) XCWINT(RTX, 0, CONST_INT)
 
 /* For a CONST_DOUBLE:
-   The usual two ints that hold the value.
-   For a DImode, that is all there are;
-    and CONST_DOUBLE_LOW is the low-order word and ..._HIGH the high-order.
-   For a float, the number of ints varies,
-    and CONST_DOUBLE_LOW is the one that should come first *in memory*.
-    So use &CONST_DOUBLE_LOW(r) as the address of an array of ints.  */
+   For a DImode, there are two integers CONST_DOUBLE_LOW is the
+     low-order word and ..._HIGH the high-order.
+   For a float, there is a REAL_VALUE_TYPE structure, and 
+     CONST_DOUBLE_REAL_VALUE(r) is a pointer to it.  */
 #define CONST_DOUBLE_LOW(r) XCWINT (r, 0, CONST_DOUBLE)
 #define CONST_DOUBLE_HIGH(r) XCWINT (r, 1, CONST_DOUBLE)
+#define CONST_DOUBLE_REAL_VALUE(r) ((struct real_value *)&CONST_DOUBLE_LOW(r))
 
 /* For a CONST_VECTOR, return element #n.  */
 #define CONST_VECTOR_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR)
@@ -1032,7 +1106,7 @@ do {                                                                      \
 #define MEM_SCALAR_P(RTX)                                              \
   (RTL_FLAG_CHECK1("MEM_SCALAR_P", (RTX), MEM)->frame_related)
 
-/* If VAL is non-zero, set MEM_IN_STRUCT_P and clear MEM_SCALAR_P in
+/* If VAL is nonzero, set MEM_IN_STRUCT_P and clear MEM_SCALAR_P in
    RTX.  Otherwise, vice versa.  Use this macro only when you are
    *sure* that you know that the MEM is in a structure, or is a
    scalar.  VAL is evaluated only once.  */
@@ -1118,8 +1192,8 @@ do {                                              \
 /* During sched, 1 if RTX is an insn that must be scheduled together
    with the preceding insn.  */
 #define SCHED_GROUP_P(RTX)                                             \
-  (RTL_FLAG_CHECK6("SCHED_GROUP_P", (RTX), INSN, JUMP_INSN, CALL_INSN, \
-                         CODE_LABEL, BARRIER, NOTE)->in_struct)
+  (RTL_FLAG_CHECK3("SCHED_GROUP_P", (RTX), INSN, JUMP_INSN, CALL_INSN  \
+                         )->in_struct)
 
 /* For a SET rtx, SET_DEST is the place that is set
    and SET_SRC is the value it is set to.  */
@@ -1163,7 +1237,6 @@ do {                                              \
 /* Define a macro to look for REG_INC notes,
    but save time on machines where they never exist.  */
 
-/* Don't continue this line--convex cc version 4.1 would lose.  */
 #if (defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT) || defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT))
 #define FIND_REG_INC_NOTE(INSN, REG)                   \
   ((REG) != NULL_RTX && REG_P ((REG))                  \
@@ -1176,7 +1249,6 @@ do {                                              \
 /* Indicate whether the machine has any sort of auto increment addressing.
    If not, we can avoid checking for REG_INC notes.  */
 
-/* Don't continue this line--convex cc version 4.1 would lose.  */
 #if (defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT) || defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT))
 #define AUTO_INC_DEC
 #endif
@@ -1415,6 +1487,9 @@ extern rtx next_label                     PARAMS ((rtx));
 extern rtx next_cc0_user               PARAMS ((rtx));
 extern rtx prev_cc0_setter             PARAMS ((rtx));
 
+/* In cfglayout.c  */
+extern tree choose_inner_scope         PARAMS ((tree, tree));
+
 /* In jump.c */
 extern rtx next_nondeleted_insn                PARAMS ((rtx));
 extern enum rtx_code reverse_condition PARAMS ((enum rtx_code));
@@ -1504,6 +1579,7 @@ extern rtx set_unique_reg_note            PARAMS ((rtx, enum reg_note, rtx));
 #define single_set_1(I) single_set_2 (I, PATTERN (I))
 
 extern int rtx_addr_can_trap_p         PARAMS ((rtx));
+extern bool nonzero_address_p          PARAMS ((rtx));
 extern int rtx_unstable_p              PARAMS ((rtx));
 extern int rtx_varies_p                        PARAMS ((rtx, int));
 extern int rtx_addr_varies_p           PARAMS ((rtx, int));
@@ -1710,6 +1786,7 @@ extern GTY(()) rtx return_address_pointer_rtx;
    should also modify gen_rtx to use the special function.  */
 
 extern rtx gen_rtx_CONST_INT PARAMS ((enum machine_mode, HOST_WIDE_INT));
+extern rtx gen_rtx_CONST_VECTOR PARAMS ((enum machine_mode, rtvec));
 extern rtx gen_raw_REG PARAMS ((enum machine_mode, int));
 extern rtx gen_rtx_REG PARAMS ((enum machine_mode, unsigned));
 extern rtx gen_rtx_SUBREG PARAMS ((enum machine_mode, rtx, int));
@@ -1762,7 +1839,7 @@ extern rtx gen_lowpart_SUBREG PARAMS ((enum machine_mode, rtx));
 #define VIRTUAL_OUTGOING_ARGS_REGNUM   ((FIRST_VIRTUAL_REGISTER) + 3)
 
 /* This points to the Canonical Frame Address of the function.  This
-   should corrospond to the CFA produced by INCOMING_FRAME_SP_OFFSET,
+   should correspond to the CFA produced by INCOMING_FRAME_SP_OFFSET,
    but is calculated relative to the arg pointer for simplicity; the
    frame pointer nor stack pointer are necessarily fixed relative to
    the CFA until after reload.  */
@@ -1870,6 +1947,7 @@ extern int invert_jump_1          PARAMS ((rtx, rtx));
 extern int invert_jump                 PARAMS ((rtx, rtx, int));
 extern int rtx_renumbered_equal_p      PARAMS ((rtx, rtx));
 extern int true_regnum                 PARAMS ((rtx));
+extern unsigned int reg_or_subregno    PARAMS ((rtx));
 extern int redirect_jump_1             PARAMS ((rtx, rtx));
 extern int redirect_jump               PARAMS ((rtx, rtx, int));
 extern void rebuild_jump_labels                PARAMS ((rtx));
@@ -2017,6 +2095,7 @@ extern int global_alloc                   PARAMS ((FILE *));
 extern void dump_global_regs           PARAMS ((FILE *));
 #endif
 #ifdef HARD_CONST
+/* Yes, this ifdef is silly, but HARD_REG_SET is not always defined.  */
 extern void retry_global_alloc         PARAMS ((int, HARD_REG_SET));
 #endif
 extern void build_insn_chain           PARAMS ((rtx));
@@ -2034,6 +2113,14 @@ extern void regclass                     PARAMS ((rtx, int, FILE *));
 extern void reg_scan                   PARAMS ((rtx, unsigned int, int));
 extern void reg_scan_update            PARAMS ((rtx, rtx, unsigned int));
 extern void fix_register               PARAMS ((const char *, int, int));
+#ifdef HARD_CONST
+extern void cannot_change_mode_set_regs PARAMS ((HARD_REG_SET *,
+                                                enum machine_mode,
+                                                unsigned int));
+#endif
+extern bool invalid_mode_change_p      PARAMS ((unsigned int,
+                                                enum reg_class,
+                                                enum machine_mode));
 
 extern int delete_null_pointer_checks  PARAMS ((rtx));
 
@@ -2059,7 +2146,7 @@ extern int function_invariant_p           PARAMS ((rtx));
 extern void init_branch_prob           PARAMS ((const char *));
 extern void branch_prob                        PARAMS ((void));
 extern void end_branch_prob            PARAMS ((void));
-extern void output_func_start_profiler PARAMS ((void));
+extern void create_profiler            PARAMS ((void));
 
 /* In reg-stack.c */
 #ifdef BUFSIZ
@@ -2194,4 +2281,38 @@ extern void invert_br_probabilities      PARAMS ((rtx));
 extern bool expensive_function_p       PARAMS ((int));
 /* In tracer.c */
 extern void tracer                     PARAMS ((void));
+
+/* In calls.c */
+
+/* Nonzero if this is a call to a `const' function.  */
+#define ECF_CONST              1
+/* Nonzero if this is a call to a `volatile' function.  */
+#define ECF_NORETURN           2
+/* Nonzero if this is a call to malloc or a related function.  */
+#define ECF_MALLOC             4
+/* Nonzero if it is plausible that this is a call to alloca.  */
+#define ECF_MAY_BE_ALLOCA      8
+/* Nonzero if this is a call to a function that won't throw an exception.  */
+#define ECF_NOTHROW            16
+/* Nonzero if this is a call to setjmp or a related function.  */
+#define ECF_RETURNS_TWICE      32
+/* Nonzero if this is a call to `longjmp'.  */
+#define ECF_LONGJMP            64
+/* Nonzero if this is a syscall that makes a new process in the image of
+   the current one.  */
+#define ECF_FORK_OR_EXEC       128
+#define ECF_SIBCALL            256
+/* Nonzero if this is a call to "pure" function (like const function,
+   but may read memory.  */
+#define ECF_PURE               512
+/* Nonzero if this is a call to a function that returns with the stack
+   pointer depressed.  */
+#define ECF_SP_DEPRESSED       1024
+/* Nonzero if this call is known to always return.  */
+#define ECF_ALWAYS_RETURN      2048
+/* Create libcall block around the call.  */
+#define ECF_LIBCALL_BLOCK      4096
+
+extern int flags_from_decl_or_type             PARAMS ((tree));
+
 #endif /* ! GCC_RTL_H */