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