1 /* Insert USEs in instructions that require mode switching. 2 This should probably be merged into mode-switching.c . 3 Copyright (C) 2011-2015 Free Software Foundation, Inc. 4 Contributed by Embecosm on behalf of Adapteva, Inc. 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3, or (at your option) 11 any later version. 12 13 GCC is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License 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 "tm.h" 26 #include "rtl.h" 27 #include "hashtab.h" 28 #include "hash-set.h" 29 #include "vec.h" 30 #include "machmode.h" 31 #include "hard-reg-set.h" 32 #include "input.h" 33 #include "function.h" 34 #include "emit-rtl.h" 35 #include "tree-pass.h" 36 #include "insn-attr.h" 37 #include "insn-config.h" 38 #include "recog.h" 39 #include "tm_p.h" 40 #include "dominance.h" 41 #include "cfg.h" 42 #include "cfgrtl.h" 43 #include "cfganal.h" 44 #include "lcm.h" 45 #include "cfgbuild.h" 46 #include "cfgcleanup.h" 47 #include "predict.h" 48 #include "basic-block.h" 49 #include "df.h" 50 51 #ifndef TARGET_INSERT_MODE_SWITCH_USE 52 #define TARGET_INSERT_MODE_SWITCH_USE NULL 53 #endif 54 55 static unsigned int 56 insert_uses (void) 57 { 58 static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING; 59 #define N_ENTITIES ARRAY_SIZE (num_modes) 60 int e; 61 void (*target_insert_mode_switch_use) (rtx_insn *insn, int, int) 62 = TARGET_INSERT_MODE_SWITCH_USE; 63 64 for (e = N_ENTITIES - 1; e >= 0; e--) 65 { 66 int no_mode = num_modes[e]; 67 rtx_insn *insn; 68 int mode; 69 70 if (!OPTIMIZE_MODE_SWITCHING (e)) 71 continue; 72 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 73 { 74 if (!INSN_P (insn)) 75 continue; 76 mode = epiphany_mode_needed (e, insn); 77 if (mode == no_mode) 78 continue; 79 if (target_insert_mode_switch_use) 80 { 81 target_insert_mode_switch_use (insn, e, mode); 82 df_insn_rescan (insn); 83 } 84 } 85 } 86 return 0; 87 } 88 89 namespace { 90 91 const pass_data pass_data_mode_switch_use = 92 { 93 RTL_PASS, /* type */ 94 "mode_switch_use", /* name */ 95 OPTGROUP_NONE, /* optinfo_flags */ 96 TV_NONE, /* tv_id */ 97 0, /* properties_required */ 98 0, /* properties_provided */ 99 0, /* properties_destroyed */ 100 0, /* todo_flags_start */ 101 0, /* todo_flags_finish */ 102 }; 103 104 class pass_mode_switch_use : public rtl_opt_pass 105 { 106 public: 107 pass_mode_switch_use(gcc::context *ctxt) 108 : rtl_opt_pass(pass_data_mode_switch_use, ctxt) 109 {} 110 111 /* opt_pass methods: */ 112 virtual unsigned int execute (function *) { return insert_uses (); } 113 114 }; // class pass_mode_switch_use 115 116 } // anon namespace 117 118 rtl_opt_pass * 119 make_pass_mode_switch_use (gcc::context *ctxt) 120 { 121 return new pass_mode_switch_use (ctxt); 122 } 123