gimple-streamer-out.c revision 1.1
1/* Routines for emitting GIMPLE to a file stream. 2 3 Copyright (C) 2011-2013 Free Software Foundation, Inc. 4 Contributed by Diego Novillo <dnovillo@google.com> 5 6This file is part of GCC. 7 8GCC is free software; you can redistribute it and/or modify it under 9the terms of the GNU General Public License as published by the Free 10Software Foundation; either version 3, or (at your option) any later 11version. 12 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14WARRANTY; without even the implied warranty of MERCHANTABILITY or 15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16for more details. 17 18You should have received a copy of the GNU General Public License 19along with GCC; see the file COPYING3. If not see 20<http://www.gnu.org/licenses/>. */ 21 22#include "config.h" 23#include "system.h" 24#include "coretypes.h" 25#include "tree.h" 26#include "tree-flow.h" 27#include "data-streamer.h" 28#include "gimple-streamer.h" 29#include "lto-streamer.h" 30#include "tree-streamer.h" 31 32/* Output PHI function PHI to the main stream in OB. */ 33 34static void 35output_phi (struct output_block *ob, gimple phi) 36{ 37 unsigned i, len = gimple_phi_num_args (phi); 38 39 streamer_write_record_start (ob, lto_gimple_code_to_tag (GIMPLE_PHI)); 40 streamer_write_uhwi (ob, SSA_NAME_VERSION (PHI_RESULT (phi))); 41 42 for (i = 0; i < len; i++) 43 { 44 stream_write_tree (ob, gimple_phi_arg_def (phi, i), true); 45 streamer_write_uhwi (ob, gimple_phi_arg_edge (phi, i)->src->index); 46 bitpack_d bp = bitpack_create (ob->main_stream); 47 stream_output_location (ob, &bp, gimple_phi_arg_location (phi, i)); 48 streamer_write_bitpack (&bp); 49 } 50} 51 52 53/* Emit statement STMT on the main stream of output block OB. */ 54 55static void 56output_gimple_stmt (struct output_block *ob, gimple stmt) 57{ 58 unsigned i; 59 enum gimple_code code; 60 enum LTO_tags tag; 61 struct bitpack_d bp; 62 63 /* Emit identifying tag. */ 64 code = gimple_code (stmt); 65 tag = lto_gimple_code_to_tag (code); 66 streamer_write_record_start (ob, tag); 67 68 /* Emit the tuple header. */ 69 bp = bitpack_create (ob->main_stream); 70 bp_pack_var_len_unsigned (&bp, gimple_num_ops (stmt)); 71 bp_pack_value (&bp, gimple_no_warning_p (stmt), 1); 72 if (is_gimple_assign (stmt)) 73 bp_pack_value (&bp, gimple_assign_nontemporal_move_p (stmt), 1); 74 bp_pack_value (&bp, gimple_has_volatile_ops (stmt), 1); 75 bp_pack_var_len_unsigned (&bp, stmt->gsbase.subcode); 76 77 /* Emit location information for the statement. */ 78 stream_output_location (ob, &bp, LOCATION_LOCUS (gimple_location (stmt))); 79 streamer_write_bitpack (&bp); 80 81 /* Emit the lexical block holding STMT. */ 82 stream_write_tree (ob, gimple_block (stmt), true); 83 84 /* Emit the operands. */ 85 switch (gimple_code (stmt)) 86 { 87 case GIMPLE_RESX: 88 streamer_write_hwi (ob, gimple_resx_region (stmt)); 89 break; 90 91 case GIMPLE_EH_MUST_NOT_THROW: 92 stream_write_tree (ob, gimple_eh_must_not_throw_fndecl (stmt), true); 93 break; 94 95 case GIMPLE_EH_DISPATCH: 96 streamer_write_hwi (ob, gimple_eh_dispatch_region (stmt)); 97 break; 98 99 case GIMPLE_ASM: 100 streamer_write_uhwi (ob, gimple_asm_ninputs (stmt)); 101 streamer_write_uhwi (ob, gimple_asm_noutputs (stmt)); 102 streamer_write_uhwi (ob, gimple_asm_nclobbers (stmt)); 103 streamer_write_uhwi (ob, gimple_asm_nlabels (stmt)); 104 streamer_write_string (ob, ob->main_stream, gimple_asm_string (stmt), 105 true); 106 /* Fallthru */ 107 108 case GIMPLE_ASSIGN: 109 case GIMPLE_CALL: 110 case GIMPLE_RETURN: 111 case GIMPLE_SWITCH: 112 case GIMPLE_LABEL: 113 case GIMPLE_COND: 114 case GIMPLE_GOTO: 115 case GIMPLE_DEBUG: 116 for (i = 0; i < gimple_num_ops (stmt); i++) 117 { 118 tree op = gimple_op (stmt, i); 119 tree *basep = NULL; 120 /* Wrap all uses of non-automatic variables inside MEM_REFs 121 so that we do not have to deal with type mismatches on 122 merged symbols during IL read in. The first operand 123 of GIMPLE_DEBUG must be a decl, not MEM_REF, though. */ 124 if (op && (i || !is_gimple_debug (stmt))) 125 { 126 basep = &op; 127 while (handled_component_p (*basep)) 128 basep = &TREE_OPERAND (*basep, 0); 129 if (TREE_CODE (*basep) == VAR_DECL 130 && !auto_var_in_fn_p (*basep, current_function_decl) 131 && !DECL_REGISTER (*basep)) 132 { 133 bool volatilep = TREE_THIS_VOLATILE (*basep); 134 *basep = build2 (MEM_REF, TREE_TYPE (*basep), 135 build_fold_addr_expr (*basep), 136 build_int_cst (build_pointer_type 137 (TREE_TYPE (*basep)), 0)); 138 TREE_THIS_VOLATILE (*basep) = volatilep; 139 } 140 else 141 basep = NULL; 142 } 143 stream_write_tree (ob, op, true); 144 /* Restore the original base if we wrapped it inside a MEM_REF. */ 145 if (basep) 146 *basep = TREE_OPERAND (TREE_OPERAND (*basep, 0), 0); 147 } 148 if (is_gimple_call (stmt)) 149 { 150 if (gimple_call_internal_p (stmt)) 151 streamer_write_enum (ob->main_stream, internal_fn, 152 IFN_LAST, gimple_call_internal_fn (stmt)); 153 else 154 stream_write_tree (ob, gimple_call_fntype (stmt), true); 155 } 156 break; 157 158 case GIMPLE_NOP: 159 case GIMPLE_PREDICT: 160 break; 161 162 case GIMPLE_TRANSACTION: 163 gcc_assert (gimple_transaction_body (stmt) == NULL); 164 stream_write_tree (ob, gimple_transaction_label (stmt), true); 165 break; 166 167 default: 168 gcc_unreachable (); 169 } 170} 171 172 173/* Output a basic block BB to the main stream in OB for this FN. */ 174 175void 176output_bb (struct output_block *ob, basic_block bb, struct function *fn) 177{ 178 gimple_stmt_iterator bsi = gsi_start_bb (bb); 179 180 streamer_write_record_start (ob, 181 (!gsi_end_p (bsi)) || phi_nodes (bb) 182 ? LTO_bb1 183 : LTO_bb0); 184 185 streamer_write_uhwi (ob, bb->index); 186 streamer_write_hwi (ob, bb->count); 187 streamer_write_hwi (ob, bb->frequency); 188 streamer_write_hwi (ob, bb->flags); 189 190 if (!gsi_end_p (bsi) || phi_nodes (bb)) 191 { 192 /* Output the statements. The list of statements is terminated 193 with a zero. */ 194 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) 195 { 196 int region; 197 gimple stmt = gsi_stmt (bsi); 198 199 output_gimple_stmt (ob, stmt); 200 201 /* Emit the EH region holding STMT. */ 202 region = lookup_stmt_eh_lp_fn (fn, stmt); 203 if (region != 0) 204 { 205 streamer_write_record_start (ob, LTO_eh_region); 206 streamer_write_hwi (ob, region); 207 } 208 else 209 streamer_write_record_start (ob, LTO_null); 210 } 211 212 streamer_write_record_start (ob, LTO_null); 213 214 for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) 215 { 216 gimple phi = gsi_stmt (bsi); 217 218 /* Only emit PHIs for gimple registers. PHI nodes for .MEM 219 will be filled in on reading when the SSA form is 220 updated. */ 221 if (!virtual_operand_p (gimple_phi_result (phi))) 222 output_phi (ob, phi); 223 } 224 225 streamer_write_record_start (ob, LTO_null); 226 } 227} 228