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