c-gimplify.c revision 1.1.1.1
1/* Tree lowering pass.  This pass gimplifies the tree representation built
2   by the C-based front ends.  The structure of gimplified, or
3   language-independent, trees is dictated by the grammar described in this
4   file.
5   Copyright (C) 2002-2013 Free Software Foundation, Inc.
6   Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
7   Re-written to support lowering of whole function trees, documentation
8   and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
9
10This file is part of GCC.
11
12GCC is free software; you can redistribute it and/or modify it under
13the terms of the GNU General Public License as published by the Free
14Software Foundation; either version 3, or (at your option) any later
15version.
16
17GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18WARRANTY; without even the implied warranty of MERCHANTABILITY or
19FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20for more details.
21
22You should have received a copy of the GNU General Public License
23along with GCC; see the file COPYING3.  If not see
24<http://www.gnu.org/licenses/>.  */
25
26#include "config.h"
27#include "system.h"
28#include "coretypes.h"
29#include "tm.h"
30#include "tree.h"
31#include "c-common.h"
32#include "gimple.h"
33#include "tree-inline.h"
34#include "diagnostic-core.h"
35#include "langhooks.h"
36#include "langhooks-def.h"
37#include "flags.h"
38#include "dumpfile.h"
39#include "c-pretty-print.h"
40#include "cgraph.h"
41
42
43/*  The gimplification pass converts the language-dependent trees
44    (ld-trees) emitted by the parser into language-independent trees
45    (li-trees) that are the target of SSA analysis and transformations.
46
47    Language-independent trees are based on the SIMPLE intermediate
48    representation used in the McCAT compiler framework:
49
50    "Designing the McCAT Compiler Based on a Family of Structured
51    Intermediate Representations,"
52    L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
53    Proceedings of the 5th International Workshop on Languages and
54    Compilers for Parallel Computing, no. 757 in Lecture Notes in
55    Computer Science, New Haven, Connecticut, pp. 406-420,
56    Springer-Verlag, August 3-5, 1992.
57
58    http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
59
60    Basically, we walk down gimplifying the nodes that we encounter.  As we
61    walk back up, we check that they fit our constraints, and copy them
62    into temporaries if not.  */
63
64/* Gimplification of statement trees.  */
65
66/* Convert the tree representation of FNDECL from C frontend trees to
67   GENERIC.  */
68
69void
70c_genericize (tree fndecl)
71{
72  FILE *dump_orig;
73  int local_dump_flags;
74  struct cgraph_node *cgn;
75
76  /* Dump the C-specific tree IR.  */
77  dump_orig = dump_begin (TDI_original, &local_dump_flags);
78  if (dump_orig)
79    {
80      fprintf (dump_orig, "\n;; Function %s",
81	       lang_hooks.decl_printable_name (fndecl, 2));
82      fprintf (dump_orig, " (%s)\n",
83	       (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
84		: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
85      fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
86      fprintf (dump_orig, "\n");
87
88      if (local_dump_flags & TDF_RAW)
89	dump_node (DECL_SAVED_TREE (fndecl),
90		   TDF_SLIM | local_dump_flags, dump_orig);
91      else
92	print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
93      fprintf (dump_orig, "\n");
94
95      dump_end (TDI_original, dump_orig);
96    }
97
98  /* Dump all nested functions now.  */
99  cgn = cgraph_get_create_node (fndecl);
100  for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
101    c_genericize (cgn->symbol.decl);
102}
103
104static void
105add_block_to_enclosing (tree block)
106{
107  unsigned i;
108  tree enclosing;
109  gimple bind;
110  vec<gimple> stack = gimple_bind_expr_stack ();
111
112  FOR_EACH_VEC_ELT (stack, i, bind)
113    if (gimple_bind_block (bind))
114      break;
115
116  enclosing = gimple_bind_block (bind);
117  BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
118}
119
120/* Genericize a scope by creating a new BIND_EXPR.
121   BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
122     In the latter case, we need to create a new BLOCK and add it to the
123     BLOCK_SUBBLOCKS of the enclosing block.
124   BODY is a chain of C _STMT nodes for the contents of the scope, to be
125     genericized.  */
126
127tree
128c_build_bind_expr (location_t loc, tree block, tree body)
129{
130  tree decls, bind;
131
132  if (block == NULL_TREE)
133    decls = NULL_TREE;
134  else if (TREE_CODE (block) == BLOCK)
135    decls = BLOCK_VARS (block);
136  else
137    {
138      decls = block;
139      if (DECL_ARTIFICIAL (decls))
140	block = NULL_TREE;
141      else
142	{
143	  block = make_node (BLOCK);
144	  BLOCK_VARS (block) = decls;
145	  add_block_to_enclosing (block);
146	}
147    }
148
149  if (!body)
150    body = build_empty_stmt (loc);
151  if (decls || block)
152    {
153      bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
154      TREE_SIDE_EFFECTS (bind) = 1;
155      SET_EXPR_LOCATION (bind, loc);
156    }
157  else
158    bind = body;
159
160  return bind;
161}
162
163/* Gimplification of expression trees.  */
164
165/* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
166   gimplify_expr.  */
167
168int
169c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
170		 gimple_seq *post_p ATTRIBUTE_UNUSED)
171{
172  enum tree_code code = TREE_CODE (*expr_p);
173
174  switch (code)
175    {
176    case DECL_EXPR:
177      /* This is handled mostly by gimplify.c, but we have to deal with
178	 not warning about int x = x; as it is a GCC extension to turn off
179	 this warning but only if warn_init_self is zero.  */
180      if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
181	  && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
182	  && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
183	  && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
184	  && !warn_init_self)
185	TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
186      break;
187
188    case PREINCREMENT_EXPR:
189    case PREDECREMENT_EXPR:
190    case POSTINCREMENT_EXPR:
191    case POSTDECREMENT_EXPR:
192      {
193	tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
194	if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
195	  {
196	    if (TYPE_OVERFLOW_UNDEFINED (type))
197	      type = unsigned_type_for (type);
198	    return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
199	  }
200	break;
201      }
202
203    default:;
204    }
205
206  return GS_UNHANDLED;
207}
208