Mercurial > hg > CbC > CbC_gcc
comparison gcc/genpeep.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Generate code from machine description to perform peephole optimizations. | 1 /* Generate code from machine description to perform peephole optimizations. |
2 Copyright (C) 1987, 1989, 1992, 1997, 1998, 1999, 2000, 2003, 2004, | 2 Copyright (C) 1987-2017 Free Software Foundation, Inc. |
3 2007, 2010 Free Software Foundation, Inc. | |
4 | 3 |
5 This file is part of GCC. | 4 This file is part of GCC. |
6 | 5 |
7 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
8 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
45 | 44 |
46 /* Number of operands used in current peephole definition. */ | 45 /* Number of operands used in current peephole definition. */ |
47 | 46 |
48 static int n_operands; | 47 static int n_operands; |
49 | 48 |
50 /* Peephole optimizations get insn codes just like insn patterns. | |
51 Count them so we know the code of the define_peephole we are handling. */ | |
52 | |
53 static int insn_code_number = 0; | |
54 | |
55 static void gen_peephole (rtx); | |
56 static void match_rtx (rtx, struct link *, int); | 49 static void match_rtx (rtx, struct link *, int); |
57 static void print_path (struct link *); | 50 static void print_path (struct link *); |
58 static void print_code (RTX_CODE); | 51 static void print_code (RTX_CODE); |
59 | 52 |
60 static void | 53 static void |
61 gen_peephole (rtx peep) | 54 gen_peephole (md_rtx_info *info) |
62 { | 55 { |
56 rtx peep = info->def; | |
63 int ninsns = XVECLEN (peep, 0); | 57 int ninsns = XVECLEN (peep, 0); |
64 int i; | 58 int i; |
65 | 59 |
66 n_operands = 0; | 60 n_operands = 0; |
67 | 61 |
70 for (i = 0; i < ninsns; i++) | 64 for (i = 0; i < ninsns; i++) |
71 { | 65 { |
72 if (i > 0) | 66 if (i > 0) |
73 { | 67 { |
74 printf (" do { insn = NEXT_INSN (insn);\n"); | 68 printf (" do { insn = NEXT_INSN (insn);\n"); |
75 printf (" if (insn == 0) goto L%d; }\n", | 69 printf (" if (insn == 0) goto L%d; }\n", info->index); |
76 insn_code_number); | |
77 printf (" while (NOTE_P (insn)\n"); | 70 printf (" while (NOTE_P (insn)\n"); |
78 printf ("\t || (NONJUMP_INSN_P (insn)\n"); | 71 printf ("\t || (NONJUMP_INSN_P (insn)\n"); |
79 printf ("\t && (GET_CODE (PATTERN (insn)) == USE\n"); | 72 printf ("\t && (GET_CODE (PATTERN (insn)) == USE\n"); |
80 printf ("\t\t || GET_CODE (PATTERN (insn)) == CLOBBER)));\n"); | 73 printf ("\t\t || GET_CODE (PATTERN (insn)) == CLOBBER)));\n"); |
81 | 74 |
82 printf (" if (LABEL_P (insn)\n\ | 75 printf (" if (LABEL_P (insn)\n\ |
83 || BARRIER_P (insn))\n goto L%d;\n", | 76 || BARRIER_P (insn))\n goto L%d;\n", info->index); |
84 insn_code_number); | |
85 } | 77 } |
86 | 78 |
87 printf (" pat = PATTERN (insn);\n"); | 79 printf (" pat = PATTERN (insn);\n"); |
88 | 80 |
89 /* Walk the insn's pattern, remembering at all times the path | 81 /* Walk the insn's pattern, remembering at all times the path |
90 down to the walking point. */ | 82 down to the walking point. */ |
91 | 83 |
92 match_rtx (XVECEXP (peep, 0, i), NULL, insn_code_number); | 84 match_rtx (XVECEXP (peep, 0, i), NULL, info->index); |
93 } | 85 } |
94 | 86 |
95 /* We get this far if the pattern matches. | 87 /* We get this far if the pattern matches. |
96 Now test the extra condition. */ | 88 Now test the extra condition. */ |
97 | 89 |
98 if (XSTR (peep, 1) && XSTR (peep, 1)[0]) | 90 if (XSTR (peep, 1) && XSTR (peep, 1)[0]) |
99 printf (" if (! (%s)) goto L%d;\n", | 91 printf (" if (! (%s)) goto L%d;\n", |
100 XSTR (peep, 1), insn_code_number); | 92 XSTR (peep, 1), info->index); |
101 | 93 |
102 /* If that matches, construct new pattern and put it in the first insn. | 94 /* If that matches, construct new pattern and put it in the first insn. |
103 This new pattern will never be matched. | 95 This new pattern will never be matched. |
104 It exists only so that insn-extract can get the operands back. | 96 It exists only so that insn-extract can get the operands back. |
105 So use a simple regular form: a PARALLEL containing a vector | 97 So use a simple regular form: a PARALLEL containing a vector |
107 | 99 |
108 printf (" PATTERN (ins1) = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (%d, operands));\n", n_operands); | 100 printf (" PATTERN (ins1) = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (%d, operands));\n", n_operands); |
109 | 101 |
110 /* Record this define_peephole's insn code in the insn, | 102 /* Record this define_peephole's insn code in the insn, |
111 as if it had been recognized to match this. */ | 103 as if it had been recognized to match this. */ |
112 printf (" INSN_CODE (ins1) = %d;\n", | 104 printf (" INSN_CODE (ins1) = %d;\n", info->index); |
113 insn_code_number); | |
114 | 105 |
115 /* Delete the remaining insns. */ | 106 /* Delete the remaining insns. */ |
116 if (ninsns > 1) | 107 if (ninsns > 1) |
117 printf (" delete_for_peephole (NEXT_INSN (ins1), insn);\n"); | 108 printf (" delete_for_peephole (NEXT_INSN (ins1), insn);\n"); |
118 | 109 |
119 /* See reload1.c for insertion of NOTE which guarantees that this | 110 /* See reload1.c for insertion of NOTE which guarantees that this |
120 cannot be zero. */ | 111 cannot be zero. */ |
121 printf (" return NEXT_INSN (insn);\n"); | 112 printf (" return NEXT_INSN (insn);\n"); |
122 | 113 |
123 printf (" L%d:\n\n", insn_code_number); | 114 printf (" L%d:\n\n", info->index); |
124 } | 115 } |
125 | 116 |
126 static void | 117 static void |
127 match_rtx (rtx x, struct link *path, int fail_label) | 118 match_rtx (rtx x, struct link *path, int fail_label) |
128 { | 119 { |
229 link.vecelt = i; | 220 link.vecelt = i; |
230 match_rtx (XVECEXP (x, 2, i), &link, fail_label); | 221 match_rtx (XVECEXP (x, 2, i), &link, fail_label); |
231 } | 222 } |
232 return; | 223 return; |
233 | 224 |
234 case ADDRESS: | |
235 match_rtx (XEXP (x, 0), path, fail_label); | |
236 return; | |
237 | |
238 default: | 225 default: |
239 break; | 226 break; |
240 } | 227 } |
241 | 228 |
242 printf (" x = "); | 229 printf (" x = "); |
284 } | 271 } |
285 | 272 |
286 printf (" if (XINT (x, %d) != %d) goto L%d;\n", | 273 printf (" if (XINT (x, %d) != %d) goto L%d;\n", |
287 i, XINT (x, i), fail_label); | 274 i, XINT (x, i), fail_label); |
288 } | 275 } |
276 else if (fmt[i] == 'r') | |
277 { | |
278 gcc_assert (i == 0); | |
279 printf (" if (REGNO (x) != %d) goto L%d;\n", | |
280 REGNO (x), fail_label); | |
281 } | |
289 else if (fmt[i] == 'w') | 282 else if (fmt[i] == 'w') |
290 { | 283 { |
291 /* Make sure that at run time `x' is the RTX we want to test. */ | 284 /* Make sure that at run time `x' is the RTX we want to test. */ |
292 if (i != 0) | 285 if (i != 0) |
293 { | 286 { |
342 static void | 335 static void |
343 print_code (RTX_CODE code) | 336 print_code (RTX_CODE code) |
344 { | 337 { |
345 const char *p1; | 338 const char *p1; |
346 for (p1 = GET_RTX_NAME (code); *p1; p1++) | 339 for (p1 = GET_RTX_NAME (code); *p1; p1++) |
347 putchar (TOUPPER(*p1)); | 340 putchar (TOUPPER (*p1)); |
348 } | 341 } |
349 | 342 |
350 extern int main (int, char **); | 343 extern int main (int, const char **); |
351 | 344 |
352 int | 345 int |
353 main (int argc, char **argv) | 346 main (int argc, const char **argv) |
354 { | 347 { |
355 rtx desc; | |
356 | |
357 max_opno = -1; | 348 max_opno = -1; |
358 | 349 |
359 progname = "genpeep"; | 350 progname = "genpeep"; |
360 | 351 |
361 if (!init_rtx_reader_args (argc, argv)) | 352 if (!init_rtx_reader_args (argc, argv)) |
365 from the machine description file `md'. */\n\n"); | 356 from the machine description file `md'. */\n\n"); |
366 | 357 |
367 printf ("#include \"config.h\"\n"); | 358 printf ("#include \"config.h\"\n"); |
368 printf ("#include \"system.h\"\n"); | 359 printf ("#include \"system.h\"\n"); |
369 printf ("#include \"coretypes.h\"\n"); | 360 printf ("#include \"coretypes.h\"\n"); |
370 printf ("#include \"tm.h\"\n"); | 361 printf ("#include \"backend.h\"\n"); |
362 printf ("#include \"tree.h\"\n"); | |
363 printf ("#include \"rtl.h\"\n"); | |
371 printf ("#include \"insn-config.h\"\n"); | 364 printf ("#include \"insn-config.h\"\n"); |
372 printf ("#include \"rtl.h\"\n"); | 365 printf ("#include \"alias.h\"\n"); |
366 printf ("#include \"varasm.h\"\n"); | |
367 printf ("#include \"stor-layout.h\"\n"); | |
368 printf ("#include \"calls.h\"\n"); | |
369 printf ("#include \"memmodel.h\"\n"); | |
373 printf ("#include \"tm_p.h\"\n"); | 370 printf ("#include \"tm_p.h\"\n"); |
374 printf ("#include \"regs.h\"\n"); | 371 printf ("#include \"regs.h\"\n"); |
375 printf ("#include \"output.h\"\n"); | 372 printf ("#include \"output.h\"\n"); |
376 printf ("#include \"recog.h\"\n"); | 373 printf ("#include \"recog.h\"\n"); |
377 printf ("#include \"except.h\"\n"); | 374 printf ("#include \"except.h\"\n"); |
378 printf ("#include \"function.h\"\n"); | |
379 printf ("#include \"diagnostic-core.h\"\n"); | 375 printf ("#include \"diagnostic-core.h\"\n"); |
380 printf ("#include \"flags.h\"\n"); | 376 printf ("#include \"flags.h\"\n"); |
381 printf ("#include \"tm-constrs.h\"\n\n"); | 377 printf ("#include \"tm-constrs.h\"\n\n"); |
382 | 378 |
383 printf ("#ifdef HAVE_peephole\n"); | |
384 printf ("extern rtx peep_operand[];\n\n"); | 379 printf ("extern rtx peep_operand[];\n\n"); |
385 printf ("#define operands peep_operand\n\n"); | 380 printf ("#define operands peep_operand\n\n"); |
386 | 381 |
387 printf ("rtx\npeephole (rtx ins1)\n{\n"); | 382 printf ("rtx_insn *\npeephole (rtx_insn *ins1)\n{\n"); |
388 printf (" rtx insn ATTRIBUTE_UNUSED, x ATTRIBUTE_UNUSED, pat ATTRIBUTE_UNUSED;\n\n"); | 383 printf (" rtx_insn *insn ATTRIBUTE_UNUSED;\n"); |
384 printf (" rtx x ATTRIBUTE_UNUSED, pat ATTRIBUTE_UNUSED;\n\n"); | |
389 | 385 |
390 /* Early out: no peepholes for insns followed by barriers. */ | 386 /* Early out: no peepholes for insns followed by barriers. */ |
391 printf (" if (NEXT_INSN (ins1)\n"); | 387 printf (" if (NEXT_INSN (ins1)\n"); |
392 printf (" && BARRIER_P (NEXT_INSN (ins1)))\n"); | 388 printf (" && BARRIER_P (NEXT_INSN (ins1)))\n"); |
393 printf (" return 0;\n\n"); | 389 printf (" return 0;\n\n"); |
394 | 390 |
395 /* Read the machine description. */ | 391 /* Read the machine description. */ |
396 | 392 |
397 while (1) | 393 md_rtx_info info; |
398 { | 394 while (read_md_rtx (&info)) |
399 int line_no, rtx_number = 0; | 395 switch (GET_CODE (info.def)) |
400 | 396 { |
401 desc = read_md_rtx (&line_no, &rtx_number); | 397 case DEFINE_PEEPHOLE: |
402 if (desc == NULL) | 398 gen_peephole (&info); |
403 break; | 399 break; |
404 | 400 |
405 if (GET_CODE (desc) == DEFINE_PEEPHOLE) | 401 default: |
406 { | 402 break; |
407 gen_peephole (desc); | 403 } |
408 insn_code_number++; | |
409 } | |
410 if (GET_CODE (desc) == DEFINE_INSN | |
411 || GET_CODE (desc) == DEFINE_EXPAND | |
412 || GET_CODE (desc) == DEFINE_SPLIT | |
413 || GET_CODE (desc) == DEFINE_PEEPHOLE2) | |
414 { | |
415 insn_code_number++; | |
416 } | |
417 } | |
418 | 404 |
419 printf (" return 0;\n}\n\n"); | 405 printf (" return 0;\n}\n\n"); |
420 | 406 |
421 if (max_opno == -1) | 407 if (max_opno == -1) |
422 max_opno = 1; | 408 max_opno = 1; |
423 | 409 |
424 printf ("rtx peep_operand[%d];\n", max_opno + 1); | 410 printf ("rtx peep_operand[%d];\n", max_opno + 1); |
425 printf ("#endif\n"); | |
426 | 411 |
427 fflush (stdout); | 412 fflush (stdout); |
428 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); | 413 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); |
429 } | 414 } |