131
|
1 /* relax-opt pass of Andes NDS32 cpu for GNU compiler
|
|
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
|
3 Contributed by Andes Technology Corporation.
|
|
4
|
|
5 This file is part of GCC.
|
|
6
|
|
7 GCC is free software; you can redistribute it and/or modify it
|
|
8 under the terms of the GNU General Public License as published
|
|
9 by the Free Software Foundation; either version 3, or (at your
|
|
10 option) any later version.
|
|
11
|
|
12 GCC is distributed in the hope that it will be useful, but WITHOUT
|
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
15 License for more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License
|
|
18 along with GCC; see the file COPYING3. If not see
|
|
19 <http://www.gnu.org/licenses/>. */
|
|
20
|
|
21 /* ------------------------------------------------------------------------ */
|
|
22
|
|
23 #define IN_TARGET_CODE 1
|
|
24
|
|
25 #include "config.h"
|
|
26 #include "system.h"
|
|
27 #include "coretypes.h"
|
|
28 #include "backend.h"
|
|
29 #include "target.h"
|
|
30 #include "rtl.h"
|
|
31 #include "tree.h"
|
|
32 #include "stringpool.h"
|
|
33 #include "attribs.h"
|
|
34 #include "df.h"
|
|
35 #include "memmodel.h"
|
|
36 #include "tm_p.h"
|
|
37 #include "optabs.h" /* For GEN_FCN. */
|
|
38 #include "regs.h"
|
|
39 #include "emit-rtl.h"
|
|
40 #include "recog.h"
|
|
41 #include "diagnostic-core.h"
|
|
42 #include "stor-layout.h"
|
|
43 #include "varasm.h"
|
|
44 #include "calls.h"
|
|
45 #include "output.h"
|
|
46 #include "explow.h"
|
|
47 #include "expr.h"
|
|
48 #include "tm-constrs.h"
|
|
49 #include "builtins.h"
|
|
50 #include "cpplib.h"
|
|
51 #include "insn-attr.h"
|
|
52 #include "cfgrtl.h"
|
|
53 #include "tree-pass.h"
|
|
54
|
|
55 using namespace nds32;
|
|
56
|
|
57 /* This is used to create unique relax hint id value.
|
|
58 The initial value is 0. */
|
|
59 static int relax_group_id = 0;
|
|
60
|
|
61 /* Group the following pattern as relax candidates:
|
|
62
|
|
63 1. sethi $ra, hi20(sym)
|
|
64 ori $ra, $ra, lo12(sym)
|
|
65 ==>
|
|
66 addi.gp $ra, sym
|
|
67
|
|
68 2. sethi $ra, hi20(sym)
|
|
69 lwi $rb, [$ra + lo12(sym)]
|
|
70 ==>
|
|
71 lwi.gp $rb, [(sym)]
|
|
72
|
|
73 3. sethi $ra, hi20(sym)
|
|
74 ori $ra, $ra, lo12(sym)
|
|
75 lwi $rb, [$ra]
|
|
76 swi $rc, [$ra]
|
|
77 ==>
|
|
78 lwi37 $rb, [(sym)]
|
|
79 swi37 $rc, [(sym)] */
|
|
80
|
|
81 /* Return true if is load/store with REG addressing mode
|
|
82 and memory mode is SImode. */
|
|
83 static bool
|
|
84 nds32_reg_base_load_store_p (rtx_insn *insn)
|
|
85 {
|
|
86 rtx mem_src = NULL_RTX;
|
|
87
|
|
88 switch (get_attr_type (insn))
|
|
89 {
|
|
90 case TYPE_LOAD:
|
|
91 mem_src = SET_SRC (PATTERN (insn));
|
|
92 break;
|
|
93 case TYPE_STORE:
|
|
94 mem_src = SET_DEST (PATTERN (insn));
|
|
95 break;
|
|
96 default:
|
|
97 break;
|
|
98 }
|
|
99
|
|
100 /* Find load/store insn with addressing mode is REG. */
|
|
101 if (mem_src != NULL_RTX)
|
|
102 {
|
|
103 if ((GET_CODE (mem_src) == ZERO_EXTEND)
|
|
104 || (GET_CODE (mem_src) == SIGN_EXTEND))
|
|
105 mem_src = XEXP (mem_src, 0);
|
|
106
|
|
107 if (GET_CODE (XEXP (mem_src, 0)) == REG)
|
|
108 return true;
|
|
109 }
|
|
110
|
|
111 return false;
|
|
112 }
|
|
113
|
|
114 /* Return true if insn is a sp/fp base or sp/fp plus load-store instruction. */
|
|
115
|
|
116 static bool
|
|
117 nds32_sp_base_or_plus_load_store_p (rtx_insn *insn)
|
|
118 {
|
|
119 rtx mem_src = NULL_RTX;
|
|
120
|
|
121 switch (get_attr_type (insn))
|
|
122 {
|
|
123 case TYPE_LOAD:
|
|
124 mem_src = SET_SRC (PATTERN (insn));
|
|
125 break;
|
|
126 case TYPE_STORE:
|
|
127 mem_src = SET_DEST (PATTERN (insn));
|
|
128 break;
|
|
129 default:
|
|
130 break;
|
|
131 }
|
|
132 /* Find load/store insn with addressing mode is REG. */
|
|
133 if (mem_src != NULL_RTX)
|
|
134 {
|
|
135 if ((GET_CODE (mem_src) == ZERO_EXTEND)
|
|
136 || (GET_CODE (mem_src) == SIGN_EXTEND))
|
|
137 mem_src = XEXP (mem_src, 0);
|
|
138
|
|
139 if ((GET_CODE (XEXP (mem_src, 0)) == PLUS))
|
|
140 mem_src = XEXP (mem_src, 0);
|
|
141
|
|
142 if (REG_P (XEXP (mem_src, 0))
|
|
143 && ((frame_pointer_needed
|
|
144 && REGNO (XEXP (mem_src, 0)) == FP_REGNUM)
|
|
145 || REGNO (XEXP (mem_src, 0)) == SP_REGNUM))
|
|
146 return true;
|
|
147 }
|
|
148
|
|
149 return false;
|
|
150 }
|
|
151
|
|
152 /* Return true if is load with [REG + REG/CONST_INT] addressing mode. */
|
|
153 static bool
|
|
154 nds32_plus_reg_load_store_p (rtx_insn *insn)
|
|
155 {
|
|
156 rtx mem_src = NULL_RTX;
|
|
157
|
|
158 switch (get_attr_type (insn))
|
|
159 {
|
|
160 case TYPE_LOAD:
|
|
161 mem_src = SET_SRC (PATTERN (insn));
|
|
162 break;
|
|
163 case TYPE_STORE:
|
|
164 mem_src = SET_DEST (PATTERN (insn));
|
|
165 break;
|
|
166 default:
|
|
167 break;
|
|
168 }
|
|
169
|
|
170 /* Find load/store insn with addressing mode is [REG + REG/CONST]. */
|
|
171 if (mem_src != NULL_RTX)
|
|
172 {
|
|
173 if ((GET_CODE (mem_src) == ZERO_EXTEND)
|
|
174 || (GET_CODE (mem_src) == SIGN_EXTEND))
|
|
175 mem_src = XEXP (mem_src, 0);
|
|
176
|
|
177 if ((GET_CODE (XEXP (mem_src, 0)) == PLUS))
|
|
178 mem_src = XEXP (mem_src, 0);
|
|
179 else
|
|
180 return false;
|
|
181
|
|
182 if (GET_CODE (XEXP (mem_src, 0)) == REG)
|
|
183 return true;
|
|
184
|
|
185 }
|
|
186
|
|
187 return false;
|
|
188 }
|
|
189
|
|
190 /* Return true if x is const and the referance is ict symbol. */
|
|
191 static bool
|
|
192 nds32_ict_const_p (rtx x)
|
|
193 {
|
|
194 if (GET_CODE (x) == CONST)
|
|
195 {
|
|
196 x = XEXP (x, 0);
|
|
197 return nds32_indirect_call_referenced_p (x);
|
|
198 }
|
|
199 return FALSE;
|
|
200 }
|
|
201
|
|
202 /* Group the following pattern as relax candidates:
|
|
203
|
|
204 GOT:
|
|
205 sethi $ra, hi20(sym)
|
|
206 ori $ra, $ra, lo12(sym)
|
|
207 lw $rb, [$ra + $gp]
|
|
208
|
|
209 GOTOFF, TLSLE:
|
|
210 sethi $ra, hi20(sym)
|
|
211 ori $ra, $ra, lo12(sym)
|
|
212 LS $rb, [$ra + $gp]
|
|
213
|
|
214 GOTOFF, TLSLE:
|
|
215 sethi $ra, hi20(sym)
|
|
216 ori $ra, $ra, lo12(sym)
|
|
217 add $rb, $ra, $gp($tp)
|
|
218
|
|
219 Initial GOT table:
|
|
220 sethi $gp,hi20(sym)
|
|
221 ori $gp, $gp, lo12(sym)
|
|
222 add5.pc $gp */
|
|
223
|
|
224 static auto_vec<rtx_insn *, 32> nds32_group_infos;
|
|
225 /* Group the PIC and TLS relax candidate instructions for linker. */
|
|
226 static bool
|
|
227 nds32_pic_tls_group (rtx_insn *def_insn,
|
|
228 enum nds32_relax_insn_type relax_type,
|
|
229 int sym_type)
|
|
230 {
|
|
231 df_ref def_record;
|
|
232 df_link *link;
|
|
233 rtx_insn *use_insn = NULL;
|
|
234 rtx pat, new_pat;
|
|
235 def_record = DF_INSN_DEFS (def_insn);
|
|
236 for (link = DF_REF_CHAIN (def_record); link; link = link->next)
|
|
237 {
|
|
238 if (!DF_REF_INSN_INFO (link->ref))
|
|
239 continue;
|
|
240
|
|
241 use_insn = DF_REF_INSN (link->ref);
|
|
242
|
|
243 /* Skip if define insn and use insn not in the same basic block. */
|
|
244 if (!dominated_by_p (CDI_DOMINATORS,
|
|
245 BLOCK_FOR_INSN (use_insn),
|
|
246 BLOCK_FOR_INSN (def_insn)))
|
|
247 return FALSE;
|
|
248
|
|
249 /* Skip if use_insn not active insn. */
|
|
250 if (!active_insn_p (use_insn))
|
|
251 return FALSE;
|
|
252
|
|
253 switch (relax_type)
|
|
254 {
|
|
255 case RELAX_ORI:
|
|
256
|
|
257 /* GOTOFF, TLSLE:
|
|
258 sethi $ra, hi20(sym)
|
|
259 ori $ra, $ra, lo12(sym)
|
|
260 add $rb, $ra, $gp($tp) */
|
|
261 if ((sym_type == UNSPEC_TLSLE
|
|
262 || sym_type == UNSPEC_GOTOFF)
|
|
263 && (recog_memoized (use_insn) == CODE_FOR_addsi3))
|
|
264 {
|
|
265 pat = XEXP (PATTERN (use_insn), 1);
|
|
266 new_pat =
|
|
267 gen_rtx_UNSPEC (SImode,
|
|
268 gen_rtvec (2, XEXP (pat, 0), XEXP (pat, 1)),
|
|
269 UNSPEC_ADD32);
|
|
270 validate_replace_rtx (pat, new_pat, use_insn);
|
|
271 nds32_group_infos.safe_push (use_insn);
|
|
272 }
|
|
273 else if (nds32_plus_reg_load_store_p (use_insn)
|
|
274 && !nds32_sp_base_or_plus_load_store_p (use_insn))
|
|
275 nds32_group_infos.safe_push (use_insn);
|
|
276 else
|
|
277 return FALSE;
|
|
278 break;
|
|
279
|
|
280 default:
|
|
281 return FALSE;
|
|
282 }
|
|
283 }
|
|
284 return TRUE;
|
|
285 }
|
|
286
|
|
287 static int
|
|
288 nds32_pic_tls_symbol_type (rtx x)
|
|
289 {
|
|
290 x = XEXP (SET_SRC (PATTERN (x)), 1);
|
|
291
|
|
292 if (GET_CODE (x) == CONST)
|
|
293 {
|
|
294 x = XEXP (x, 0);
|
|
295
|
|
296 if (GET_CODE (x) == PLUS)
|
|
297 x = XEXP (x, 0);
|
|
298
|
|
299 return XINT (x, 1);
|
|
300 }
|
|
301
|
|
302 return XINT (x, 1);
|
|
303 }
|
|
304
|
|
305 /* Group the relax candidates with group id. */
|
|
306 static void
|
|
307 nds32_group_insns (rtx_insn *sethi)
|
|
308 {
|
|
309 df_ref def_record, use_record;
|
|
310 df_link *link;
|
|
311 rtx_insn *use_insn = NULL;
|
|
312 rtx group_id;
|
|
313 bool valid;
|
|
314
|
|
315 def_record = DF_INSN_DEFS (sethi);
|
|
316
|
|
317 for (link = DF_REF_CHAIN (def_record); link; link = link->next)
|
|
318 {
|
|
319 if (!DF_REF_INSN_INFO (link->ref))
|
|
320 continue;
|
|
321
|
|
322 use_insn = DF_REF_INSN (link->ref);
|
|
323
|
|
324 /* Skip if define insn and use insn not in the same basic block. */
|
|
325 if (!dominated_by_p (CDI_DOMINATORS,
|
|
326 BLOCK_FOR_INSN (use_insn),
|
|
327 BLOCK_FOR_INSN (sethi)))
|
|
328 return;
|
|
329
|
|
330 /* Skip if the low-part used register is from different high-part
|
|
331 instructions. */
|
|
332 use_record = DF_INSN_USES (use_insn);
|
|
333 if (DF_REF_CHAIN (use_record) && DF_REF_CHAIN (use_record)->next)
|
|
334 return;
|
|
335
|
|
336 /* Skip if use_insn not active insn. */
|
|
337 if (!active_insn_p (use_insn))
|
|
338 return;
|
|
339
|
|
340 /* Initial use_insn_type. */
|
|
341 if (!(recog_memoized (use_insn) == CODE_FOR_lo_sum
|
|
342 || nds32_symbol_load_store_p (use_insn)
|
|
343 || (nds32_reg_base_load_store_p (use_insn)
|
|
344 &&!nds32_sp_base_or_plus_load_store_p (use_insn))))
|
|
345 return;
|
|
346 }
|
|
347
|
|
348 group_id = GEN_INT (relax_group_id);
|
|
349 /* Insert .relax_* directive for sethi. */
|
|
350 emit_insn_before (gen_relax_group (group_id), sethi);
|
|
351
|
|
352 /* Scan the use insns and insert the directive. */
|
|
353 for (link = DF_REF_CHAIN (def_record); link; link = link->next)
|
|
354 {
|
|
355 if (!DF_REF_INSN_INFO (link->ref))
|
|
356 continue;
|
|
357
|
|
358 use_insn = DF_REF_INSN (link->ref);
|
|
359
|
|
360 /* Insert .relax_* directive. */
|
|
361 if (active_insn_p (use_insn))
|
|
362 emit_insn_before (gen_relax_group (group_id), use_insn);
|
|
363
|
|
364 /* Find ori ra, ra, unspec(symbol) instruction. */
|
|
365 if (use_insn != NULL
|
|
366 && recog_memoized (use_insn) == CODE_FOR_lo_sum
|
|
367 && !nds32_const_unspec_p (XEXP (SET_SRC (PATTERN (use_insn)), 1)))
|
|
368 {
|
|
369 int sym_type = nds32_pic_tls_symbol_type (use_insn);
|
|
370 valid = nds32_pic_tls_group (use_insn, RELAX_ORI, sym_type);
|
|
371
|
|
372 /* Insert .relax_* directive. */
|
|
373 while (!nds32_group_infos.is_empty ())
|
|
374 {
|
|
375 use_insn = nds32_group_infos.pop ();
|
|
376 if (valid)
|
|
377 emit_insn_before (gen_relax_group (group_id), use_insn);
|
|
378 }
|
|
379 }
|
|
380 }
|
|
381
|
|
382 relax_group_id++;
|
|
383 }
|
|
384
|
|
385 /* Convert relax group id in rtl. */
|
|
386
|
|
387 static void
|
|
388 nds32_group_tls_insn (rtx insn)
|
|
389 {
|
|
390 rtx pat = PATTERN (insn);
|
|
391 rtx unspec_relax_group = XEXP (XVECEXP (pat, 0, 1), 0);
|
|
392
|
|
393 while (GET_CODE (pat) != SET && GET_CODE (pat) == PARALLEL)
|
|
394 {
|
|
395 pat = XVECEXP (pat, 0, 0);
|
|
396 }
|
|
397
|
|
398 if (GET_CODE (unspec_relax_group) == UNSPEC
|
|
399 && XINT (unspec_relax_group, 1) == UNSPEC_VOLATILE_RELAX_GROUP)
|
|
400 {
|
|
401 XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (relax_group_id);
|
|
402 }
|
|
403
|
|
404 relax_group_id++;
|
|
405 }
|
|
406
|
|
407 static bool
|
|
408 nds32_float_reg_load_store_p (rtx_insn *insn)
|
|
409 {
|
|
410 rtx pat = PATTERN (insn);
|
|
411
|
|
412 if (get_attr_type (insn) == TYPE_FLOAD
|
|
413 && GET_CODE (pat) == SET
|
|
414 && (GET_MODE (XEXP (pat, 0)) == SFmode
|
|
415 || GET_MODE (XEXP (pat, 0)) == DFmode)
|
|
416 && MEM_P (XEXP (pat, 1)))
|
|
417 {
|
|
418 rtx addr = XEXP (XEXP (pat, 1), 0);
|
|
419
|
|
420 /* [$ra] */
|
|
421 if (REG_P (addr))
|
|
422 return true;
|
|
423 /* [$ra + offset] */
|
|
424 if (GET_CODE (addr) == PLUS
|
|
425 && REG_P (XEXP (addr, 0))
|
|
426 && CONST_INT_P (XEXP (addr, 1)))
|
|
427 return true;
|
|
428 }
|
|
429 return false;
|
|
430 }
|
|
431
|
|
432
|
|
433 /* Group float load-store instructions:
|
|
434 la $ra, symbol
|
|
435 flsi $rt, [$ra + offset] */
|
|
436
|
|
437 static void
|
|
438 nds32_group_float_insns (rtx_insn *insn)
|
|
439 {
|
|
440 df_ref def_record, use_record;
|
|
441 df_link *link;
|
|
442 rtx_insn *use_insn = NULL;
|
|
443 rtx group_id;
|
|
444
|
|
445 def_record = DF_INSN_DEFS (insn);
|
|
446
|
|
447 for (link = DF_REF_CHAIN (def_record); link; link = link->next)
|
|
448 {
|
|
449 if (!DF_REF_INSN_INFO (link->ref))
|
|
450 continue;
|
|
451
|
|
452 use_insn = DF_REF_INSN (link->ref);
|
|
453
|
|
454 /* Skip if define insn and use insn not in the same basic block. */
|
|
455 if (!dominated_by_p (CDI_DOMINATORS,
|
|
456 BLOCK_FOR_INSN (use_insn),
|
|
457 BLOCK_FOR_INSN (insn)))
|
|
458 return;
|
|
459
|
|
460 /* Skip if the low-part used register is from different high-part
|
|
461 instructions. */
|
|
462 use_record = DF_INSN_USES (use_insn);
|
|
463 if (DF_REF_CHAIN (use_record) && DF_REF_CHAIN (use_record)->next)
|
|
464 return;
|
|
465
|
|
466 /* Skip if use_insn not active insn. */
|
|
467 if (!active_insn_p (use_insn))
|
|
468 return;
|
|
469
|
|
470 if (!nds32_float_reg_load_store_p (use_insn)
|
|
471 || find_post_update_rtx (use_insn) != -1)
|
|
472 return;
|
|
473 }
|
|
474
|
|
475 group_id = GEN_INT (relax_group_id);
|
|
476 /* Insert .relax_* directive for insn. */
|
|
477 emit_insn_before (gen_relax_group (group_id), insn);
|
|
478
|
|
479 /* Scan the use insns and insert the directive. */
|
|
480 for (link = DF_REF_CHAIN (def_record); link; link = link->next)
|
|
481 {
|
|
482 if (!DF_REF_INSN_INFO (link->ref))
|
|
483 continue;
|
|
484
|
|
485 use_insn = DF_REF_INSN (link->ref);
|
|
486
|
|
487 /* Insert .relax_* directive. */
|
|
488 emit_insn_before (gen_relax_group (group_id), use_insn);
|
|
489 }
|
|
490
|
|
491 relax_group_id++;
|
|
492 }
|
|
493
|
|
494 /* Group the relax candidate instructions for linker. */
|
|
495 static void
|
|
496 nds32_relax_group (void)
|
|
497 {
|
|
498 rtx_insn *insn;
|
|
499
|
|
500 compute_bb_for_insn ();
|
|
501
|
|
502 df_chain_add_problem (DF_DU_CHAIN | DF_UD_CHAIN);
|
|
503 df_insn_rescan_all ();
|
|
504 df_analyze ();
|
|
505 df_set_flags (DF_DEFER_INSN_RESCAN);
|
|
506 calculate_dominance_info (CDI_DOMINATORS);
|
|
507
|
|
508 insn = get_insns ();
|
|
509 gcc_assert (NOTE_P (insn));
|
|
510
|
|
511 for (insn = next_active_insn (insn); insn; insn = next_active_insn (insn))
|
|
512 {
|
|
513 if (NONJUMP_INSN_P (insn))
|
|
514 {
|
|
515 /* Find sethi ra, symbol instruction. */
|
|
516 if (recog_memoized (insn) == CODE_FOR_sethi
|
|
517 && nds32_symbolic_operand (XEXP (SET_SRC (PATTERN (insn)), 0),
|
|
518 SImode)
|
|
519 && !nds32_ict_const_p (XEXP (SET_SRC (PATTERN (insn)), 0)))
|
|
520 nds32_group_insns (insn);
|
|
521 else if (recog_memoized (insn) == CODE_FOR_tls_ie)
|
|
522 nds32_group_tls_insn (insn);
|
|
523 else if (TARGET_FPU_SINGLE
|
|
524 && recog_memoized (insn) == CODE_FOR_move_addr
|
|
525 && !nds32_ict_const_p (XEXP (SET_SRC (PATTERN (insn)), 0)))
|
|
526 {
|
|
527 nds32_group_float_insns (insn);
|
|
528 }
|
|
529 }
|
|
530 else if (CALL_P (insn) && recog_memoized (insn) == CODE_FOR_tls_desc)
|
|
531 {
|
|
532 nds32_group_tls_insn (insn);
|
|
533 }
|
|
534 }
|
|
535
|
|
536 /* We must call df_finish_pass manually because it should be invoked before
|
|
537 BB information is destroyed. Hence we cannot set the TODO_df_finish flag
|
|
538 to the pass manager. */
|
|
539 df_insn_rescan_all ();
|
|
540 df_finish_pass (false);
|
|
541 free_dominance_info (CDI_DOMINATORS);
|
|
542 }
|
|
543
|
|
544 static unsigned int
|
|
545 nds32_relax_opt (void)
|
|
546 {
|
|
547 if (TARGET_RELAX_HINT)
|
|
548 nds32_relax_group ();
|
|
549 return 1;
|
|
550 }
|
|
551
|
|
552 const pass_data pass_data_nds32_relax_opt =
|
|
553 {
|
|
554 RTL_PASS, /* type */
|
|
555 "relax_opt", /* name */
|
|
556 OPTGROUP_NONE, /* optinfo_flags */
|
|
557 TV_MACH_DEP, /* tv_id */
|
|
558 0, /* properties_required */
|
|
559 0, /* properties_provided */
|
|
560 0, /* properties_destroyed */
|
|
561 0, /* todo_flags_start */
|
|
562 TODO_df_finish, /* todo_flags_finish */
|
|
563 };
|
|
564
|
|
565 class pass_nds32_relax_opt : public rtl_opt_pass
|
|
566 {
|
|
567 public:
|
|
568 pass_nds32_relax_opt (gcc::context *ctxt)
|
|
569 : rtl_opt_pass (pass_data_nds32_relax_opt, ctxt)
|
|
570 {}
|
|
571
|
|
572 /* opt_pass methods: */
|
|
573 bool gate (function *) { return TARGET_RELAX_HINT; }
|
|
574 unsigned int execute (function *) { return nds32_relax_opt (); }
|
|
575 };
|
|
576
|
|
577 rtl_opt_pass *
|
|
578 make_pass_nds32_relax_opt (gcc::context *ctxt)
|
|
579 {
|
|
580 return new pass_nds32_relax_opt (ctxt);
|
|
581 }
|