Commit bc08ecba by Prasad Ghangal Committed by Richard Biener

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.

From-SVN: r242388
parent 1ee62b92
/* Declarations for the parser for C and Objective-C.
Copyright (C) 1987-2016 Free Software Foundation, Inc.
Parser actions based on the old Bison parser; structure somewhat
influenced by and fragments based on the C++ parser.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_C_PARSER_H
#define GCC_C_PARSER_H
/* 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;
}
};
/* The parser. */
struct c_parser;
/* 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
};
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
};
extern c_token * c_parser_peek_token (c_parser *parser);
extern c_token * c_parser_peek_2nd_token (c_parser *parser);
extern c_token * c_parser_peek_nth_token (c_parser *parser, unsigned int n);
extern bool c_parser_require (c_parser *parser, enum cpp_ttype type,
const char *msgid);
extern void c_parser_error (c_parser *parser, const char *gmsgid);
extern void c_parser_consume_token (c_parser *parser);
extern void c_parser_skip_until_found (c_parser *parser, enum cpp_ttype type,
const char *msgid);
extern bool c_parser_next_token_starts_declspecs (c_parser *parser);
bool c_parser_next_tokens_start_declaration (c_parser *parser);
bool c_token_starts_typename (c_token *token);
/* Abstraction to avoid defining c_parser here which messes up gengtype
output wrt ObjC due to vec<c_token> routines being put in gtype-c.h
but not gtype-objc.h. */
extern c_token * c_parser_tokens_buf (c_parser *parser, unsigned n);
extern bool c_parser_error (c_parser *parser);
extern void c_parser_set_error (c_parser *parser, bool);
/* 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;
}
extern struct c_declarator *
c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
bool *seen_id);
extern void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
bool, bool, bool, enum c_lookahead_kind);
extern struct c_type_name *c_parser_type_name (c_parser *);
#endif
/* Declarations for the parser for GIMPLE.
Copyright (C) 2016 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_GIMPLE_PARSER_H
#define GCC_GIMPLE_PARSER_H
/* Gimple parsing functions. */
extern void c_parser_parse_gimple_body (c_parser *);
extern char *c_parser_gimple_pass_list (c_parser *);
#endif
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
int i;
void __GIMPLE foo()
{
i = 1;
}
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
int __GIMPLE() bar(int a, int b, int c)
{
a = 1;
b = a + 1;
c = b * 4;
return b;
}
void __GIMPLE() foo()
{
int a;
int b;
int c;
b = bar(a, b, c);
}
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
void __GIMPLE() bar(int a, int b, int c)
{
a = 1;
b = a + 1;
c = b * 4;
return;
}
void __GIMPLE() foo()
{
int a;
int b;
int c;
bar(a, b, c);
}
/* { dg-do compile } */
/* { dg-options "-O -fgimple" } */
void __GIMPLE (startwith ("ccp1")) foo ()
{
int a;
int b;
a = b + 2;
return;
}
/* { dg-do compile } */
/* { dg-options "-O -fgimple" } */
void __GIMPLE (startwith ("dse2")) foo ()
{
int a;
bb_2:
if (a > 4)
goto bb_3;
else
goto bb_4;
bb_3:
a_2 = 10;
goto bb_5;
bb_4:
a_3 = 20;
bb_5:
a_1 = __PHI (bb_3: a_2, bb_4: a_3);
a_4 = a_1 + 4;
return;
}
/* { dg-do run } */
/* { dg-options "-O -fgimple" } */
int __GIMPLE ()
main (int argc, char * * argv)
{
int a;
bb_2:
switch (argc_2(D)) {default: L2; case 1: L0; case 2: L1; }
L0:
a_4 = 0;
goto bb_6;
L1:
a_3 = 3;
goto bb_6;
L2:
a_5 = -1;
bb_6:
a_1 = __PHI (L0: a_4, L1: a_3, L2: a_5);
return a_1;
}
/* { dg-do compile } */
/* { dg-options "-O -fgimple" } */
struct Y { int b[2]; };
struct X { int a; struct Y y; };
struct X x;
int __GIMPLE ()
foo (struct X *p, _Complex int q)
{
int b;
b = __real q;
p->a = b;
x.y.b[b] = b;
b = p->y.b[1];
b = x.a;
return b;
}
/* { dg-do compile } */
/* { dg-options "-O -fgimple" } */
struct Y { int b[2]; };
struct X { int a; struct Y y; };
struct X x;
int __GIMPLE ()
foo (struct X *p, _Complex int q)
{
int b;
b_1 = __real q;
p_4(D)->a = b_1;
x.y.b[b_1] = b_1;
b_2 = p->y.b[1];
b_3 = x.a;
return b_3;
}
/* { dg-do compile } */
/* { dg-options "-fgimple -fdump-tree-ssa" } */
int
__GIMPLE () *
foo ()
{
int _1;
int j;
int *b;
_1 = 1;
bb1:
if (_1)
goto bb3;
else
goto bb2;
bb2:
b_2 = (int *)0;
bb3:
b_4 = __PHI (bb1: b_3(D), bb2: b_2);
return b_4;
}
/* { dg-final { scan-tree-dump-not "_1_" "ssa" } } */
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
int
__GIMPLE () *
foo ()
{
int _1;
int j;
int *b;
_1 = 1;
bb1:
if (_1)
goto bb3;
else
goto bb2;
bb2:
b_2 = (int *)0;
bb3:
b_4 = __PHI (bb1: &j, bb2: b_2);
return b_4;
}
/* { dg-do compile }*/
/* { dg-options "-fgimple" } */
int a;
void __GIMPLE () foo ()
{
int b;
b = a;
b = b + 1;
a = b;
}
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
void __GIMPLE () foo ()
{
int *b;
*b = 1;
}
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
void __GIMPLE () foo ()
{
int a;
char b;
a = (int) b;
return;
}
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
int a;
void __GIMPLE () foo ()
{
int b;
int c;
bb_2:
b = a;
if (b > 3)
goto bb_3;
else
goto bb_4;
bb_3:
b = c + 4;
goto bb_5;
bb_4:
b = b + 1;
goto bb_5;
bb_5:
a = b;
return;
}
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
void __GIMPLE () foo ()
{
int a;
int b;
int c;
int d;
bb_2:
a = ~b;
b = a << c;
c = a & b;
d = b | c;
bb_3:
return;
}
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
void __GIMPLE () foo ()
{
int a;
bb_2:
if (a > 4)
goto bb_3;
else
goto bb_4;
bb_3:
a_2 = 10;
goto bb_5;
bb_4:
a_3 = 20;
bb_5:
a_1 = __PHI (bb_3: a_2, bb_4: a_3);
a_4 = a_1 + 4;
return;
}
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
int __GIMPLE () foo ()
{
int a;
int b;
bb_2:
b = a_1(D) + 1;
bb_3:
return b;
}
/* { dg-do compile } */
/* { dg-options "-fgimple" } */
int __GIMPLE() bar()
{
int a;
a = a + 1;
return a;
}
void __GIMPLE() foo()
{
int b;
b = bar();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment