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