summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrasad Ghangal <prasad.ghangal@gmail.com>2016-11-14 13:51:48 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-11-14 13:51:48 +0000
commit1ee62b926411dda2bffbca8019b494481183ee15 (patch)
tree8d83980f6ddcd52182f277bc95f6bdd8c523ebf2
parent4d2098539a53d9e2dddd6233fb68820715d95862 (diff)
downloadgcc-1ee62b926411dda2bffbca8019b494481183ee15.tar.gz
Make-lang.in (C_AND_OBJC_OBJS): Add gimple-parser.o.
2016-11-14 Prasad Ghangal <prasad.ghangal@gmail.com> Richard Biener <rguenther@suse.de> c/ * Make-lang.in (C_AND_OBJC_OBJS): Add gimple-parser.o. * config-lang.in (gtfiles): Add c/c-parser.h. * c-tree.h (enum c_declspec_word): Add cdw_gimple. (struct c_declspecs): Add gimple_pass member and gimple_p flag. * c-parser.c (enum c_id_kind, struct c_token, c_parser_next_token_is, c_parser_next_token_is_not, c_parser_next_token_is_keyword, enum c_lookahead_kind, enum c_dtr_syn, enum c_parser_prec): Split out to ... * c-parser.h: ... new header. * c-parser.c: Include c-parser.h and gimple-parser.h. (c_parser_peek_token, c_parser_peek_2nd_token, c_token_starts_typename, c_parser_next_token_starts_declspecs, c_parser_next_tokens_start_declaration, c_parser_consume_token, c_parser_error, c_parser_require, c_parser_skip_until_found, c_parser_declspecs, c_parser_declarator, c_parser_peek_nth_token, c_parser_type_name): Export. (c_parser_tokens_buf): New function. (c_parser_error): Likewise. (c_parser_set_error): Likewise. (c_parser_declspecs): Handle RID_GIMPLE. (c_parser_declaration_or_fndef): Parse __GIMPLE marked body via c_parser_parse_gimple_body. * c-parser.h (c_parser_peek_token, c_parser_peek_2nd_token, c_token_starts_typename, c_parser_next_token_starts_declspecs, c_parser_next_tokens_start_declaration, c_parser_consume_token, c_parser_error, c_parser_require, c_parser_skip_until_found, c_parser_declspecs, c_parser_declarator, c_parser_peek_nth_token, c_parser_type_name): Declare. (struct c_parser): Declare forward. (c_parser_tokens_buf): Declare. (c_parser_error): Likewise. (c_parser_set_error): Likewise. * gimple-parser.c: New file. * gimple-parser.h: Likewise. obj-c/ * config-lang.in (gtfiles): Add c/c-parser.h. c-family/ * c-common.h (c_common_resword): Add RID_GIMPLE, RID_PHI types. * c-common.h (enum rid): Add RID_GIMPLE, RID_PHI. * c.opt (fgimple): New option. * doc/invoke.texi (fgimple): Document. * dumpfile.h (TDF_GIMPLE): Add. * dumpfile.c (dump_options): Add gimple. * gimple-pretty-print.c (dump_gimple_switch): Adjust dump for TDF_GIMPLE. (dump_gimple_label): Likewise. (dump_gimple_phi): Likewise. (dump_gimple_bb_header): Likewise. (dump_phi_nodes): Likewise. (pp_cfg_jump): Likewise. Pass in dump flags. (dump_implicit_edges): Adjust. * passes.c (pass_init_dump_file): Do not dump function header for TDF_GIMPLE. * tree-cfg.c (dump_function_to_file): Dump function return type and __GIMPLE keyword for TDF_GIMPLE. Change guard for dumping GIMPLE stmts. * tree-pretty-print.c (dump_decl_name): Adjust dump for TDF_GIMPLE. (dump_generic_node): Likewise. * function.h (struct function): Add pass_startwith member. * passes.c (execute_one_pass): Implement startwith. * tree-ssanames.c (make_ssa_name_fn): New argument, check for version and assign proper version for parsed ssa names. * tree-ssanames.h (make_ssa_name_fn): Add new argument to the function. * internal-fn.c (expand_PHI): New function. * internal-fn.h (expand_PHI): Declared here. * internal-fn.def: New defination for PHI. * tree-cfg.c (lower_phi_internal_fn): New function. (build_gimple_cfg): Call it. (verify_gimple_call): Condition for passing label as arg in internal function PHI. * tree-into-ssa.c (rewrite_add_phi_arguments): Handle already present PHIs with arguments. testsuite/ * gcc.dg/gimplefe-1.c: New testcase. * gcc.dg/gimplefe-2.c: Likewise. * gcc.dg/gimplefe-3.c: Likewise. * gcc.dg/gimplefe-4.c: Likewise. * gcc.dg/gimplefe-5.c: Likewise. * gcc.dg/gimplefe-6.c: Likewise. * gcc.dg/gimplefe-7.c: Likewise. * gcc.dg/gimplefe-8.c: Likewise. * gcc.dg/gimplefe-9.c: Likewise. * gcc.dg/gimplefe-10.c: Likewise. * gcc.dg/gimplefe-11.c: Likewise. * gcc.dg/gimplefe-12.c: Likewise. * gcc.dg/gimplefe-13.c: Likewise. * gcc.dg/gimplefe-14.c: Likewise. * gcc.dg/gimplefe-15.c: Likewise. * gcc.dg/gimplefe-16.c: Likewise. * gcc.dg/gimplefe-17.c: Likewise. * gcc.dg/gimplefe-18.c: Likewise. Co-Authored-By: Richard Biener <rguenther@suse.de> From-SVN: r242387
-rw-r--r--gcc/ChangeLog36
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/c-common.c2
-rw-r--r--gcc/c-family/c-common.h6
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c/ChangeLog39
-rw-r--r--gcc/c/Make-lang.in3
-rw-r--r--gcc/c/c-parser.c235
-rw-r--r--gcc/c/c-tree.h5
-rw-r--r--gcc/c/config-lang.in2
-rw-r--r--gcc/doc/invoke.texi9
-rw-r--r--gcc/dumpfile.c4
-rw-r--r--gcc/dumpfile.h7
-rw-r--r--gcc/function.h3
-rw-r--r--gcc/gimple-pretty-print.c106
-rw-r--r--gcc/internal-fn.c6
-rw-r--r--gcc/internal-fn.def1
-rw-r--r--gcc/internal-fn.h1
-rw-r--r--gcc/objc/ChangeLog5
-rw-r--r--gcc/objc/config-lang.in2
-rw-r--r--gcc/passes.c33
-rw-r--r--gcc/testsuite/ChangeLog22
-rw-r--r--gcc/tree-cfg.c61
-rw-r--r--gcc/tree-into-ssa.c12
-rw-r--r--gcc/tree-pretty-print.c22
-rw-r--r--gcc/tree-ssanames.c19
-rw-r--r--gcc/tree-ssanames.h3
27 files changed, 447 insertions, 208 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f8dc1bd2bf8..4fea3461b76 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,39 @@
+2016-11-14 Prasad Ghangal <prasad.ghangal@gmail.com>
+ Richard Biener <rguenther@suse.de>
+
+ * doc/invoke.texi (fgimple): Document.
+ * dumpfile.h (TDF_GIMPLE): Add.
+ * dumpfile.c (dump_options): Add gimple.
+ * gimple-pretty-print.c (dump_gimple_switch): Adjust dump
+ for TDF_GIMPLE.
+ (dump_gimple_label): Likewise.
+ (dump_gimple_phi): Likewise.
+ (dump_gimple_bb_header): Likewise.
+ (dump_phi_nodes): Likewise.
+ (pp_cfg_jump): Likewise. Pass in dump flags.
+ (dump_implicit_edges): Adjust.
+ * passes.c (pass_init_dump_file): Do not dump function header
+ for TDF_GIMPLE.
+ * tree-cfg.c (dump_function_to_file): Dump function return type
+ and __GIMPLE keyword for TDF_GIMPLE. Change guard for dumping
+ GIMPLE stmts.
+ * tree-pretty-print.c (dump_decl_name): Adjust dump for TDF_GIMPLE.
+ (dump_generic_node): Likewise.
+ * function.h (struct function): Add pass_startwith member.
+ * passes.c (execute_one_pass): Implement startwith.
+ * tree-ssanames.c (make_ssa_name_fn): New argument, check for version
+ and assign proper version for parsed ssa names.
+ * tree-ssanames.h (make_ssa_name_fn): Add new argument to the function.
+ * internal-fn.c (expand_PHI): New function.
+ * internal-fn.h (expand_PHI): Declared here.
+ * internal-fn.def: New defination for PHI.
+ * tree-cfg.c (lower_phi_internal_fn): New function.
+ (build_gimple_cfg): Call it.
+ (verify_gimple_call): Condition for passing label as arg in internal
+ function PHI.
+ * tree-into-ssa.c (rewrite_add_phi_arguments): Handle already
+ present PHIs with arguments.
+
2016-11-14 Martin Liska <mliska@suse.cz>
PR bootstrap/78069
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 8c99b75aa56..2360d9ed17c 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,10 @@
+2016-11-14 Prasad Ghangal <prasad.ghangal@gmail.com>
+ Richard Biener <rguenther@suse.de>
+
+ * c-common.h (c_common_resword): Add RID_GIMPLE, RID_PHI types.
+ * c-common.h (enum rid): Add RID_GIMPLE, RID_PHI.
+ * c.opt (fgimple): New option.
+
2016-11-13 Eric Botcazou <ebotcazou@adacore.com>
* c-ada-spec.c (print_ada_declaration): For typedef declarations, look
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 307862b9c7c..2997c83925f 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -435,6 +435,8 @@ const struct c_common_resword c_common_reswords[] =
{ "__underlying_type", RID_UNDERLYING_TYPE, D_CXXONLY },
{ "__volatile", RID_VOLATILE, 0 },
{ "__volatile__", RID_VOLATILE, 0 },
+ { "__GIMPLE", RID_GIMPLE, D_CONLY },
+ { "__PHI", RID_PHI, D_CONLY },
{ "alignas", RID_ALIGNAS, D_CXXONLY | D_CXX11 | D_CXXWARN },
{ "alignof", RID_ALIGNOF, D_CXXONLY | D_CXX11 | D_CXXWARN },
{ "asm", RID_ASM, D_ASM },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 4f27f81b5b3..241b3454e06 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -118,6 +118,12 @@ enum rid
RID_FRACT, RID_ACCUM, RID_AUTO_TYPE, RID_BUILTIN_CALL_WITH_STATIC_CHAIN,
+ /* "__GIMPLE", for the GIMPLE-parsing extension to the C frontend. */
+ RID_GIMPLE,
+
+ /* "__PHI", for parsing PHI function in GIMPLE FE. */
+ RID_PHI,
+
/* C11 */
RID_ALIGNAS, RID_GENERIC,
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index cf946e7b86e..722d3800cf0 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -200,6 +200,10 @@ F
Driver C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs)
-F <dir> Add <dir> to the end of the main framework include path.
+fgimple
+C Var(flag_gimple) Init(0)
+Enable parsing GIMPLE.
+
H
C ObjC C++ ObjC++
Print the name of header files as they are used.
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index ee50c304b5f..75f39d7ed8b 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,42 @@
+2016-11-14 Prasad Ghangal <prasad.ghangal@gmail.com>
+ Richard Biener <rguenther@suse.de>
+
+ * Make-lang.in (C_AND_OBJC_OBJS): Add gimple-parser.o.
+ * config-lang.in (gtfiles): Add c/c-parser.h.
+ * c-tree.h (enum c_declspec_word): Add cdw_gimple.
+ (struct c_declspecs): Add gimple_pass member and gimple_p flag.
+ * c-parser.c (enum c_id_kind, struct c_token,
+ c_parser_next_token_is, c_parser_next_token_is_not,
+ c_parser_next_token_is_keyword,
+ enum c_lookahead_kind, enum c_dtr_syn, enum c_parser_prec):
+ Split out to ...
+ * c-parser.h: ... new header.
+ * c-parser.c: Include c-parser.h and gimple-parser.h.
+ (c_parser_peek_token, c_parser_peek_2nd_token,
+ c_token_starts_typename, c_parser_next_token_starts_declspecs,
+ c_parser_next_tokens_start_declaration, c_parser_consume_token,
+ c_parser_error, c_parser_require, c_parser_skip_until_found,
+ c_parser_declspecs, c_parser_declarator, c_parser_peek_nth_token,
+ c_parser_type_name): Export.
+ (c_parser_tokens_buf): New function.
+ (c_parser_error): Likewise.
+ (c_parser_set_error): Likewise.
+ (c_parser_declspecs): Handle RID_GIMPLE.
+ (c_parser_declaration_or_fndef): Parse __GIMPLE marked body
+ via c_parser_parse_gimple_body.
+ * c-parser.h (c_parser_peek_token, c_parser_peek_2nd_token,
+ c_token_starts_typename, c_parser_next_token_starts_declspecs,
+ c_parser_next_tokens_start_declaration, c_parser_consume_token,
+ c_parser_error, c_parser_require, c_parser_skip_until_found,
+ c_parser_declspecs, c_parser_declarator, c_parser_peek_nth_token,
+ c_parser_type_name): Declare.
+ (struct c_parser): Declare forward.
+ (c_parser_tokens_buf): Declare.
+ (c_parser_error): Likewise.
+ (c_parser_set_error): Likewise.
+ * gimple-parser.c: New file.
+ * gimple-parser.h: Likewise.
+
2016-09-11 Le-Chun Wu <lcwu@google.com>
Mark Wielaard <mjw@redhat.com>
diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
index 72c9ae74f87..cd7108b8afa 100644
--- a/gcc/c/Make-lang.in
+++ b/gcc/c/Make-lang.in
@@ -51,7 +51,8 @@ CFLAGS-c/gccspec.o += $(DRIVER_DEFINES)
# Language-specific object files for C and Objective C.
C_AND_OBJC_OBJS = attribs.o c/c-errors.o c/c-decl.o c/c-typeck.o \
c/c-convert.o c/c-aux-info.o c/c-objc-common.o c/c-parser.o \
- c/c-array-notation.o c/c-fold.o $(C_COMMON_OBJS) $(C_TARGET_OBJS)
+ c/c-array-notation.o c/c-fold.o c/gimple-parser.o \
+ $(C_COMMON_OBJS) $(C_TARGET_OBJS)
# Language-specific object files for C.
C_OBJS = c/c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS)
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 52a5eddff7b..00fe7312c4c 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -59,6 +59,8 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-expr.h"
#include "context.h"
#include "gcc-rich-location.h"
+#include "c-parser.h"
+#include "gimple-parser.h"
/* We need to walk over decls with incomplete struct/union/enum types
after parsing the whole translation unit.
@@ -150,63 +152,6 @@ c_parse_init (void)
}
}
-/* The C lexer intermediates between the lexer in cpplib and c-lex.c
- and the C parser. Unlike the C++ lexer, the parser structure
- stores the lexer information instead of using a separate structure.
- Identifiers are separated into ordinary identifiers, type names,
- keywords and some other Objective-C types of identifiers, and some
- look-ahead is maintained.
-
- ??? It might be a good idea to lex the whole file up front (as for
- C++). It would then be possible to share more of the C and C++
- lexer code, if desired. */
-
-/* More information about the type of a CPP_NAME token. */
-enum c_id_kind {
- /* An ordinary identifier. */
- C_ID_ID,
- /* An identifier declared as a typedef name. */
- C_ID_TYPENAME,
- /* An identifier declared as an Objective-C class name. */
- C_ID_CLASSNAME,
- /* An address space identifier. */
- C_ID_ADDRSPACE,
- /* Not an identifier. */
- C_ID_NONE
-};
-
-/* A single C token after string literal concatenation and conversion
- of preprocessing tokens to tokens. */
-struct GTY (()) c_token {
- /* The kind of token. */
- ENUM_BITFIELD (cpp_ttype) type : 8;
- /* If this token is a CPP_NAME, this value indicates whether also
- declared as some kind of type. Otherwise, it is C_ID_NONE. */
- ENUM_BITFIELD (c_id_kind) id_kind : 8;
- /* If this token is a keyword, this value indicates which keyword.
- Otherwise, this value is RID_MAX. */
- ENUM_BITFIELD (rid) keyword : 8;
- /* If this token is a CPP_PRAGMA, this indicates the pragma that
- was seen. Otherwise it is PRAGMA_NONE. */
- ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
- /* The location at which this token was found. */
- location_t location;
- /* The value associated with this token, if any. */
- tree value;
- /* Token flags. */
- unsigned char flags;
-
- source_range get_range () const
- {
- return get_range_from_loc (line_table, location);
- }
-
- location_t get_finish () const
- {
- return get_range ().m_finish;
- }
-};
-
/* A parser structure recording information about the state and
context of parsing. Includes lexer information with up to two
tokens of look-ahead; more are not needed for C. */
@@ -259,6 +204,30 @@ struct GTY(()) c_parser {
vec <c_token, va_gc> *cilk_simd_fn_tokens;
};
+/* Return a pointer to the Nth token in PARSERs tokens_buf. */
+
+c_token *
+c_parser_tokens_buf (c_parser *parser, unsigned n)
+{
+ return &parser->tokens_buf[n];
+}
+
+/* Return the error state of PARSER. */
+
+bool
+c_parser_error (c_parser *parser)
+{
+ return parser->error;
+}
+
+/* Set the error state of PARSER to ERR. */
+
+void
+c_parser_set_error (c_parser *parser, bool err)
+{
+ parser->error = err;
+}
+
/* The actual parser and external interface. ??? Does this need to be
garbage-collected? */
@@ -454,7 +423,7 @@ c_lex_one_token (c_parser *parser, c_token *token)
/* Return a pointer to the next token from PARSER, reading it in if
necessary. */
-static inline c_token *
+c_token *
c_parser_peek_token (c_parser *parser)
{
if (parser->tokens_avail == 0)
@@ -465,37 +434,10 @@ c_parser_peek_token (c_parser *parser)
return &parser->tokens[0];
}
-/* Return true if the next token from PARSER has the indicated
- TYPE. */
-
-static inline bool
-c_parser_next_token_is (c_parser *parser, enum cpp_ttype type)
-{
- return c_parser_peek_token (parser)->type == type;
-}
-
-/* Return true if the next token from PARSER does not have the
- indicated TYPE. */
-
-static inline bool
-c_parser_next_token_is_not (c_parser *parser, enum cpp_ttype type)
-{
- return !c_parser_next_token_is (parser, type);
-}
-
-/* Return true if the next token from PARSER is the indicated
- KEYWORD. */
-
-static inline bool
-c_parser_next_token_is_keyword (c_parser *parser, enum rid keyword)
-{
- return c_parser_peek_token (parser)->keyword == keyword;
-}
-
/* Return a pointer to the next-but-one token from PARSER, reading it
in if necessary. The next token is already read in. */
-static c_token *
+c_token *
c_parser_peek_2nd_token (c_parser *parser)
{
if (parser->tokens_avail >= 2)
@@ -511,7 +453,7 @@ c_parser_peek_2nd_token (c_parser *parser)
/* Return a pointer to the Nth token from PARSER, reading it
in if necessary. The N-1th token is already read in. */
-static c_token *
+c_token *
c_parser_peek_nth_token (c_parser *parser, unsigned int n)
{
/* N is 1-based, not zero-based. */
@@ -570,7 +512,7 @@ c_keyword_starts_typename (enum rid keyword)
/* Return true if TOKEN can start a type name,
false otherwise. */
-static bool
+bool
c_token_starts_typename (c_token *token)
{
switch (token->type)
@@ -601,18 +543,6 @@ c_token_starts_typename (c_token *token)
}
}
-enum c_lookahead_kind {
- /* Always treat unknown identifiers as typenames. */
- cla_prefer_type,
-
- /* Could be parsing a nonabstract declarator. Only treat an identifier
- as a typename if followed by another identifier or a star. */
- cla_nonabstract_decl,
-
- /* Never treat identifiers as typenames. */
- cla_prefer_id
-};
-
/* Return true if the next token from PARSER can start a type name,
false otherwise. LA specifies how to do lookahead in order to
detect unknown type names. If unsure, pick CLA_PREFER_ID. */
@@ -779,7 +709,7 @@ c_token_starts_declaration (c_token *token)
/* Return true if the next token from PARSER can start declaration
specifiers, false otherwise. */
-static inline bool
+bool
c_parser_next_token_starts_declspecs (c_parser *parser)
{
c_token *token = c_parser_peek_token (parser);
@@ -801,7 +731,7 @@ c_parser_next_token_starts_declspecs (c_parser *parser)
/* Return true if the next tokens from PARSER can start declaration
specifiers or a static assertion, false otherwise. */
-static inline bool
+bool
c_parser_next_tokens_start_declaration (c_parser *parser)
{
c_token *token = c_parser_peek_token (parser);
@@ -829,7 +759,7 @@ c_parser_next_tokens_start_declaration (c_parser *parser)
/* Consume the next token from PARSER. */
-static void
+void
c_parser_consume_token (c_parser *parser)
{
gcc_assert (parser->tokens_avail >= 1);
@@ -922,7 +852,7 @@ c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
this way is not i18n-friendly and some other approach should be
used. */
-static void
+void
c_parser_error (c_parser *parser, const char *gmsgid)
{
c_token *token = c_parser_peek_token (parser);
@@ -965,7 +895,7 @@ c_parser_error (c_parser *parser, const char *gmsgid)
been produced and no message will be produced this time. Returns
true if found, false otherwise. */
-static bool
+bool
c_parser_require (c_parser *parser,
enum cpp_ttype type,
const char *msgid)
@@ -1008,7 +938,7 @@ c_parser_require_keyword (c_parser *parser,
already been produced and no message will be produced this
time. */
-static void
+void
c_parser_skip_until_found (c_parser *parser,
enum cpp_ttype type,
const char *msgid)
@@ -1243,42 +1173,6 @@ restore_extension_diagnostics (int flags)
warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
}
-/* Possibly kinds of declarator to parse. */
-enum c_dtr_syn {
- /* A normal declarator with an identifier. */
- C_DTR_NORMAL,
- /* An abstract declarator (maybe empty). */
- C_DTR_ABSTRACT,
- /* A parameter declarator: may be either, but after a type name does
- not redeclare a typedef name as an identifier if it can
- alternatively be interpreted as a typedef name; see DR#009,
- applied in C90 TC1, omitted from C99 and reapplied in C99 TC2
- following DR#249. For example, given a typedef T, "int T" and
- "int *T" are valid parameter declarations redeclaring T, while
- "int (T)" and "int * (T)" and "int (T[])" and "int (T (int))" are
- abstract declarators rather than involving redundant parentheses;
- the same applies with attributes inside the parentheses before
- "T". */
- C_DTR_PARM
-};
-
-/* The binary operation precedence levels, where 0 is a dummy lowest level
- used for the bottom of the stack. */
-enum c_parser_prec {
- PREC_NONE,
- PREC_LOGOR,
- PREC_LOGAND,
- PREC_BITOR,
- PREC_BITXOR,
- PREC_BITAND,
- PREC_EQ,
- PREC_REL,
- PREC_SHIFT,
- PREC_ADD,
- PREC_MULT,
- NUM_PRECS
-};
-
/* Helper data structure for parsing #pragma acc routine. */
struct oacc_routine_data {
bool error_seen; /* Set if error has been reported. */
@@ -1295,15 +1189,11 @@ static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
bool * = NULL);
static void c_parser_static_assert_declaration_no_semi (c_parser *);
static void c_parser_static_assert_declaration (c_parser *);
-static void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
- bool, bool, bool, enum c_lookahead_kind);
static struct c_typespec c_parser_enum_specifier (c_parser *);
static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
static tree c_parser_struct_declaration (c_parser *);
static struct c_typespec c_parser_typeof_specifier (c_parser *);
static tree c_parser_alignas_specifier (c_parser *);
-static struct c_declarator *c_parser_declarator (c_parser *, bool, c_dtr_syn,
- bool *);
static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
c_dtr_syn, bool *);
static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
@@ -1315,7 +1205,6 @@ static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
static struct c_parm *c_parser_parameter_declaration (c_parser *, tree);
static tree c_parser_simple_asm_expr (c_parser *);
static tree c_parser_attributes (c_parser *);
-static struct c_type_name *c_parser_type_name (c_parser *);
static struct c_expr c_parser_initializer (c_parser *);
static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
struct obstack *);
@@ -1652,7 +1541,13 @@ static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
OpenMP:
declaration:
- threadprivate-directive */
+ threadprivate-directive
+
+ GIMPLE:
+
+ gimple-function-definition:
+ declaration-specifiers[opt] __GIMPLE (gimple-pass-list) declarator
+ declaration-list[opt] compound-statement */
static void
c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
@@ -1752,6 +1647,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
c_parser_skip_to_end_of_block_or_statement (parser);
return;
}
+
finish_declspecs (specs);
bool auto_type_p = specs->typespec_word == cts_auto_type;
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
@@ -1882,7 +1778,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
struct c_declarator *declarator;
bool dummy = false;
timevar_id_t tv;
- tree fnbody;
+ tree fnbody = NULL_TREE;
/* Declaring either one or more declarators (in which case we
should diagnose if there were no declaration specifiers) or a
function definition (in which case the diagnostic for
@@ -2173,9 +2069,24 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
= c_parser_peek_token (parser)->location;
- fnbody = c_parser_compound_statement (parser);
- if (flag_cilkplus && contains_array_notation_expr (fnbody))
- fnbody = expand_array_notation_exprs (fnbody);
+
+ /* If the definition was marked with __GIMPLE then parse the
+ function body as GIMPLE. */
+ if (specs->gimple_p)
+ {
+ cfun->pass_startwith = specs->gimple_pass;
+ bool saved = in_late_binary_op;
+ in_late_binary_op = true;
+ c_parser_parse_gimple_body (parser);
+ in_late_binary_op = saved;
+ }
+ else
+ {
+ fnbody = c_parser_compound_statement (parser);
+ if (flag_cilkplus && contains_array_notation_expr (fnbody))
+ fnbody = expand_array_notation_exprs (fnbody);
+ }
+ tree fndecl = current_function_decl;
if (nested)
{
tree decl = current_function_decl;
@@ -2191,9 +2102,13 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
}
else
{
- add_stmt (fnbody);
+ if (fnbody)
+ add_stmt (fnbody);
finish_function ();
}
+ /* Get rid of the empty stmt list for GIMPLE. */
+ if (specs->gimple_p)
+ DECL_SAVED_TREE (fndecl) = NULL_TREE;
timevar_pop (tv);
break;
@@ -2416,7 +2331,7 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
objc-protocol-refs
*/
-static void
+void
c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
bool scspec_ok, bool typespec_ok, bool start_attr_ok,
bool alignspec_ok, bool auto_type_ok,
@@ -2681,6 +2596,14 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
align = c_parser_alignas_specifier (parser);
declspecs_add_alignas (loc, specs, align);
break;
+ case RID_GIMPLE:
+ if (! flag_gimple)
+ error_at (loc, "%<__GIMPLE%> only valid with -fgimple");
+ c_parser_consume_token (parser);
+ specs->gimple_p = true;
+ specs->locations[cdw_gimple] = loc;
+ specs->gimple_pass = c_parser_gimple_pass_list (parser);
+ break;
default:
goto out;
}
@@ -3415,7 +3338,7 @@ c_parser_alignas_specifier (c_parser * parser)
This function also accepts an omitted abstract declarator as being
an abstract declarator, although not part of the formal syntax. */
-static struct c_declarator *
+struct c_declarator *
c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
bool *seen_id)
{
@@ -4311,7 +4234,7 @@ c_parser_attributes (c_parser *parser)
specifier-qualifier-list abstract-declarator[opt]
*/
-static struct c_type_name *
+struct c_type_name *
c_parser_type_name (c_parser *parser)
{
struct c_declspecs *specs = build_null_declspecs ();
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index e8060f8b197..a8cf353eb4d 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -267,6 +267,7 @@ enum c_declspec_word {
cdw_saturating,
cdw_alignas,
cdw_address_space,
+ cdw_gimple,
cdw_number_of_elements /* This one must always be the last
enumerator. */
};
@@ -290,6 +291,8 @@ struct c_declspecs {
NULL; attributes (possibly from multiple lists) will be passed
separately. */
tree attrs;
+ /* The pass to start compiling a __GIMPLE function with. */
+ char *gimple_pass;
/* The base-2 log of the greatest alignment required by an _Alignas
specifier, in bytes, or -1 if no such specifiers with nonzero
alignment. */
@@ -362,6 +365,8 @@ struct c_declspecs {
/* Whether any alignment specifier (even with zero alignment) was
specified. */
BOOL_BITFIELD alignas_p : 1;
+ /* Whether any __GIMPLE specifier was specified. */
+ BOOL_BITFIELD gimple_p : 1;
/* The address space that the declaration belongs to. */
addr_space_t address_space;
};
diff --git a/gcc/c/config-lang.in b/gcc/c/config-lang.in
index b9cdc8e66ce..51fbb5366d3 100644
--- a/gcc/c/config-lang.in
+++ b/gcc/c/config-lang.in
@@ -29,4 +29,4 @@ compilers="cc1\$(exeext)"
target_libs=
-gtfiles="\$(srcdir)/c/c-lang.c \$(srcdir)/c/c-tree.h \$(srcdir)/c/c-decl.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/c/c-objc-common.c \$(srcdir)/c/c-parser.c \$(srcdir)/c/c-lang.h"
+gtfiles="\$(srcdir)/c/c-lang.c \$(srcdir)/c/c-tree.h \$(srcdir)/c/c-decl.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/c/c-objc-common.c \$(srcdir)/c/c-parser.h \$(srcdir)/c/c-parser.c \$(srcdir)/c/c-lang.h"
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 0668d2bb9ee..8e2f46617b8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -179,7 +179,7 @@ in the following sections.
@xref{C Dialect Options,,Options Controlling C Dialect}.
@gccoptlist{-ansi -std=@var{standard} -fgnu89-inline @gol
-aux-info @var{filename} -fallow-parameterless-variadic-functions @gol
--fno-asm -fno-builtin -fno-builtin-@var{function} @gol
+-fno-asm -fno-builtin -fno-builtin-@var{function} -fgimple@gol
-fhosted -ffreestanding -fopenacc -fopenmp -fopenmp-simd @gol
-fms-extensions -fplan9-extensions -fsso-struct=@var{endianness}
-fallow-single-precision -fcond-mismatch -flax-vector-conversions @gol
@@ -1951,6 +1951,13 @@ built-in functions selectively when using @option{-fno-builtin} or
#define strcpy(d, s) __builtin_strcpy ((d), (s))
@end smallexample
+@item -fgimple
+@opindex fgimple
+
+Enable parsing of function definitions marked with @code{__GIMPLE}.
+This is an experimental feature that allows unit testing of GIMPLE
+passes.
+
@item -fhosted
@opindex fhosted
@cindex hosted environment
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
index 74522a66fc0..e9483bc8d4d 100644
--- a/gcc/dumpfile.c
+++ b/gcc/dumpfile.c
@@ -108,13 +108,15 @@ static const struct dump_option_value_info dump_options[] =
{"nouid", TDF_NOUID},
{"enumerate_locals", TDF_ENUMERATE_LOCALS},
{"scev", TDF_SCEV},
+ {"gimple", TDF_GIMPLE},
{"optimized", MSG_OPTIMIZED_LOCATIONS},
{"missed", MSG_MISSED_OPTIMIZATION},
{"note", MSG_NOTE},
{"optall", MSG_ALL},
{"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
| TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
- | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS | TDF_SCEV)},
+ | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS | TDF_SCEV
+ | TDF_GIMPLE)},
{NULL, 0}
};
diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h
index 3f08b162458..b7d70f2804b 100644
--- a/gcc/dumpfile.h
+++ b/gcc/dumpfile.h
@@ -82,9 +82,10 @@ enum tree_dump_index
#define TDF_CSELIB (1 << 23) /* Dump cselib details. */
#define TDF_SCEV (1 << 24) /* Dump SCEV details. */
#define TDF_COMMENT (1 << 25) /* Dump lines with prefix ";;" */
-#define MSG_OPTIMIZED_LOCATIONS (1 << 26) /* -fopt-info optimized sources */
-#define MSG_MISSED_OPTIMIZATION (1 << 27) /* missed opportunities */
-#define MSG_NOTE (1 << 28) /* general optimization info */
+#define TDF_GIMPLE (1 << 26) /* Dump in GIMPLE FE syntax */
+#define MSG_OPTIMIZED_LOCATIONS (1 << 27) /* -fopt-info optimized sources */
+#define MSG_MISSED_OPTIMIZATION (1 << 28) /* missed opportunities */
+#define MSG_NOTE (1 << 29) /* general optimization info */
#define MSG_ALL (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \
| MSG_NOTE)
diff --git a/gcc/function.h b/gcc/function.h
index e854c7f1c99..b564f4533f2 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -234,6 +234,9 @@ struct GTY(()) function {
/* The loops in this function. */
struct loops *x_current_loops;
+ /* Filled by the GIMPLE FE, pass to start compilation with. */
+ char *pass_startwith;
+
/* The stack usage of this function. */
struct stack_usage *su;
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index f588f5e445e..82863260ac3 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -893,7 +893,10 @@ dump_gimple_switch (pretty_printer *buffer, gswitch *gs, int spc,
{
pp_string (buffer, "switch (");
dump_generic_node (buffer, gimple_switch_index (gs), spc, flags, true);
- pp_string (buffer, ") <");
+ if (flags & TDF_GIMPLE)
+ pp_string (buffer, ") {");
+ else
+ pp_string (buffer, ") <");
}
for (i = 0; i < gimple_switch_num_labels (gs); i++)
@@ -904,9 +907,17 @@ dump_gimple_switch (pretty_printer *buffer, gswitch *gs, int spc,
pp_space (buffer);
dump_generic_node (buffer, CASE_LABEL (case_label), spc, flags, false);
if (i < gimple_switch_num_labels (gs) - 1)
- pp_string (buffer, ", ");
+ {
+ if (flags & TDF_GIMPLE)
+ pp_string (buffer, "; ");
+ else
+ pp_string (buffer, ", ");
+ }
}
- pp_greater (buffer);
+ if (flags & TDF_GIMPLE)
+ pp_string (buffer, "; }");
+ else
+ pp_greater (buffer);
}
@@ -962,12 +973,14 @@ dump_gimple_label (pretty_printer *buffer, glabel *gs, int spc, int flags)
{
tree label = gimple_label_label (gs);
if (flags & TDF_RAW)
- dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, label);
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, label);
else
{
dump_generic_node (buffer, label, spc, flags, false);
pp_colon (buffer);
}
+ if (flags & TDF_GIMPLE)
+ return;
if (DECL_NONLOCAL (label))
pp_string (buffer, " [non-local]");
if ((flags & TDF_EH) && EH_LANDING_PAD_NR (label))
@@ -2039,21 +2052,44 @@ dump_gimple_phi (pretty_printer *buffer, gphi *phi, int spc, bool comment,
else
{
dump_generic_node (buffer, lhs, spc, flags, false);
- pp_string (buffer, " = PHI <");
+ if (flags & TDF_GIMPLE)
+ pp_string (buffer, " = __PHI (");
+ else
+ pp_string (buffer, " = PHI <");
}
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
if ((flags & TDF_LINENO) && gimple_phi_arg_has_location (phi, i))
dump_location (buffer, gimple_phi_arg_location (phi, i));
+ if (flags & TDF_GIMPLE)
+ {
+ basic_block src = gimple_phi_arg_edge (phi, i)->src;
+ gimple *stmt = first_stmt (src);
+ if (!stmt || gimple_code (stmt) != GIMPLE_LABEL)
+ {
+ pp_string (buffer, "bb_");
+ pp_decimal_int (buffer, src->index);
+ }
+ else
+ dump_generic_node (buffer, gimple_label_label (as_a <glabel *> (stmt)), 0, flags,
+ false);
+ pp_string (buffer, ": ");
+ }
dump_generic_node (buffer, gimple_phi_arg_def (phi, i), spc, flags,
false);
- pp_left_paren (buffer);
- pp_decimal_int (buffer, gimple_phi_arg_edge (phi, i)->src->index);
- pp_right_paren (buffer);
+ if (! (flags & TDF_GIMPLE))
+ {
+ pp_left_paren (buffer);
+ pp_decimal_int (buffer, gimple_phi_arg_edge (phi, i)->src->index);
+ pp_right_paren (buffer);
+ }
if (i < gimple_phi_num_args (phi) - 1)
pp_string (buffer, ", ");
}
- pp_greater (buffer);
+ if (flags & TDF_GIMPLE)
+ pp_string (buffer, ");");
+ else
+ pp_greater (buffer);
}
@@ -2502,7 +2538,12 @@ dump_gimple_bb_header (FILE *outf, basic_block bb, int indent, int flags)
{
gimple *stmt = first_stmt (bb);
if (!stmt || gimple_code (stmt) != GIMPLE_LABEL)
- fprintf (outf, "%*s<bb %d>:\n", indent, "", bb->index);
+ {
+ if (flags & TDF_GIMPLE)
+ fprintf (outf, "%*sbb_%d:\n", indent, "", bb->index);
+ else
+ fprintf (outf, "%*s<bb %d>:\n", indent, "", bb->index);
+ }
}
}
@@ -2535,7 +2576,8 @@ dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
if (!virtual_operand_p (gimple_phi_result (phi)) || (flags & TDF_VOPS))
{
INDENT (indent);
- dump_gimple_phi (buffer, phi, indent, true, flags);
+ dump_gimple_phi (buffer, phi, indent,
+ (flags & TDF_GIMPLE) ? false : true, flags);
pp_newline (buffer);
}
}
@@ -2546,26 +2588,32 @@ dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
to BUFFER. */
static void
-pp_cfg_jump (pretty_printer *buffer, basic_block bb)
+pp_cfg_jump (pretty_printer *buffer, basic_block bb, int flags)
{
- gimple *stmt;
-
- stmt = first_stmt (bb);
-
- pp_string (buffer, "goto <bb ");
- pp_decimal_int (buffer, bb->index);
- pp_greater (buffer);
- if (stmt && gimple_code (stmt) == GIMPLE_LABEL)
+ if (flags & TDF_GIMPLE)
{
- pp_string (buffer, " (");
- dump_generic_node (buffer,
- gimple_label_label (as_a <glabel *> (stmt)),
- 0, 0, false);
- pp_right_paren (buffer);
+ pp_string (buffer, "goto bb_");
+ pp_decimal_int (buffer, bb->index);
pp_semicolon (buffer);
}
else
- pp_semicolon (buffer);
+ {
+ gimple *stmt = first_stmt (bb);
+ pp_string (buffer, "goto <bb ");
+ pp_decimal_int (buffer, bb->index);
+ pp_greater (buffer);
+ if (stmt && gimple_code (stmt) == GIMPLE_LABEL)
+ {
+ pp_string (buffer, " (");
+ dump_generic_node (buffer,
+ gimple_label_label (as_a <glabel *> (stmt)),
+ 0, 0, false);
+ pp_right_paren (buffer);
+ pp_semicolon (buffer);
+ }
+ else
+ pp_semicolon (buffer);
+ }
}
@@ -2593,11 +2641,11 @@ dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
INDENT (indent + 2);
- pp_cfg_jump (buffer, true_edge->dest);
+ pp_cfg_jump (buffer, true_edge->dest, flags);
newline_and_indent (buffer, indent);
pp_string (buffer, "else");
newline_and_indent (buffer, indent + 2);
- pp_cfg_jump (buffer, false_edge->dest);
+ pp_cfg_jump (buffer, false_edge->dest, flags);
pp_newline (buffer);
return;
}
@@ -2614,7 +2662,7 @@ dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
&& e->goto_locus != UNKNOWN_LOCATION)
dump_location (buffer, e->goto_locus);
- pp_cfg_jump (buffer, e->dest);
+ pp_cfg_jump (buffer, e->dest, flags);
pp_newline (buffer);
}
}
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index cbee97ea82c..08755594db1 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -2505,3 +2505,9 @@ expand_internal_call (gcall *stmt)
{
expand_internal_call (gimple_call_internal_fn (stmt), stmt);
}
+
+void
+expand_PHI (internal_fn, gcall *)
+{
+ gcc_unreachable ();
+}
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 0869b2fd52d..d1cd1a55b8f 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -170,6 +170,7 @@ DEF_INTERNAL_FN (VA_ARG, ECF_NOTHROW | ECF_LEAF, NULL)
other such optimizations. The first argument distinguishes
between uses. See internal-fn.h for usage. */
DEF_INTERNAL_FN (UNIQUE, ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (PHI, 0, NULL)
/* DIM_SIZE and DIM_POS return the size of a particular compute
dimension and the executing thread's position within that
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index 4e5dbaa79d4..672a60f0619 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -178,5 +178,6 @@ extern bool set_edom_supported_p (void);
extern void expand_internal_call (gcall *);
extern void expand_internal_call (internal_fn, gcall *);
+extern void expand_PHI (internal_fn, gcall *);
#endif
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index 74dda97e39c..4963e812fe4 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,8 @@
+2016-11-14 Prasad Ghangal <prasad.ghangal@gmail.com>
+ Richard Biener <rguenther@suse.de>
+
+ * config-lang.in (gtfiles): Add c/c-parser.h.
+
2016-09-27 Jakub Jelinek <jakub@redhat.com>
* objc-act.c (continue_class): Remove break after return.
diff --git a/gcc/objc/config-lang.in b/gcc/objc/config-lang.in
index f5a74a7d173..912af224b00 100644
--- a/gcc/objc/config-lang.in
+++ b/gcc/objc/config-lang.in
@@ -35,4 +35,4 @@ lang_requires="c"
# Order is important. If you change this list, make sure you test
# building without C++ as well; that is, remove the gcc/cp directory,
# and build with --enable-languages=c,objc.
-gtfiles="\$(srcdir)/objc/objc-map.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/objc/objc-act.h \$(srcdir)/objc/objc-act.c \$(srcdir)/objc/objc-runtime-shared-support.c \$(srcdir)/objc/objc-gnu-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-02.c \$(srcdir)/c/c-parser.c \$(srcdir)/c/c-tree.h \$(srcdir)/c/c-decl.c \$(srcdir)/c/c-lang.h \$(srcdir)/c/c-objc-common.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c"
+gtfiles="\$(srcdir)/objc/objc-map.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/objc/objc-act.h \$(srcdir)/objc/objc-act.c \$(srcdir)/objc/objc-runtime-shared-support.c \$(srcdir)/objc/objc-gnu-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-02.c \$(srcdir)/c/c-parser.h \$(srcdir)/c/c-parser.c \$(srcdir)/c/c-tree.h \$(srcdir)/c/c-decl.c \$(srcdir)/c/c-lang.h \$(srcdir)/c/c-objc-common.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c"
diff --git a/gcc/passes.c b/gcc/passes.c
index e78f9ed79af..51d0d84b74d 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -2099,7 +2099,7 @@ pass_init_dump_file (opt_pass *pass)
release_dump_file_name ();
dump_file_name = dumps->get_dump_file_name (pass->static_pass_number);
dumps->dump_start (pass->static_pass_number, &dump_flags);
- if (dump_file && current_function_decl)
+ if (dump_file && current_function_decl && ! (dump_flags & TDF_GIMPLE))
dump_function_header (dump_file, current_function_decl, dump_flags);
if (initializing_dump
&& dump_file && (dump_flags & TDF_GRAPH)
@@ -2313,6 +2313,35 @@ execute_one_pass (opt_pass *pass)
return false;
}
+ /* For skipping passes until startwith pass */
+ if (cfun
+ && cfun->pass_startwith
+ /* But we can't skip the lowering phase yet -- ideally we'd
+ drive that phase fully via properties. */
+ && (cfun->curr_properties & PROP_ssa))
+ {
+ size_t namelen = strlen (pass->name);
+ if (! strncmp (pass->name, cfun->pass_startwith, namelen))
+ {
+ /* The following supports starting with the Nth invocation
+ of a pass (where N does not necessarily is equal to the
+ dump file suffix). */
+ if (cfun->pass_startwith[namelen] == '\0'
+ || (cfun->pass_startwith[namelen] == '1'
+ && cfun->pass_startwith[namelen + 1] == '\0'))
+ cfun->pass_startwith = NULL;
+ else
+ {
+ if (cfun->pass_startwith[namelen + 1] != '\0')
+ return true;
+ --cfun->pass_startwith[namelen];
+ return true;
+ }
+ }
+ else
+ return true;
+ }
+
/* Pass execution event trigger: useful to identify passes being
executed. */
invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass);
@@ -2428,7 +2457,7 @@ execute_pass_list_1 (opt_pass *pass)
if (cfun == NULL)
return;
if (execute_one_pass (pass) && pass->sub)
- execute_pass_list_1 (pass->sub);
+ execute_pass_list_1 (pass->sub);
pass = pass->next;
}
while (pass);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c47c8b2af5c..e9485591659 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,25 @@
+2016-11-14 Prasad Ghangal <prasad.ghangal@gmail.com>
+ Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/gimplefe-1.c: New testcase.
+ * gcc.dg/gimplefe-2.c: Likewise.
+ * gcc.dg/gimplefe-3.c: Likewise.
+ * gcc.dg/gimplefe-4.c: Likewise.
+ * gcc.dg/gimplefe-5.c: Likewise.
+ * gcc.dg/gimplefe-6.c: Likewise.
+ * gcc.dg/gimplefe-7.c: Likewise.
+ * gcc.dg/gimplefe-8.c: Likewise.
+ * gcc.dg/gimplefe-9.c: Likewise.
+ * gcc.dg/gimplefe-10.c: Likewise.
+ * gcc.dg/gimplefe-11.c: Likewise.
+ * gcc.dg/gimplefe-12.c: Likewise.
+ * gcc.dg/gimplefe-13.c: Likewise.
+ * gcc.dg/gimplefe-14.c: Likewise.
+ * gcc.dg/gimplefe-15.c: Likewise.
+ * gcc.dg/gimplefe-16.c: Likewise.
+ * gcc.dg/gimplefe-17.c: Likewise.
+ * gcc.dg/gimplefe-18.c: Likewise.
+
2016-11-14 Martin Liska <mliska@suse.cz>
PR bootstrap/78069
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index dfa82aaef73..e99e1022b6c 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -170,6 +170,7 @@ static edge find_taken_edge_computed_goto (basic_block, tree);
static edge find_taken_edge_cond_expr (basic_block, tree);
static edge find_taken_edge_switch_expr (gswitch *, basic_block, tree);
static tree find_case_label_for_value (gswitch *, tree);
+static void lower_phi_internal_fn ();
void
init_empty_tree_cfg_for_function (struct function *fn)
@@ -244,6 +245,7 @@ build_gimple_cfg (gimple_seq seq)
discriminator_per_locus = new hash_table<locus_discrim_hasher> (13);
make_edges ();
assign_discriminators ();
+ lower_phi_internal_fn ();
cleanup_dead_labels ();
delete discriminator_per_locus;
discriminator_per_locus = NULL;
@@ -345,6 +347,49 @@ replace_loop_annotate (void)
}
}
+/* Lower internal PHI function from GIMPLE FE. */
+
+static void
+lower_phi_internal_fn ()
+{
+ basic_block bb, pred = NULL;
+ gimple_stmt_iterator gsi;
+ tree lhs;
+ gphi *phi_node;
+ gimple *stmt;
+
+ /* After edge creation, handle __PHI function from GIMPLE FE. */
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
+ {
+ stmt = gsi_stmt (gsi);
+ if (! gimple_call_internal_p (stmt, IFN_PHI))
+ {
+ gsi_next (&gsi);
+ continue;
+ }
+
+ lhs = gimple_call_lhs (stmt);
+ phi_node = create_phi_node (lhs, bb);
+
+ /* Add arguments to the PHI node. */
+ for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
+ {
+ tree arg = gimple_call_arg (stmt, i);
+ if (TREE_CODE (arg) == LABEL_DECL)
+ pred = label_to_block (arg);
+ else
+ {
+ edge e = find_edge (pred, bb);
+ add_phi_arg (phi_node, arg, e, UNKNOWN_LOCATION);
+ }
+ }
+
+ gsi_remove (&gsi, true);
+ }
+ }
+}
static unsigned int
execute_build_cfg (void)
@@ -3337,6 +3382,11 @@ verify_gimple_call (gcall *stmt)
debug_generic_stmt (fn);
return true;
}
+ /* FIXME : for passing label as arg in internal fn PHI from GIMPLE FE*/
+ else if (gimple_call_internal_fn (stmt) == IFN_PHI)
+ {
+ return false;
+ }
}
else
{
@@ -7497,7 +7547,14 @@ dump_function_to_file (tree fndecl, FILE *file, int flags)
}
current_function_decl = fndecl;
- fprintf (file, "%s %s(", function_name (fun), tmclone ? "[tm-clone] " : "");
+ if (flags & TDF_GIMPLE)
+ {
+ print_generic_expr (file, TREE_TYPE (TREE_TYPE (fndecl)),
+ dump_flags | TDF_SLIM);
+ fprintf (file, " __GIMPLE ()\n%s (", function_name (fun));
+ }
+ else
+ fprintf (file, "%s %s(", function_name (fun), tmclone ? "[tm-clone] " : "");
arg = DECL_ARGUMENTS (fndecl);
while (arg)
@@ -7609,7 +7666,7 @@ dump_function_to_file (tree fndecl, FILE *file, int flags)
fprintf (file, "}\n");
}
- else if (DECL_SAVED_TREE (fndecl) == NULL)
+ else if (fun->curr_properties & PROP_gimple_any)
{
/* The function is now in GIMPLE form but the CFG has not been
built yet. Emit the single sequence of GIMPLE statements
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index e5b59a7a29f..0e7884519d6 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -1378,12 +1378,20 @@ rewrite_add_phi_arguments (basic_block bb)
for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi);
gsi_next (&gsi))
{
- tree currdef, res;
+ tree currdef, res, argvar;
location_t loc;
phi = gsi.phi ();
res = gimple_phi_result (phi);
- currdef = get_reaching_def (SSA_NAME_VAR (res));
+ /* If we have pre-existing PHI (via the GIMPLE FE) its args may
+ be different vars than existing vars and they may be constants
+ as well. Note the following supports partial SSA for PHI args. */
+ argvar = gimple_phi_arg_def (phi, e->dest_idx);
+ if (argvar && ! DECL_P (argvar))
+ continue;
+ if (!argvar)
+ argvar = SSA_NAME_VAR (res);
+ currdef = get_reaching_def (argvar);
/* Virtual operand PHI args do not need a location. */
if (virtual_operand_p (res))
loc = UNKNOWN_LOCATION;
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index ebbf606ff8b..096eefdd4f6 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -257,10 +257,11 @@ dump_decl_name (pretty_printer *pp, tree node, int flags)
else
pp_tree_identifier (pp, DECL_NAME (node));
}
+ char uid_sep = (flags & TDF_GIMPLE) ? '_' : '.';
if ((flags & TDF_UID) || DECL_NAME (node) == NULL_TREE)
{
if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
- pp_printf (pp, "L.%d", (int) LABEL_DECL_UID (node));
+ pp_printf (pp, "L%c%d", uid_sep, (int) LABEL_DECL_UID (node));
else if (TREE_CODE (node) == DEBUG_EXPR_DECL)
{
if (flags & TDF_NOUID)
@@ -274,7 +275,7 @@ dump_decl_name (pretty_printer *pp, tree node, int flags)
if (flags & TDF_NOUID)
pp_printf (pp, "%c.xxxx", c);
else
- pp_printf (pp, "%c.%u", c, DECL_UID (node));
+ pp_printf (pp, "%c%c%u", c, uid_sep, DECL_UID (node));
}
}
if ((flags & TDF_ALIAS) && DECL_PT_UID (node) != DECL_UID (node))
@@ -1762,13 +1763,23 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, int flags,
if (DECL_NAME (node))
dump_decl_name (pp, node, flags);
else if (LABEL_DECL_UID (node) != -1)
- pp_printf (pp, "<L%d>", (int) LABEL_DECL_UID (node));
+ {
+ if (flags & TDF_GIMPLE)
+ pp_printf (pp, "L%d", (int) LABEL_DECL_UID (node));
+ else
+ pp_printf (pp, "<L%d>", (int) LABEL_DECL_UID (node));
+ }
else
{
if (flags & TDF_NOUID)
pp_string (pp, "<D.xxxx>");
else
- pp_printf (pp, "<D.%u>", DECL_UID (node));
+ {
+ if (flags & TDF_GIMPLE)
+ pp_printf (pp, "<D%u>", DECL_UID (node));
+ else
+ pp_printf (pp, "<D.%u>", DECL_UID (node));
+ }
}
break;
@@ -2695,7 +2706,8 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, int flags,
&& SSA_NAME_VAR (node)
&& DECL_NAMELESS (SSA_NAME_VAR (node)))
dump_fancy_name (pp, SSA_NAME_IDENTIFIER (node));
- else
+ else if (! (flags & TDF_GIMPLE)
+ || SSA_NAME_VAR (node))
dump_generic_node (pp, SSA_NAME_IDENTIFIER (node),
spc, flags, false);
}
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 913d142f046..bd5d10ab28b 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -252,10 +252,12 @@ flush_ssaname_freelist (void)
/* Return an SSA_NAME node for variable VAR defined in statement STMT
in function FN. STMT may be an empty statement for artificial
references (e.g., default definitions created when a variable is
- used without a preceding definition). */
+ used without a preceding definition). If VERISON is not zero then
+ allocate the SSA name with that version. */
tree
-make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
+make_ssa_name_fn (struct function *fn, tree var, gimple *stmt,
+ unsigned int version)
{
tree t;
use_operand_p imm;
@@ -265,8 +267,19 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
|| TREE_CODE (var) == RESULT_DECL
|| (TYPE_P (var) && is_gimple_reg_type (var)));
+ /* Get the specified SSA name version. */
+ if (version != 0)
+ {
+ t = make_node (SSA_NAME);
+ SSA_NAME_VERSION (t) = version;
+ if (version >= SSANAMES (fn)->length ())
+ vec_safe_grow_cleared (SSANAMES (fn), version + 1);
+ gcc_assert ((*SSANAMES (fn))[version] == NULL);
+ (*SSANAMES (fn))[version] = t;
+ ssa_name_nodes_created++;
+ }
/* If our free list has an element, then use it. */
- if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
+ else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
{
t = FREE_SSANAMES (fn)->pop ();
ssa_name_nodes_reused++;
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index d39cc9d4e27..57e887ec7ae 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -78,7 +78,8 @@ extern bool ssa_name_has_boolean_range (tree);
extern void init_ssanames (struct function *, int);
extern void fini_ssanames (struct function *);
extern void ssanames_print_statistics (void);
-extern tree make_ssa_name_fn (struct function *, tree, gimple *);
+extern tree make_ssa_name_fn (struct function *, tree, gimple *,
+ unsigned int version = 0);
extern void release_ssa_name_fn (struct function *, tree);
extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
unsigned int *);