aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Ornstein <andrea.ornstein@st.com>2008-04-23 13:15:39 +0000
committerAndrea Ornstein <andrea.ornstein@st.com>2008-04-23 13:15:39 +0000
commit44e6ca034fd5c1f899b67634ea46b09a43ca2652 (patch)
tree0c7c64d5bf8a963322b24ed5327bb71e08ada190
parentd93cae7b420abda43c4ad2dee0cf899d950e430b (diff)
New Snapshot from ST 2008-04-23 (rev 1062)
........ Added the -mno-stloc-ldloc-removal flag ........ if a STRING_CST is smaller than its type zero initialize the rest ........ Bugfix in expansion of builtin object_size ........ refactor emition of types (compare names using IDENTIFIER_NODE) add function print_pinvoke_function (code to generate pinvokes moved out of gen_cil_fini) add missing prototypes of static functions ........ add expansion of builtins bcmp, bzero and bcopy using memcmp, memset and memmove (they are used in the testsuite) ........ bugfix: change how names of anonymous structs/unions are created, they need to be unique ........ add option -mlittle-endian: Assume target CPU is configured as little endian, compiler will generate initializers for little endian (no runtime check if assumption is correct) ........ refactor linker options passed by the gcc driver ........ Use a pointer map for storing the labels whose address has been taken and their assigned IDs instead of reusing TREE_CHAIN (). This avoids trashing the TREE_CHAIN () field of the labels which is already used by GCC for other purposes. ........ new cil32 builtins added - CIL32_BUILT_IN_CPBLK - CIL32_BUILT_IN_INITBLK - CIL32_BUILT_IN_ENDIAN_SELECT, takes two pointersand returns the first if the target is Little Endian the second one otherwise collect all builtins in an array called cil32_builtins and enable GTY on it in tree-simp-cil use new builtins CPBLK and INITBLK to avoid pops use new builtins ENDIAN_SELECT instead of IS_LITTLE_ENDIAN to avoid control flow in initializers ........ gcc prefixes assembler names that have to be emitted verbatin with a * ........ Cleaned up the code for emitting computed GOTO statements ........ The labels of a computed GOTO replacement switch were not always emitted in the correct order, fixed. ........ Issue an internal error instead of emitting a floordiv() call as we do not have it implemented in libgcc4net. ........ Register pragmas ivdep and loopdep. ........ array attribute used to recognize valuetypes representing arrays ........ fix call to vararg function (emit correct convertions) ........ Added simplication of BIT_FIELD_REFs used for accessing scalar elements inside vectors, this fixes 22 failures in the testsuite (and adds 11 passes). Also cleaned up the code that simplifies switches. ........ Modified simp_lhs_bitfield_component_ref() to emit better code by using less temporaries, folding unnecessary conversions and also removing unnecessary copies and operations when dealing with constants. ........ Modified simp_lhs_bitfield_component_ref () and simp_bitfield_ref () to emit better code and handle properly more corner cases. This fixes 14 failures, 14 related unresolved cases and adds 28 passes to the test suite. ........ Removed the last free_cfg_annotation pass and replaced it with a garbage collector invocation at the end of gen-cil. This removes 53 failures, 39 unresolved cases and adds 85 passes to the test suite. ........ Unnecessary header files removed ........ split print_valuetype_decl in 3 functions: print_enum_decl, print_array_decl and print_struct_union_decl ........ change how CONST STRINGS are generated (their type now is different from array one) add attributes to string and array type definition to allow recognition by the CIL FE ........ git-svn-id: https://gcc.gnu.org/svn/gcc/branches/st/cli@134593 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/config/cil32/bb-layout.c4
-rw-r--r--gcc/config/cil32/bit-stream.c1
-rw-r--r--gcc/config/cil32/cil32-protos.h7
-rw-r--r--gcc/config/cil32/cil32.c314
-rw-r--r--gcc/config/cil32/cil32.h53
-rw-r--r--gcc/config/cil32/cil32.opt18
-rw-r--r--gcc/config/cil32/emit-hints.c41
-rw-r--r--gcc/config/cil32/gen-cil.c770
-rw-r--r--gcc/config/cil32/rm-ldloc.c12
-rw-r--r--gcc/config/cil32/t-cil3236
-rw-r--r--gcc/config/cil32/tree-simp-cil-early.c399
-rw-r--r--gcc/config/cil32/tree-simp-cil.c682
-rw-r--r--gcc/config/cil32/tree-simp-cil.h3
-rw-r--r--gcc/passes.c1
14 files changed, 1390 insertions, 951 deletions
diff --git a/gcc/config/cil32/bb-layout.c b/gcc/config/cil32/bb-layout.c
index 97ae836702e..ce3afcc18a3 100644
--- a/gcc/config/cil32/bb-layout.c
+++ b/gcc/config/cil32/bb-layout.c
@@ -35,13 +35,9 @@ Erven Rohou <erven.rohou@st.com>
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
-#include "diagnostic.h"
-#include "hashtab.h"
#include "tree-flow.h"
-#include "langhooks.h"
#include "tree-pass.h"
#include "timevar.h"
-#include "assert.h"
static inline void
visit_block (basic_block bb)
diff --git a/gcc/config/cil32/bit-stream.c b/gcc/config/cil32/bit-stream.c
index e75e598eb9a..ed2570d368c 100644
--- a/gcc/config/cil32/bit-stream.c
+++ b/gcc/config/cil32/bit-stream.c
@@ -31,7 +31,6 @@ Erven Rohou <erven.rohou@st.com>
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "assert.h"
#include "bit-stream.h"
diff --git a/gcc/config/cil32/cil32-protos.h b/gcc/config/cil32/cil32-protos.h
index 92919213bbb..11e07297614 100644
--- a/gcc/config/cil32/cil32-protos.h
+++ b/gcc/config/cil32/cil32-protos.h
@@ -1,6 +1,6 @@
/* Definitions for GCC. Part of the machine description for cil32.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006-2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -29,3 +29,8 @@ Contact information at STMicroelectronics:
Andrea C. Ornstein <andrea.ornstein@st.com>
Erven Rohou <erven.rohou@st.com>
*/
+
+extern void cil32_ivdep (struct cpp_reader *);
+extern void cil32_loopdep_liberal (struct cpp_reader *);
+extern void cil32_loopdep_parallel (struct cpp_reader *);
+extern void cil32_loopdep_vector (struct cpp_reader *);
diff --git a/gcc/config/cil32/cil32.c b/gcc/config/cil32/cil32.c
index 73386c9cca1..0c1df97a1de 100644
--- a/gcc/config/cil32/cil32.c
+++ b/gcc/config/cil32/cil32.c
@@ -1,6 +1,6 @@
/* Definitions for GCC. Part of the machine description for cil32.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006-2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -176,31 +176,37 @@ cil32_assemble_integer (rtx x ATTRIBUTE_UNUSED,
return true;
}
-tree cil32_builtin_va_start_decl;
-tree cil32_builtin_va_arg_decl;
-tree cil32_builtin_va_end_decl;
-tree cil32_builtin_va_copy_decl;
-tree cil32_builtin_is_LE_decl;
-tree cil32_va_list_type = NULL_TREE;
-tree cil32_arg_iterator_type;
-/* constructors of vector types. */
-/* float */
-tree cil32_v2sf_ctor;
-tree cil32_v4sf_ctor;
-/* 32-bit integer */
-tree cil32_v4qi_ctor;
-tree cil32_v2hi_ctor;
-/* 64-bit integer */
-tree cil32_v8qi_ctor;
-tree cil32_v4hi_ctor;
-tree cil32_v2si_ctor;
-/* 128-bit integer */
-tree cil32_v4si_ctor;
-tree cil32_v8hi_ctor;
-tree cil32_v16qi_ctor;
+void
+cil32_ivdep (struct cpp_reader * x ATTRIBUTE_UNUSED)
+{
+ warning (OPT_Wcil_pragma_ignored, "pragma ivdep not implemented yet");
+}
+
+void
+cil32_loopdep_liberal (struct cpp_reader * x ATTRIBUTE_UNUSED)
+{
+ warning (OPT_Wcil_pragma_ignored, "pragma loopdep not implemented yet");
+}
+
+void
+cil32_loopdep_parallel (struct cpp_reader * x ATTRIBUTE_UNUSED)
+{
+ warning (OPT_Wcil_pragma_ignored, "pragma loopdep not implemented yet");
+}
+
+void
+cil32_loopdep_vector (struct cpp_reader * x ATTRIBUTE_UNUSED)
+{
+ warning (OPT_Wcil_pragma_ignored, "pragma loopdep not implemented yet");
+}
+
+tree cil32_builtins[CIL32_MAX_BUILT_IN] = {NULL_TREE};
+
+tree cil32_va_list_type = NULL_TREE;
+tree cil32_arg_iterator_type;
static void
cil32_build_builtin_types (void)
@@ -235,90 +241,132 @@ cil32_init_builtins (void)
cil32_build_builtin_types ();
arglist = build_tree_list (NULL_TREE, cil32_va_list_type);
- cil32_builtin_va_start_decl = add_builtin_function ("__builtin_cil_va_start",
- build_function_type (void_type_node,
- arglist),
- CIL32_BUILT_IN_VA_START,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_BUILT_IN_VA_START] =
+ add_builtin_function ("__builtin_cil_va_start",
+ build_function_type (void_type_node,
+ arglist),
+ CIL32_BUILT_IN_VA_START,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, ptr_type_node);
arglist = tree_cons (NULL_TREE, cil32_va_list_type, arglist);
- cil32_builtin_va_arg_decl = add_builtin_function ("__builtin_cil_va_arg",
- build_function_type (ptr_type_node,
- arglist),
- CIL32_BUILT_IN_VA_ARG,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_BUILT_IN_VA_ARG] =
+ add_builtin_function ("__builtin_cil_va_arg",
+ build_function_type (ptr_type_node,
+ arglist),
+ CIL32_BUILT_IN_VA_ARG,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, cil32_va_list_type);
- cil32_builtin_va_end_decl = add_builtin_function ("__builtin_cil_va_end",
- build_function_type (void_type_node,
- arglist),
- CIL32_BUILT_IN_VA_END,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_BUILT_IN_VA_END] =
+ add_builtin_function ("__builtin_cil_va_end",
+ build_function_type (void_type_node,
+ arglist),
+ CIL32_BUILT_IN_VA_END,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, cil32_va_list_type);
arglist = tree_cons (NULL_TREE, cil32_va_list_type, arglist);
- cil32_builtin_va_copy_decl = add_builtin_function ("__builtin_cil_va_copy",
- build_function_type (void_type_node,
- arglist),
- CIL32_BUILT_IN_VA_COPY,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
- cil32_builtin_is_LE_decl = add_builtin_function ("__builtin_isLittleEndian",
- build_function_type (integer_type_node,
- NULL_TREE),
- CIL32_BUILT_IN_IS_LITTLE_ENDIAN,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
-
+ cil32_builtins[CIL32_BUILT_IN_VA_COPY] =
+ add_builtin_function ("__builtin_cil_va_copy",
+ build_function_type (void_type_node,
+ arglist),
+ CIL32_BUILT_IN_VA_COPY,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
+ arglist = build_tree_list (NULL_TREE, integer_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_CPBLK] =
+ add_builtin_function ("__builtin_cil_cpblk",
+ build_function_type (void_type_node,
+ arglist),
+ CIL32_BUILT_IN_CPBLK,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
+ arglist = build_tree_list (NULL_TREE, integer_type_node);
+ arglist = tree_cons (NULL_TREE, integer_type_node, arglist);
+ arglist = tree_cons (NULL_TREE, ptr_type_node, arglist);
+ cil32_builtins[CIL32_BUILT_IN_INITBLK] =
+ add_builtin_function ("__builtin_cil_initblk",
+ build_function_type (void_type_node,
+ arglist),
+ CIL32_BUILT_IN_INITBLK,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
+ cil32_builtins[CIL32_BUILT_IN_IS_LITTLE_ENDIAN] =
+ add_builtin_function ("__builtin_isLittleEndian",
+ build_function_type (integer_type_node,
+ NULL_TREE),
+ CIL32_BUILT_IN_IS_LITTLE_ENDIAN,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
+
+ arglist = build_tree_list (NULL_TREE, ptr_type_node);
+ arglist = tree_cons (NULL_TREE, ptr_type_node, arglist);
+ cil32_builtins[CIL32_BUILT_IN_ENDIAN_SELECT] =
+ add_builtin_function ("__builtin_EndianSelect",
+ build_function_type (ptr_type_node,
+ arglist),
+ CIL32_BUILT_IN_ENDIAN_SELECT,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
+
arglist = build_tree_list (NULL_TREE, float_type_node);
arglist = tree_cons (NULL_TREE, float_type_node, arglist);
- cil32_v2sf_ctor = add_builtin_function ("V2SF_ctor1",
- build_function_type (build_vector_type (float_type_node, 2),
- arglist),
- CIL32_V2SF_CTOR,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_V2SF_CTOR] =
+ add_builtin_function ("V2SF_ctor1",
+ build_function_type (build_vector_type (float_type_node, 2),
+ arglist),
+ CIL32_V2SF_CTOR,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, float_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);
- cil32_v4sf_ctor = add_builtin_function ("V4SF_ctor1",
- build_function_type (build_vector_type (float_type_node, 4),
- arglist),
- CIL32_V4SF_CTOR,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_V4SF_CTOR] =
+ add_builtin_function ("V4SF_ctor1",
+ build_function_type (build_vector_type (float_type_node, 4),
+ arglist),
+ CIL32_V4SF_CTOR,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, unsigned_intQI_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);
- cil32_v4qi_ctor = add_builtin_function ("V4QI_ctor1",
- build_function_type (build_vector_type (intQI_type_node, 4),
- arglist),
- CIL32_V4QI_CTOR,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_V4QI_CTOR] =
+ add_builtin_function ("V4QI_ctor1",
+ build_function_type (build_vector_type (intQI_type_node, 4),
+ arglist),
+ CIL32_V4QI_CTOR,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, unsigned_intHI_type_node);
arglist = tree_cons (NULL_TREE, intHI_type_node, arglist);
- cil32_v2hi_ctor = add_builtin_function ("V2HI_ctor1",
- build_function_type (build_vector_type (intHI_type_node, 2),
- arglist),
- CIL32_V2HI_CTOR,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_V2HI_CTOR] =
+ add_builtin_function ("V2HI_ctor1",
+ build_function_type (build_vector_type (intHI_type_node, 2),
+ arglist),
+ CIL32_V2HI_CTOR,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, unsigned_intQI_type_node);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
@@ -328,47 +376,51 @@ cil32_init_builtins (void)
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);
- cil32_v8qi_ctor = add_builtin_function ("V8QI_ctor1",
- build_function_type (build_vector_type (intQI_type_node, 8),
- arglist),
- CIL32_V8QI_CTOR,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_V8QI_CTOR] =
+ add_builtin_function ("V8QI_ctor1",
+ build_function_type (build_vector_type (intQI_type_node, 8),
+ arglist),
+ CIL32_V8QI_CTOR,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, unsigned_intHI_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);
- cil32_v4hi_ctor = add_builtin_function ("V4HI_ctor1",
- build_function_type (build_vector_type (intHI_type_node, 4),
- arglist),
- CIL32_V4HI_CTOR,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_V4HI_CTOR] =
+ add_builtin_function ("V4HI_ctor1",
+ build_function_type (build_vector_type (intHI_type_node, 4),
+ arglist),
+ CIL32_V4HI_CTOR,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, unsigned_intSI_type_node);
arglist = tree_cons (NULL_TREE, unsigned_intSI_type_node, arglist);
- cil32_v2si_ctor = add_builtin_function ("V2SI_ctor1",
- build_function_type (build_vector_type (intSI_type_node, 2),
- arglist),
- CIL32_V2SI_CTOR,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_V2SI_CTOR] =
+ add_builtin_function ("V2SI_ctor1",
+ build_function_type (build_vector_type (intSI_type_node, 2),
+ arglist),
+ CIL32_V2SI_CTOR,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, unsigned_intSI_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);
- cil32_v4si_ctor = add_builtin_function ("V4SI_ctor1",
- build_function_type (build_vector_type (intSI_type_node, 4),
- arglist),
- CIL32_V4SI_CTOR,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_V4SI_CTOR] =
+ add_builtin_function ("V4SI_ctor1",
+ build_function_type (build_vector_type (intSI_type_node, 4),
+ arglist),
+ CIL32_V4SI_CTOR,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, unsigned_intHI_type_node);
arglist = tree_cons (NULL_TREE, unsigned_intHI_type_node, arglist);
@@ -378,13 +430,14 @@ cil32_init_builtins (void)
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);
- cil32_v8hi_ctor = add_builtin_function ("V8HI_ctor1",
- build_function_type (build_vector_type (intHI_type_node, 8),
- arglist),
- CIL32_V8HI_CTOR,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_V8HI_CTOR] =
+ add_builtin_function ("V8HI_ctor1",
+ build_function_type (build_vector_type (intHI_type_node, 8),
+ arglist),
+ CIL32_V8HI_CTOR,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
arglist = build_tree_list (NULL_TREE, unsigned_intQI_type_node);
arglist = tree_cons (NULL_TREE, unsigned_intQI_type_node, arglist);
@@ -402,13 +455,14 @@ cil32_init_builtins (void)
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);
- cil32_v16qi_ctor = add_builtin_function ("V16QI_ctor1",
- build_function_type (build_vector_type (intQI_type_node, 16),
- arglist),
- CIL32_V16QI_CTOR,
- BUILT_IN_MD,
- NULL,
- NULL_TREE);
+ cil32_builtins[CIL32_V16QI_CTOR] =
+ add_builtin_function ("V16QI_ctor1",
+ build_function_type (build_vector_type (intQI_type_node, 16),
+ arglist),
+ CIL32_V16QI_CTOR,
+ BUILT_IN_MD,
+ NULL,
+ NULL_TREE);
}
static tree
@@ -425,7 +479,7 @@ cil32_gimplify_va_arg (tree valist, tree type, tree *pre_p ATTRIBUTE_UNUSED, tre
tree ptr_type = build_pointer_type (type);
tree arglist = build_tree_list (NULL_TREE, build_int_cstu (ptr_type, 0));
arglist = tree_cons (NULL_TREE, valist, arglist);
- fcall = build_function_call_expr (cil32_builtin_va_arg_decl, arglist);
+ fcall = build_function_call_expr (cil32_builtins[CIL32_BUILT_IN_VA_ARG], arglist);
TREE_TYPE (fcall) = ptr_type;
return build1 (INDIRECT_REF, type, fcall);
}
diff --git a/gcc/config/cil32/cil32.h b/gcc/config/cil32/cil32.h
index cd5321b58ad..cd183e40310 100644
--- a/gcc/config/cil32/cil32.h
+++ b/gcc/config/cil32/cil32.h
@@ -1,6 +1,6 @@
/* Definitions for GCC. Part of the machine description for cil32.
- Copyright (C) 2006-2007 Free Software Foundation, Inc.
+ Copyright (C) 2006-2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -44,9 +44,9 @@ Erven Rohou <erven.rohou@st.com>
/* Node: Driver */
#define CC1_SPEC "%{!mnoopensystemc:-mopensystemc}"
-#define LIB_SPEC ""
-#define LIBGCC_SPEC ""
-#define LINK_SPEC "--no-stdlib %{!nostdlib:-l gcc4net.dll} %{shared:--format dll}"
+#define LIB_SPEC "-l libstd.dll"
+#define LIBGCC_SPEC "-l gcc4net.dll"
+#define LINK_SPEC "%{shared:--shared}"
#define STARTFILE_SPEC ""
#define ENDFILE_SPEC ""
@@ -500,6 +500,15 @@ struct cum_args {int regs;};
/* Node: Misc */
+/* Handle pragmas. */
+#define REGISTER_TARGET_PRAGMAS() do { \
+ c_register_pragma (0, "ivdep", cil32_ivdep); \
+ c_register_pragma ("loopdep", "LIBERAL", cil32_loopdep_liberal); \
+ c_register_pragma ("loopdep", "PARALLEL", cil32_loopdep_parallel); \
+ c_register_pragma ("loopdep", "VECTOR", cil32_loopdep_vector); \
+} while (0)
+
+
#define CASE_VECTOR_MODE HImode
/* The maximum number of bytes that a single instruction can move quickly
@@ -535,42 +544,36 @@ extern struct tree_opt_pass pass_gen_cil;
/* cil32 builtin ID */
enum cil32_builtin
{
- CIL32_BUILT_IN_VA_START,
+ CIL32_BUILT_IN_VA_START = 0,
CIL32_BUILT_IN_VA_ARG,
CIL32_BUILT_IN_VA_END,
CIL32_BUILT_IN_VA_COPY,
+ CIL32_BUILT_IN_CPBLK,
+ CIL32_BUILT_IN_INITBLK,
CIL32_BUILT_IN_IS_LITTLE_ENDIAN,
+ CIL32_BUILT_IN_ENDIAN_SELECT,
+/* constructors of vector types. */
+/* float */
CIL32_V2SF_CTOR,
CIL32_V4SF_CTOR,
+/* 32-bit integer */
CIL32_V4QI_CTOR,
CIL32_V2HI_CTOR,
+/* 64-bit integer */
CIL32_V8QI_CTOR,
CIL32_V4HI_CTOR,
CIL32_V2SI_CTOR,
+/* 128-bit integer */
CIL32_V4SI_CTOR,
CIL32_V8HI_CTOR,
- CIL32_V16QI_CTOR
+ CIL32_V16QI_CTOR,
+ CIL32_MAX_BUILT_IN
};
-extern tree cil32_builtin_va_start_decl;
-extern tree cil32_builtin_va_arg_decl;
-extern tree cil32_builtin_va_end_decl;
-extern tree cil32_builtin_va_copy_decl;
-extern tree cil32_builtin_is_LE_decl;
-
-extern tree cil32_va_list_type;
-extern tree cil32_arg_iterator_type;
-
-extern tree cil32_v2sf_ctor;
-extern tree cil32_v4sf_ctor;
-extern tree cil32_v4qi_ctor;
-extern tree cil32_v2hi_ctor;
-extern tree cil32_v8qi_ctor;
-extern tree cil32_v4hi_ctor;
-extern tree cil32_v2si_ctor;
-extern tree cil32_v4si_ctor;
-extern tree cil32_v8hi_ctor;
-extern tree cil32_v16qi_ctor;
+extern GTY(()) tree cil32_builtins[CIL32_MAX_BUILT_IN];
+
+extern GTY(()) tree cil32_va_list_type;
+extern GTY(()) tree cil32_arg_iterator_type;
/*
* Local variables:
diff --git a/gcc/config/cil32/cil32.opt b/gcc/config/cil32/cil32.opt
index 2ea0e864466..2597293e3e4 100644
--- a/gcc/config/cil32/cil32.opt
+++ b/gcc/config/cil32/cil32.opt
@@ -1,6 +1,6 @@
; Options for the CIL32 port of the compiler.
;
-; Copyright (C) 2006 Free Software Foundation, Inc.
+; Copyright (C) 2006-2008 Free Software Foundation, Inc.
;
; This file is part of GCC.
;
@@ -37,6 +37,10 @@ mnoopensystemc
Target InverseMask(OPENSYSTEMC)
Disable use of OpenSystem.C Attributes
+mno-stloc-ldloc-removal
+Target Mask(NO_STLOC_LDLOC_REMOVAL)
+Do not do stloc/ldloc couples removal
+
mexpand-abs
Target Mask(EXPAND_ABS)
Expand abs (absolute value) instead of generating a call to Crt::abs
@@ -64,3 +68,15 @@ Emits compilation hints for a JIT encoded in custom attributes
Wcil-missing-prototypes
Target Var(warn_cil_missing_prototypes) Init(1)
Warn about missing prototypes dangerous for CLI generation
+
+Wcil-pragma-ignored
+Target Var(warn_cil_pragma_ignored) Init(1)
+Warn about ignored pragmas
+
+mbig-endian
+Target Report RejectNegative Mask(BIG_ENDIAN)
+Assume target CPU is configured as big endian
+
+mlittle-endian
+Target Report RejectNegative Mask(LITTLE_ENDIAN)
+Assume target CPU is configured as little endian
diff --git a/gcc/config/cil32/emit-hints.c b/gcc/config/cil32/emit-hints.c
index d1ce3dc21ed..5662af0088d 100644
--- a/gcc/config/cil32/emit-hints.c
+++ b/gcc/config/cil32/emit-hints.c
@@ -33,12 +33,7 @@ Erven Rohou <erven.rohou@st.com>
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
-#include "diagnostic.h"
#include "tree-flow.h"
-#include "langhooks.h"
-#include "tree-iterator.h"
-#include "assert.h"
-#include "toplev.h"
#include "gen-cil.h"
#include "bit-stream.h"
#include "emit-hints.h"
@@ -123,16 +118,19 @@ static struct branch_prob_list_node *branch_prob_list_tail = NULL;
void
branch_probability_add (FILE *file, tree node)
{
- basic_block src_bb, dest_bb;
edge e;
struct branch_prob_list_node *n;
gcc_assert (TREE_CODE (node) == COND_EXPR);
- src_bb = get_stmt_ann (node)->bb;
- dest_bb = label_to_block (GOTO_DESTINATION (COND_EXPR_THEN (node)));
- e = find_edge (src_bb, dest_bb);
- gcc_assert (e);
+ {
+ edge true_edge;
+ edge false_edge;
+ basic_block src_bb = get_stmt_ann (node)->bb;
+ extract_true_false_edges_from_block (src_bb, &true_edge, &false_edge);
+ e = true_edge;
+ gcc_assert (e);
+ }
/* Initialize new branch probability node */
n = XNEW (struct branch_prob_list_node);
@@ -269,10 +267,13 @@ basic_block_frequency_emit (FILE *file)
{
tree last = bsi_stmt (last_bsi);
- if (TREE_CODE (last) == COND_EXPR
- && label_to_block (GOTO_DESTINATION (COND_EXPR_ELSE (last)))
- != bb->next_bb)
- ++emitted_bbs;
+ if (TREE_CODE (last) == COND_EXPR) {
+ edge true_edge;
+ edge false_edge;
+ extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
+ if (false_edge->dest != bb->next_bb)
+ ++emitted_bbs;
+ }
}
}
@@ -297,7 +298,6 @@ basic_block_frequency_emit (FILE *file)
{
block_stmt_iterator last_bsi = bsi_last (bb);
int freq_class;
- tree last;
/* Frequency is not emitted for an empty basic block */
if (bsi_end_p (last_bsi))
@@ -311,11 +311,14 @@ basic_block_frequency_emit (FILE *file)
coding[freq_class].num_bits,
coding[freq_class].code);
- last = bsi_stmt (last_bsi);
- if (TREE_CODE (last) == COND_EXPR)
+ if (TREE_CODE (bsi_stmt (last_bsi)) == COND_EXPR)
{
- tree label_decl = GOTO_DESTINATION (COND_EXPR_ELSE (last));
- basic_block dest_bb = label_to_block (label_decl);
+ edge true_edge;
+ edge false_edge;
+ basic_block dest_bb;
+
+ extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
+ dest_bb = false_edge->dest;
if (dest_bb != bb->next_bb)
{
diff --git a/gcc/config/cil32/gen-cil.c b/gcc/config/cil32/gen-cil.c
index 4e720689cd5..994fcc0306e 100644
--- a/gcc/config/cil32/gen-cil.c
+++ b/gcc/config/cil32/gen-cil.c
@@ -41,14 +41,13 @@ Erven Rohou <erven.rohou@st.com>
#include "tree-flow.h"
#include "langhooks.h"
#include "tree-iterator.h"
-#include "tree-chrec.h"
#include "tree-pass.h"
#include "timevar.h"
-#include "assert.h"
#include "toplev.h"
#include "pointer-set.h"
#include "output.h"
#include "varray.h"
+#include "ebitmap.h"
#include "ggc.h"
#include "tree-simp-cil.h"
#include "gen-cil.h"
@@ -90,6 +89,7 @@ struct pointer_id_data
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);
@@ -108,7 +108,11 @@ 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);
+static void print_struct_union_decl (FILE *, tree);
static void dump_type (FILE *, tree, bool, bool);
+static void dump_string_type (FILE *, tree);
static void dump_complex_type (FILE *, tree, bool);
static void dump_vector_type (FILE *, tree, bool);
static void dump_type_promotion (FILE *, tree, bool);
@@ -126,12 +130,18 @@ static void gen_binary_cond_branch (FILE *, tree, tree);
static void gen_call_expr (FILE *, tree);
static void gen_start_function (FILE *);
static void gen_string_custom_attr (FILE *, const char*);
+static void gen_computed_goto (FILE *, tree);
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 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 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;
@@ -142,8 +152,10 @@ static unsigned int pointer_next_id = 0;
static unsigned int stack;
static unsigned int max_stack;
static basic_block bb;
-static tree addr_taken_labels = NULL;
+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
@@ -390,7 +402,6 @@ mark_referenced_string (tree t)
VARRAY_PUSH_TREE (referenced_strings, t);
pointer_set_insert (referenced_string_ptrs,
(void *)(TREE_STRING_POINTER (t)));
- mark_referenced_type (TREE_TYPE (t));
}
}
@@ -443,7 +454,13 @@ dump_decl_name (FILE* file, tree node)
mark_decl_referenced (node);
if (DECL_ASSEMBLER_NAME_SET_P (node))
- fprintf (file, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node)));
+ {
+ const char* tname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node));
+ if (tname[0] == '*')
+ fprintf (file, tname+1);
+ else
+ fprintf (file, tname);
+ }
else if (DECL_NAME (node))
fprintf (file, IDENTIFIER_POINTER (DECL_NAME (node)));
else
@@ -480,6 +497,20 @@ 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)
{
@@ -748,6 +779,27 @@ dump_type (FILE *file, tree node, bool ref, bool qualif)
}
+static void
+dump_string_type (FILE *file, tree node)
+{
+ tree domain;
+ tree min;
+ tree max;
+ unsigned int size;
+ gcc_assert(TREE_CODE (node) == ARRAY_TYPE
+ && TYPE_DOMAIN (node)
+ && ! ARRAY_TYPE_VARLENGTH (node));
+ domain = TYPE_DOMAIN (node);
+ min = TYPE_MIN_VALUE (domain);
+ max = TYPE_MAX_VALUE (domain);
+ gcc_assert(min
+ && max
+ && integer_zerop (min)
+ && host_integerp (max, 0));
+ size = TREE_INT_CST_LOW (max) + 1;
+ fprintf (file, "valuetype '?string_type?%d'", size);
+}
+
static void
dump_complex_type (FILE *file, tree node, bool full)
@@ -1109,7 +1161,7 @@ gen_addr_expr (FILE *file, tree t)
case STRING_CST:
mark_referenced_string (t);
fputs ("\n\tldsflda\t", file);
- dump_type (file, TREE_TYPE (t), true, false);
+ dump_string_type (file, TREE_TYPE (t));
fputs (" ", file);
dump_string_name (file, t);
stack_push (1);
@@ -1148,20 +1200,13 @@ gen_addr_expr (FILE *file, tree t)
case LABEL_DECL:
{
- /* We cannot emit the address of the label in CIL, so we map each
- label to an ID and emit the ID. The GOTO will then be implemented
- with a switch based on that ID. The ID is simply the position in
- the list of all address taken labels. */
-
- int pos = 0;
- tree label_iter = addr_taken_labels;
- while (label_iter != t)
- {
- gcc_assert (label_iter);
- ++pos;
- label_iter = TREE_CHAIN (label_iter);
- }
- fprintf (file, "\n\tldc.i4\t%d", pos);
+ /* We cannot emit the address of the label in CIL, so we map each
+ label to an ID and emit the ID. The GOTO will then be implemented
+ 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);
}
break;
@@ -1488,13 +1533,6 @@ gen_call_expr (FILE *file, tree node)
tree fun_expr;
tree fun_type;
bool direct_call;
- tree static_chain;
- tree args;
- tree args_type;
- tree last_arg_type;
- bool varargs;
- int promote_types = 0;
- unsigned int aidx;
unsigned int nargs;
gcc_assert(TREE_CODE (node) == CALL_EXPR);
@@ -1612,6 +1650,40 @@ gen_call_expr (FILE *file, tree node)
}
break;
+ case CIL32_BUILT_IN_CPBLK:
+ {
+ tree ptr_dst = CALL_EXPR_ARG (node, 0);
+ tree ptr_src = CALL_EXPR_ARG (node, 1);
+ tree size = CALL_EXPR_ARG (node, 2);
+
+ gen_cil_node (file, ptr_dst);
+ gen_cil_node (file, ptr_src);
+ gen_cil_node (file, size);
+
+ fputs ("\n\tunaligned. 1"
+ "\n\tcpblk", file);
+ stack_pop (3);
+ done = true;
+ }
+ break;
+
+ case CIL32_BUILT_IN_INITBLK:
+ {
+ tree ptr = CALL_EXPR_ARG (node, 0);
+ tree value = CALL_EXPR_ARG (node, 1);
+ tree size = CALL_EXPR_ARG (node, 2);
+
+ gen_cil_node (file, ptr);
+ gen_cil_node (file, value);
+ gen_cil_node (file, size);
+
+ fputs ("\n\tunaligned. 1"
+ "\n\tinitblk", file);
+ stack_pop (3);
+ done = true;
+ }
+ break;
+
case CIL32_BUILT_IN_IS_LITTLE_ENDIAN:
{
fputs ("\n\tcall\tbool [gcc4net]gcc4net.Crt::__isLittleEndian()",
@@ -1622,6 +1694,22 @@ gen_call_expr (FILE *file, tree node)
}
break;
+ case CIL32_BUILT_IN_ENDIAN_SELECT:
+ {
+ tree le_tree = CALL_EXPR_ARG (node, 0);
+ tree be_tree = CALL_EXPR_ARG (node, 1);
+
+ gen_cil_node (file, le_tree);
+ gen_cil_node (file, be_tree);
+ fputs ("\n\tcall\tvoid* [gcc4net]gcc4net.Crt::__EndianSelect(void*, void*)",
+ file);
+
+ stack_pop (2);
+ stack_push (1);
+ done = true;
+ }
+ break;
+
case CIL32_V2SF_CTOR:
case CIL32_V4SF_CTOR:
case CIL32_V4QI_CTOR:
@@ -1861,6 +1949,45 @@ gen_call_expr (FILE *file, tree node)
if (!done)
{
+ tree args;
+ tree args_type;
+ tree static_chain;
+ bool varargs;
+ unsigned int nargs_base;
+ unsigned int aidx;
+
+ args_type = TYPE_ARG_TYPES (fun_type);
+ varargs = FALSE;
+
+ if (args_type == NULL)
+ {
+ if (direct_call)
+ warning (OPT_Wcil_missing_prototypes,
+ "Missing function %s prototype, guessing it, "
+ "you should fix the code",
+ IDENTIFIER_POINTER (DECL_NAME (fdecl)));
+ else
+ warning (OPT_Wcil_missing_prototypes,
+ "Missing indirect function prototype, guessing it, "
+ "you should fix the code");
+ /* Guess types using the type of the arguments */
+ nargs_base = 0;
+ }
+ else
+ {
+ tree last_arg_type = tree_last (args_type);
+ nargs_base = list_length (args_type);
+
+ if (TREE_VALUE (last_arg_type) != void_type_node)
+ {
+ varargs = TRUE;
+ }
+ else
+ {
+ --nargs_base;
+ }
+ }
+
/* Print parameters. */
/* If static Chain present, it will be the first argument */
@@ -1868,8 +1995,20 @@ gen_call_expr (FILE *file, tree node)
if (static_chain)
gen_cil_node (file, static_chain);
- for (aidx=0;aidx<nargs;++aidx)
- gen_cil_node (file, CALL_EXPR_ARG (node, aidx));
+ for (aidx=0;aidx<nargs_base;++aidx)
+ {
+ gen_cil_node (file, CALL_EXPR_ARG (node, aidx));
+ }
+
+ for (;aidx<nargs;++aidx) {
+ tree targ = CALL_EXPR_ARG (node, aidx);
+ tree targ_type = TREE_TYPE(targ);
+ gen_cil_node (file, targ);
+ if (TREE_CODE (targ_type) == POINTER_TYPE
+ || (TREE_CODE (targ_type) == ARRAY_TYPE
+ && (! TYPE_DOMAIN (targ_type) || ARRAY_TYPE_VARLENGTH (targ_type))))
+ fputs ("\n\tconv.i", file);
+ }
/* Print function pointer, in case of indirect call */
if (!direct_call)
@@ -1890,35 +2029,6 @@ gen_call_expr (FILE *file, tree node)
else
fputs ("calli\t", file);
- args_type = TYPE_ARG_TYPES (fun_type);
- last_arg_type = 0;
- varargs = FALSE;
-
- if (args_type == NULL)
- {
- if (direct_call)
- warning (OPT_Wcil_missing_prototypes,
- "Missing function %s prototype, guessing it, "
- "you should fix the code",
- IDENTIFIER_POINTER (DECL_NAME (fdecl)));
- else
- warning (OPT_Wcil_missing_prototypes,
- "Missing indirect function prototype, guessing it, "
- "you should fix the code");
- /* Guess types using the type of the arguments */
- promote_types = 1;
- }
- else
- {
- last_arg_type = tree_last (args_type);
-
- if (TREE_VALUE (last_arg_type) != void_type_node)
- {
- last_arg_type = 0;
- varargs = TRUE;
- }
- }
-
if (varargs)
fputs ("vararg ", file);
@@ -1948,32 +2058,32 @@ gen_call_expr (FILE *file, tree node)
if (static_chain)
{
dump_type (file, TREE_TYPE (static_chain), true, true);
- if (args_type != last_arg_type)
+ if (nargs_base > 0)
fputs (", ", file);
}
- for (aidx=0;aidx<nargs;++aidx)
+ for (aidx=0;aidx<nargs_base;++aidx)
{
if (aidx!=0)
{
- if (!promote_types && varargs && args_type == last_arg_type)
- {
- fputs (", ..., ", file);
- promote_types = 1;
- }
- else
- fputs (", ", file);
+ fputs (", ", file);
}
- if (promote_types)
- {
- dump_type_promotion (file, TREE_TYPE (CALL_EXPR_ARG (node, aidx)), true);
- }
- else
+ dump_type (file, TREE_VALUE (args_type), true, true);
+ args_type = TREE_CHAIN (args_type);
+ }
+
+ if (varargs && aidx<nargs)
+ fputs (", ..., ", file);
+
+ for (;aidx<nargs;++aidx)
+ {
+ if (aidx!=nargs_base)
{
- dump_type (file, TREE_VALUE (args_type), true, true);
- args_type = TREE_CHAIN (args_type);
+ fputs (", ", file);
}
+
+ dump_type_promotion (file, TREE_TYPE (CALL_EXPR_ARG (node, aidx)), true);
}
fputs (")", file);
@@ -2162,24 +2272,13 @@ gen_cil_node (FILE *file, tree node)
case GOTO_EXPR:
{
tree label_decl = GOTO_DESTINATION (node);
- tree label_iter = addr_taken_labels;
- if (TREE_CODE (label_decl) != LABEL_DECL)
- {
- /* This is a goto to the address of a label. Labels have been
- numbered, and we emit a switch based on that ID. */
- gen_cil_node (file, label_decl);
- fputs ("\n\tswitch (", file);
- while (label_iter)
- {
- dump_label_name (file, label_iter);
- label_iter = TREE_CHAIN (label_iter);
- if (label_iter)
- fputs (", ", file);
- }
- fputs (")", file);
- stack_pop (1);
- }
+ if (TREE_CODE (label_decl) != LABEL_DECL)
+ {
+ /* This is a goto to the address of a label. Labels have been
+ numbered, and we emit a switch based on that ID. */
+ gen_computed_goto (file, label_decl);
+ }
else
{
basic_block dest_bb = label_to_block (label_decl);
@@ -2715,13 +2814,7 @@ gen_cil_node (FILE *file, tree node)
fputs ("\n\tdiv.un", file);
}
else
- {
- fputs ("\n\tcall\t int32 [gcc4net]gcc4net.Crt::floordiv(", file);
- dump_type_for_builtin (file, TREE_TYPE (op0), true);
- fputs (", ", file);
- dump_type_for_builtin (file, TREE_TYPE (op1), true);
- fputs (")", file);
- }
+ internal_error ("\n\nFLOOR_DIV_EXPR is not completely supported\n");
/* No need for conversions even in case of values with precision
smaller than the one used on the evaluation stack,
@@ -3352,14 +3445,22 @@ 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;
- encode_type:
type = TYPE_MAIN_VARIANT (type);
- switch (TREE_CODE (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);
@@ -3390,11 +3491,38 @@ append_coded_type (char *str, tree type,
}
break;
- pointer:
case POINTER_TYPE:
- str = append_string (str, "*", len, max_len);
- type = TREE_TYPE (type);
- goto encode_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);
+
+ 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 (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
+ {
+ 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))
@@ -3422,10 +3550,15 @@ append_coded_type (char *str, tree type,
str = append_string (str, "]", len, max_len);
}
- else
- goto pointer;
- type = TREE_TYPE (type);
- goto encode_type;
+ 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:
@@ -3451,7 +3584,7 @@ append_coded_type (char *str, tree type,
else
type_str = IDENTIFIER_POINTER (DECL_NAME (type_name));
- switch (TREE_CODE (type))
+ switch (type_code)
{
case ENUMERAL_TYPE:
prefix = "E";
@@ -3477,6 +3610,8 @@ append_coded_type (char *str, tree type,
break;
default:
+/* debug_tree(type); */
+/* gcc_assert (0); */
str = append_string (str, "unknown", len, max_len);
}
@@ -3634,104 +3769,107 @@ make_valuetype_identifier (tree t)
}
static void
-print_valuetype_decl (FILE *file, tree t)
+print_enum_decl (FILE *file, tree t)
{
- bool is_enum;
+ gcc_assert (t != NULL_TREE && TREE_CODE (t) == ENUMERAL_TYPE);
- if (t == NULL_TREE || t == error_mark_node)
- return;
+ fputs ("\n.class ", file);
- if (!AGGREGATE_TYPE_P (t) && TREE_CODE (t) != ENUMERAL_TYPE)
- return;
+ if (TYPE_FILE_SCOPE_P (t)) fputs ("public ", file);
+ else fputs ("private ", file);
- if (file == 0)
- return;
+ fputs ("sealed serializable ansi ", file);
+ dump_valuetype_name (file, t);
+ fputs (" extends ['mscorlib']System.Enum\n"
+ "{\n", file);
- gcc_assert (TYPE_MAIN_VARIANT (t) == t);
- gcc_assert (TYPE_NAME (t));
+ {
+ int type_size = TYPE_PRECISION (t);
+ char tmp_str[8] = "int";
+ char *base_type_str = tmp_str;
+ tree tmp;
- is_enum = (TREE_CODE (t) == ENUMERAL_TYPE);
+ snprintf (base_type_str + 3, 5, "%d", type_size);
- /* Print the name of the valuetype. */
- fputs ("\n.class ", file);
+ fputs ("\t.field public specialname rtspecialname ", file);
- if (TYPE_FILE_SCOPE_P (t))
- fputs ("public ", file);
- else
- fputs ("private ", file);
+ if (!TYPE_UNSIGNED (t))
+ fputs ("unsigned ", file);
- if (!is_enum)
- fputs ("explicit ", file);
+ fprintf (file, "%s 'value__'\n", base_type_str);
- fputs ("sealed serializable ansi ", file);
- dump_valuetype_name (file, t);
- fputs (" extends ['mscorlib']System.", file);
+ tmp = TYPE_VALUES (t);
+ while (tmp)
+ {
+ fputs ("\t.field public static literal ", file);
+ dump_type (file, t, false, false);
+ fputs (" '", file);
+ gcc_assert (TREE_CODE (TREE_PURPOSE (tmp)) == IDENTIFIER_NODE);
+ fprintf (file, IDENTIFIER_POINTER (TREE_PURPOSE (tmp)));
+ fprintf (file, "' = %s(%ld)\n",
+ base_type_str, TREE_INT_CST_LOW (TREE_VALUE (tmp)));
+ tmp = TREE_CHAIN (tmp);
+ }
+ }
- if (is_enum)
- fputs ("Enum\n", file);
- else
- fputs ("ValueType\n", file);
+ fputs ("}\n", file);
+}
- /* Print the contents of the valuetype. */
- fputs ("{\n", file);
+static void
+print_array_decl (FILE *file, tree t)
+{
+ fputs ("\n.class ", file);
- if (is_enum)
- {
- int type_size = TYPE_PRECISION (t);
- char tmp_str[8] = "int";
- char *base_type_str = tmp_str;
- tree tmp;
+ if (TYPE_FILE_SCOPE_P (t)) fputs ("public ", file);
+ else fputs ("private ", file);
- snprintf (base_type_str + 3, 5, "%d", type_size);
+ fputs ("explicit sealed serializable ansi ", file);
+ dump_valuetype_name (file, t);
+ fputs (" extends ['mscorlib']System.ValueType\n"
+ "{\n"
+ "\t.custom instance "
+ "void [gcc4net]gcc4net.C_Attributes.ArrayType::.ctor() "
+ "= (01 00 00 00)\n", file);
+
+ fprintf (file, "\t.size %ld\n", TREE_INT_CST_LOW (TYPE_SIZE_UNIT (t)));
+ fputs ("\t.field [0] public specialname ", file);
+ dump_type (file, TREE_TYPE (t), false, false);
+ fputs (" 'elem__'\n"
+ "}\n", file);
+}
- fputs ("\t.field public specialname rtspecialname ", file);
+static void
+print_struct_union_decl (FILE *file, tree t)
+{
+ tree tmp;
- if (!TYPE_UNSIGNED (t))
- fputs ("unsigned ", file);
+ fputs ("\n.class ", file);
- fprintf (file, "%s 'value__'\n", base_type_str);
+ if (TYPE_FILE_SCOPE_P (t)) fputs ("public ", file);
+ else fputs ("private ", file);
- tmp = TYPE_VALUES (t);
- while (tmp)
- {
- fputs ("\t.field public static literal ", file);
- dump_type (file, t, false, false);
- fputs (" '", file);
- gcc_assert (TREE_CODE (TREE_PURPOSE (tmp)) == IDENTIFIER_NODE);
- fprintf (file, IDENTIFIER_POINTER (TREE_PURPOSE (tmp)));
- fprintf (file, "' = %s(%ld)\n",
- base_type_str, TREE_INT_CST_LOW (TREE_VALUE (tmp)));
- tmp = TREE_CHAIN (tmp);
- }
- }
- else if (TREE_CODE (t) == ARRAY_TYPE)
- {
- /* array */
- fprintf (file, "\t.size %ld\n", TREE_INT_CST_LOW (TYPE_SIZE_UNIT (t)));
- fputs ("\t.field [0] public specialname ", file);
- dump_type (file, TREE_TYPE (t), false, false);
- fputs (" 'elem__'\n", file);
- }
- else
- {
- /* struct and union */
- tree tmp;
+ fputs ("explicit sealed serializable ansi ", file);
+ dump_valuetype_name (file, t);
+ fputs (" extends ['mscorlib']System.ValueType\n"
+ "{\n", file);
- fprintf (file, "\t.size %ld\n", TREE_INT_CST_LOW (TYPE_SIZE_UNIT (t)));
+ fprintf (file, "\t.size %ld\n", TREE_INT_CST_LOW (TYPE_SIZE_UNIT (t)));
- tmp = TYPE_FIELDS (t);
- while (tmp)
+ tmp = TYPE_FIELDS (t);
+ while (tmp)
+ {
+
+ if (DECL_NAME (tmp) == 0 && DECL_BIT_FIELD (tmp))
+ {
+ /* Skip unnamed bitfields */
+ }
+ else
{
tree type;
- unsigned int bit_offset =
- TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (tmp));
- unsigned int byte_offset =
- TREE_INT_CST_LOW (DECL_FIELD_OFFSET (tmp));
+ unsigned int bit_offset = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (tmp));
+ unsigned int byte_offset = TREE_INT_CST_LOW (DECL_FIELD_OFFSET (tmp));
unsigned int offset;
- /* Skip unnamed bitfields */
- if (DECL_NAME (tmp) == 0 && DECL_BIT_FIELD (tmp))
- goto next;
if (DECL_BIT_FIELD (tmp))
{
@@ -3760,14 +3898,37 @@ print_valuetype_decl (FILE *file, tree t)
fputs (" ", file );
dump_decl_name (file, tmp);
fputs ("\n", file);
- next:
- tmp = TREE_CHAIN (tmp);
}
+
+ tmp = TREE_CHAIN (tmp);
}
fputs ("}\n", file);
}
+static void
+print_valuetype_decl (FILE *file, tree t)
+{
+ if (t == NULL_TREE || t == error_mark_node)
+ return;
+
+ if (!AGGREGATE_TYPE_P (t) && TREE_CODE (t) != ENUMERAL_TYPE)
+ return;
+
+ gcc_assert (file != 0);
+
+ gcc_assert (TYPE_MAIN_VARIANT (t) == t);
+ gcc_assert (TYPE_NAME (t));
+
+ if (TREE_CODE (t) == ENUMERAL_TYPE)
+ print_enum_decl (file, t);
+ else if (TREE_CODE (t) == ARRAY_TYPE)
+ print_array_decl (file, t);
+ else /* struct or union */
+ print_struct_union_decl (file, t);
+
+}
+
/* The attribute string must be less than 127 characters and
contain only 7-bit ASCII chars. No checks though. */
static void
@@ -3777,28 +3938,56 @@ gen_string_custom_attr (FILE *stream, const char* parameter)
int len = strlen (parameter);
if (TARGET_EMIT_GIMPLE_COMMENTS)
- fprintf (stream, "\n\t// Custom attribute String \"%s\"", parameter);
+ fprintf (stream, "\t// Custom attribute String \"%s\"\n", parameter);
gcc_assert (len <= 127);
- fprintf (stream, "\n\t.custom instance void [mscorlib]System.String::.ctor(int8 *) = (01 00 %02x ", len);
+ fprintf (stream, "\t.custom instance void [mscorlib]System.String::.ctor(int8 *) = (01 00 %02x ", len);
for (i=0; i < len; ++i)
fprintf (stream, "%02x ", parameter[i]);
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)
+{
+ 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);
+
+ for (i = 0; i < taken_labels; i++)
+ {
+ dump_label_name (file, goto_labels[i]);
+
+ if (i + 1 < taken_labels)
+ fputs (", ", file);
+ }
+
+ fputs (")", file);
+ stack_pop (1);
+}
+
static void
print_string_decl (FILE *file, tree t)
{
const char *str;
- int len, i;
+ int len, len_type, i;
gcc_assert (TREE_CODE (t) == STRING_CST);
str = TREE_STRING_POINTER (t);
len = TREE_STRING_LENGTH (t);
- mark_referenced_type (TREE_TYPE (t));
+ len_type = TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t)))) + 1;
/* Emit the string in readable form as a comment. */
fputs ("// string: \"", file);
@@ -3815,16 +4004,79 @@ print_string_decl (FILE *file, tree t)
fprintf (file, ".data 'DataStr%u' = bytearray(", get_string_cst_id (t));
for (i=0; i < len; ++i)
fprintf (file, "%02x ", (unsigned char)str[i]);
+ for (; i < len_type; ++i)
+ fputs ("00 ", file);
fputs (")\n", file);
fputs (".field private static ", file);
- dump_type (file, TREE_TYPE (t), true, false);
+ dump_string_type (file, TREE_TYPE (t));
fputs (" ", file);
dump_string_name (file, t);
fprintf (file, " at 'DataStr%u'\n", get_string_cst_id (t));
}
static void
+print_used_strings (FILE *file)
+{
+ ebitmap used_stringtypes;
+ int i, n;
+
+ used_stringtypes = ebitmap_alloc (1);
+
+ i = 0;
+ n = VARRAY_ACTIVE_SIZE (referenced_strings);
+ for (; i < n; ++i)
+ {
+ tree str = VARRAY_TREE (referenced_strings, i);
+ unsigned int str_size = TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE(str)))) + 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);
+ }
+ }
+}
+
+static void
+print_pinvoke_function (FILE *file, tree fun)
+{
+ tree fun_type = TREE_TYPE (fun);
+ struct fnct_attr attributes;
+
+ decode_function_attrs (fun, &attributes);
+
+ fputs (".method ", file);
+
+ if (TREE_PUBLIC (fun)) fputs ("public ", file);
+ else fputs ("private ", file);
+
+ fprintf (file, "static pinvokeimpl(\"%s\"", attributes.pinvoke_assembly);
+
+ if (attributes.pinvoke_fname)
+ fprintf (file, " as \"%s\"", attributes.pinvoke_fname);
+
+ fputs (") ", file);
+
+ dump_fun_type (file, fun_type, fun, NULL, false);
+
+ fputs (" cil managed {}\n", file);
+}
+
+static void
gen_start_function (FILE *stream)
{
int nargs;
@@ -4003,9 +4255,9 @@ gen_cil_1 (FILE *stream)
bool varargs = FALSE;
tree args;
- remove_stloc_ldloc ();
+ if (!TARGET_NO_STLOC_LDLOC_REMOVAL)
+ remove_stloc_ldloc ();
- addr_taken_labels = NULL;
FOR_EACH_BB (bb)
{
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
@@ -4019,8 +4271,12 @@ gen_cil_1 (FILE *stream)
/* Check if the label has its address taken. */
if (FORCED_LABEL (label))
{
- TREE_CHAIN (label) = addr_taken_labels; /* prepend */
- addr_taken_labels = label; /* new list head */
+ 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++;
}
}
}
@@ -4136,9 +4392,9 @@ gen_cil_1 (FILE *stream)
gen_string_custom_attr (stream, "initfun");
if (TARGET_OPENSYSTEMC)
- fputs ("\n\t.custom instance "
+ fputs ("\t.custom instance "
"void ['OpenSystem.C']'OpenSystem.C'.InitializerAttribute::.ctor() "
- "= (01 00 00 00)", stream);
+ "= (01 00 00 00)\n", stream);
}
{
@@ -4329,16 +4585,15 @@ gen_cil_init (void)
{
FILE *stream = asm_out_file;
- fputs (".assembly extern gcc4net {}", stream);
+ fputs (".assembly extern gcc4net {}\n", stream);
if (TARGET_EMIT_EXTERNAL_ASSEMBLY)
- fputs ("\n.assembly '_C_MONO_ASSEMBLY' {}", stream);
- fputs ("\n.module '<Module>'", stream);
+ fputs (".assembly '_C_MONO_ASSEMBLY' {}\n", stream);
+ fputs (".module '<Module>'\n", stream);
if (TARGET_OPENSYSTEMC)
- fputs ("\n.custom instance "
+ fputs (".custom instance "
"void ['OpenSystem.C']'OpenSystem.C'.ModuleAttribute::.ctor() "
- "= (01 00 00 00)"
- "\n", stream);
+ "= (01 00 00 00)\n", stream);
referenced_types = pointer_set_create ();
VARRAY_TREE_INIT (referenced_strings, 32, "strings used in current unit");
@@ -4352,6 +4607,9 @@ gen_cil_init (void)
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");
}
@@ -4361,8 +4619,6 @@ gen_cil_fini (void)
{
FILE *stream = asm_out_file;
struct pointer_set_iter_t it;
- int i, n;
-
if (VARRAY_ACTIVE_SIZE (pending_ctors) > 0)
{
@@ -4370,12 +4626,9 @@ gen_cil_fini (void)
}
VARRAY_CLEAR (pending_ctors);
- i = 0;
- n = VARRAY_ACTIVE_SIZE (referenced_strings);
- for (; i < n; ++i)
+ if (VARRAY_ACTIVE_SIZE (referenced_strings) > 0)
{
- tree type = VARRAY_TREE (referenced_strings, i);
- print_string_decl (stream, type);
+ print_used_strings (stream);
}
VARRAY_CLEAR (referenced_strings);
pointer_set_destroy (referenced_string_ptrs);
@@ -4390,78 +4643,40 @@ gen_cil_fini (void)
Hence, before emitting a type, make sure no type with the same name
has already been emitted. */
- it = pointer_set_begin (referenced_types);
- while (!POINTER_SET_ITER_IS_END (it))
- {
- tree type = (tree)POINTER_SET_ITER_ELEM (it);
- bool found = false;
- struct pointer_set_iter_t it2;
- tree type_name = TYPE_NAME (type);
- const char* type_str;
-
- if (COMPLETE_TYPE_P (type))
- {
- gcc_assert (DECL_P (type_name)
- || TREE_CODE (type_name) == IDENTIFIER_NODE);
-
- if (TREE_CODE (type_name) == IDENTIFIER_NODE)
- type_str = IDENTIFIER_POINTER (type_name);
- else
- type_str = IDENTIFIER_POINTER (DECL_NAME (type_name));
-
- it2 = pointer_set_begin (referenced_types);
- while (!found && POINTER_SET_ITER_ELEM (it2) != type)
- {
- tree type2 = (tree)POINTER_SET_ITER_ELEM (it2);
- tree type2_name = TYPE_NAME (type2);
- const char* type2_str;
-
- gcc_assert (DECL_P (type2_name)
- || TREE_CODE (type2_name) == IDENTIFIER_NODE);
-
- if (TREE_CODE (type2_name) == IDENTIFIER_NODE)
- type2_str = IDENTIFIER_POINTER (type2_name);
- else
- type2_str = IDENTIFIER_POINTER (DECL_NAME (type2_name));
-
- found = strcmp (type2_str, type_str) == 0;
- it2 = pointer_set_next (referenced_types, it2);
- }
+ {
+ struct pointer_set_t *emitted_types = pointer_set_create ();
- if (!found)
- print_valuetype_decl (stream, type);
- }
+ it = pointer_set_begin (referenced_types);
+ while (!POINTER_SET_ITER_IS_END (it))
+ {
+ tree type = (tree)POINTER_SET_ITER_ELEM (it);
- it = pointer_set_next (referenced_types, it);
- }
- pointer_set_destroy (referenced_types);
+ 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);
+ }
it = pointer_set_begin (referenced_pinvoke);
while (!POINTER_SET_ITER_IS_END (it))
{
- tree fun = (tree)POINTER_SET_ITER_ELEM (it);
- tree fun_type = TREE_TYPE (fun);
- struct fnct_attr attributes;
-
- decode_function_attrs (fun, &attributes);
-
- fputs (".method ", stream);
-
- if (TREE_PUBLIC (fun))
- fputs ("public ", stream);
- else
- fputs ("private ", stream);
-
- fprintf (stream, "static pinvokeimpl(\"%s\"", attributes.pinvoke_assembly);
-
- if (attributes.pinvoke_fname)
- fprintf (stream, " as \"%s\"", attributes.pinvoke_fname);
-
- fputs (") ", stream);
-
- dump_fun_type (stream, fun_type, fun, NULL, false);
-
- fputs (" cil managed {}\n", stream);
+ print_pinvoke_function (stream, (tree)POINTER_SET_ITER_ELEM (it));
it = pointer_set_next (referenced_pinvoke, it);
}
pointer_set_destroy (referenced_pinvoke);
@@ -4469,6 +4684,11 @@ gen_cil_fini (void)
/* Delete hash table for pointer ids */
htab_delete (pointer_id_htable);
+ pointer_map_destroy (labels_map);
+
+ if (goto_labels != NULL)
+ XDELETEVEC (goto_labels);
+
if (TARGET_EMIT_VCG)
fprintf (stdout, "}\n");
}
diff --git a/gcc/config/cil32/rm-ldloc.c b/gcc/config/cil32/rm-ldloc.c
index 30758940378..0272084dc9c 100644
--- a/gcc/config/cil32/rm-ldloc.c
+++ b/gcc/config/cil32/rm-ldloc.c
@@ -36,20 +36,8 @@ Erven Rohou <erven.rohou@st.com>
#include "tm.h"
#include "tree.h"
#include "diagnostic.h"
-#include "real.h"
-#include "hashtab.h"
#include "tree-flow.h"
-#include "langhooks.h"
-#include "tree-iterator.h"
-#include "tree-chrec.h"
-#include "tree-pass.h"
-#include "timevar.h"
-#include "assert.h"
-#include "toplev.h"
#include "pointer-set.h"
-#include "output.h"
-#include "varray.h"
-#include "ggc.h"
#include "gen-cil.h"
/* Local functions, macros and variables. */
diff --git a/gcc/config/cil32/t-cil32 b/gcc/config/cil32/t-cil32
index 677e4356d3c..75d81fcd1b7 100644
--- a/gcc/config/cil32/t-cil32
+++ b/gcc/config/cil32/t-cil32
@@ -31,45 +31,41 @@
# Erven Rohou <erven.rohou@st.com>
bit-stream.o: $(srcdir)/config/cil32/bit-stream.c \
- $(srcdir)/config/cil32/bit-stream.h \
- $(DIAGNOSTIC_H) $(TM_H) coretypes.h
+ $(srcdir)/config/cil32/bit-stream.h $(CONFIG_H) $(SYSTEM_H) coretypes.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 \
- $(TREE_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) \
- $(TM_H) coretypes.h tree-iterator.h langhooks.h
+ $(srcdir)/config/cil32/gen-cil.h $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \
+ $(TREE_FLOW_H) coretypes.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
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 gt-gen-cil.h \
- $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) $(DIAGNOSTIC_H) real.h $(HASHTAB_H) $(TREE_FLOW_H) $(TIMEVAR_H) \
- $(TM_H) coretypes.h tree-iterator.h tree-chrec.h langhooks.h tree-pass.h
+ $(srcdir)/config/cil32/emit-hints.h $(srcdir)/config/cil32/tree-simp-cil.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
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
rm-ldloc.o: $(srcdir)/config/cil32/rm-ldloc.c $(srcdir)/config/cil32/gen-cil.h \
- $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_H)
+ $(CONFIG_H) $(DIAGNOSTIC_H) $(SYSTEM_H) $(TM_H) $(TREE_H) $(TREE_FLOW_H) \
+ coretypes.h pointer-set.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) \
- $(TREE_H) $(DIAGNOSTIC_H) real.h $(HASHTAB_H) $(TREE_FLOW_H) $(TIMEVAR_H) \
- $(TM_H) coretypes.h tree-iterator.h tree-chrec.h langhooks.h tree-pass.h
+ $(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
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
tree-simp-cil-early.o: $(srcdir)/config/cil32/tree-simp-cil-early.c \
- $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) $(DIAGNOSTIC_H) real.h $(HASHTAB_H) $(TREE_FLOW_H) $(TIMEVAR_H) \
- $(TM_H) coretypes.h tree-iterator.h tree-chrec.h langhooks.h tree-pass.h
+ $(srcdir)/config/cil32/tree-simp-cil.h $(CONFIG_H) $(SYSTEM_H) $(TIMEVAR_H) \
+ $(TM_H) $(TREE_H) coretypes.h toplev.h tree-gimple.h tree-pass.h \
+ pointer-set.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
bb-layout.o: $(srcdir)/config/cil32/bb-layout.c \
- $(CONFIG_H) $(SYSTEM_H) \
- $(TM_H) $(TREE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) $(TREE_FLOW_H) $(TIMEVAR_H) \
- langhooks.h tree-pass.h
+ $(CONFIG_H) $(SYSTEM_H) $(TIMEVAR_H) $(TM_H) $(TREE_H) $(TREE_FLOW_H) \
+ coretypes.h tree-pass.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
$(out_object_file): gt-gen-cil.h
diff --git a/gcc/config/cil32/tree-simp-cil-early.c b/gcc/config/cil32/tree-simp-cil-early.c
index a7141de7dbe..845cb12d340 100644
--- a/gcc/config/cil32/tree-simp-cil-early.c
+++ b/gcc/config/cil32/tree-simp-cil-early.c
@@ -1,7 +1,7 @@
/* Simplify non-SSA GIMPLE trees before control flow-graph construction and
optimization passes.
- Copyright (C) 2007 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -33,86 +33,78 @@ Erven Rohou <erven.rohou@st.com>
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
-#include "diagnostic.h"
-#include "real.h"
-#include "hashtab.h"
-#include "tree-flow.h"
-#include "langhooks.h"
+#include "tree-gimple.h"
#include "tree-iterator.h"
-#include "tree-chrec.h"
#include "tree-pass.h"
#include "timevar.h"
-#include "assert.h"
-#include "toplev.h"
-#include "output.h"
+#include "pointer-set.h"
+#include "tree-simp-cil.h"
-/* Type definitions */
-struct eqv_label_entry
+/******************************************************************************
+ * Type definitions *
+ ******************************************************************************/
+
+/* Entry of the equivalent labels hash-table */
+struct eqv_label_entry_t
{
- tree label;
- unsigned int val;
+ tree label; /* Pointer to the label declaration */
+ unsigned int val; /* Equivalence class */
};
-typedef struct eqv_label_entry *eqv_label_entry_t;
-
-/* Local function prototypes, macros and variables */
-
-/* Misc functions */
-static bool is_copy_required (tree);
+/******************************************************************************
+ * Local function prototypes, macros and variables *
+ ******************************************************************************/
/* Label manipulation functions */
-static hashval_t label_hash (const void *);
-static int label_eq (const void *, const void *);
-static void label_del (void *);
static bool is_eqv_label (tree, tree);
static void group_labels (tree);
+static bool eqv_label_dispose (void *, void **, void *data);
/* Switch-conversion functions */
static void merge_cases_into_ranges (tree);
static void case_to_cond_expr (tree, tree, tree *);
static void case_range_to_cond_expr (tree, tree, tree *);
static void cases_to_switch (tree, unsigned int, unsigned int, tree *);
-static void simp_cil_switch (tree *);
+static tree simp_cil_switch (tree);
+
+/* Bit-field conversion functions */
+static tree bf_vector_container_address (tree, unsigned HOST_WIDE_INT, tree,
+ tree *);
+static tree simp_lhs_vector_bitfield_ref (tree);
+static tree simp_rhs_vector_bitfield_ref (tree);
/* Top-level functionality */
-static void simp_cil_node (tree *);
+static tree simp_cil_stmt (tree);
static unsigned int simp_cil_early (void);
static bool simp_cil_early_gate (void);
+/******************************************************************************
+ * Globals *
+ ******************************************************************************/
+
/* Values used by the switch-conversion heuristics */
#define SIMP_SWITCH_RANGE_SIZE (4)
#define SIMP_SWITCH_HOLE_SIZE (4)
/* Hash-table used for storing equivalent labels */
-static htab_t eqv_labels = NULL;
+static struct pointer_map_t *eqv_labels = NULL;
/******************************************************************************
* Misc functions *
******************************************************************************/
-/* In the case of multiple uses of tree NODE, return whether
- it is required to compute NODE only once or not.
- If NODE has side effects, TRUE is obviously always returned.
- If NODE has no side effects, TRUE is still returned if
- it looks more profitable to compute NODE only once,
- FALSE otherwise (this is a heuristic decision). */
+/* Set the location of the statements in the statement list pointed by LIST to
+ the location passed in LOCUS */
-static bool
-is_copy_required (tree node)
+void
+set_statement_list_location (tree list, location_t locus)
{
- if (TREE_SIDE_EFFECTS (node))
- return TRUE;
+ tree_stmt_iterator tsi = tsi_start (list);
- switch (TREE_CODE (node))
+ while (!tsi_end_p (tsi))
{
- case INTEGER_CST:
- case REAL_CST:
- case VAR_DECL:
- case PARM_DECL:
- return FALSE;
-
- default:
- return TRUE;
+ SET_EXPR_LOCATION (tsi_stmt (tsi), locus);
+ tsi_next (&tsi);
}
}
@@ -120,45 +112,15 @@ is_copy_required (tree node)
* Label manipulation functions *
******************************************************************************/
-/* Returns the hash value of a label, implements the htab_hash function of the
- hash table structure */
-
-static hashval_t
-label_hash (const void *ptr)
-{
- const eqv_label_entry_t entry = (const eqv_label_entry_t) ptr;
-
- return (hashval_t) (ptrdiff_t) entry->label;
-}
-
-/* Compares two labels when used as hash entries, implements the htab_eq
- function of the hash table structure */
-
-static int
-label_eq (const void *ptr, const void *key)
-{
- const eqv_label_entry_t entry = (const eqv_label_entry_t) ptr;
-
- return entry->label == key;
-}
-
-/* Deletes a live element from the hash table, implements the htab_del function
- of the hash table structure */
-
-static void
-label_del (void *ptr)
-{
- free(ptr);
-}
-
/* Returns true if two labels are equivalent. */
-static bool is_eqv_label (tree label1, tree label2)
+static bool
+is_eqv_label (tree label1, tree label2)
{
- eqv_label_entry_t t1, t2;
+ struct eqv_label_entry_t *t1, *t2;
- t1 = htab_find_with_hash (eqv_labels, label1, (ptrdiff_t) label1);
- t2 = htab_find_with_hash (eqv_labels, label2, (ptrdiff_t) label2);
+ t1 = *pointer_map_contains(eqv_labels, label1);
+ t2 = *pointer_map_contains(eqv_labels, label2);
if (t1 == NULL || t2 == NULL)
return false;
@@ -180,8 +142,7 @@ group_labels(tree func)
tree t = NULL_TREE;
unsigned int value = 0;
bool prev_label = false;
- eqv_label_entry_t *slot;
- eqv_label_entry_t entry;
+ struct eqv_label_entry_t *entry;
tsi = tsi_start (func);
@@ -193,28 +154,31 @@ group_labels(tree func)
if (TREE_CODE (t) == LABEL_EXPR)
{
/* Insert the label in the hash-table */
- entry = xcalloc(1, sizeof(struct eqv_label_entry));
+ entry = XCNEW (struct eqv_label_entry_t);
entry->label = LABEL_EXPR_LABEL (t);
entry->val = value;
- slot = (eqv_label_entry_t *)
- htab_find_slot_with_hash (eqv_labels, LABEL_EXPR_LABEL (t),
- (ptrdiff_t) LABEL_EXPR_LABEL (t),
- INSERT);
- gcc_assert (*slot == NULL);
- *slot = entry;
+ *pointer_map_insert (eqv_labels, LABEL_EXPR_LABEL (t)) = entry;
prev_label = true;
}
- else
+ else if (prev_label)
{
- if (prev_label)
- {
- prev_label = false;
- value++;
- }
+ prev_label = false;
+ value++;
}
}
}
+/* Used in pointer_map_traverse() to free eqv_label_t entries */
+
+static bool
+eqv_label_dispose (void *key ATTRIBUTE_UNUSED, void **value,
+ void *data ATTRIBUTE_UNUSED)
+{
+ XDELETE (*value);
+
+ return true;
+}
+
/******************************************************************************
* Switch-conversion functions *
******************************************************************************/
@@ -307,7 +271,6 @@ case_to_cond_expr (tree switch_stmt, tree single_case, tree *list)
{
tree cmp_stmt, label;
tree label_decl = create_artificial_label ();
- location_t locus = EXPR_LOCATION (switch_stmt);
/* Build the COND_EXPR */
cmp_stmt = build3 (COND_EXPR, void_type_node,
@@ -317,7 +280,6 @@ case_to_cond_expr (tree switch_stmt, tree single_case, tree *list)
build1 (GOTO_EXPR, void_type_node,
CASE_LABEL (single_case)),
build1 (GOTO_EXPR, void_type_node, label_decl));
- SET_EXPR_LOCATION (cmp_stmt, locus);
/* Append the COND_EXPR to the list */
append_to_statement_list(cmp_stmt, list);
@@ -335,7 +297,6 @@ case_range_to_cond_expr(tree switch_stmt, tree case_range, tree *list)
tree label_decl1 = create_artificial_label ();
tree label_decl2 = create_artificial_label ();
tree cmp1_stmt, cmp2_stmt, label;
- location_t locus = EXPR_LOCATION (switch_stmt);
gcc_assert(CASE_HIGH (case_range) != NULL_TREE
&& CASE_LOW (case_range) != NULL_TREE);
@@ -349,7 +310,6 @@ case_range_to_cond_expr(tree switch_stmt, tree case_range, tree *list)
label_decl1),
build1 (GOTO_EXPR, void_type_node,
label_decl2));
- SET_EXPR_LOCATION (cmp1_stmt, locus);
/* Append the 1st COND_EXPR to the list */
append_to_statement_list(cmp1_stmt, list);
@@ -367,7 +327,6 @@ case_range_to_cond_expr(tree switch_stmt, tree case_range, tree *list)
CASE_LABEL (case_range)),
build1 (GOTO_EXPR, void_type_node,
label_decl2));
- SET_EXPR_LOCATION (cmp2_stmt, locus);
/* Append the 2nd COND_EXPR to the list */
append_to_statement_list (cmp2_stmt, list);
@@ -387,7 +346,6 @@ cases_to_switch (tree switch_stmt, unsigned int start, unsigned int end,
tree label_decl = create_artificial_label ();
tree labels = SWITCH_LABELS (switch_stmt);
tree stmt, label, vec, deft, elt;
- location_t locus = EXPR_LOCATION (switch_stmt);
unsigned int i, len;
double_int low, high, range, limit = shwi_to_double_int (8192);
@@ -424,7 +382,6 @@ cases_to_switch (tree switch_stmt, unsigned int start, unsigned int end,
/* Build the switch statement */
stmt = build3 (SWITCH_EXPR, TREE_TYPE (switch_stmt),
SWITCH_COND (switch_stmt), NULL, vec);
- SET_EXPR_LOCATION (stmt, locus);
/* Append the SWITCH to the list */
append_to_statement_list(stmt, list);
@@ -438,19 +395,19 @@ cases_to_switch (tree switch_stmt, unsigned int start, unsigned int end,
}
}
-/* Break a switch statement into multiple expressions in order to produce
- better/smaller code in the CIL back-end. Large case ranges or isolated cases
- are turned into COND_EXPRs, large 'holes' inside the switch are removed
- replacing a switch with two or more distinct switches */
+/* Break a switch statement pointed by SWITCH_STMT into multiple expressions in
+ order to produce better/smaller code in the CIL back-end. Large case ranges
+ or isolated cases are turned into COND_EXPRs, large 'holes' inside the switch
+ are removed replacing a single switch with two or more distinct switches. The
+ list holding the replacement is returned. If no replacement is needed
+ NULL_TREE is returned instead */
-static void
-simp_cil_switch (tree *tp)
+static tree
+simp_cil_switch (tree switch_stmt)
{
- tree switch_stmt = *tp;
tree curr, next;
tree labels = SWITCH_LABELS (switch_stmt);
tree list = NULL_TREE;
- location_t locus = EXPR_LOCATION (switch_stmt);
double_int range_size = shwi_to_double_int (SIMP_SWITCH_RANGE_SIZE);
double_int hole_size = shwi_to_double_int (SIMP_SWITCH_HOLE_SIZE);
double_int curr_high, next_low;
@@ -469,20 +426,10 @@ simp_cil_switch (tree *tp)
{
/* Only the default statement, nothing to do as this will be optimized
out later by the subsequent passes */
- return;
+ return NULL_TREE;
}
- if (is_copy_required (SWITCH_COND (switch_stmt)))
- {
- /* Copy the switch condition as we may use it more than once. */
- tree cond = SWITCH_COND (switch_stmt);
- tree copy_var = create_tmp_var (TREE_TYPE (cond), "cilsimp");
- tree copy_stmt = build_gimple_modify_stmt(copy_var, cond);
-
- SET_EXPR_LOCATION (copy_stmt, locus);
- append_to_statement_list (copy_stmt, &list);
- SWITCH_COND (switch_stmt) = copy_var;
- }
+ gcc_assert (!is_copy_required (SWITCH_COND (switch_stmt)));
while (true)
{
@@ -492,9 +439,16 @@ simp_cil_switch (tree *tp)
if (CASE_LOW (next) == NULL_TREE)
{
/* This is the last case, the next one is the default label, emit the
- previous cases. */
+ previous cases if needed. If base_idx != i and base_idx is 0 then
+ the original switch has been left untouched and it is not
+ replaced */
if (base_idx != i)
- cases_to_switch (switch_stmt, base_idx, i, &list);
+ {
+ if (base_idx == 0)
+ return NULL_TREE;
+ else
+ cases_to_switch (switch_stmt, base_idx, i, &list);
+ }
else if (CASE_HIGH (curr) != NULL_TREE)
case_range_to_cond_expr (switch_stmt, curr, &list);
else
@@ -502,7 +456,7 @@ simp_cil_switch (tree *tp)
/* Add a label which jumps to the default label. */
append_to_statement_list (build1 (GOTO_EXPR, void_type_node,
- CASE_LABEL(next)),
+ CASE_LABEL(next)),
&list);
break;
}
@@ -554,9 +508,9 @@ simp_cil_switch (tree *tp)
/* Detect 'holes', if a large enough hole is found emit the previous
cases. */
if (CASE_HIGH (curr) != NULL_TREE)
- curr_high = TREE_INT_CST (CASE_HIGH (curr));
+ curr_high = TREE_INT_CST (CASE_HIGH (curr));
else
- curr_high = TREE_INT_CST (CASE_LOW (curr));
+ curr_high = TREE_INT_CST (CASE_LOW (curr));
next_low = TREE_INT_CST (CASE_LOW (next));
@@ -578,47 +532,159 @@ simp_cil_switch (tree *tp)
i++;
}
- /* Replace the original switch with the new list. */
- *tp = list;
+ return list;
+}
+
+/******************************************************************************
+ * Bit-field access modes information *
+ ******************************************************************************/
+
+/* Get the address of the container suitable for replacing a BIT_FIELD_REF
+ expression used for accessing the element of a vector. The container type is
+ pointed by CONT_TYPE, BIT_OFFSET holds the offset of the element from the
+ base address of the vector pointed by OBJ. Put the calculated address in the
+ location pointed by DST_PTR. */
+
+static tree
+bf_vector_container_address (tree cont_type, unsigned HOST_WIDE_INT bit_offset,
+ tree obj, tree *dst_ptr)
+{
+ tree stmt;
+ tree obj_ptr, cont_ptr;
+ tree obj_ptr_type, cont_ptr_type;
+ tree list = NULL_TREE;
+
+ cont_ptr_type = build_pointer_type (cont_type);
+ cont_ptr = create_tmp_var (cont_ptr_type, "cilsimp");
+ *dst_ptr = cont_ptr;
+ obj_ptr_type = build_pointer_type (TREE_TYPE (obj));
+ obj_ptr = create_tmp_var (obj_ptr_type, "cilsimp");
+
+ stmt = build_gimple_modify_stmt (obj_ptr,
+ build_fold_addr_expr (obj));
+ append_to_statement_list (stmt, &list);
+
+ stmt = build_gimple_modify_stmt(cont_ptr,
+ build1 (NOP_EXPR, cont_ptr_type, obj_ptr));
+ append_to_statement_list (stmt, &list);
+
+ if (bit_offset > 0)
+ {
+ tree offset_tree = build_int_cst (long_unsigned_type_node,
+ bit_offset / BITS_PER_UNIT);
+
+ stmt = build_gimple_modify_stmt (cont_ptr,
+ build2 (POINTER_PLUS_EXPR, cont_ptr_type,
+ cont_ptr,
+ offset_tree));
+ append_to_statement_list (stmt, &list);
+ }
+
+ return list;
+}
+
+/* Simplify a GIMPLE_MODIFY_STMT pointed by BF_STMT with a BIT_FIELD_REF as its
+ right hand side operand used to extract a component from a vector. Return a
+ statement list holding the replacement code. */
+
+static tree
+simp_rhs_vector_bitfield_ref (tree bf_stmt)
+{
+ tree op_rhs = GIMPLE_STMT_OPERAND (bf_stmt, 1);
+ tree obj = TREE_OPERAND (op_rhs, 0);
+ unsigned HOST_WIDE_INT bit_offset;
+ tree list = NULL_TREE;
+ tree cont_type;
+ tree cont_ptr;
+ tree stmt;
+
+ /* Create the necessary types and temp variables */
+ cont_type = TREE_TYPE (TREE_TYPE (obj));
+
+ /* Compute the element address and store it in CONT_PTR */
+ bit_offset = tree_low_cst (TREE_OPERAND (op_rhs, 2), 1);
+ list = bf_vector_container_address (cont_type, bit_offset, obj, &cont_ptr);
+
+ /* Load the element from the vector and store it in the left hand side
+ variable */
+ stmt = build_gimple_modify_stmt (GIMPLE_STMT_OPERAND (bf_stmt, 0),
+ build1 (INDIRECT_REF, cont_type, cont_ptr));
+ append_to_statement_list (stmt, &list);
+
+ return list;
+}
+
+/* Simplify a GIMPLE_MODIFY_STMT pointed by BF_STMT with a BIT_FIELD_REF as its
+ left hand side operand used to insert a component inside a vector. Return a
+ statement list holding the replacement code. */
+
+static tree
+simp_lhs_vector_bitfield_ref (tree bf_stmt)
+{
+ tree op_lhs = GIMPLE_STMT_OPERAND (bf_stmt, 0);
+ tree obj = TREE_OPERAND (op_lhs, 0);
+ unsigned HOST_WIDE_INT bit_offset;
+ tree list = NULL_TREE;
+ tree cont_type;
+ tree cont_ptr;
+ tree stmt;
+
+ /* Create the necessary types and temp variables */
+ cont_type = TREE_TYPE (TREE_TYPE (obj));
+
+ /* Compute the element address and store it in CONT_PTR */
+ bit_offset = tree_low_cst (TREE_OPERAND (op_lhs, 2), 1);
+ list = bf_vector_container_address (cont_type, bit_offset, obj, &cont_ptr);
+
+ /* Store the value inside the vector */
+ stmt = build_gimple_modify_stmt (build1 (INDIRECT_REF, cont_type, cont_ptr),
+ GIMPLE_STMT_OPERAND (bf_stmt, 1));
+ append_to_statement_list (stmt, &list);
+
+ return list;
}
/******************************************************************************
* Top-level functionality *
******************************************************************************/
-/* Simplify a GIMPLE tree in order to improve CIL code emission. */
+/* Simplify a GIMPLE statement. */
-static void
-simp_cil_node (tree *tp)
+static tree
+simp_cil_stmt (tree stmt)
{
- tree_stmt_iterator tsi;
- tree t = *tp;
+ tree list = NULL_TREE; /* Replacement list for the current statement */
- switch (TREE_CODE (t))
+ switch (TREE_CODE (stmt))
{
case SWITCH_EXPR:
- simp_cil_switch (tp);
+ list = simp_cil_switch (stmt);
break;
- case STATEMENT_LIST:
- for (tsi = tsi_start (t); !tsi_end_p (tsi); )
- {
- simp_cil_node (tsi_stmt_ptr (tsi));
- t = tsi_stmt (tsi);
+ case GIMPLE_MODIFY_STMT:
+ {
+ tree op_lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ tree op_rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (t) == STATEMENT_LIST)
- {
- tsi_link_before (&tsi, t, TSI_SAME_STMT);
- tsi_delink (&tsi);
- }
- else
- tsi_next (&tsi);
- }
- break;
+ if (TREE_CODE (op_lhs) == BIT_FIELD_REF)
+ {
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (op_lhs, 0))) == VECTOR_TYPE)
+ list = simp_lhs_vector_bitfield_ref (stmt);
+ }
+ else if (TREE_CODE (op_rhs) == BIT_FIELD_REF)
+ {
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (op_rhs, 0))) == VECTOR_TYPE)
+ list = simp_rhs_vector_bitfield_ref (stmt);
+ }
+
+ break;
+ }
default:
break;
}
+
+ return list;
}
/* Main function of this pass. */
@@ -626,13 +692,34 @@ simp_cil_node (tree *tp)
static unsigned int
simp_cil_early (void)
{
- tree *body_p = &DECL_SAVED_TREE (current_function_decl);
+ tree_stmt_iterator tsi;
+
+ /* Create the structures used by the pass */
+ eqv_labels = pointer_map_create ();
+
+ group_labels (DECL_SAVED_TREE (current_function_decl));
+
+ tsi = tsi_start (DECL_SAVED_TREE (current_function_decl));
+
+ while (!tsi_end_p (tsi))
+ {
+ tree list = simp_cil_stmt (tsi_stmt (tsi));
+
+ if (list != NULL_TREE)
+ {
+ location_t locus = EXPR_LOCATION (tsi_stmt (tsi));
+
+ set_statement_list_location (list, locus);
+ tsi_link_before (&tsi, list, TSI_SAME_STMT);
+ tsi_delink (&tsi);
+ }
+ else
+ tsi_next (&tsi);
+ }
- eqv_labels = htab_create_alloc (100, label_hash, label_eq, label_del, xcalloc,
- free);
- group_labels (*body_p);
- simp_cil_node (body_p);
- htab_delete (eqv_labels);
+ /* Dispose of the structures created by the pass */
+ pointer_map_traverse (eqv_labels, eqv_label_dispose, NULL);
+ pointer_map_destroy (eqv_labels);
return 0;
}
diff --git a/gcc/config/cil32/tree-simp-cil.c b/gcc/config/cil32/tree-simp-cil.c
index 770743bfcd3..1cda110a5b3 100644
--- a/gcc/config/cil32/tree-simp-cil.c
+++ b/gcc/config/cil32/tree-simp-cil.c
@@ -36,18 +36,10 @@ Erven Rohou <erven.rohou@st.com>
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
-#include "diagnostic.h"
-#include "real.h"
-#include "hashtab.h"
#include "tree-flow.h"
-#include "langhooks.h"
-#include "tree-iterator.h"
-#include "tree-chrec.h"
#include "tree-pass.h"
#include "timevar.h"
-#include "assert.h"
#include "toplev.h"
-#include "output.h"
#include "tree-simp-cil.h"
/* The purpose of this pass is to simplify GIMPLE trees in order
@@ -184,7 +176,6 @@ Erven Rohou <erven.rohou@st.com>
*/
/* Local functions, macros and variables. */
-static bool is_copy_required (tree);
static bool mostly_zeros_p (tree);
static bool all_zeros_p (tree);
static void simp_cond_stmt (block_stmt_iterator, tree);
@@ -199,8 +190,6 @@ static void simp_shift (block_stmt_iterator *, tree);
static void simp_target_mem_ref (block_stmt_iterator *, tree *);
static void compute_array_ref_base_disp (tree, tree *, tree *);
static void simp_array_ref (block_stmt_iterator *, tree *);
-static void simp_bitfield (block_stmt_iterator *, tree *, tree, unsigned int,
- unsigned int, unsigned int, HOST_WIDEST_INT, bool);
static void simp_rhs_bitfield_component_ref (block_stmt_iterator *, tree *);
static void simp_lhs_bitfield_component_ref (block_stmt_iterator *, tree *);
static void simp_bitfield_ref (block_stmt_iterator *, tree *);
@@ -222,6 +211,9 @@ do { tree _node = (NODE); \
static bool simp_final;
static tree res_var;
+static GTY(()) tree two = NULL_TREE;
+static GTY(()) tree bits_per_unit = NULL_TREE;
+
/* Return the integer type with size BITS bits.
The type is unsigned or signed depending on UNS. */
@@ -265,7 +257,7 @@ get_integer_type (int bits, bool uns)
it looks more profitable to compute NODE only once,
FALSE otherwise (this is a heuristic decision). */
-static bool
+bool
is_copy_required (tree node)
{
if (TREE_SIDE_EFFECTS (node))
@@ -735,7 +727,7 @@ simp_builtin_call (block_stmt_iterator bsi, tree *node_ptr)
new_args = tree_cons (NULL, va, NULL);
- stmt = build_function_call_expr (cil32_builtin_va_start_decl,
+ stmt = build_function_call_expr (cil32_builtins[CIL32_BUILT_IN_VA_START],
new_args);
bsi_replace (&bsi, stmt, true);
}
@@ -773,7 +765,7 @@ simp_builtin_call (block_stmt_iterator bsi, tree *node_ptr)
new_args = tree_cons (NULL, va, NULL);
- stmt = build_function_call_expr (cil32_builtin_va_end_decl,
+ stmt = build_function_call_expr (cil32_builtins[CIL32_BUILT_IN_VA_END],
new_args);
bsi_replace (&bsi, stmt, true);
}
@@ -824,7 +816,7 @@ simp_builtin_call (block_stmt_iterator bsi, tree *node_ptr)
new_args = tree_cons (NULL, va_src, NULL);
new_args = tree_cons (NULL, va_dest, new_args);
- stmt = build_function_call_expr (cil32_builtin_va_copy_decl,
+ stmt = build_function_call_expr (cil32_builtins[CIL32_BUILT_IN_VA_COPY],
new_args);
bsi_replace (&bsi, stmt, true);
}
@@ -835,10 +827,13 @@ simp_builtin_call (block_stmt_iterator bsi, tree *node_ptr)
{
/* Inspired from 'expand_builtin_object_size' in builtins.c. We
return -1 for types 0 and 1, and 0 for types 2 and 3. */
- tree arg2 = CALL_EXPR_ARG (node, 0);
+ tree arg2 = CALL_EXPR_ARG (node, 1);
int obj_type;
+
+ STRIP_NOPS (arg2);
gcc_assert (TREE_CODE (arg2) == INTEGER_CST);
- obj_type = TREE_INT_CST_LOW (arg2);
+
+ obj_type = tree_low_cst (arg2, 0);
switch (obj_type)
{
case 0:
@@ -895,6 +890,59 @@ simp_builtin_call (block_stmt_iterator bsi, tree *node_ptr)
}
break;
+ case BUILT_IN_BCMP:
+ {
+ tree src1 = CALL_EXPR_ARG (node, 0);
+ tree src2 = CALL_EXPR_ARG (node, 1);
+ tree size = CALL_EXPR_ARG (node, 2);
+
+ 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);
+
+ stmt = build_function_call_expr (built_in_decls[BUILT_IN_MEMCMP], new_args);
+ bsi_replace (&bsi, stmt, true);
+ }
+ break;
+
+ case BUILT_IN_BZERO:
+ {
+ tree src1 = CALL_EXPR_ARG (node, 0);
+ tree size = CALL_EXPR_ARG (node, 1);
+
+ 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);
+
+ stmt = build_function_call_expr (built_in_decls[BUILT_IN_MEMSET], new_args);
+ bsi_replace (&bsi, stmt, true);
+ }
+ break;
+
+ case BUILT_IN_BCOPY:
+ {
+ tree src1 = CALL_EXPR_ARG (node, 0);
+ tree dst1 = CALL_EXPR_ARG (node, 1);
+ tree size = CALL_EXPR_ARG (node, 2);
+
+ 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);
+
+ stmt = build_function_call_expr (built_in_decls[BUILT_IN_MEMMOVE], new_args);
+ bsi_replace (&bsi, stmt, true);
+ }
+ break;
+
default:
;
}
@@ -1584,149 +1632,114 @@ simp_array_ref (block_stmt_iterator *bsi, tree *node_ptr)
*node_ptr = t1;
}
-/* Expand a bit-field reference by transforming it
+/* Expand the COMPONENT_REF (pointed by NODE_PTR) accessing
+ a BIT_FIELD_DECL and being on a right-hand side by transforming it
into an INDIRECT_REF and applying the necessary bit mask operations.
BSI points to the iterator of the statement that contains *NODE_PTR
(in order to allow insertion of new statements).
BSI is passed by reference because instructions are inserted.
NODE is passed by reference because simplification requires
- replacing the node.
- OBJ is the object containing the bit-field.
- CONT_SIZE is the number of bits of the bit-field container.
- BFLD_SIZE is the number of bits being referenced.
- BFLD_OFF is the position of the first referenced bit.
- OFF is an additional offset in bytes of the bit-field from the
- beginning of the OBJ.
- UNS tells whether the bit-field is unsigned or not. */
+ replacing the node. */
static void
-simp_bitfield (block_stmt_iterator *bsi, tree *node_ptr,
- tree obj, unsigned int cont_size, unsigned int bfld_size,
- unsigned int bfld_off, HOST_WIDEST_INT off, bool uns)
+simp_rhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
{
tree node = *node_ptr;
- location_t locus = EXPR_LOCATION (bsi_stmt (*bsi));
- tree new_type, new_type_ptr, obj_ptr_type;
- tree tmp_var, tmp_stmt;
- tree t;
+ tree stmt = bsi_stmt (*bsi);
+ location_t locus = EXPR_LOCATION (stmt);
+ tree obj = TREE_OPERAND (node, 0);
+ tree fld = TREE_OPERAND (node, 1);
+ tree fld_type, cont_type, cont_type_ptr, obj_ptr_type;
+ tree fld_off, fld_size, cont_size, diff;
+ tree lshift_cst, rshift_cst, ptr_off_cst;
+ tree obj_addr, addr, cont_var;
+ tree new_stmt, list = NULL_TREE;
+ tree two = build_int_cst_type (size_type_node, 2);
+ tree bits_per_unit = fold_convert (size_type_node, bitsize_unit_node);
- gcc_assert (cont_size >= bfld_size + bfld_off);
+ /* Extract bit field layout */
+ fld_type = TREE_TYPE (fld);
+ fld_off = size_binop (MULT_EXPR, DECL_FIELD_OFFSET (fld), bits_per_unit);
+ fld_off = size_binop (PLUS_EXPR, fld_off,
+ fold_convert (size_type_node,
+ DECL_FIELD_BIT_OFFSET (fld)));
+ fld_size = build_int_cst_type (size_type_node, TYPE_PRECISION (fld_type));
+ cont_size = size_binop (TRUNC_DIV_EXPR, bits_per_unit, two);
+
+ do {
+ cont_size = size_binop (MULT_EXPR, cont_size, two);
+ diff = size_binop (TRUNC_MOD_EXPR, fld_off, cont_size);
+ diff = size_binop (PLUS_EXPR, diff, fld_size);
+ } while (tree_int_cst_lt (cont_size, diff));
+
+ /* lshift_cst = cont_size + ((fld_off % cont_size) + fld_size) */
+ lshift_cst = size_binop (TRUNC_MOD_EXPR, fld_off, cont_size);
+ lshift_cst = size_binop (PLUS_EXPR, lshift_cst, fld_size);
+ lshift_cst = size_binop (MINUS_EXPR, cont_size, lshift_cst);
+
+ /* rshift_cst = cont_size - fld_size */
+ rshift_cst = size_binop (MINUS_EXPR, cont_size, fld_size);
- /* Set that the object being accessed is addressable */
- UPDATE_ADDRESSABLE (obj);
+ /* Build the new type for the equivalent access (and a pointer type to it) */
+ cont_type = get_integer_type (tree_low_cst (cont_size, true), true);
+ cont_type_ptr = build_pointer_type (cont_type);
/* Build the type corresponding of a pointer to the object */
obj_ptr_type = build_pointer_type (TREE_TYPE (obj));
- /* Build the new type for the equivalent access (and a pointer type to it) */
- new_type = get_integer_type (cont_size, uns);
- new_type_ptr = build_pointer_type (new_type);
+ /* Build expression to compute the address to be accessed */
+ obj_addr = create_tmp_var (obj_ptr_type, "cilsimp");
+ new_stmt = build_gimple_modify_stmt (obj_addr,
+ build_fold_addr_expr (obj));
+ gcc_assert (TREE_CODE (obj) != CALL_EXPR);
+ append_to_statement_list (new_stmt, &list);
- /* Build the (gimplified) equivalent expression */
+ addr = create_tmp_var (cont_type_ptr, "cilsimp");
+ new_stmt = build_gimple_modify_stmt (addr,
+ fold_convert (cont_type_ptr, obj_addr));
+ append_to_statement_list (new_stmt, &list);
- tmp_var = create_tmp_var (obj_ptr_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build1 (ADDR_EXPR, obj_ptr_type, obj));
- gcc_assert (TREE_CODE (obj) != CALL_EXPR);
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
- tmp_var = create_tmp_var (new_type_ptr, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build1 (NOP_EXPR, new_type_ptr, t));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
-
- if (off > 0)
+ /* ptr_off_cst = ((fld_off / cont_size) * cont_size) / 8 */
+ ptr_off_cst = size_binop (TRUNC_DIV_EXPR, fld_off, cont_size);
+ ptr_off_cst = size_binop (MULT_EXPR, ptr_off_cst, cont_size);
+ ptr_off_cst = size_binop (TRUNC_DIV_EXPR, ptr_off_cst, bits_per_unit);
+
+ if (!tree_int_cst_equal (ptr_off_cst, size_zero_node))
{
- tmp_var = create_tmp_var (new_type_ptr, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build2 (POINTER_PLUS_EXPR, new_type_ptr,
- t,
- build_int_cst (long_unsigned_type_node, off)));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
+ new_stmt = build_gimple_modify_stmt (addr,
+ build2 (POINTER_PLUS_EXPR,
+ cont_type_ptr, addr,
+ ptr_off_cst));
+ append_to_statement_list (new_stmt, &list);
}
- tmp_var = create_tmp_var (new_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build1 (INDIRECT_REF, new_type, t));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
+ /* Read the value at the address just computed */
+ cont_var = create_tmp_var (cont_type, "cilsimp");
+ new_stmt = build_gimple_modify_stmt(cont_var,
+ build_fold_indirect_ref (addr));
+ append_to_statement_list (new_stmt, &list);
- if (cont_size > bfld_size + bfld_off)
+ /* Shift the bit-field into position, clearing the upper bits */
+ if (! tree_int_cst_equal (lshift_cst, size_zero_node))
{
- tmp_var = create_tmp_var (new_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build2 (LSHIFT_EXPR, new_type,
- t,
- build_int_cstu (unsigned_intSI_type_node,
- cont_size - bfld_size - bfld_off)));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
+ new_stmt = build_gimple_modify_stmt (cont_var,
+ build2 (LSHIFT_EXPR, cont_type,
+ cont_var, lshift_cst));
+ append_to_statement_list (new_stmt, &list);
}
- if (cont_size > bfld_size)
+ if (! tree_int_cst_equal (rshift_cst, size_zero_node))
{
- tmp_var = create_tmp_var (new_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build2 (RSHIFT_EXPR, new_type,
- t,
- build_int_cstu (unsigned_intSI_type_node,
- cont_size - bfld_size)));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
+ new_stmt = build_gimple_modify_stmt (cont_var,
+ build2 (RSHIFT_EXPR, cont_type,
+ cont_var, rshift_cst));
+ append_to_statement_list (new_stmt, &list);
}
- gcc_assert (t && t != error_mark_node);
-
- /* Update the current node */
- *node_ptr = fold_convert (TREE_TYPE (node), t);
-}
-
-/* Expand the COMPONENT_REF (pointed by NODE_PTR) accessing
- a BIT_FIELD_DECL and being on a right-hand side by transforming it
- into an INDIRECT_REF and applying the necessary bit mask operations.
- BSI points to the iterator of the statement that contains *NODE_PTR
- (in order to allow insertion of new statements).
- BSI is passed by reference because instructions are inserted.
- NODE is passed by reference because simplification requires
- replacing the node. */
-
-static void
-simp_rhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
-{
- tree node = *node_ptr;
- tree obj = TREE_OPERAND (node, 0);
- tree fld = TREE_OPERAND (node, 1);
- tree fld_type, fld_off;
- unsigned int cont_size, bfld_size, bfld_off;
- HOST_WIDEST_INT off;
-
- gcc_assert (TREE_CODE (node) == COMPONENT_REF);
- gcc_assert (DECL_BIT_FIELD (fld));
-
- /* Extract bit field layout */
- fld_type = DECL_BIT_FIELD_TYPE (fld);
- fld_off = DECL_FIELD_OFFSET (fld);
- cont_size = TREE_INT_CST_LOW (TYPE_SIZE (fld_type));
- bfld_size = TYPE_PRECISION (TREE_TYPE (fld));
- bfld_off = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld)) & (cont_size - 1);
- gcc_assert (cont_size >= TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (node))));
- gcc_assert (TREE_INT_CST_HIGH (fld_off) == 0);
- off = TREE_INT_CST_LOW (fld_off)
- + ((TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld))
- & ~(cont_size - 1))
- / 8);
-
- /* Simplify the bit-field */
- simp_bitfield (bsi, node_ptr, obj, cont_size, bfld_size, bfld_off, off,
- DECL_UNSIGNED (fld));
+ /* Update the current statement (and the current node) */
+ set_statement_list_location (list, locus);
+ bsi_insert_before (bsi, list, BSI_SAME_STMT);
+ *node_ptr = fold_convert (TREE_TYPE (node), cont_var);
}
/* Expand the COMPONENT_REF (pointed by NODE_PTR) accessing
@@ -1742,154 +1755,143 @@ static void
simp_lhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
{
tree node = *node_ptr;
- location_t locus = EXPR_LOCATION (bsi_stmt (*bsi));
+ tree stmt = bsi_stmt (*bsi);
+ location_t locus = EXPR_LOCATION (stmt);
tree obj = TREE_OPERAND (node, 0);
tree fld = TREE_OPERAND (node, 1);
- tree fld_type, fld_off ;
- unsigned int cont_size, bfld_size, bfld_off;
- tree stmt = bsi_stmt (*bsi), rhs, addr;
- tree new_type, new_type_ptr, obj_ptr_type;
- tree tmp_var, tmp_stmt;
- tree t;
- HOST_WIDEST_INT off;
- unsigned HOST_WIDEST_INT mask = 0;
+ tree fld_type, cont_type, cont_type_ptr, obj_ptr_type;
+ tree fld_off, fld_size, cont_size, diff;
+ tree shift_cst, mask_cst, ptr_off_cst;
+ tree obj_addr, addr, rhs, folded_rhs, cont_var;
+ tree new_stmt, list = NULL_TREE;
+ tree two = build_int_cst_type (size_type_node, 2);
+ tree bits_per_unit = fold_convert (size_type_node, bitsize_unit_node);
gcc_assert (TREE_CODE (node) == COMPONENT_REF);
- gcc_assert (DECL_BIT_FIELD (fld));
gcc_assert ((TREE_CODE (stmt) == MODIFY_EXPR
- || TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
- && GENERIC_TREE_OPERAND (stmt, 0) == node);
-
- /* Set that the object being accessed is addressable */
- UPDATE_ADDRESSABLE (obj);
+ || TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ && GENERIC_TREE_OPERAND (stmt, 0) == node);
/* Extract bit field layout */
- fld_type = DECL_BIT_FIELD_TYPE (fld);
- fld_off = DECL_FIELD_OFFSET (fld);
- cont_size = TREE_INT_CST_LOW (TYPE_SIZE (fld_type));
- bfld_size = TYPE_PRECISION (TREE_TYPE (fld));
- bfld_off = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld)) & (cont_size - 1);
- gcc_assert (cont_size >= TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (node))));
+ fld_type = TREE_TYPE (fld);
+ fld_off = size_binop (MULT_EXPR, DECL_FIELD_OFFSET (fld), bits_per_unit);
+ fld_off = size_binop (PLUS_EXPR, fld_off,
+ fold_convert (size_type_node,
+ DECL_FIELD_BIT_OFFSET (fld)));
+ fld_size = build_int_cst_type (size_type_node, TYPE_PRECISION (fld_type));
+ cont_size = size_binop (TRUNC_DIV_EXPR, bits_per_unit, two);
+
+ do {
+ cont_size = size_binop (MULT_EXPR, cont_size, two);
+ diff = size_binop (TRUNC_MOD_EXPR, fld_off, cont_size);
+ diff = size_binop (PLUS_EXPR, diff, fld_size);
+ } while (tree_int_cst_lt (cont_size, diff));
+
+ shift_cst = size_binop (TRUNC_MOD_EXPR, fld_off, cont_size);
/* Build the new type for the equivalent access (and a pointer type to it) */
- new_type = get_integer_type (cont_size, true);
- new_type_ptr = build_pointer_type (new_type);
+ cont_type = get_integer_type (tree_low_cst (cont_size, true), true);
+ cont_type_ptr = build_pointer_type (cont_type);
/* Build the type corresponding of a pointer to the object */
obj_ptr_type = build_pointer_type (TREE_TYPE (obj));
- /* Convert the original rhs into the new type */
- gcc_assert (TREE_CODE (GENERIC_TREE_OPERAND (stmt, 1)) == VAR_DECL);
- tmp_var = create_tmp_var (new_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build1 (NOP_EXPR, new_type, GENERIC_TREE_OPERAND (stmt, 1)));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- rhs = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
-
- /* Shift the rhs in order that it is in the right bit position */
- if (cont_size > bfld_size)
+ /* Create the mask */
+ mask_cst = build_int_cst_type (cont_type, 1);
+ mask_cst = size_binop (LSHIFT_EXPR, mask_cst, fld_size);
+ mask_cst = size_binop (MINUS_EXPR, mask_cst,
+ build_int_cst_type (cont_type, 1));
+ mask_cst = size_binop (LSHIFT_EXPR, mask_cst, shift_cst);
+
+ /* If the rhs is a constant fold the shift & mask operations, if it is not
+ copy it and convert it in the container type */
+ rhs = fold_convert (cont_type, GENERIC_TREE_OPERAND (stmt, 1));
+ folded_rhs = fold_binary_to_constant (LSHIFT_EXPR, cont_type, rhs, shift_cst);
+
+ if (folded_rhs != NULL_TREE)
{
- tmp_var = create_tmp_var (new_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build2 (LSHIFT_EXPR, new_type,
- rhs,
- build_int_cstu (unsigned_intSI_type_node,
- cont_size - bfld_size)));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- rhs = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
+ folded_rhs = fold_binary_to_constant (BIT_AND_EXPR, cont_type, folded_rhs,
+ mask_cst);
}
- if (cont_size > bfld_size + bfld_off)
+
+ if (folded_rhs != NULL_TREE)
+ rhs = folded_rhs;
+ else
{
- /* Remark: new_type is unsigned by construction:
- therefore, the right shift doesn't introduce any 1 */
-
- tmp_var = create_tmp_var (new_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build2 (RSHIFT_EXPR, new_type,
- rhs,
- build_int_cstu (unsigned_intSI_type_node,
- cont_size - bfld_size - bfld_off)));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- rhs = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
+ rhs = create_tmp_var (cont_type, "cilsimp");
+ new_stmt = fold_convert (cont_type, GENERIC_TREE_OPERAND (stmt, 1));
+ new_stmt = build_gimple_modify_stmt (rhs, new_stmt);
+ append_to_statement_list (new_stmt, &list);
+
+ new_stmt = build_gimple_modify_stmt (rhs,
+ build2 (LSHIFT_EXPR, cont_type,
+ rhs, shift_cst));
+ append_to_statement_list (new_stmt, &list);
+
+ new_stmt = build_gimple_modify_stmt (rhs,
+ build2 (BIT_AND_EXPR, cont_type,
+ rhs, mask_cst));
+ append_to_statement_list (new_stmt, &list);
}
/* Build expression to compute the address to be accessed */
- tmp_var = create_tmp_var (obj_ptr_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build1 (ADDR_EXPR, obj_ptr_type, obj));
+ obj_addr = create_tmp_var (obj_ptr_type, "cilsimp");
+ new_stmt = build_gimple_modify_stmt (obj_addr,
+ build_fold_addr_expr (obj));
gcc_assert (TREE_CODE (obj) != CALL_EXPR);
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
- tmp_var = create_tmp_var (new_type_ptr, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build1 (NOP_EXPR, new_type_ptr, t));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
-
- off = TREE_INT_CST_LOW (fld_off)
- + ((TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld))
- & ~(cont_size - 1))
- / 8);
-
- gcc_assert (TREE_INT_CST_HIGH (fld_off) == 0);
-
- if (off > 0)
+ append_to_statement_list (new_stmt, &list);
+
+ addr = create_tmp_var (cont_type_ptr, "cilsimp");
+ new_stmt = build_gimple_modify_stmt (addr,
+ fold_convert (cont_type_ptr, obj_addr));
+ append_to_statement_list (new_stmt, &list);
+
+ /* ptr_off_cst = ((fld_off / cont_size) * cont_size) / 8 */
+ ptr_off_cst = size_binop (TRUNC_DIV_EXPR, fld_off, cont_size);
+ ptr_off_cst = size_binop (MULT_EXPR, ptr_off_cst, cont_size);
+ ptr_off_cst = size_binop (TRUNC_DIV_EXPR, ptr_off_cst, bits_per_unit);
+
+ if (tree_int_cst_compare (ptr_off_cst, size_zero_node) != 0)
{
- tmp_var = create_tmp_var (new_type_ptr, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build2 (POINTER_PLUS_EXPR, new_type_ptr,
- t,
- build_int_cst (long_unsigned_type_node, off)));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
+ new_stmt = build_gimple_modify_stmt (addr,
+ build2 (POINTER_PLUS_EXPR,
+ cont_type_ptr, addr,
+ ptr_off_cst));
+ append_to_statement_list (new_stmt, &list);
}
- addr = t;
/* Read existing value at the address just computed */
- tmp_var = create_tmp_var (new_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build1 (INDIRECT_REF, new_type, t));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
+ cont_var = create_tmp_var (cont_type, "cilsimp");
+ new_stmt = build_gimple_modify_stmt(cont_var,
+ build_fold_indirect_ref (addr));
+ append_to_statement_list (new_stmt, &list);
/* Compute the mask to be applied to the existing value */
- gcc_assert (HOST_BITS_PER_WIDEST_INT >= 64);
- mask |= (1LL << (cont_size - bfld_size - bfld_off)) - 1LL;
- mask <<= bfld_off + bfld_size;
- mask |= (1LL << bfld_off) - 1;
+ mask_cst = size_binop (BIT_XOR_EXPR, mask_cst,
+ build_int_cst_type (cont_type, -1));
+ mask_cst = fold_convert (cont_type, mask_cst);
/* Apply the mask to the existing value */
- tmp_var = create_tmp_var (new_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build2 (BIT_AND_EXPR, new_type,
- t,
- build_int_cst_wide (new_type,
- mask,
- mask >> HOST_BITS_PER_WIDE_INT)));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- t = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
+ new_stmt = build_gimple_modify_stmt (cont_var,
+ build2 (BIT_AND_EXPR, cont_type,
+ cont_var, mask_cst));
+ append_to_statement_list (new_stmt, &list);
/* Compute the new value for the rhs of the current statement */
- tmp_var = create_tmp_var (new_type, "cilsimp");
- tmp_stmt = build_gimple_modify_stmt(tmp_var,
- build2 (BIT_IOR_EXPR, new_type,
- rhs,
- t));
- SET_EXPR_LOCATION (tmp_stmt, locus);
- rhs = tmp_var;
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
+ if (!((TREE_CODE (rhs) == INTEGER_CST)
+ && tree_int_cst_equal (rhs, size_zero_node)))
+ {
+ new_stmt = build_gimple_modify_stmt (cont_var,
+ build2 (BIT_IOR_EXPR, cont_type,
+ cont_var, rhs));
+ append_to_statement_list (new_stmt, &list);
+ }
/* Update the current statement (and the current node) */
- *node_ptr = build1 (INDIRECT_REF, new_type, addr);
- GENERIC_TREE_OPERAND (stmt, 1) = rhs;
+ set_statement_list_location (list, locus);
+ bsi_insert_before (bsi, list, BSI_SAME_STMT);
+ *node_ptr = build_fold_indirect_ref (addr);
+ GENERIC_TREE_OPERAND (stmt, 1) = cont_var;
}
/* Expand the BIT_FIELD_REF (pointed by NODE_PTR) by transforming it
@@ -1904,37 +1906,95 @@ static void
simp_bitfield_ref (block_stmt_iterator *bsi, tree *node_ptr)
{
tree node = *node_ptr;
+ tree stmt = bsi_stmt (*bsi);
+ location_t locus = EXPR_LOCATION (stmt);
tree obj = TREE_OPERAND (node, 0);
- unsigned int ref_bfld_off, cont_size, bfld_size, bfld_off;
- HOST_WIDE_INT off;
-
- gcc_assert (TREE_CODE (node) == BIT_FIELD_REF);
+ tree type, cont_type, cont_type_ptr, obj_ptr_type;
+ tree obj_addr, addr, cont_var;
+ tree off, size, cont_size, diff;
+ tree lshift_cst, rshift_cst, ptr_off_cst;
+ tree new_stmt, list = NULL_TREE;
/* Extract bit field layout */
- bfld_size = TREE_INT_CST_LOW (TREE_OPERAND (node, 1));
- ref_bfld_off = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
- gcc_assert (bfld_size <= 64);
-
- /* At least, cont_size is the next power of two of the bit-field size */
- cont_size = bfld_size - 1;
- cont_size |= (cont_size >> 1);
- cont_size |= (cont_size >> 2);
- cont_size |= (cont_size >> 4);
- ++cont_size;
- gcc_assert (cont_size == 8 || cont_size == 16
- || cont_size == 32 || cont_size == 64);
-
- /* Widen the container until an aligned access is enough */
- while ((ref_bfld_off & ~(cont_size - 1))
- != ((ref_bfld_off + bfld_size - 1) & ~(cont_size - 1)))
- cont_size <<= 1;
-
- bfld_off = ref_bfld_off & (cont_size - 1);
- off = (ref_bfld_off - bfld_off) >> 3;
-
- /* Simplify the bit-field */
- simp_bitfield (bsi, node_ptr, obj, cont_size, bfld_size, bfld_off, off,
- BIT_FIELD_REF_UNSIGNED (node));
+ size = fold_convert (size_type_node, TREE_OPERAND (node, 1));
+ off = fold_convert (size_type_node, TREE_OPERAND (node, 2));
+ type = TREE_TYPE (node);
+ cont_size = size_binop (TRUNC_DIV_EXPR, bits_per_unit, two);
+
+ do {
+ cont_size = size_binop (MULT_EXPR, cont_size, two);
+ diff = size_binop (TRUNC_MOD_EXPR, off, cont_size);
+ diff = size_binop (PLUS_EXPR, diff, size);
+ } while (tree_int_cst_lt (cont_size, diff));
+
+ /* lshift_cst = cont_size + ((fld_off % cont_size) + fld_size) */
+ lshift_cst = size_binop (TRUNC_MOD_EXPR, off, cont_size);
+ lshift_cst = size_binop (PLUS_EXPR, lshift_cst, size);
+ lshift_cst = size_binop (MINUS_EXPR, cont_size, lshift_cst);
+
+ /* rshift_cst = cont_size - fld_size */
+ rshift_cst = size_binop (MINUS_EXPR, cont_size, size);
+
+ /* Build the new type for the equivalent access (and a pointer type to it) */
+ cont_type = get_integer_type (tree_low_cst (cont_size, true), true);
+ cont_type_ptr = build_pointer_type (cont_type);
+
+ /* Build the type corresponding of a pointer to the object */
+ obj_ptr_type = build_pointer_type (TREE_TYPE (obj));
+
+ /* Build expression to compute the address to be accessed */
+ obj_addr = create_tmp_var (obj_ptr_type, "cilsimp");
+ new_stmt = build_gimple_modify_stmt (obj_addr,
+ build_fold_addr_expr (obj));
+ gcc_assert (TREE_CODE (obj) != CALL_EXPR);
+ append_to_statement_list (new_stmt, &list);
+
+ addr = create_tmp_var (cont_type_ptr, "cilsimp");
+ new_stmt = build_gimple_modify_stmt (addr,
+ fold_convert (cont_type_ptr, obj_addr));
+ append_to_statement_list (new_stmt, &list);
+
+ /* ptr_off_cst = ((fld_off / cont_size) * cont_size) / 8 */
+ ptr_off_cst = size_binop (TRUNC_DIV_EXPR, off, cont_size);
+ ptr_off_cst = size_binop (MULT_EXPR, ptr_off_cst, cont_size);
+ ptr_off_cst = size_binop (TRUNC_DIV_EXPR, ptr_off_cst, bits_per_unit);
+
+ if (!tree_int_cst_equal (ptr_off_cst, size_zero_node))
+ {
+ new_stmt = build_gimple_modify_stmt (addr,
+ build2 (POINTER_PLUS_EXPR,
+ cont_type_ptr, addr,
+ ptr_off_cst));
+ append_to_statement_list (new_stmt, &list);
+ }
+
+ /* Read the value at the address just computed */
+ cont_var = create_tmp_var (cont_type, "cilsimp");
+ new_stmt = build_gimple_modify_stmt(cont_var,
+ build_fold_indirect_ref (addr));
+ append_to_statement_list (new_stmt, &list);
+
+ /* Shift the bit-field into position, clearing the upper bits */
+ if (! tree_int_cst_equal (lshift_cst, size_zero_node))
+ {
+ new_stmt = build_gimple_modify_stmt (cont_var,
+ build2 (LSHIFT_EXPR, cont_type,
+ cont_var, lshift_cst));
+ append_to_statement_list (new_stmt, &list);
+ }
+
+ if (! tree_int_cst_equal (rshift_cst, size_zero_node))
+ {
+ new_stmt = build_gimple_modify_stmt (cont_var,
+ build2 (RSHIFT_EXPR, cont_type,
+ cont_var, rshift_cst));
+ append_to_statement_list (new_stmt, &list);
+ }
+
+ /* Update the current statement (and the current node) */
+ set_statement_list_location (list, locus);
+ bsi_insert_before (bsi, list, BSI_SAME_STMT);
+ *node_ptr = fold_convert (TREE_TYPE (node), cont_var);
}
/* Expand the INIT_EXPR (or MODIFY_EXPR) in NODE having
@@ -2105,7 +2165,7 @@ expand_init_to_stmt_list1 (tree decl, tree init,
args = tree_cons (NULL, integer_zero_node, args);
decl_ptr = build_fold_addr_expr (decl);
args = tree_cons (NULL, decl_ptr, args);
- t = implicit_built_in_decls[BUILT_IN_MEMSET];
+ t = cil32_builtins[CIL32_BUILT_IN_INITBLK];
t = build_function_call_expr (t, args);
append_to_statement_list (t, stmt_list1);
@@ -2130,7 +2190,7 @@ expand_init_to_stmt_list1 (tree decl, tree init,
args = tree_cons (NULL, to_ptr, args);
/* We know they do not overlap */
- t = implicit_built_in_decls[BUILT_IN_MEMCPY];
+ t = cil32_builtins[CIL32_BUILT_IN_CPBLK];
t = build_function_call_expr (t, args);
append_to_statement_list (t, stmt_list1);
@@ -2183,7 +2243,7 @@ expand_init_to_stmt_list1 (tree decl, tree init,
args = tree_cons (NULL, integer_zero_node, args);
decl_ptr = build_fold_addr_expr (decl);
args = tree_cons (NULL, decl_ptr, args);
- t = implicit_built_in_decls[BUILT_IN_MEMSET];
+ t = cil32_builtins[CIL32_BUILT_IN_INITBLK];
t = build_function_call_expr (t, args);
append_to_statement_list (t, stmt_list1);
@@ -2319,7 +2379,7 @@ expand_init_to_stmt_list1 (tree decl, tree init,
args = tree_cons (NULL, integer_zero_node, args);
decl_ptr = build_fold_addr_expr (decl);
args = tree_cons (NULL, decl_ptr, args);
- t = implicit_built_in_decls[BUILT_IN_MEMSET];
+ t = cil32_builtins[CIL32_BUILT_IN_INITBLK];
t = build_function_call_expr (t, args);
append_to_statement_list (t, stmt_list1);
@@ -2406,30 +2466,30 @@ expand_init_to_stmt_list1 (tree decl, tree init,
{
case 2:
if (vec_size == 32)
- ctor_fun = cil32_v2hi_ctor;
+ ctor_fun = cil32_builtins[CIL32_V2HI_CTOR];
else if (vec_size == 64)
- ctor_fun = cil32_v2si_ctor;
+ ctor_fun = cil32_builtins[CIL32_V2SI_CTOR];
break;
case 4:
if (vec_size == 32)
- ctor_fun = cil32_v4qi_ctor;
+ ctor_fun = cil32_builtins[CIL32_V4QI_CTOR];
else if (vec_size == 64)
- ctor_fun = cil32_v4hi_ctor;
+ ctor_fun = cil32_builtins[CIL32_V4HI_CTOR];
else if (vec_size == 128)
- ctor_fun = cil32_v4si_ctor;
+ ctor_fun = cil32_builtins[CIL32_V4SI_CTOR];
break;
case 8:
if (vec_size == 64)
- ctor_fun = cil32_v8qi_ctor;
+ ctor_fun = cil32_builtins[CIL32_V8QI_CTOR];
else if (vec_size == 128)
- ctor_fun = cil32_v8hi_ctor;
+ ctor_fun = cil32_builtins[CIL32_V8HI_CTOR];
break;
case 16:
if (vec_size == 128)
- ctor_fun = cil32_v16qi_ctor;
+ ctor_fun = cil32_builtins[CIL32_V16QI_CTOR];
break;
default:
@@ -2447,7 +2507,7 @@ expand_init_to_stmt_list1 (tree decl, tree init,
fprintf (stderr, "V%dSF vectors not supported\n", num_elt);
gcc_assert (0);
}
- ctor_fun = cil32_v2sf_ctor;
+ ctor_fun = cil32_builtins[CIL32_V2SF_CTOR];
}
gcc_assert (ctor_fun);
@@ -2558,7 +2618,6 @@ expand_init_to_stmt_list (tree decl, tree init, tree *stmt_list)
int num_list1;
tree stmt_list2 = alloc_stmt_list ();
int num_list2;
- bool le_eq_be;
memset (le_image, 0, size);
memset (be_image, 0, size);
@@ -2567,43 +2626,44 @@ expand_init_to_stmt_list (tree decl, tree init, tree *stmt_list)
&stmt_list1, FALSE,
&stmt_list2, le_image, be_image);
- le_eq_be = (memcmp (le_image, be_image, size) == 0);
num_list1 = statement_list_num_instr (stmt_list1);
num_list2 = statement_list_num_instr (stmt_list2);
/* Decide what to do */
- if ((num_list2 + 2) < num_list1)
+ if (TARGET_BIG_ENDIAN || TARGET_LITTLE_ENDIAN
+ || ( (num_list2 + 2) < num_list1))
{
tree mem_cpy;
tree args;
tree from_ptr;
tree to_ptr = build_fold_addr_expr (decl);
- tree sconst = build_string_literal (size, le_image);
-
- if (le_eq_be)
+ if (TARGET_LITTLE_ENDIAN || (memcmp (le_image, be_image, size) == 0))
+ {
+ from_ptr = build_string_literal (size, le_image);
+ }
+ else if (TARGET_BIG_ENDIAN)
{
- from_ptr = sconst;
+ from_ptr = build_string_literal (size, be_image);
}
else
{
+ tree sconst = build_string_literal (size, le_image);
tree sconst2 = build_string_literal (size, be_image);
gcc_assert (TREE_TYPE (sconst) == TREE_TYPE (sconst2));
- from_ptr = fold_build3 (COND_EXPR,
- TREE_TYPE (sconst),
- build_function_call_expr (cil32_builtin_is_LE_decl, NULL_TREE),
- sconst,
- sconst2);
+ args = tree_cons (NULL, sconst2, NULL);
+ args = tree_cons (NULL, sconst, args);
+ from_ptr = build_function_call_expr (cil32_builtins[CIL32_BUILT_IN_ENDIAN_SELECT], args);
}
args = tree_cons (NULL, size_int (size), NULL);
args = tree_cons (NULL, from_ptr, args);
args = tree_cons (NULL, to_ptr, args);
- mem_cpy = build_function_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
+ mem_cpy = build_function_call_expr (cil32_builtins[CIL32_BUILT_IN_CPBLK],
args);
append_to_statement_list (mem_cpy, stmt_list);
@@ -2696,6 +2756,8 @@ simp_cil_final (void)
basic_block bb;
block_stmt_iterator bsi;
+ two = build_int_cst_type (size_type_node, 2);
+ bits_per_unit = fold_convert (size_type_node, bitsize_unit_node);
simp_final = true;
push_gimplify_context ();
res_var = NULL_TREE;
@@ -2725,8 +2787,12 @@ simp_cil_final (void)
|| TREE_CODE (rhs) == STRING_CST)
pre_simp_init (&bsi, stmt, lhs, rhs);
else if (TREE_CODE (lhs) == COMPONENT_REF
- && DECL_BIT_FIELD (TREE_OPERAND (lhs, 1)))
- split_use (bsi, &GENERIC_TREE_OPERAND (stmt, 1), false);
+ && DECL_BIT_FIELD (TREE_OPERAND (lhs, 1))
+ && (TREE_CODE (GENERIC_TREE_OPERAND (stmt, 1))
+ != INTEGER_CST))
+ {
+ split_use (bsi, &GENERIC_TREE_OPERAND (stmt, 1), false);
+ }
}
}
}
@@ -2747,6 +2813,7 @@ simp_cil_final (void)
tree stmt;
bsi = bsi_last (bb);
stmt = bsi_stmt (bsi);
+
if (simp_final && TREE_CODE (stmt) != RETURN_EXPR)
{
tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
@@ -2763,6 +2830,9 @@ simp_cil_final (void)
}
pop_gimplify_context (NULL);
+ two = NULL_TREE;
+ bits_per_unit = NULL_TREE;
+
return 0;
}
@@ -2790,7 +2860,7 @@ struct tree_opt_pass pass_simp_cil_final =
/* ??? If TER is enabled, we also kill gimple. */
0, /* properties_destroyed */
0,
- TODO_dump_func, /* todo_flags_finish */
+ TODO_ggc_collect | TODO_dump_func, /* todo_flags_finish */
0 /* letter */
};
diff --git a/gcc/config/cil32/tree-simp-cil.h b/gcc/config/cil32/tree-simp-cil.h
index 9d469a5bb98..2ee919f1052 100644
--- a/gcc/config/cil32/tree-simp-cil.h
+++ b/gcc/config/cil32/tree-simp-cil.h
@@ -24,6 +24,7 @@ Authors:
Andrea Ornstein
Erven Rohou
Roberto Costa
+ Gabriele Svelto
Contact information at STMicroelectronics:
Andrea C. Ornstein <andrea.ornstein@st.com>
@@ -37,5 +38,7 @@ Erven Rohou <erven.rohou@st.com>
extern void expand_init_to_stmt_list (tree, tree, tree *);
extern tree get_integer_type (int, bool);
+extern bool is_copy_required (tree);
+extern void set_statement_list_location (tree, location_t);
#endif /* TREE_SIMP_CIL_H */
diff --git a/gcc/passes.c b/gcc/passes.c
index 3c9fe9fc394..d846d780f23 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -692,7 +692,6 @@ init_optimization_passes (void)
NEXT_PASS (pass_bb_layout);
NEXT_PASS (pass_simp_cil_final);
NEXT_PASS (pass_gen_cil); /* <--- CIL */
- NEXT_PASS (pass_free_cfg_annotations);
#else /* !defined(DISABLE_RTL_PASSES) */
NEXT_PASS (pass_mudflap_2);
NEXT_PASS (pass_free_cfg_annotations);