aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Ornstein <andrea.ornstein@st.com>2008-04-30 17:04:44 +0000
committerAndrea Ornstein <andrea.ornstein@st.com>2008-04-30 17:04:44 +0000
commit38eb3575c5bc038cdfed3b79e5cdab05debb6422 (patch)
tree0d9442b28b4d837a5a9f0ccae1c8481702ee16a9
parent08919ecb3b4fbe65d9768e025e6737db5ddcf009 (diff)
New Snapshot from ST 2008-04-30 (rev 1092)
Changes from Erven Rohou, Gabriele Svelto and Andrea Ornstein ........ CIL BE: Moved the type/string/pinvoke marking machinery from gen-cil.c and into an external file. Also moved the name-mangling functionality there and added proper garbage collection to the various containers. ........ CIL BE: Promote emit-cil-vcg to a pass and remove code from gen_cil add new function in gen_cil 'gen_cil_bb' that emits all instructions of a basic_block move calls to refs_init and refs_fini to cil32.c ........ CIL BE: Emulation of the computed GOTOs when more than one function used them in the same compilation unit was broken and didn't interact properly with the GC. Both issues have been fixed. ........ git-svn-id: https://gcc.gnu.org/svn/gcc/branches/st/cli@134831 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/config.gcc5
-rw-r--r--gcc/config/cil32/cil-refs.c895
-rw-r--r--gcc/config/cil32/cil-refs.h288
-rw-r--r--gcc/config/cil32/cil-types.h67
-rw-r--r--gcc/config/cil32/cil32.c63
-rw-r--r--gcc/config/cil32/cil32.h1
-rw-r--r--gcc/config/cil32/gen-cil.c1123
-rw-r--r--gcc/config/cil32/gen-cil.h8
-rw-r--r--gcc/config/cil32/t-cil3215
-rw-r--r--gcc/config/cil32/tree-simp-cil.c8
-rw-r--r--gcc/passes.c1
11 files changed, 1570 insertions, 904 deletions
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 1e046bc6937..501dc416297 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -856,8 +856,9 @@ c4x-* | tic4x-*)
cil32-*-*)
gas=no
use_collect2=no
- extra_objs="tree-simp-cil.o tree-simp-cil-early.o bit-stream.o emit-hints.o gen-cil.o bb-layout.o rm-ldloc.o"
- target_gtfiles="\$(srcdir)/config/cil32/gen-cil.c"
+ extra_objs="tree-simp-cil.o tree-simp-cil-early.o bit-stream.o emit-hints.o gen-cil.o bb-layout.o rm-ldloc.o cil-refs.o"
+ tm_file="${tm_file} cil32/cil-types.h"
+ target_gtfiles="\$(srcdir)/config/cil32/gen-cil.c \$(srcdir)/config/cil32/cil-refs.c"
;;
cris-*-aout)
tm_file="dbxelf.h ${tm_file} cris/aout.h"
diff --git a/gcc/config/cil32/cil-refs.c b/gcc/config/cil32/cil-refs.c
new file mode 100644
index 00000000000..db4cf302aea
--- /dev/null
+++ b/gcc/config/cil32/cil-refs.c
@@ -0,0 +1,895 @@
+/* Database of entities referenced in a compilation unit implementation.
+
+ Copyright (C) 2006-2008 Free Software Foundation, Inc.
+
+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, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+Authors:
+ Andrea Ornstein
+ Erven Rohou
+ Gabriele Svelto
+
+Contact information at STMicroelectronics:
+Andrea C. Ornstein <andrea.ornstein@st.com>
+Erven Rohou <erven.rohou@st.com>
+*/
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "ggc.h"
+#include "debug.h"
+#include "errors.h"
+#include "tree.h"
+#include "hashtab.h"
+#include "vec.h"
+#include "cil-types.h"
+#include "cil-refs.h"
+
+/******************************************************************************
+ * Local function prototypes *
+ ******************************************************************************/
+
+static char *append_string (char *, const char *, size_t *, size_t *);
+static char *append_coded_type (char *, tree, size_t *, size_t *);
+static char *get_compact_identifier (const char *, size_t, size_t *);
+static tree make_valuetype_identifier (tree);
+
+static hashval_t str_ref_hash (const void *);
+static int str_ref_eq (const void *, const void *);
+static int ref_str_trav (void **, void *);
+
+static int ref_pinvoke_trav (void **, void *);
+
+static hashval_t label_addr_hash (const void *);
+static int label_addr_eq (const void *, const void *);
+static int fill_label_addrs (void **, void *);
+
+/******************************************************************************
+ * Globals *
+ ******************************************************************************/
+
+static GTY((param_is (union tree_node))) htab_t ref_types = NULL;
+static GTY((param_is (struct str_ref_d))) htab_t ref_strings = NULL;
+static GTY((param_is (union tree_node))) htab_t ref_pinvokes = NULL;
+static unsigned int string_id = 0;
+static GTY((param_is (struct label_addr_d))) htab_t labels_map = NULL;
+static unsigned int label_id;
+static tree *label_addrs;
+
+/******************************************************************************
+ * Initialization and teardown *
+ ******************************************************************************/
+
+/* Initialize the database of referenced entities. */
+
+void
+refs_init (void)
+{
+ ref_types = htab_create_ggc (32, htab_hash_pointer, htab_eq_pointer, NULL);
+ ref_pinvokes = htab_create_ggc (32, htab_hash_pointer, htab_eq_pointer, NULL);
+ ref_strings = htab_create_ggc (32, str_ref_hash, str_ref_eq, NULL);
+ labels_map = htab_create_ggc (32, label_addr_hash, label_addr_eq, NULL);
+ label_id = 0;
+ label_addrs = NULL;
+}
+
+/* Tears down the database of referenced entities. */
+
+void refs_fini (void)
+{
+ ref_types = NULL;
+ ref_pinvokes = NULL;
+ ref_strings = NULL;
+ labels_map = NULL;
+}
+
+/* This function must be called at the beginning of the first of our phase to
+ mark the beginning of a new function context. */
+
+void
+refs_begin_new_function (void)
+{
+ if (label_addrs)
+ XDELETEVEC (label_addrs);
+
+ label_id = 0;
+ label_addrs = NULL;
+}
+
+/******************************************************************************
+ * Referenced types *
+ ******************************************************************************/
+
+/* Warning: these strings are not null-terminated */
+static char *
+append_string (char *str, const char *to_append, unsigned int *len,
+ unsigned int *max_len)
+{
+ size_t i, orig_len = *len;
+ size_t append_len = strlen (to_append);
+
+ *len += append_len;
+
+ if (*len > *max_len)
+ {
+ while (*len > *max_len)
+ *max_len *= 2;
+
+ str = XRESIZEVEC (char, str, *max_len);
+ }
+
+ for (i = 0; i < append_len; i++)
+ str[orig_len + i] = to_append[i];
+
+ return str;
+}
+
+/* Warning: these strings are not null-terminated */
+static char *
+append_coded_type (char *str, tree type,
+ unsigned int *len, unsigned int *max_len)
+{
+ enum tree_code type_code;
+
+ if (type == NULL_TREE || type == error_mark_node)
+ return str;
+
+ type = TYPE_MAIN_VARIANT (type);
+ type_code = TREE_CODE (type);
+
+restartswitch:
+ switch (type_code)
+ {
+ case VOID_TYPE:
+ str = append_string (str, "VOID", len, max_len);
+ break;
+
+ case INTEGER_TYPE:
+ {
+ int type_size = TYPE_PRECISION (type);
+ char tmp_str[8] = "UI";
+ char *tmp_str_ptr = tmp_str;
+
+ snprintf (tmp_str_ptr + 2, 6, "%d", type_size);
+
+ if (!TYPE_UNSIGNED (type))
+ tmp_str_ptr++;
+
+ str = append_string (str, tmp_str_ptr, len, max_len);
+ }
+ break;
+
+ case BOOLEAN_TYPE:
+ str = append_string (str, "B", len, max_len);
+ break;
+
+ case REAL_TYPE:
+ {
+ int type_size = TYPE_PRECISION (type);
+ char tmp_str[4] = "F";
+
+ snprintf (tmp_str + 1, 3, "%d", type_size);
+
+ str = append_string (str, tmp_str, len, max_len);
+ }
+ break;
+
+ case POINTER_TYPE:
+ if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
+ {
+ tree fun_type = TREE_TYPE (type);
+ tree args_type = TYPE_ARG_TYPES (fun_type);
+/* bool varargs = TREE_VALUE (tree_last (args_type)) != void_type_node; */
+ unsigned int nargs_base = list_length (args_type);
+ unsigned int i;
+ char tmp_str[5] = "FP";
+
+ snprintf (tmp_str + 2, 3, "%d", nargs_base);
+ str = append_string (str, tmp_str, len, max_len);
+ str = append_string (str, "_", len, max_len);
+ str = append_coded_type (str, TREE_TYPE (fun_type), len, max_len);
+ str = append_string (str, "_", len, max_len);
+
+ for (i = 0; i < nargs_base; i++)
+ {
+ str = append_string (str, "_", len, max_len);
+ str = append_coded_type (str, TREE_VALUE (args_type), len, max_len);
+ args_type = TREE_CHAIN (args_type);
+ }
+ }
+ else
+ {
+ str = append_string (str, "*", len, max_len);
+ type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
+ type_code = TREE_CODE (type);
+ goto restartswitch;
+ }
+ break;
+
+ case ARRAY_TYPE:
+ if (TYPE_DOMAIN (type) && ! ARRAY_TYPE_VARLENGTH (type))
+ {
+ tree domain = TYPE_DOMAIN (type);
+ tree min = TYPE_MIN_VALUE (domain);
+ tree max = TYPE_MAX_VALUE (domain);
+
+ str = append_string (str, "[", len, max_len);
+
+ if (ARRAY_TYPE_ZEROLENGTH (type))
+ str = append_string (str, "0", len, max_len);
+ else if (min && max && integer_zerop (min) && host_integerp (max, 0))
+ {
+ unsigned int size = TREE_INT_CST_LOW (max) + 1;
+ char tmp_str[32];
+
+ snprintf (tmp_str, 32, "%d", size);
+ str = append_string (str, tmp_str, len, max_len);
+ }
+ else
+ str = append_string (str, "unk", len, max_len);
+
+ str = append_string (str, "]", len, max_len);
+ }
+ else
+ {
+ type_code = POINTER_TYPE;
+ goto restartswitch;
+ }
+
+ type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
+ type_code = TREE_CODE (type);
+ goto restartswitch;
+
+ case ENUMERAL_TYPE:
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ {
+ const char *prefix;
+ const char *type_str;
+ tree type_name;
+
+ /* Give the aggregate a name unless it has it already */
+ if (TYPE_NAME (type) == 0)
+ {
+ tree type_decl = build0 (TYPE_DECL, type);
+ DECL_NAME (type_decl) = make_valuetype_identifier (type);
+ TYPE_NAME (type) = type_decl;
+ }
+
+ type_name = TYPE_NAME (type);
+
+ if (TREE_CODE (type_name) == IDENTIFIER_NODE)
+ type_str = IDENTIFIER_POINTER (type_name);
+ else
+ type_str = IDENTIFIER_POINTER (DECL_NAME (type_name));
+
+ switch (type_code)
+ {
+ case ENUMERAL_TYPE:
+ prefix = "E";
+ break;
+
+ case RECORD_TYPE:
+ prefix = "S";
+ break;
+
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ prefix = "UN";
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ str = append_string (str, prefix, len, max_len);
+ str = append_string (str, type_str, len, max_len);
+ }
+ break;
+
+ default:
+/* debug_tree(type); */
+/* gcc_assert (0); */
+ str = append_string (str, "unknown", len, max_len);
+ }
+
+ return str;
+}
+
+/* Compute and return a compact identifier from identifier STR of size LEN.
+ Memory is allocated for the compact identifier.
+ Store the length of the compact identifier in COMPACT_LEN. */
+
+static char *
+get_compact_identifier (const char *str, size_t len, size_t *compact_len)
+{
+ char *compact_str;
+ size_t i;
+ unsigned char buffer[COMPACT_ID_LENGTH / 2];
+
+ gcc_assert (COMPACT_ID_LENGTH % 2 == 0);
+
+ /* If the string is shorter than the length of compact strings,
+ then return it unchanged. */
+ if (len <= COMPACT_ID_LENGTH)
+ {
+ compact_str = XNEWVEC (char, len);
+ memcpy (compact_str, str, len);
+
+ *compact_len = len;
+ return compact_str;
+ }
+
+ /* Fill the buffer */
+ memset (buffer, 0, COMPACT_ID_LENGTH / 2);
+
+ for (i = 0; i < len; i++)
+ {
+ int j = 0;
+ unsigned char c = str[i];
+
+ while (true)
+ {
+ unsigned char tmp_c;
+
+ /* Modify a position in buffer */
+ buffer[(i + j) % (COMPACT_ID_LENGTH / 2)] ^= c;
+
+ if (j == COMPACT_ID_LENGTH / 2)
+ break;
+
+ /* Rotate c 1-bit right */
+ tmp_c = c >> 1;
+ tmp_c |= (c & 1) << 7;
+ c = tmp_c;
+
+ j++;
+ }
+ }
+
+ /* Build the compact string */
+ compact_str = XNEWVEC (char, COMPACT_ID_LENGTH);
+
+ for (i = 0; i < COMPACT_ID_LENGTH / 2; i++)
+ {
+ unsigned char c1, c2;
+
+ c1 = buffer[i] & 0xf;
+ c2 = buffer[i] >> 4;
+
+ compact_str[i * 2] = c1 + ((c1 < 10) ? '0' : 'a' - 10);
+ compact_str[i * 2 + 1] = c2 + ((c2 < 10) ? '0' : 'a' - 10);
+ }
+
+ /* Return the compact string and its length */
+ *compact_len = COMPACT_ID_LENGTH;
+ return compact_str;
+}
+
+static tree
+make_valuetype_identifier (tree t)
+{
+ size_t tmp_name_max_len = 256;
+ size_t tmp_name_len = 0;
+ char *tmp_name;
+ size_t vt_name_len = 0;
+ char *vt_name;
+ tree ident;
+
+ tmp_name = XNEWVEC (char, tmp_name_max_len);
+
+ if (TREE_CODE (t) == ENUMERAL_TYPE)
+ {
+ tree tmp;
+
+ tmp_name = append_string (tmp_name, "enum?",
+ &tmp_name_len, &tmp_name_max_len);
+ tmp = TYPE_VALUES (t);
+
+ while (tmp)
+ {
+ tmp_name = append_string (tmp_name,
+ IDENTIFIER_POINTER (TREE_PURPOSE (tmp)),
+ &tmp_name_len, &tmp_name_max_len);
+ tmp_name = append_string (tmp_name, "?",
+ &tmp_name_len, &tmp_name_max_len);
+ tmp = TREE_CHAIN (tmp);
+ }
+ }
+ else if (TREE_CODE (t) == ARRAY_TYPE)
+ {
+ gcc_assert (TYPE_DOMAIN (t) && ! ARRAY_TYPE_VARLENGTH (t));
+ tmp_name = append_string (tmp_name, "array?",
+ &tmp_name_len, &tmp_name_max_len);
+ tmp_name = append_coded_type (tmp_name, t,
+ &tmp_name_len, &tmp_name_max_len);
+ }
+ else
+ {
+ tree tmp;
+
+ if (TREE_CODE (t) == RECORD_TYPE)
+ tmp_name = append_string (tmp_name, "struct?",
+ &tmp_name_len, &tmp_name_max_len);
+ else
+ tmp_name = append_string (tmp_name, "union?",
+ &tmp_name_len, &tmp_name_max_len);
+
+ tmp = TYPE_FIELDS (t);
+ while (tmp)
+ {
+ tree ttype = TREE_TYPE (tmp);
+
+ tmp_name = append_coded_type (tmp_name, ttype,
+ &tmp_name_len, &tmp_name_max_len);
+ tmp_name = append_string (tmp_name, "?",
+ &tmp_name_len, &tmp_name_max_len);
+ if (DECL_NAME (tmp) != NULL_TREE)
+ {
+ tmp_name = append_string (tmp_name,
+ IDENTIFIER_POINTER (DECL_NAME (tmp)),
+ &tmp_name_len, &tmp_name_max_len);
+ }
+ else
+ {
+ /* Unnamed bitfields or unions */
+ tmp_name = append_string (tmp_name, "?unnamed",
+ &tmp_name_len, &tmp_name_max_len);
+ }
+
+ tmp_name = append_string (tmp_name, "?",
+ &tmp_name_len, &tmp_name_max_len);
+ tmp = TREE_CHAIN (tmp);
+ }
+ }
+
+ vt_name = get_compact_identifier (tmp_name, tmp_name_len, &vt_name_len);
+ XDELETEVEC (tmp_name);
+
+ ident = get_identifier_with_length (vt_name, vt_name_len);
+ XDELETEVEC (vt_name);
+
+ return ident;
+}
+
+/* Mark the type represented by tree T as referenced.
+ This function works recursively, since types referenced by type T
+ itself are also marked as referenced.
+ Referenced types are emitted at the end of the compilation unit,
+ non-referenced types are not.
+ T must be a type node. */
+
+void
+mark_referenced_type (tree t)
+{
+ void **slot;
+
+ if (t == NULL_TREE || t == error_mark_node)
+ return;
+
+ t = TYPE_MAIN_VARIANT (t);
+
+ if (t == cil32_arg_iterator_type)
+ return;
+
+ /* If the type was already referenced, nothing else to do */
+ slot = htab_find_slot (ref_types, t, INSERT);
+
+ if (*slot != NULL)
+ return;
+
+ /* Give the aggregate a name unless it has it already */
+ switch (TREE_CODE (t))
+ {
+ /* Incomplete and variable-length arrays are pointers and
+ they must be dealt with as such. */
+ case ARRAY_TYPE:
+ if (! TYPE_DOMAIN (t) || ARRAY_TYPE_VARLENGTH (t))
+ break;
+
+ case ENUMERAL_TYPE:
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ if (TYPE_NAME (t) == NULL_TREE)
+ {
+ tree type_decl = build0 (TYPE_DECL, t);
+ DECL_NAME (type_decl) = make_valuetype_identifier (t);
+ TYPE_NAME (t) = type_decl;
+ }
+ break;
+
+ default:
+ /* Nothing to do for the other types */
+ ;
+ }
+
+ /* Transform local-scope types into global-scope types */
+ if (!TYPE_FILE_SCOPE_P (t))
+ {
+ tree type_name = TYPE_NAME (t);
+ const char *orig_name;
+ size_t tmp_name_max_len = 256;
+ size_t tmp_name_len = 0;
+ char *tmp_name;
+ char suffix[32];
+
+ gcc_assert (type_name != 0);
+ gcc_assert (DECL_P (type_name)
+ || TREE_CODE (type_name) == IDENTIFIER_NODE);
+
+ if (TREE_CODE (type_name) == IDENTIFIER_NODE)
+ orig_name = IDENTIFIER_POINTER (type_name);
+ else
+ orig_name = IDENTIFIER_POINTER (DECL_NAME (type_name));
+
+ snprintf (suffix, 15, "?vt%u", TYPE_UID (t));
+
+ tmp_name = XNEWVEC (char, tmp_name_max_len);
+ tmp_name = append_string (tmp_name, orig_name,
+ &tmp_name_len, &tmp_name_max_len);
+ tmp_name = append_string (tmp_name, suffix,
+ &tmp_name_len, &tmp_name_max_len);
+
+ TYPE_NAME (t) = get_identifier_with_length (tmp_name, tmp_name_len);
+ TYPE_CONTEXT (t) = 0;
+ XDELETEVEC (tmp_name);
+ }
+
+ switch (TREE_CODE (t))
+ {
+ case ENUMERAL_TYPE:
+ *slot = t;
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ {
+ tree tmp;
+
+ *slot = t;
+ tmp = TYPE_FIELDS (t);
+
+ while (tmp)
+ {
+ if (DECL_BIT_FIELD (tmp))
+ mark_referenced_type (DECL_BIT_FIELD_TYPE (tmp));
+ else
+ mark_referenced_type (TREE_TYPE (tmp));
+
+ tmp = TREE_CHAIN (tmp);
+ }
+ }
+ break;
+
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ mark_referenced_type (TREE_TYPE (t));
+ break;
+
+ case ARRAY_TYPE:
+ if (TYPE_DOMAIN (t) && !ARRAY_TYPE_VARLENGTH (t))
+ *slot = t;
+
+ mark_referenced_type (TREE_TYPE (t));
+ break;
+
+ case FUNCTION_TYPE:
+ {
+ tree args_type;
+
+ mark_referenced_type (TREE_TYPE (t));
+ args_type = TYPE_ARG_TYPES (t);
+
+ while (args_type)
+ {
+ mark_referenced_type (TREE_VALUE (args_type));
+ args_type = TREE_CHAIN (args_type);
+ }
+ }
+ break;
+
+ default:
+ /* Nothing to do for the other types */
+ ;
+ }
+}
+
+/* Helper function for filling the referenced types iterator's emebbeded
+ vector with the contents of the referenced pinvoked function table. */
+
+static int
+ref_types_trav (void **slot, void *data)
+{
+ VEC (tree, heap) *vec = data;
+
+ VEC_quick_push (tree, vec, *slot);
+ return true;
+}
+
+/* Creates a new referenced types iterator. */
+
+types_iterator
+rti_begin (void)
+{
+ types_iterator rti = XNEW (struct types_iterator_d);
+
+ rti->types = VEC_alloc (tree, heap, htab_elements (ref_types));
+ htab_traverse_noresize (ref_types, ref_types_trav, rti->types);
+ rti->i = 0;
+
+ return rti;
+}
+
+/******************************************************************************
+ * Strings *
+ ******************************************************************************/
+
+/* Hash value calculation function for referenced strings. */
+
+static hashval_t
+str_ref_hash (const void *ptr)
+{
+ str_ref ref = (str_ref) ptr;
+ const char *str = TREE_STRING_POINTER (ref->cst);
+ hashval_t hash = 0;
+ size_t len = TREE_STRING_LENGTH (ref->cst);
+ size_t i;
+
+ for (i = 0; i < len; i++)
+ {
+ hash += str[i];
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+
+ return hash;
+}
+
+/* Equality function for referenced strings. */
+
+static int
+str_ref_eq (const void *ptr1, const void *ptr2)
+{
+ const char *str1 = TREE_STRING_POINTER (((str_ref) ptr1)->cst);
+ const char *str2 = TREE_STRING_POINTER (((str_ref) ptr2)->cst);
+
+ return str1 == str2;
+}
+
+/* Mark the string represented by tree STR as referenced. If an identical
+ string has been already marked it will be returned, otherwise STR will
+ will be returnd. Referenced strings are emitted at the end of the
+ compilation unit, non-referenced strings are not. STR must be a STRING_CST
+ node. */
+
+tree
+mark_referenced_string (tree str)
+{
+ struct str_ref_d tmp;
+ void **slot;
+
+ tmp.cst = str;
+ slot = htab_find_slot (ref_strings, &tmp, INSERT);
+
+ if (*slot == NULL)
+ {
+ str_ref ref = GGC_NEW (struct str_ref_d);
+
+ ref->cst = str;
+ ref->id = string_id++;
+ *slot = ref;
+
+ return str;
+ }
+ else
+ return ((str_ref) *slot)->cst;
+}
+
+/* Get an unique id for string constant NODE. */
+
+unsigned int
+get_string_cst_id (tree str)
+{
+ struct str_ref_d tmp;
+ void **slot;
+
+ tmp.cst = str;
+ slot = htab_find_slot (ref_strings, &tmp, INSERT);
+
+ gcc_assert (*slot != NULL);
+ return ((str_ref) *slot)->id;
+}
+
+/* Helper function for filling the referenced strings iterator's emebbeded
+ vector with the contents of the referenced strings table. */
+
+static int
+ref_str_trav (void **slot, void *data)
+{
+ VEC (str_ref, heap) *vec = data;
+
+ VEC_quick_push (str_ref, vec, *slot);
+ return true;
+}
+
+/* Creates a new referenced strings iterator. */
+
+ref_str_iterator
+rsi_begin (void)
+{
+ ref_str_iterator rsi = XNEW (struct ref_str_iterator_d);
+
+ rsi->strings = VEC_alloc (str_ref, heap, htab_elements (ref_strings));
+ htab_traverse_noresize (ref_strings, ref_str_trav, rsi->strings);
+ rsi->i = 0;
+
+ return rsi;
+}
+
+/******************************************************************************
+ * Functions *
+ ******************************************************************************/
+
+/* Mark the function represented by tree T as a pinvoke.
+ T must be a FUNCTION_DECL node. */
+
+void
+cil_add_pinvoke (tree t)
+{
+ void **slot;
+
+ gcc_assert (TREE_CODE (t) == FUNCTION_DECL);
+
+ slot = htab_find_slot (ref_pinvokes, t, INSERT);
+
+ if (*slot == NULL)
+ *slot = t;
+
+ mark_referenced_type (TREE_TYPE (t));
+}
+
+/* Helper function for filling the referenced pinvoked functions iterator's
+ emebbeded vector with the contents of the referenced pinvoked function
+ table. */
+
+static int
+ref_pinvoke_trav (void **slot, void *data)
+{
+ VEC (tree, heap) *vec = data;
+
+ VEC_quick_push (tree, vec, *slot);
+ return true;
+}
+
+/* Creates a new pinvoked functions iterator. */
+
+pinvoke_iterator
+rpi_begin (void)
+{
+ pinvoke_iterator rpi = XNEW (struct pinvoke_iterator_d);
+
+ rpi->functions = VEC_alloc (tree, heap, htab_elements (ref_pinvokes));
+ htab_traverse_noresize (ref_pinvokes, ref_pinvoke_trav, rpi->functions);
+ rpi->i = 0;
+
+ return rpi;
+}
+
+/******************************************************************************
+ * Labels *
+ ******************************************************************************/
+
+/* Hash and equality functions for label addresses. */
+
+static hashval_t
+label_addr_hash (const void *ptr)
+{
+ const label_addr addr = (const label_addr) ptr;
+
+ return (hashval_t) ((long) addr->label >> 3);
+}
+
+/* Equality function for label addresses. */
+
+static int
+label_addr_eq (const void *ptr1, const void *ptr2)
+{
+ const label_addr addr1 = (const label_addr) ptr1;
+ const label_addr addr2 = (const label_addr) ptr2;
+
+ return addr1->label == addr2->label;
+}
+
+/* Add a LABEL_DECL to the map of labels whose addresses were taken. */
+
+void
+record_addr_taken_label (tree label)
+{
+ void **slot;
+ label_addr addr = GGC_NEW (struct label_addr_d);
+
+ addr->label = label;
+ addr->id = build_int_cst (intSI_type_node, label_id);
+ label_id++;
+
+ gcc_assert (htab_find (labels_map, addr) == NULL);
+ slot = htab_find_slot (labels_map, addr, INSERT);
+ *slot = addr;
+}
+
+/* Returns the integer ID corresponding to the label LABEL. */
+
+tree
+get_addr_taken_label_id (tree label)
+{
+ struct label_addr_d addr;
+
+ addr.label = label;
+ addr.id = NULL_TREE;
+
+ return ((label_addr) htab_find (labels_map, &addr))->id;
+}
+
+/* Helper function used by get_label_addr_ids(). */
+
+static int
+fill_label_addrs (void **slot, void *data)
+{
+ tree *addrs = data;
+ label_addr addr = *slot;
+
+ if (DECL_CONTEXT (addr->label) == current_function_decl)
+ addrs[tree_low_cst (addr->id, 1)] = addr->label;
+
+ return 1;
+}
+
+/* Return a tree array holding the INTEGER_CST used as IDs for mimicking the
+ label addresses in computed GOTO statements. The underlying array is
+ allocated lazily. */
+
+tree *
+get_label_addrs ( void )
+{
+ if (label_addrs == NULL)
+ {
+ label_addrs = XNEWVEC (tree, label_id);
+ htab_traverse (labels_map, fill_label_addrs, label_addrs);
+ }
+
+ return label_addrs;
+}
+
+/* Return the number of labels of this function whose address was taken. */
+
+unsigned int
+get_label_addrs_n ( void )
+{
+ return label_id;
+}
+
+#include "gt-cil-refs.h"
diff --git a/gcc/config/cil32/cil-refs.h b/gcc/config/cil32/cil-refs.h
new file mode 100644
index 00000000000..10ce7c9cb0d
--- /dev/null
+++ b/gcc/config/cil32/cil-refs.h
@@ -0,0 +1,288 @@
+/* Database of entities referenced in a compilation unit.
+
+ Copyright (C) 2006-2008 Free Software Foundation, Inc.
+
+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, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+Authors:
+ Andrea Ornstein
+ Erven Rohou
+ Gabriele Svelto
+
+Contact information at STMicroelectronics:
+Andrea C. Ornstein <andrea.ornstein@st.com>
+Erven Rohou <erven.rohou@st.com>
+*/
+
+#ifndef CIL_REFS_H
+#define CIL_REFS_H
+
+#include "coretypes.h"
+#include "ggc.h"
+#include "debug.h"
+#include "vec.h"
+#include "tree.h"
+#include "cil-types.h"
+
+/******************************************************************************
+ * Macros *
+ ******************************************************************************/
+
+/* Nonzero for a type which is at file scope. */
+#define TYPE_FILE_SCOPE_P(EXP) \
+ (! TYPE_CONTEXT (EXP) \
+ || TREE_CODE (TYPE_CONTEXT (EXP)) == TRANSLATION_UNIT_DECL)
+
+/* Nonzero for a zero-length array type */
+#define ARRAY_TYPE_ZEROLENGTH(EXP) \
+ (TYPE_SIZE (EXP) == NULL_TREE)
+
+/* Nonzero for a variable-length array type */
+#define ARRAY_TYPE_VARLENGTH(EXP) \
+ (TYPE_SIZE (EXP) != NULL_TREE && TREE_CODE (TYPE_SIZE (EXP)) != INTEGER_CST)
+
+/* Length of compacted identifiers (in characters) */
+#define COMPACT_ID_LENGTH 16
+
+/*****************************************************************************
+ * Initialization and teardown *
+ *****************************************************************************/
+
+extern void refs_init (void);
+extern void refs_fini (void);
+extern void refs_begin_new_function (void);
+
+/*****************************************************************************
+ * Types *
+ *****************************************************************************/
+
+extern void mark_referenced_type (tree);
+
+/* Referenced pinvoke functions iterator. */
+
+struct types_iterator_d
+{
+ /* Vector of referenced types. */
+ VEC (tree, heap) *types;
+
+ /* Current type. */
+ unsigned int i;
+};
+
+typedef struct types_iterator_d *types_iterator;
+
+extern types_iterator rti_begin (void);
+static inline void rti_destroy (types_iterator);
+static inline bool rti_end_p (types_iterator);
+static inline tree rti_type (types_iterator);
+static inline void rti_next (types_iterator);
+
+/* Disposes of the referenced types iterator specified by RTI. */
+
+static inline void
+rti_destroy (types_iterator rti)
+{
+ VEC_free (tree, heap, rti->types);
+ XDELETE (rti);
+}
+
+/* Returns false if some referenced types which haven't yet been iterated
+ over are present, true otherwise. */
+
+static inline bool
+rti_end_p (types_iterator rti)
+{
+ if (rti->i == VEC_length (tree, rti->types))
+ return true;
+ else
+ return false;
+}
+
+/* Returns the TYPE_DECL of the current referenced type. */
+
+static inline tree
+rti_type (types_iterator rti)
+{
+ return VEC_index (tree, rti->types, rti->i);
+}
+
+/* Move to the next type. */
+
+static inline void
+rti_next (types_iterator rti)
+{
+ gcc_assert (rti->i < VEC_length (tree, rti->types));
+
+ rti->i++;
+}
+
+/******************************************************************************
+ * Strings *
+ ******************************************************************************/
+
+extern tree mark_referenced_string (tree);
+extern unsigned int get_string_cst_id (tree);
+
+/* Referenced strings vector. */
+
+DEF_VEC_P(str_ref);
+DEF_VEC_ALLOC_P(str_ref, heap);
+
+/* Referenced strings iterator. */
+
+struct ref_str_iterator_d
+{
+ /* Vector of referenced strings. */
+ VEC (str_ref, heap) *strings;
+
+ /* Current string. */
+ unsigned int i;
+};
+
+typedef struct ref_str_iterator_d *ref_str_iterator;
+
+extern ref_str_iterator rsi_begin (void);
+static inline void rsi_destroy (ref_str_iterator);
+static inline bool rsi_end_p (ref_str_iterator);
+static inline tree rsi_string (ref_str_iterator);
+static inline unsigned int rsi_id (ref_str_iterator);
+static inline void rsi_next (ref_str_iterator);
+
+/* Disposes of the string reference iterator specified by RSI. */
+
+static inline void
+rsi_destroy (ref_str_iterator rsi)
+{
+ VEC_free (str_ref, heap, rsi->strings);
+ XDELETE (rsi);
+}
+
+/* Returns false if some strings which haven't yet been iterated over are
+ present, true otherwise. */
+
+static inline bool
+rsi_end_p (ref_str_iterator rsi)
+{
+ if (rsi->i == VEC_length (str_ref, rsi->strings))
+ return true;
+ else
+ return false;
+}
+
+/* Returns the STRING_CST associated with the current string. */
+
+static inline tree
+rsi_string (ref_str_iterator rsi)
+{
+ str_ref elem = VEC_index (str_ref, rsi->strings, rsi->i);
+
+ return elem->cst;
+}
+
+/* Return the unique ID associated with the current string. */
+
+static inline unsigned int
+rsi_id (ref_str_iterator rsi)
+{
+ return VEC_index (str_ref, rsi->strings, rsi->i)->id;
+}
+
+/* Move to the next string. */
+
+static inline void
+rsi_next (ref_str_iterator rsi)
+{
+ gcc_assert (rsi->i < VEC_length (str_ref, rsi->strings));
+
+ rsi->i++;
+}
+
+/******************************************************************************
+ * Functions *
+ ******************************************************************************/
+
+extern void cil_add_pinvoke (tree);
+
+/* Referenced pinvoke functions iterator. */
+
+struct pinvoke_iterator_d
+{
+ /* Vector of referenced pinvoke functions. */
+ VEC (tree, heap) *functions;
+
+ /* Current function. */
+ unsigned int i;
+};
+
+typedef struct pinvoke_iterator_d *pinvoke_iterator;
+
+extern pinvoke_iterator rpi_begin (void);
+static inline void rpi_destroy (pinvoke_iterator);
+static inline bool rpi_end_p (pinvoke_iterator);
+static inline tree rpi_function (pinvoke_iterator);
+static inline void rpi_next (pinvoke_iterator);
+
+/* Disposes of the pinvoked function iterator specified by RPI. */
+
+static inline void
+rpi_destroy (pinvoke_iterator rpi)
+{
+ VEC_free (tree, heap, rpi->functions);
+ XDELETE (rpi);
+}
+
+/* Returns false if some pinvoked functions which haven't yet been iterated
+ over are present, true otherwise. */
+
+static inline bool
+rpi_end_p (pinvoke_iterator rpi)
+{
+ if (rpi->i == VEC_length (tree, rpi->functions))
+ return true;
+ else
+ return false;
+}
+
+/* Returns the FUNCTION_DECL of the current pinvoked function. */
+
+static inline tree
+rpi_function (pinvoke_iterator rpi)
+{
+ return VEC_index (tree, rpi->functions, rpi->i);
+}
+
+/* Move to the next function. */
+
+static inline void
+rpi_next (pinvoke_iterator rpi)
+{
+ gcc_assert (rpi->i < VEC_length (tree, rpi->functions));
+
+ rpi->i++;
+}
+
+/******************************************************************************
+ * Labels *
+ ******************************************************************************/
+
+extern void record_addr_taken_label (tree);
+extern tree get_addr_taken_label_id (tree);
+extern tree *get_label_addrs ( void );
+extern unsigned int get_label_addrs_n ( void );
+
+#endif /* !CIL_REFS_H */
diff --git a/gcc/config/cil32/cil-types.h b/gcc/config/cil32/cil-types.h
new file mode 100644
index 00000000000..912652d4750
--- /dev/null
+++ b/gcc/config/cil32/cil-types.h
@@ -0,0 +1,67 @@
+/* Type related function prototypes and declarations.
+
+ Copyright (C) 2006-2008 Free Software Foundation, Inc.
+
+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, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+Authors:
+ Andrea Ornstein
+ Erven Rohou
+ Gabriele Svelto
+
+Contact information at STMicroelectronics:
+Andrea C. Ornstein <andrea.ornstein@st.com>
+Erven Rohou <erven.rohou@st.com>
+*/
+
+#ifndef CIL_TYPES_H
+#define CIL_TYPES_H
+
+#include "coretypes.h"
+
+/******************************************************************************
+ * Misc types *
+ ******************************************************************************/
+
+/* Referenced string entry. */
+
+struct str_ref_d GTY(())
+{
+ /* STRING_CST node. */
+ tree cst;
+
+ /* Unique ID. */
+ size_t id;
+};
+
+typedef struct str_ref_d *str_ref;
+
+/* Mapping for label's whose addresses have been taken. */
+
+struct label_addr_d GTY(())
+{
+ /* LABEL_DECL node. */
+ tree label;
+
+ /* Unique id as an INTEGER_CST of type intSI_type_node. */
+ tree id;
+};
+
+typedef struct label_addr_d *label_addr;
+
+#endif /* !CIL_TYPES_H */
diff --git a/gcc/config/cil32/cil32.c b/gcc/config/cil32/cil32.c
index 0c1df97a1de..52aa04283a1 100644
--- a/gcc/config/cil32/cil32.c
+++ b/gcc/config/cil32/cil32.c
@@ -57,6 +57,7 @@ Erven Rohou <erven.rohou@st.com>
#include "ggc.h"
#include "optabs.h"
#include "langhooks.h"
+#include "cil-refs.h"
#include "gen-cil.h"
/* Per-function machine data. */
@@ -146,13 +147,17 @@ const struct attribute_spec cil32_attribute_table[] =
static void
cil32_file_start (void)
{
+ refs_init ();
gen_cil_init ();
+ cil_vcg_init ();
}
static void
cil32_file_end (void)
{
+ cil_vcg_fini ();
gen_cil_fini ();
+ refs_fini ();
}
static void
@@ -240,7 +245,8 @@ cil32_init_builtins (void)
cil32_build_builtin_types ();
- arglist = build_tree_list (NULL_TREE, cil32_va_list_type);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, cil32_va_list_type, arglist);
cil32_builtins[CIL32_BUILT_IN_VA_START] =
add_builtin_function ("__builtin_cil_va_start",
build_function_type (void_type_node,
@@ -249,7 +255,8 @@ cil32_init_builtins (void)
BUILT_IN_MD,
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, ptr_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, ptr_type_node, arglist);
arglist = tree_cons (NULL_TREE, cil32_va_list_type, arglist);
cil32_builtins[CIL32_BUILT_IN_VA_ARG] =
add_builtin_function ("__builtin_cil_va_arg",
@@ -259,7 +266,8 @@ cil32_init_builtins (void)
BUILT_IN_MD,
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, cil32_va_list_type);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, cil32_va_list_type, arglist);
cil32_builtins[CIL32_BUILT_IN_VA_END] =
add_builtin_function ("__builtin_cil_va_end",
build_function_type (void_type_node,
@@ -268,7 +276,8 @@ cil32_init_builtins (void)
BUILT_IN_MD,
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, cil32_va_list_type);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, cil32_va_list_type, arglist);
arglist = tree_cons (NULL_TREE, cil32_va_list_type, arglist);
cil32_builtins[CIL32_BUILT_IN_VA_COPY] =
add_builtin_function ("__builtin_cil_va_copy",
@@ -278,7 +287,8 @@ cil32_init_builtins (void)
BUILT_IN_MD,
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, integer_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, integer_type_node, arglist);
arglist = tree_cons (NULL_TREE, ptr_type_node, arglist);
arglist = tree_cons (NULL_TREE, ptr_type_node, arglist);
cil32_builtins[CIL32_BUILT_IN_CPBLK] =
@@ -289,7 +299,8 @@ cil32_init_builtins (void)
BUILT_IN_MD,
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, integer_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, integer_type_node, arglist);
arglist = tree_cons (NULL_TREE, integer_type_node, arglist);
arglist = tree_cons (NULL_TREE, ptr_type_node, arglist);
cil32_builtins[CIL32_BUILT_IN_INITBLK] =
@@ -300,16 +311,18 @@ cil32_init_builtins (void)
BUILT_IN_MD,
NULL,
NULL_TREE);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
cil32_builtins[CIL32_BUILT_IN_IS_LITTLE_ENDIAN] =
add_builtin_function ("__builtin_isLittleEndian",
build_function_type (integer_type_node,
- NULL_TREE),
+ arglist),
CIL32_BUILT_IN_IS_LITTLE_ENDIAN,
BUILT_IN_MD,
NULL,
NULL_TREE);
-
- arglist = build_tree_list (NULL_TREE, ptr_type_node);
+
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, ptr_type_node, arglist);
arglist = tree_cons (NULL_TREE, ptr_type_node, arglist);
cil32_builtins[CIL32_BUILT_IN_ENDIAN_SELECT] =
add_builtin_function ("__builtin_EndianSelect",
@@ -319,8 +332,9 @@ cil32_init_builtins (void)
BUILT_IN_MD,
NULL,
NULL_TREE);
-
- arglist = build_tree_list (NULL_TREE, float_type_node);
+
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, float_type_node, arglist);
arglist = tree_cons (NULL_TREE, float_type_node, arglist);
cil32_builtins[CIL32_V2SF_CTOR] =
add_builtin_function ("V2SF_ctor1",
@@ -331,7 +345,8 @@ cil32_init_builtins (void)
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, float_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, float_type_node, arglist);
arglist = tree_cons (NULL_TREE, float_type_node, arglist);
arglist = tree_cons (NULL_TREE, float_type_node, arglist);
arglist = tree_cons (NULL_TREE, float_type_node, arglist);
@@ -344,7 +359,8 @@ cil32_init_builtins (void)
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, unsigned_intQI_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
@@ -357,7 +373,8 @@ cil32_init_builtins (void)
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, unsigned_intHI_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, unsigned_intHI_type_node, arglist);
arglist = tree_cons (NULL_TREE, intHI_type_node, arglist);
cil32_builtins[CIL32_V2HI_CTOR] =
add_builtin_function ("V2HI_ctor1",
@@ -368,7 +385,8 @@ cil32_init_builtins (void)
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, unsigned_intQI_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
@@ -385,7 +403,8 @@ cil32_init_builtins (void)
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, unsigned_intHI_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, unsigned_intHI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intHI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intHI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intHI_type_node, arglist);
@@ -398,7 +417,8 @@ cil32_init_builtins (void)
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, unsigned_intSI_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, unsigned_intSI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intSI_type_node, arglist);
cil32_builtins[CIL32_V2SI_CTOR] =
add_builtin_function ("V2SI_ctor1",
@@ -409,7 +429,8 @@ cil32_init_builtins (void)
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, unsigned_intSI_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, unsigned_intSI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intSI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intSI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intSI_type_node, arglist);
@@ -422,7 +443,8 @@ cil32_init_builtins (void)
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, unsigned_intHI_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, unsigned_intHI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intHI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intHI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intHI_type_node, arglist);
@@ -439,7 +461,8 @@ cil32_init_builtins (void)
NULL,
NULL_TREE);
- arglist = build_tree_list (NULL_TREE, unsigned_intQI_type_node);
+ arglist = build_tree_list (NULL_TREE, void_type_node);
+ arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
diff --git a/gcc/config/cil32/cil32.h b/gcc/config/cil32/cil32.h
index cd183e40310..bf5e5612339 100644
--- a/gcc/config/cil32/cil32.h
+++ b/gcc/config/cil32/cil32.h
@@ -540,6 +540,7 @@ extern struct tree_opt_pass pass_bb_layout;
extern struct tree_opt_pass pass_simp_cil_early;
extern struct tree_opt_pass pass_simp_cil_final;
extern struct tree_opt_pass pass_gen_cil;
+extern struct tree_opt_pass pass_cil_vcg;
/* cil32 builtin ID */
enum cil32_builtin
diff --git a/gcc/config/cil32/gen-cil.c b/gcc/config/cil32/gen-cil.c
index 994fcc0306e..3c36e5e1c6b 100644
--- a/gcc/config/cil32/gen-cil.c
+++ b/gcc/config/cil32/gen-cil.c
@@ -50,25 +50,10 @@ Erven Rohou <erven.rohou@st.com>
#include "ebitmap.h"
#include "ggc.h"
#include "tree-simp-cil.h"
+#include "cil-refs.h"
#include "gen-cil.h"
#include "emit-hints.h"
-/* Nonzero for a type which is at file scope. */
-#define TYPE_FILE_SCOPE_P(EXP) \
- (! TYPE_CONTEXT (EXP) \
- || TREE_CODE (TYPE_CONTEXT (EXP)) == TRANSLATION_UNIT_DECL)
-
-/* Nonzero for a zero-length array type */
-#define ARRAY_TYPE_ZEROLENGTH(EXP) \
- (TYPE_SIZE (EXP) == NULL_TREE)
-
-/* Nonzero for a variable-length array type */
-#define ARRAY_TYPE_VARLENGTH(EXP) \
- (TYPE_SIZE (EXP) != NULL_TREE && TREE_CODE (TYPE_SIZE (EXP)) != INTEGER_CST)
-
-/* Length of compacted identifiers (in characters) */
-#define COMPACT_ID_LENGTH 16
-
struct fnct_attr
{
const char *assembly_name;
@@ -78,21 +63,8 @@ struct fnct_attr
const char *pinvoke_fname;
};
-/* Element of the pointer id hash table */
-struct pointer_id_data
-{
- const void *ptr;
- unsigned int id;
-};
-
/* Local functions, macros and variables. */
-static hashval_t pointer_id_data_hash (const void *);
-static int pointer_id_data_eq (const void *, const void *);
static void decode_function_attrs (tree, struct fnct_attr *);
-static bool fill_goto_labels (void *, void **, void *);
-static void mark_referenced_type (tree);
-static void mark_referenced_string (tree);
-static unsigned int get_string_cst_id (tree);
static void dump_decl_name (FILE *, tree);
static void dump_string_name (FILE *, tree);
static void dump_label_name (FILE *, tree);
@@ -102,11 +74,6 @@ static void dump_valuetype_name (FILE *, tree);
static void gen_addr_expr (FILE *, tree);
static void print_type_suffix (FILE *, tree, bool);
static void gen_cil_modify_expr (FILE *, tree, tree);
-static char * append_string (char *, const char *,
- unsigned int *, unsigned int *);
-static char * append_coded_type (char *, tree, unsigned int *, unsigned int *);
-static char * get_compact_identifier (const char *, size_t, size_t *);
-static tree make_valuetype_identifier (tree);
static void print_valuetype_decl (FILE *, tree);
static void print_array_decl (FILE *, tree);
static void print_enum_decl (FILE *, tree);
@@ -135,44 +102,21 @@ static unsigned int gen_cil (void);
static void gen_cil_vcg (FILE *);
static void gen_cil_1 (FILE *);
static void gen_cil_node (FILE *, tree);
+static void gen_cil_bb (FILE *, basic_block);
static bool gen_cil_gate (void);
static void print_pinvoke_function (FILE *, tree);
static void print_string_decl (FILE *, tree);
static void print_used_strings (FILE *);
+static void print_referenced_types (FILE *);
+static void print_referenced_pinvokes (FILE *);
static void create_init_method(void);
-static struct pointer_set_t *referenced_types;
-static GTY(()) varray_type referenced_strings;
-static struct pointer_set_t *referenced_string_ptrs;
-static struct pointer_set_t *referenced_pinvoke;
static GTY(()) varray_type pending_ctors;
-static htab_t pointer_id_htable;
-static unsigned int pointer_next_id = 0;
static unsigned int stack;
static unsigned int max_stack;
static basic_block bb;
-static struct pointer_map_t *labels_map;
-static tree *goto_labels;
-static unsigned int taken_labels;
-
-/* Hashing and equality routines for pointer id hash table. */
-static hashval_t
-pointer_id_data_hash (const void *p)
-{
- return ((unsigned long)((struct pointer_id_data *)p)->ptr >> 4) & 255;
-}
-
-static int
-pointer_id_data_eq (const void *p1, const void *p2)
-{
- const void* ptr1 = ((struct pointer_id_data *)p1)->ptr;
- const void* ptr2 = ((struct pointer_id_data *)p2)->ptr;
-
- return ptr1 == ptr2;
-}
-
/* stack_* functions are used to keep track of the number of elements
in the evaluation stack, in order to record the maximum number.
This is emitted in .maxstack directive for each function. */
@@ -252,197 +196,6 @@ decode_function_attrs (tree t, struct fnct_attr *attrs)
}
}
-/* Mark the type represented by tree T as referenced.
- This function works recursively, since types referenced by type T
- itself are also marked as referenced.
- Referenced types are emitted at the end of the compilation unit,
- non-referenced types are not.
- T must be a type node. */
-
-static void
-mark_referenced_type (tree t)
-{
- if (t == NULL_TREE || t == error_mark_node)
- return;
-
- t = TYPE_MAIN_VARIANT (t);
-
- if (t == cil32_arg_iterator_type)
- return;
-
- /* If the type was already referenced, nothing else to do */
- if (pointer_set_contains (referenced_types, t))
- return;
-
- /* Give the aggregate a name unless it has it already */
- switch (TREE_CODE (t))
- {
- /* Incomplete and variable-length arrays are pointers and
- they must be dealt with as such. */
- case ARRAY_TYPE:
- if (! TYPE_DOMAIN (t) || ARRAY_TYPE_VARLENGTH (t))
- break;
- case ENUMERAL_TYPE:
- case RECORD_TYPE:
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- if (TYPE_NAME (t) == 0)
- {
- tree type_decl = build0 (TYPE_DECL, t);
- DECL_NAME (type_decl) = make_valuetype_identifier (t);
- TYPE_NAME (t) = type_decl;
- }
- break;
-
- default:
- /* Nothing to do for the other types */
- ;
- }
-
- /* Transform local-scope types into global-scope types */
- if (!TYPE_FILE_SCOPE_P (t))
- {
- tree type_name = TYPE_NAME (t);
- const char *orig_name;
- size_t tmp_name_max_len = 256;
- size_t tmp_name_len = 0;
- char *tmp_name;
- char suffix[32];
-
- gcc_assert (type_name != 0);
- gcc_assert (DECL_P (type_name)
- || TREE_CODE (type_name) == IDENTIFIER_NODE);
-
- if (TREE_CODE (type_name) == IDENTIFIER_NODE)
- orig_name = IDENTIFIER_POINTER (type_name);
- else
- orig_name = IDENTIFIER_POINTER (DECL_NAME (type_name));
-
- snprintf (suffix, 15, "?vt%u", TYPE_UID (t));
-
- tmp_name = (char *)xmalloc (tmp_name_max_len);
- tmp_name = append_string (tmp_name, orig_name,
- &tmp_name_len, &tmp_name_max_len);
- tmp_name = append_string (tmp_name, suffix,
- &tmp_name_len, &tmp_name_max_len);
-
- TYPE_NAME (t) = get_identifier_with_length (tmp_name, tmp_name_len);
- TYPE_CONTEXT (t) = 0;
- free (tmp_name);
- }
-
- switch (TREE_CODE (t))
- {
- case ENUMERAL_TYPE:
- pointer_set_insert (referenced_types, t);
- break;
-
- case RECORD_TYPE:
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- {
- tree tmp;
-
- pointer_set_insert (referenced_types, t);
- tmp = TYPE_FIELDS (t);
-
- while (tmp)
- {
- if (DECL_BIT_FIELD (tmp))
- mark_referenced_type (DECL_BIT_FIELD_TYPE (tmp));
- else
- mark_referenced_type (TREE_TYPE (tmp));
- tmp = TREE_CHAIN (tmp);
- }
- }
- break;
-
- case POINTER_TYPE:
- case REFERENCE_TYPE:
- mark_referenced_type (TREE_TYPE (t));
- break;
-
- case ARRAY_TYPE:
- if (TYPE_DOMAIN (t) && ! ARRAY_TYPE_VARLENGTH (t))
- pointer_set_insert (referenced_types, t);
- mark_referenced_type (TREE_TYPE (t));
- break;
-
- case FUNCTION_TYPE:
- {
- tree args_type;
- mark_referenced_type (TREE_TYPE (t));
- args_type = TYPE_ARG_TYPES (t);
- while (args_type)
- {
- mark_referenced_type (TREE_VALUE (args_type));
- args_type = TREE_CHAIN (args_type);
- }
- }
- break;
-
- default:
- /* Nothing to do for the other types */
- ;
- }
-}
-
-/* Mark the string represented by tree T as referenced.
- Referenced strings are emitted at the end of the compilation unit,
- non-referenced strings are not.
- T must be a STRING_CST node. */
-
-static void
-mark_referenced_string (tree t)
-{
- gcc_assert (TREE_CODE (t) == STRING_CST);
- if (!pointer_set_contains (referenced_string_ptrs,
- (void *)(TREE_STRING_POINTER (t))))
- {
- VARRAY_PUSH_TREE (referenced_strings, t);
- pointer_set_insert (referenced_string_ptrs,
- (void *)(TREE_STRING_POINTER (t)));
- }
-}
-
-/* Get an unique id for string constant NODE. */
-
-static
-unsigned int get_string_cst_id (tree node)
-{
- struct pointer_id_data tmp_pid;
- void **slot;
-
- gcc_assert (TREE_CODE (node) == STRING_CST);
-
- tmp_pid.ptr = TREE_STRING_POINTER (node);
- slot = htab_find_slot (pointer_id_htable, &tmp_pid, INSERT);
-
- if (*slot != NULL)
- return ((struct pointer_id_data *)(*slot))->id;
- else
- {
- struct pointer_id_data *pid = XNEW (struct pointer_id_data);
-
- *slot = pid;
- pid->ptr = TREE_STRING_POINTER (node);
- pid->id = pointer_next_id++;
-
- return pid->id;
- }
-}
-
-/* Mark the function represented by tree T as a pinvoke.
- T must be a FUNCTION_DECL node. */
-
-void
-cil_add_pinvoke (tree t)
-{
- gcc_assert (TREE_CODE (t) == FUNCTION_DECL);
- pointer_set_insert (referenced_pinvoke, t);
- mark_referenced_type (TREE_TYPE (t));
-}
-
/* Dump the name of a _DECL node. */
static void
@@ -497,20 +250,6 @@ dump_label_name (FILE* file, tree node)
}
}
-/* Helper function used to fill the computed GOTOs label array. */
-
-static bool
-fill_goto_labels (void *key, void **val, void *data)
-{
- tree *goto_labels = (tree *) data;
- tree label_decl = (tree) key;
- unsigned int idx = tree_low_cst ((tree) *val, 1);
-
- goto_labels[idx] = label_decl;
-
- return true;
-}
-
static void
dump_entry_label_name (FILE *stream, basic_block bb)
{
@@ -1205,9 +944,9 @@ gen_addr_expr (FILE *file, tree t)
with a switch based on that ID. The ID is simply the position in
the list of all address taken labels. */
- tree cst = *pointer_map_contains (labels_map, t);
- fprintf (file, "\n\tldc.i4\t%d", (unsigned int) tree_low_cst (cst, 1));
- stack_push (1);
+ tree id = get_addr_taken_label_id (t);
+ fprintf (file, "\n\tldc.i4\t%u", (unsigned int) tree_low_cst (id, 1));
+ stack_push (1);
}
break;
@@ -3417,356 +3156,62 @@ gen_cil_modify_expr (FILE *file, tree lhs, tree rhs)
}
}
-/* Warning: these strings are not null-terminated */
-static char *
-append_string (char *str, const char *to_append,
- unsigned int *len, unsigned int *max_len)
-{
- size_t i, orig_len = *len;
- size_t append_len = strlen (to_append);
-
- *len += append_len;
-
- if (*len > *max_len)
- {
- while (*len > *max_len)
- *max_len *= 2;
- str = (char *)xrealloc (str, *max_len);
- }
-
- for (i=0; i < append_len; ++i)
- str[orig_len + i] = to_append[i];
-
- return str;
-}
+/* */
-/* Warning: these strings are not null-terminated */
-static char *
-append_coded_type (char *str, tree type,
- unsigned int *len, unsigned int *max_len)
+static void
+gen_cil_bb (FILE *stream, basic_block bb)
{
- enum tree_code type_code;
-
- if (type == NULL_TREE || type == error_mark_node)
- return str;
-
- type = TYPE_MAIN_VARIANT (type);
-
- type_code = TREE_CODE (type);
+ block_stmt_iterator bsi;
+ tree stmt = NULL_TREE;
- restartswitch:
- switch (type_code)
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{
- case VOID_TYPE:
- str = append_string (str, "VOID", len, max_len);
- break;
-
- case INTEGER_TYPE:
- {
- int type_size = TYPE_PRECISION (type);
- char tmp_str[8] = "UI";
- char *tmp_str_ptr = tmp_str;
-
- snprintf (tmp_str_ptr + 2, 6, "%d", type_size);
-
- if (!TYPE_UNSIGNED (type))
- ++tmp_str_ptr;
-
- str = append_string (str, tmp_str_ptr, len, max_len);
- }
- break;
-
- case BOOLEAN_TYPE:
- str = append_string (str, "B", len, max_len);
- break;
-
- case REAL_TYPE:
- {
- int type_size = TYPE_PRECISION (type);
- char tmp_str[4] = "F";
-
- snprintf (tmp_str + 1, 3, "%d", type_size);
-
- str = append_string (str, tmp_str, len, max_len);
- }
- break;
-
- case POINTER_TYPE:
- if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
- {
- tree fun_type = TREE_TYPE (type);
- tree args_type = TYPE_ARG_TYPES (fun_type);
-/* bool varargs = TREE_VALUE (tree_last (args_type)) != void_type_node; */
- unsigned int nargs_base = list_length (args_type);
- unsigned int aidx;
- char tmp_str[5] = "FP";
-
- snprintf (tmp_str + 2, 3, "%d", nargs_base);
- str = append_string (str, tmp_str, len, max_len);
+ gcc_assert (stack == 0);
- str = append_string (str, "_", len, max_len);
- str = append_coded_type (str, TREE_TYPE (fun_type), len, max_len);
- str = append_string (str, "_", len, max_len);
+ stmt = bsi_stmt (bsi);
- for (aidx=0;aidx<nargs_base;++aidx)
- {
- str = append_string (str, "_", len, max_len);
- str = append_coded_type (str, TREE_VALUE (args_type), len, max_len);
- args_type = TREE_CHAIN (args_type);
- }
- }
- else
+ if (TARGET_EMIT_GIMPLE_COMMENTS)
{
- str = append_string (str, "*", len, max_len);
- type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
- type_code = TREE_CODE (type);
- goto restartswitch;
+ fprintf (stream, "\n\t/* ");
+ print_generic_expr (stream, stmt, 0);
+ fprintf (stream, " */");
}
- break;
- case ARRAY_TYPE:
- if (TYPE_DOMAIN (type) && ! ARRAY_TYPE_VARLENGTH (type))
- {
- tree domain = TYPE_DOMAIN (type);
- tree min = TYPE_MIN_VALUE (domain);
- tree max = TYPE_MAX_VALUE (domain);
+ if (TREE_CODE (stmt) != NOP_EXPR
+ || TREE_CODE (TREE_OPERAND (stmt, 0)) != INTEGER_CST)
+ gen_cil_node (stream, stmt);
- str = append_string (str, "[", len, max_len);
+ if (TREE_CODE (stmt) == CALL_EXPR)
+ {
+ tree fun_expr = CALL_EXPR_FN (stmt);
+ tree fun_type = TREE_TYPE (TREE_TYPE (fun_expr));
- if (ARRAY_TYPE_ZEROLENGTH (type))
- str = append_string (str, "0", len, max_len);
- else if (min && max
- && integer_zerop (min)
- && host_integerp (max, 0))
+ if (TREE_CODE (TREE_TYPE (fun_type)) != VOID_TYPE)
{
- unsigned int size = TREE_INT_CST_LOW (max) + 1;
- char tmp_str[32];
-
- snprintf (tmp_str, 32, "%d", size);
- str = append_string (str, tmp_str, len, max_len);
+ fputs ("\n\tpop", stream);
+ stack_pop (1);
}
- else
- str = append_string (str, "unk", len, max_len);
-
- str = append_string (str, "]", len, max_len);
}
- else {
- type_code = POINTER_TYPE;
- goto restartswitch;
- }
- type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
- type_code = TREE_CODE (type);
- goto restartswitch;
-
- break;
-
- case ENUMERAL_TYPE:
- case RECORD_TYPE:
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- {
- const char *prefix;
- const char *type_str;
- tree type_name;
-
- /* Give the aggregate a name unless it has it already */
- if (TYPE_NAME (type) == 0)
- {
- tree type_decl = build0 (TYPE_DECL, type);
- DECL_NAME (type_decl) = make_valuetype_identifier (type);
- TYPE_NAME (type) = type_decl;
- }
-
- type_name = TYPE_NAME (type);
-
- if (TREE_CODE (type_name) == IDENTIFIER_NODE)
- type_str = IDENTIFIER_POINTER (type_name);
- else
- type_str = IDENTIFIER_POINTER (DECL_NAME (type_name));
-
- switch (type_code)
- {
- case ENUMERAL_TYPE:
- prefix = "E";
- break;
-
- case RECORD_TYPE:
- prefix = "S";
- break;
-
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- prefix = "UN";
- break;
-
- default:
- gcc_assert (0);
- prefix = "error";
- }
-
- str = append_string (str, prefix, len, max_len);
- str = append_string (str, type_str, len, max_len);
- }
- break;
-
- default:
-/* debug_tree(type); */
-/* gcc_assert (0); */
- str = append_string (str, "unknown", len, max_len);
- }
-
- return str;
-}
-
-/* Compute and return a compact identifier from identifier STR of size LEN.
- Memory is allocated for the compact identifier.
- Store the length of the compact identifier in COMPACT_LEN. */
-
-static char *
-get_compact_identifier (const char *str, size_t len, size_t *compact_len)
-{
- char *compact_str;
- size_t i;
- unsigned char buffer[COMPACT_ID_LENGTH / 2];
-
- gcc_assert (COMPACT_ID_LENGTH % 2 == 0);
-
- /* If the string is shorter than the length of compact strings,
- then return it unchanged. */
- if (len <= COMPACT_ID_LENGTH)
- {
- compact_str = (char *)xmalloc (len);
- memcpy (compact_str, str, len);
-
- *compact_len = len;
- return compact_str;
}
- /* Fill the buffer */
- memset (buffer, 0, COMPACT_ID_LENGTH / 2);
- for (i=0; i < len; ++i)
+ if ((!stmt || (TREE_CODE (stmt) != COND_EXPR)) && single_succ_p (bb))
{
- int j = 0;
- unsigned char c = str[i];
+ basic_block succ = single_succ (bb);
- while (true)
+ /* The last part of the test (succ != bb->next_bb) is a HACK. It
+ avoids generating a branch to the successor in case of a
+ fallthrough. To be fixed when we have a proper layout of basic
+ blocks. */
+ if ((succ->index != EXIT_BLOCK) && (succ != bb->next_bb))
{
- unsigned char tmp_c;
-
- /* Modify a position in buffer */
- buffer[(i + j) % (COMPACT_ID_LENGTH / 2)] ^= c;
-
- if (j == COMPACT_ID_LENGTH / 2)
- break;
-
- /* Rotate c 1-bit right */
- tmp_c = c >> 1;
- tmp_c |= (c & 1) << 7;
- c = tmp_c;
-
- ++j;
+ tree label = tree_block_label (succ);
+ fputs ("\n\tbr\t", stream);
+ dump_label_name (stream, label);
+ gcc_assert (stack == 0);
}
}
-
- /* Build the compact string */
- compact_str = (char *)xmalloc (COMPACT_ID_LENGTH);
- for (i=0; i < COMPACT_ID_LENGTH / 2; ++i)
- {
- unsigned char c1, c2;
-
- c1 = buffer[i] & 0xf;
- c2 = buffer[i] >> 4;
-
- compact_str[i * 2] = c1 + ((c1 < 10) ? '0' : 'a' - 10);
- compact_str[i * 2 + 1] = c2 + ((c2 < 10) ? '0' : 'a' - 10);
- }
-
- /* Return the compact string and its length */
- *compact_len = COMPACT_ID_LENGTH;
- return compact_str;
}
-static tree
-make_valuetype_identifier (tree t)
-{
- size_t tmp_name_max_len = 256;
- size_t tmp_name_len = 0;
- char *tmp_name;
- size_t vt_name_len = 0;
- char *vt_name;
- tree ident;
-
- tmp_name = (char *)xmalloc (tmp_name_max_len);
-
- if (TREE_CODE (t) == ENUMERAL_TYPE)
- {
- tree tmp;
-
- tmp_name = append_string (tmp_name, "enum?",
- &tmp_name_len, &tmp_name_max_len);
-
- tmp = TYPE_VALUES (t);
-
- while (tmp)
- {
- tmp_name = append_string (tmp_name,
- IDENTIFIER_POINTER (TREE_PURPOSE (tmp)),
- &tmp_name_len, &tmp_name_max_len);
- tmp_name = append_string (tmp_name, "?",
- &tmp_name_len, &tmp_name_max_len);
- tmp = TREE_CHAIN (tmp);
- }
- }
- else if (TREE_CODE (t) == ARRAY_TYPE)
- {
- gcc_assert (TYPE_DOMAIN (t) && ! ARRAY_TYPE_VARLENGTH (t));
- tmp_name = append_string (tmp_name, "array?",
- &tmp_name_len, &tmp_name_max_len);
- tmp_name = append_coded_type (tmp_name, t,
- &tmp_name_len, &tmp_name_max_len);
- }
- else
- {
- tree tmp;
-
- if (TREE_CODE (t) == RECORD_TYPE)
- tmp_name = append_string (tmp_name, "struct?",
- &tmp_name_len, &tmp_name_max_len);
- else
- tmp_name = append_string (tmp_name, "union?",
- &tmp_name_len, &tmp_name_max_len);
-
- tmp = TYPE_FIELDS (t);
- while (tmp)
- {
- tree ttype = TREE_TYPE (tmp);
-
- tmp_name = append_coded_type (tmp_name, ttype,
- &tmp_name_len, &tmp_name_max_len);
- tmp_name = append_string (tmp_name, "?",
- &tmp_name_len, &tmp_name_max_len);
- if (DECL_NAME (tmp) != 0)
- tmp_name = append_string (tmp_name,
- IDENTIFIER_POINTER (DECL_NAME (tmp)),
- &tmp_name_len, &tmp_name_max_len);
- else
- /* Unnamed bitfields or unions */
- tmp_name = append_string (tmp_name, "?unnamed",
- &tmp_name_len, &tmp_name_max_len);
- tmp_name = append_string (tmp_name, "?",
- &tmp_name_len, &tmp_name_max_len);
- tmp = TREE_CHAIN (tmp);
- }
- }
-
- vt_name = get_compact_identifier (tmp_name, tmp_name_len, &vt_name_len);
- free (tmp_name);
-
- ident = get_identifier_with_length (vt_name, vt_name_len);
- free (vt_name);
-
- return ident;
-}
static void
print_enum_decl (FILE *file, tree t)
@@ -3929,8 +3374,8 @@ print_valuetype_decl (FILE *file, tree t)
}
- /* The attribute string must be less than 127 characters and
- contain only 7-bit ASCII chars. No checks though. */
+/* The attribute string must be less than 127 characters and contain only
+ 7-bit ASCII chars. No checks though. */
static void
gen_string_custom_attr (FILE *stream, const char* parameter)
{
@@ -3948,32 +3393,27 @@ gen_string_custom_attr (FILE *stream, const char* parameter)
fputs ("00 00)\n", stream);
}
-
/* Dumps the labels of a switch used for implementing a computed GOTO */
static void
gen_computed_goto (FILE *file, tree node)
{
+ tree *addrs = get_label_addrs ();
+ unsigned int n = get_label_addrs_n ();
unsigned int i;
- if (goto_labels == NULL && taken_labels != 0)
- {
- goto_labels = XNEWVEC (tree, taken_labels);
- pointer_map_traverse (labels_map, fill_goto_labels, goto_labels);
- }
-
gen_cil_node (file, node);
- fputs ("\n\tswitch (", file);
+ fprintf (file, "\n\tswitch (");
- for (i = 0; i < taken_labels; i++)
+ for (i = 0; i < n; i++)
{
- dump_label_name (file, goto_labels[i]);
+ dump_label_name (file, addrs[i]);
- if (i + 1 < taken_labels)
- fputs (", ", file);
+ if (i + 1 < n)
+ fprintf (file, ", ");
}
- fputs (")", file);
+ fprintf (file, ")");
stack_pop (1);
}
@@ -4018,37 +3458,88 @@ print_string_decl (FILE *file, tree t)
static void
print_used_strings (FILE *file)
{
+ ref_str_iterator rsi;
ebitmap used_stringtypes;
- int i, n;
+ tree str;
+ unsigned int str_size;
+ ebitmap_iterator ebi;
used_stringtypes = ebitmap_alloc (1);
+ rsi = rsi_begin ();
- i = 0;
- n = VARRAY_ACTIVE_SIZE (referenced_strings);
- for (; i < n; ++i)
+ while (!rsi_end_p (rsi))
{
- tree str = VARRAY_TREE (referenced_strings, i);
- unsigned int str_size = TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE(str)))) + 1;
+ str = rsi_string (rsi);
+ rsi_next (rsi);
+ str_size = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (str))),
+ 1) + 1;
print_string_decl (file, str);
ebitmap_set_bit (used_stringtypes, str_size);
}
- {
- unsigned int str_size;
- ebitmap_iterator it;
- EXECUTE_IF_SET_IN_EBITMAP(used_stringtypes, 0, str_size, it)
- {
- fprintf (file, "\n.class public explicit sealed serializable ansi '?string_type?%d'", str_size);
- fputs (" extends ['mscorlib']System.ValueType\n"
- "{\n"
- "\t.custom instance "
- "void [gcc4net]gcc4net.C_Attributes.ConstStringType::.ctor() "
- "= (01 00 00 00)\n", file);
- fprintf (file, "\t.size %d\n", str_size);
- fputs ("\t.field [0] public specialname int8 'elem__'\n"
- "}\n", file);
- }
- }
+ rsi_destroy (rsi);
+
+ EXECUTE_IF_SET_IN_EBITMAP(used_stringtypes, 0, str_size, ebi)
+ {
+ fprintf (file,
+ "\n.class public explicit sealed serializable ansi '?string_type?%d'"
+ " extends ['mscorlib']System.ValueType\n"
+ "{\n"
+ "\t.custom instance "
+ "void [gcc4net]gcc4net.C_Attributes.ConstStringType::.ctor() "
+ "= (01 00 00 00)\n"
+ "\t.size %d\n"
+ "\t.field [0] public specialname int8 'elem__'\n"
+ "}\n", str_size, str_size);
+ }
+
+ ebitmap_free (used_stringtypes);
+}
+
+/* Emit the valuetypes referenced by the current function. */
+
+static void
+print_referenced_types (FILE *file)
+{
+ /* There may be distinct tree types that correspond to identical types.
+ In order not to slow down mark_referenced_type(...) function (which
+ may typically be called several times for the same type), insertion
+ of types in the mark set makes only sure that the same tree type
+ pointer is not inserted twice. As a consequence, there may still be
+ distinct tree types that correspond to identical types in the
+ reference type set.
+ Hence, before emitting a type, make sure no type with the same name
+ has already been emitted. */
+
+ struct pointer_set_t *emitted_types = pointer_set_create ();
+ types_iterator rti = rti_begin ();
+
+ while (!rti_end_p (rti))
+ {
+ tree type = rti_type (rti);
+
+ if (COMPLETE_TYPE_P (type))
+ {
+ tree type_name = TYPE_NAME (type);
+
+ gcc_assert (DECL_P (type_name)
+ || TREE_CODE (type_name) == IDENTIFIER_NODE);
+
+ if (TREE_CODE (type_name) != IDENTIFIER_NODE)
+ type_name = DECL_NAME (type_name);
+
+ if (!pointer_set_contains (emitted_types, type_name))
+ {
+ print_valuetype_decl (file, type);
+ pointer_set_insert (emitted_types, type_name);
+ }
+ }
+
+ rti_next (rti);
+ }
+
+ rti_destroy (rti);
+ pointer_set_destroy (emitted_types);
}
static void
@@ -4076,6 +3567,26 @@ print_pinvoke_function (FILE *file, tree fun)
fputs (" cil managed {}\n", file);
}
+/* Emit the PINVOKES referenced in this compilation unit. */
+
+static void
+print_referenced_pinvokes (FILE *file)
+{
+ pinvoke_iterator rpi;
+ tree pinvoke;
+
+ rpi = rpi_begin ();
+
+ while (!rpi_end_p (rpi))
+ {
+ pinvoke = rpi_function (rpi);
+ rpi_next (rpi);
+ print_pinvoke_function (file, pinvoke);
+ }
+
+ rpi_destroy (rpi);
+}
+
static void
gen_start_function (FILE *stream)
{
@@ -4144,110 +3655,6 @@ gen_start_function (FILE *stream)
"\n\n", stream);
}
-
-/* This function is mostly a copy of the last part of 'gen_cil'. */
-static void
-gen_cil_vcg (FILE *vcg_stream)
-{
- block_stmt_iterator bsi;
- edge_iterator ei;
- const char *fun_name = lang_hooks.decl_printable_name (current_function_decl, 1);
- edge e;
- int i=0;
-
- fprintf (vcg_stream, "graph: {\n");
- fprintf (vcg_stream, "title: \"%s\"\n",
- lang_hooks.decl_printable_name (current_function_decl, 1));
- fprintf (vcg_stream, "node: { title: \"%sBB%d\" label: \"ENTRY %s\" }\n",
- fun_name, ENTRY_BLOCK, fun_name);
- fprintf (vcg_stream, "node: { title: \"%sBB%d\" label: \"EXIT\" }\n",
- fun_name, EXIT_BLOCK);
- fprintf (vcg_stream, "edge:{sourcename: \"%sBB%d\" targetname: \"%sBB%d\"}\n",
- fun_name, ENTRY_BLOCK,
- fun_name, single_succ (ENTRY_BLOCK_PTR)->index);
-
- FOR_EACH_BB (bb)
- {
- tree stmt = NULL_TREE;
-
- fprintf (vcg_stream, "node: { title: \"%sBB%d\" label: \"(BB%d, pos: %d)",
- fun_name, bb->index, bb->index, i++);
-
- if (bb->loop_depth)
- fprintf (vcg_stream, " LOOP DEPTH %d ", bb->loop_depth);
-
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- stmt = bsi_stmt (bsi);
- if (TARGET_EMIT_GIMPLE_COMMENTS)
- {
- fprintf (vcg_stream, "\n\t [ ");
- print_generic_expr (vcg_stream, stmt, 0);
- fprintf (vcg_stream, " ]");
- }
- gcc_assert (stack == 0);
-
- if (TREE_CODE (stmt) != NOP_EXPR
- || TREE_CODE (TREE_OPERAND (stmt, 0)) != INTEGER_CST)
- gen_cil_node (vcg_stream, stmt);
-
- if (TREE_CODE (stmt) == CALL_EXPR)
- {
- tree fun_expr = CALL_EXPR_FN (stmt);
- tree fun_type = TREE_TYPE (TREE_TYPE (fun_expr));
-
- if (TREE_CODE (TREE_TYPE (fun_type)) != VOID_TYPE)
- {
- fputs ("\n\tpop", vcg_stream);
- stack_pop (1);
- }
- }
- }
-
- if ((!stmt || (TREE_CODE (stmt) != COND_EXPR)) && single_succ_p (bb))
- {
- basic_block succ = single_succ (bb);
-
- /* The last part of the test (succ != bb->next_bb) is a HACK. It
- avoids generating a branch to the successor in case of a
- fallthrough. To be fixed when we have a proper layout of basic
- blocks. Note that branches from COND_EXPR are still generated,
- even to a fallthrough. */
- if ((succ->index != EXIT_BLOCK) && (succ != bb->next_bb))
- {
- tree label = tree_block_label (succ);
- fputs ("\n\tbr\t", vcg_stream);
- dump_label_name (vcg_stream, label);
- gcc_assert (stack == 0);
- }
- }
- fprintf (vcg_stream, "\" }\n"); /* close 'label' clause */
-
- for (ei = ei_start (bb->succs); ei_cond (ei, &e); ei_next (&ei))
- {
- if (e->flags & EDGE_DFS_BACK)
- fprintf (vcg_stream, "backedge: { color: red");
- else if (e->flags & EDGE_LOOP_EXIT)
- fprintf (vcg_stream, "edge: { color: blue");
- else
- fprintf (vcg_stream, "edge: {");
-
- fprintf (vcg_stream, " label:\"%d", e->probability);
-
- if (e->flags & EDGE_LOOP_EXIT)
- fprintf (vcg_stream, " loop_exit");
-
- fprintf (vcg_stream, "\"");
-
- fprintf (vcg_stream,
- " sourcename: \"%sBB%d\" targetname: \"%sBB%d\" }\n",
- fun_name, bb->index, fun_name, e->dest->index);
- }
- }
- fprintf (vcg_stream, "}\n");
-}
-
-
static void
gen_cil_1 (FILE *stream)
{
@@ -4270,14 +3677,7 @@ gen_cil_1 (FILE *stream)
tree label = LABEL_EXPR_LABEL (stmt);
/* Check if the label has its address taken. */
if (FORCED_LABEL (label))
- {
- void **slot;
-
- gcc_assert (pointer_map_contains (labels_map, label) == NULL);
- slot = pointer_map_insert (labels_map, label);
- *slot = build_int_cst (intSI_type_node, taken_labels);
- taken_labels++;
- }
+ record_addr_taken_label (label);
}
}
}
@@ -4406,7 +3806,6 @@ gen_cil_1 (FILE *stream)
FOR_EACH_BB (bb)
{
- tree stmt = NULL_TREE;
if (TARGET_EMIT_GIMPLE_COMMENTS)
{
@@ -4414,50 +3813,7 @@ gen_cil_1 (FILE *stream)
bb->frequency * 100 / BB_FREQ_MAX);
}
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- stmt = bsi_stmt (bsi);
- if (TARGET_EMIT_GIMPLE_COMMENTS)
- {
- fprintf (stream, "\n\t/* ");
- print_generic_expr (stream, stmt, 0);
- fprintf (stream, " */");
- }
- gcc_assert (stack == 0);
-
- if (TREE_CODE (stmt) != NOP_EXPR
- || TREE_CODE (TREE_OPERAND (stmt, 0)) != INTEGER_CST)
- gen_cil_node (stream, stmt);
-
- if (TREE_CODE (stmt) == CALL_EXPR)
- {
- tree fun_expr = CALL_EXPR_FN (stmt);
- tree fun_type = TREE_TYPE (TREE_TYPE (fun_expr));
-
- if (TREE_CODE (TREE_TYPE (fun_type)) != VOID_TYPE)
- {
- fputs ("\n\tpop", stream);
- stack_pop (1);
- }
- }
- }
-
- if ((!stmt || (TREE_CODE (stmt) != COND_EXPR)) && single_succ_p (bb))
- {
- basic_block succ = single_succ (bb);
-
- /* The last part of the test (succ != bb->next_bb) is a HACK. It
- avoids generating a branch to the successor in case of a
- fallthrough. To be fixed when we have a proper layout of basic
- blocks. */
- if ((succ->index != EXIT_BLOCK) && (succ != bb->next_bb))
- {
- tree label = tree_block_label (succ);
- fputs ("\n\tbr\t", stream);
- dump_label_name (stream, label);
- gcc_assert (stack == 0);
- }
- }
+ gen_cil_bb (stream, bb);
if (TARGET_EMIT_GIMPLE_COMMENTS)
{
@@ -4510,7 +3866,6 @@ create_init_method (void)
/* DECL_SOURCE_LOCATION (fun_decl) = DECL_SOURCE_LOCATION (decl); */
/* cfun->function_end_locus = DECL_SOURCE_LOCATION (decl); */
-
TREE_STATIC (fun_decl) = 1;
TREE_USED (fun_decl) = 1;
DECL_ARTIFICIAL (fun_decl) = 1;
@@ -4595,30 +3950,13 @@ gen_cil_init (void)
"void ['OpenSystem.C']'OpenSystem.C'.ModuleAttribute::.ctor() "
"= (01 00 00 00)\n", stream);
- referenced_types = pointer_set_create ();
- VARRAY_TREE_INIT (referenced_strings, 32, "strings used in current unit");
- referenced_string_ptrs = pointer_set_create ();
- referenced_pinvoke = pointer_set_create ();
VARRAY_TREE_INIT (pending_ctors, 32, "pending ctors");
-
- /* Allocate hash table for pointer ids */
- pointer_id_htable = htab_create (256,
- pointer_id_data_hash,
- pointer_id_data_eq,
- free);
-
- labels_map = pointer_map_create ();
- taken_labels = 0;
-
- if (TARGET_EMIT_VCG)
- fprintf (stdout, "graph: {\ndisplay_edge_labels: yes\n");
}
void
gen_cil_fini (void)
{
FILE *stream = asm_out_file;
- struct pointer_set_iter_t it;
if (VARRAY_ACTIVE_SIZE (pending_ctors) > 0)
{
@@ -4626,97 +3964,136 @@ gen_cil_fini (void)
}
VARRAY_CLEAR (pending_ctors);
- if (VARRAY_ACTIVE_SIZE (referenced_strings) > 0)
- {
- print_used_strings (stream);
- }
- VARRAY_CLEAR (referenced_strings);
- pointer_set_destroy (referenced_string_ptrs);
+ print_used_strings (stream);
+ print_referenced_types (stream);
+ print_referenced_pinvokes (stream);
+}
- /* There may be distinct tree types that correspond to identical types.
- In order not to slow down mark_referenced_type(...) function (which
- may typically be called several times for the same type), insertion
- of types in the mark set makes only sure that the same tree type
- pointer is not inserted twice. As a consequence, there may still be
- distinct tree types that correspond to identical types in the
- reference type set.
- Hence, before emitting a type, make sure no type with the same name
- has already been emitted. */
+static bool
+gen_cil_gate (void)
+{
+ return current_function_decl != NULL;
+}
- {
- struct pointer_set_t *emitted_types = pointer_set_create ();
+static unsigned int
+gen_cil (void)
+{
+ gen_cil_1 (asm_out_file);
- it = pointer_set_begin (referenced_types);
- while (!POINTER_SET_ITER_IS_END (it))
- {
- tree type = (tree)POINTER_SET_ITER_ELEM (it);
+ return 0;
+}
- if (COMPLETE_TYPE_P (type))
- {
- tree type_name = TYPE_NAME (type);
- gcc_assert (DECL_P (type_name)
- || TREE_CODE (type_name) == IDENTIFIER_NODE);
-
- if (TREE_CODE (type_name) != IDENTIFIER_NODE)
- type_name = DECL_NAME (type_name);
-
- if (!pointer_set_contains (emitted_types, type_name))
- {
- print_valuetype_decl (stream, type);
- pointer_set_insert (emitted_types, type_name);
- }
- }
-
- it = pointer_set_next (referenced_types, it);
- }
- pointer_set_destroy (referenced_types);
- pointer_set_destroy (emitted_types);
- }
+/* Define the parameters of the gen-CIL pass. */
+
+struct tree_opt_pass pass_gen_cil =
+{
+ "cil", /* name */
+ gen_cil_gate, /* gate */
+ gen_cil, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_REST_OF_COMPILATION, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ /* ??? If TER is enabled, we also kill gimple. */
+ 0, /* properties_destroyed */
+ 0,
+ 0,
+ 0 /* letter */
+};
+
+/* This function is mostly a copy of the last part of 'gen_cil'. */
+static void
+gen_cil_vcg (FILE *vcg_stream)
+{
+ edge_iterator ei;
+ const char *fun_name = lang_hooks.decl_printable_name (current_function_decl, 1);
+ edge e;
+ int i=0;
+
+ fprintf (vcg_stream, "graph: {\n");
+ fprintf (vcg_stream, "title: \"%s\"\n", fun_name);
+ fprintf (vcg_stream, "node: { title: \"%sBB%d\" label: \"ENTRY %s\" }\n",
+ fun_name, ENTRY_BLOCK, fun_name);
+ fprintf (vcg_stream, "node: { title: \"%sBB%d\" label: \"EXIT\" }\n",
+ fun_name, EXIT_BLOCK);
+ fprintf (vcg_stream, "edge:{sourcename: \"%sBB%d\" targetname: \"%sBB%d\"}\n",
+ fun_name, ENTRY_BLOCK,
+ fun_name, single_succ (ENTRY_BLOCK_PTR)->index);
- it = pointer_set_begin (referenced_pinvoke);
- while (!POINTER_SET_ITER_IS_END (it))
+ FOR_EACH_BB (bb)
{
- print_pinvoke_function (stream, (tree)POINTER_SET_ITER_ELEM (it));
- it = pointer_set_next (referenced_pinvoke, it);
- }
- pointer_set_destroy (referenced_pinvoke);
+ fprintf (vcg_stream, "node: { title: \"%sBB%d\" label: \"(BB%d, pos: %d)",
+ fun_name, bb->index, bb->index, i++);
+
+ if (bb->loop_depth)
+ fprintf (vcg_stream, " LOOP DEPTH %d ", bb->loop_depth);
+
+ gen_cil_bb (vcg_stream, bb);
+
+ fprintf (vcg_stream, "\" }\n"); /* close 'label' clause */
+
+ for (ei = ei_start (bb->succs); ei_cond (ei, &e); ei_next (&ei))
+ {
+ if (e->flags & EDGE_DFS_BACK)
+ fprintf (vcg_stream, "backedge: { color: red");
+ else if (e->flags & EDGE_LOOP_EXIT)
+ fprintf (vcg_stream, "edge: { color: blue");
+ else
+ fprintf (vcg_stream, "edge: {");
+
+ fprintf (vcg_stream, " label:\"%d", e->probability);
- /* Delete hash table for pointer ids */
- htab_delete (pointer_id_htable);
+ if (e->flags & EDGE_LOOP_EXIT)
+ fprintf (vcg_stream, " loop_exit");
+
+ fprintf (vcg_stream, "\"");
- pointer_map_destroy (labels_map);
+ fprintf (vcg_stream,
+ " sourcename: \"%sBB%d\" targetname: \"%sBB%d\" }\n",
+ fun_name, bb->index, fun_name, e->dest->index);
+ }
+ }
+ fprintf (vcg_stream, "}\n");
+}
- if (goto_labels != NULL)
- XDELETEVEC (goto_labels);
+void
+cil_vcg_init (void)
+{
+ if (TARGET_EMIT_VCG)
+ fputs ("graph: {\n"
+ "display_edge_labels: yes\n", stdout);
+}
+void
+cil_vcg_fini (void)
+{
if (TARGET_EMIT_VCG)
- fprintf (stdout, "}\n");
+ fputs ("}\n", stdout);
}
static bool
-gen_cil_gate (void)
+cil_vcg_gate (void)
{
- return current_function_decl != NULL;
+ return TARGET_EMIT_VCG && current_function_decl != NULL;
}
static unsigned int
-gen_cil (void)
+cil_vcg (void)
{
- gen_cil_1 (asm_out_file);
-
- if (TARGET_EMIT_VCG)
- gen_cil_vcg(stdout);
+ gen_cil_vcg(stdout);
return 0;
}
-/* Define the parameters of the gen-CIL pass. */
+/* Define the parameters of the CIL_VCG pass. */
-struct tree_opt_pass pass_gen_cil =
+struct tree_opt_pass pass_cil_vcg =
{
- "cil", /* name */
- gen_cil_gate, /* gate */
- gen_cil, /* execute */
+ "cil_vcg", /* name */
+ cil_vcg_gate, /* gate */
+ cil_vcg, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
diff --git a/gcc/config/cil32/gen-cil.h b/gcc/config/cil32/gen-cil.h
index 3905c304856..954107b9546 100644
--- a/gcc/config/cil32/gen-cil.h
+++ b/gcc/config/cil32/gen-cil.h
@@ -39,13 +39,15 @@ void
make_decl_cil (FILE *, tree);
void
-cil_add_pinvoke(tree);
-
-void
gen_cil_init (void);
void
gen_cil_fini (void);
+void
+cil_vcg_init (void);
+void
+cil_vcg_fini (void);
+
/* Defined in rm_ldloc.c */
void remove_stloc_ldloc (void);
diff --git a/gcc/config/cil32/t-cil32 b/gcc/config/cil32/t-cil32
index 75d81fcd1b7..557b3416f44 100644
--- a/gcc/config/cil32/t-cil32
+++ b/gcc/config/cil32/t-cil32
@@ -34,6 +34,12 @@ bit-stream.o: $(srcdir)/config/cil32/bit-stream.c \
$(srcdir)/config/cil32/bit-stream.h $(CONFIG_H) $(SYSTEM_H) coretypes.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
+cil-refs.o : $(srcdir)/config/cil32/cil-refs.c \
+ $(srcdir)/config/cil32/cil-refs.h $(srcdir)/config/cil32/cil-types.h \
+ $(CONFIG_H) $(GGC_H) $(HASHTAB_H) $(SYSTEM_H) $(TM_H) $(TREE_H) coretypes.h \
+ debug.h errors.h gt-cil-refs.h vec.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
+
emit-hints.o: $(srcdir)/config/cil32/emit-hints.c \
$(srcdir)/config/cil32/emit-hints.h $(srcdir)/config/cil32/bit-stream.h \
$(srcdir)/config/cil32/gen-cil.h $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \
@@ -42,6 +48,7 @@ emit-hints.o: $(srcdir)/config/cil32/emit-hints.c \
gen-cil.o: $(srcdir)/config/cil32/gen-cil.c $(srcdir)/config/cil32/gen-cil.h \
$(srcdir)/config/cil32/emit-hints.h $(srcdir)/config/cil32/tree-simp-cil.h \
+ $(srcdir)/config/cil32/cil-refs.h $(srcdir)/config/cil32/cil-types.h \
gt-gen-cil.h $(CONFIG_H) $(DIAGNOSTIC_H) $(HASHTAB_H) $(SYSTEM_H) \
$(TIMEVAR_H) $(TM_H) $(TREE_H) $(TREE_FLOW_H) coretypes.h ggc.h langhooks.h \
output.h pointer-set.h real.h toplev.h tree-iterator.h tree-pass.h varray.h
@@ -53,8 +60,9 @@ rm-ldloc.o: $(srcdir)/config/cil32/rm-ldloc.c $(srcdir)/config/cil32/gen-cil.h \
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
tree-simp-cil.o: $(srcdir)/config/cil32/tree-simp-cil.c \
- $(srcdir)/config/cil32/tree-simp-cil.h $(CONFIG_H) $(SYSTEM_H) $(TIMEVAR_H) \
- $(TM_H) $(TREE_H) $(TREE_FLOW_H) coretypes.h toplev.h tree-pass.h
+ $(srcdir)/config/cil32/tree-simp-cil.h $(srcdir)/config/cil32/cil-refs.h \
+ $(CONFIG_H) $(SYSTEM_H) $(TIMEVAR_H) $(TM_H) $(TREE_H) $(TREE_FLOW_H) \
+ coretypes.h toplev.h tree-pass.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
tree-simp-cil-early.o: $(srcdir)/config/cil32/tree-simp-cil-early.c \
@@ -65,8 +73,9 @@ tree-simp-cil-early.o: $(srcdir)/config/cil32/tree-simp-cil-early.c \
bb-layout.o: $(srcdir)/config/cil32/bb-layout.c \
$(CONFIG_H) $(SYSTEM_H) $(TIMEVAR_H) $(TM_H) $(TREE_H) $(TREE_FLOW_H) \
- coretypes.h tree-pass.h
+ coretypes.h tree-pass.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
$(out_object_file): gt-gen-cil.h
gt-gen-cil.h : s-gtype ; @true
+gt-cil-refs.h : s-gtype ; @true
diff --git a/gcc/config/cil32/tree-simp-cil.c b/gcc/config/cil32/tree-simp-cil.c
index 1cda110a5b3..0fbb7d3c1fa 100644
--- a/gcc/config/cil32/tree-simp-cil.c
+++ b/gcc/config/cil32/tree-simp-cil.c
@@ -41,6 +41,7 @@ Erven Rohou <erven.rohou@st.com>
#include "timevar.h"
#include "toplev.h"
#include "tree-simp-cil.h"
+#include "cil-refs.h"
/* The purpose of this pass is to simplify GIMPLE trees in order
to make CIL emission easier.
@@ -898,7 +899,7 @@ simp_builtin_call (block_stmt_iterator bsi, tree *node_ptr)
tree stmt;
tree new_args;
-
+
new_args = tree_cons (NULL, fold_convert(sizetype, size), NULL);
new_args = tree_cons (NULL, src2, new_args);
new_args = tree_cons (NULL, src1, new_args);
@@ -915,7 +916,7 @@ simp_builtin_call (block_stmt_iterator bsi, tree *node_ptr)
tree stmt;
tree new_args;
-
+
new_args = tree_cons (NULL, fold_convert(sizetype, size), NULL);
new_args = tree_cons (NULL, integer_zero_node, new_args);
new_args = tree_cons (NULL, src1, new_args);
@@ -933,7 +934,7 @@ simp_builtin_call (block_stmt_iterator bsi, tree *node_ptr)
tree stmt;
tree new_args;
-
+
new_args = tree_cons (NULL, fold_convert(sizetype, size), NULL);
new_args = tree_cons (NULL, src1, new_args);
new_args = tree_cons (NULL, dst1, new_args);
@@ -2756,6 +2757,7 @@ simp_cil_final (void)
basic_block bb;
block_stmt_iterator bsi;
+ refs_begin_new_function ();
two = build_int_cst_type (size_type_node, 2);
bits_per_unit = fold_convert (size_type_node, bitsize_unit_node);
simp_final = true;
diff --git a/gcc/passes.c b/gcc/passes.c
index d846d780f23..5fd0fdeb232 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -692,6 +692,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_bb_layout);
NEXT_PASS (pass_simp_cil_final);
NEXT_PASS (pass_gen_cil); /* <--- CIL */
+ NEXT_PASS (pass_cil_vcg);
#else /* !defined(DISABLE_RTL_PASSES) */
NEXT_PASS (pass_mudflap_2);
NEXT_PASS (pass_free_cfg_annotations);