]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Make-lang.in (C_AND_OBJC_OBJS): Add gimple-parser.o.
authorPrasad Ghangal <prasad.ghangal@gmail.com>
Mon, 14 Nov 2016 13:51:48 +0000 (13:51 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 14 Nov 2016 13:51:48 +0000 (13:51 +0000)
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

27 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c-family/c.opt
gcc/c/ChangeLog
gcc/c/Make-lang.in
gcc/c/c-parser.c
gcc/c/c-tree.h
gcc/c/config-lang.in
gcc/doc/invoke.texi
gcc/dumpfile.c
gcc/dumpfile.h
gcc/function.h
gcc/gimple-pretty-print.c
gcc/internal-fn.c
gcc/internal-fn.def
gcc/internal-fn.h
gcc/objc/ChangeLog
gcc/objc/config-lang.in
gcc/passes.c
gcc/testsuite/ChangeLog
gcc/tree-cfg.c
gcc/tree-into-ssa.c
gcc/tree-pretty-print.c
gcc/tree-ssanames.c
gcc/tree-ssanames.h

index f8dc1bd2bf84dc00b48d724494ca96d7087ff297..4fea3461b765951034eaec3dcbb3a9ae400bea31 100644 (file)
@@ -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
index 8c99b75aa56317e60d1166c38e174ff56b65fd67..2360d9ed17c6e2cc4ed2af6d27b081d88a601009 100644 (file)
@@ -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
index 307862b9c7c4d694acb5a42c7491ee8e3ecef80d..2997c83925f36d761ce3933ff816e0acd3ed38de 100644 (file)
@@ -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 },
index 4f27f81b5b3a6adfa31220bfd22fbbd92d62f73b..241b3454e06478cc0a4e589263b258ceeb2aa457 100644 (file)
@@ -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,
 
index cf946e7b86ea28255104af51a85f2bf3a6709402..722d3800cf0b9303a6eebbb1d88818f4fc7710e9 100644 (file)
@@ -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.
index ee50c304b5f6dc361c3d623df79e19a7f01eb161..75f39d7ed8b40a78083be1d64d508fa77a731952 100644 (file)
@@ -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>
 
index 72c9ae74f87e149ef5d7860bcbe38cab9994b760..cd7108b8afab05162cf787be97364eaab088642a 100644 (file)
@@ -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)
index 52a5eddff7b46acdc1061629bb8ba7541873c683..00fe7312c4c836196737efe5cd4068c192316675 100644 (file)
@@ -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)
     }
 }
 \f
-/* 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 ();
index e8060f8b1977afde270cb90bf829d814af59139a..a8cf353eb4dc37c70043edbbf220c57a6fae67e3 100644 (file)
@@ -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;
 };
index b9cdc8e66ced82741a752c1ae917c3efb1660eca..51fbb5366d3e349ee0da906d7b7ec3f3c834226e 100644 (file)
@@ -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"
index 0668d2bb9ee65c48e10ff949187eb517ef4ef006..8e2f46617b8e44ccf16941c31029ab5625322867 100644 (file)
@@ -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
index 74522a66fc0244ec3414d062accb24e62e4370d6..e9483bc8d4d4e9ef3caa1de860fa456aabf61524 100644 (file)
@@ -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}
 };
 
index 3f08b1624586049df8210baf00258ffb56f9e973..b7d70f2804bb4d8c3813a83b4d9d96b33d7eab6a 100644 (file)
@@ -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)
 
index e854c7f1c99f070b3641af1be31e5e5b64657844..b564f4533f2aca1028bb6765a1f55a408a8dae16 100644 (file)
@@ -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;
 
index f588f5e445edb22672b8e565cf7ebf1e472e18db..82863260ac3afa53903453b535c26eb63a678943 100644 (file)
@@ -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);
     }
 }
index cbee97ea82c88fb29c16549fd7a8ce2ce7f41f14..08755594db1402682473c14d1d457085d5325f85 100644 (file)
@@ -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 ();
+}
index 0869b2fd52d5a64842bfd7f6194875f97d10f13a..d1cd1a55b8fd71eb0484e17a3fd0afbe033f341b 100644 (file)
@@ -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
index 4e5dbaa79d4aaf510fda7cd35a2be6c70e5e1b25..672a60f0619fc5bd7a24b4d9911b4df565f05c15 100644 (file)
@@ -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
index 74dda97e39c96f711e6cfb624dc87059ab17c4e4..4963e812fe4958feb6279783112cc9cff89f0a9f 100644 (file)
@@ -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.
index f5a74a7d17382a8f8f41e92ebe9b96bfb23639fe..912af224b00a92e5c45dc583cfe706eacf92377f 100644 (file)
@@ -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"
index e78f9ed79af25fa856e5f32145c32fb136c42b37..51d0d84b74de3a0db6ead04a26cd517844f59d83 100644 (file)
@@ -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);
index c47c8b2af5c3425772cc3b0b5c8594fa5f80f408..e9485591659a2414c8ab2ec236a52544c91b1790 100644 (file)
@@ -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
index dfa82aaef7375eb3529f2e16abf19dae891566d3..e99e1022b6c9cf44ff0520910eb52648b37dd645 100644 (file)
@@ -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
index e5b59a7a29f822508d239249cd331e4d14aeaf38..0e7884519d681df0549d12a62352c5928b276086 100644 (file)
@@ -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;
index ebbf606ff8b60682bad0235f19ac72398c160005..096eefdd4f63ceb5636994b84fab46ccf64e30b4 100644 (file)
@@ -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);
        }
index 913d142f0462e1647401bdefa21c2527b153ed5b..bd5d10ab28b53420fa8ffdba0141eff844279769 100644 (file)
@@ -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++;
index d39cc9d4e27c46c98176edcee02be7e7339875e9..57e887ec7ae1cb3de80d958a7f3a12b004a736fc 100644 (file)
@@ -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 *);