Line data Source code
1 : /* Expands front end tree to back end RTL for GCC
2 : Copyright (C) 1987-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : /* This file handles the generation of rtl code from tree structure
21 : above the level of expressions, using subroutines in exp*.c and emit-rtl.cc.
22 : The functions whose names start with `expand_' are called by the
23 : expander to generate RTL instructions for various kinds of constructs. */
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 "gimple.h"
33 : #include "cfghooks.h"
34 : #include "predict.h"
35 : #include "memmodel.h"
36 : #include "tm_p.h"
37 : #include "optabs.h"
38 : #include "regs.h"
39 : #include "emit-rtl.h"
40 : #include "pretty-print.h"
41 : #include "diagnostic-core.h"
42 : #include "output.h"
43 : #include "gimplify_reg_info.h"
44 :
45 : #include "fold-const.h"
46 : #include "varasm.h"
47 : #include "stor-layout.h"
48 : #include "dojump.h"
49 : #include "explow.h"
50 : #include "stmt.h"
51 : #include "expr.h"
52 : #include "langhooks.h"
53 : #include "cfganal.h"
54 : #include "tree-cfg.h"
55 : #include "dumpfile.h"
56 : #include "builtins.h"
57 : #include "cfgexpand.h"
58 : #include "output.h"
59 :
60 :
61 : /* Functions and data structures for expanding case statements. */
62 :
63 : /* Case label structure, used to hold info on labels within case
64 : statements. We handle "range" labels; for a single-value label
65 : as in C, the high and low limits are the same.
66 :
67 : We start with a vector of case nodes sorted in ascending order, and
68 : the default label as the last element in the vector.
69 :
70 : Switch statements are expanded in jump table form.
71 :
72 : */
73 :
74 : class simple_case_node
75 : {
76 : public:
77 79052 : simple_case_node (tree low, tree high, tree code_label):
78 79052 : m_low (low), m_high (high), m_code_label (code_label)
79 : {}
80 :
81 : /* Lowest index value for this label. */
82 : tree m_low;
83 : /* Highest index value for this label. */
84 : tree m_high;
85 : /* Label to jump to when node matches. */
86 : tree m_code_label;
87 : };
88 :
89 : static bool check_unique_operand_names (tree, tree, tree);
90 : static char *resolve_operand_name_1 (char *, tree, tree, tree);
91 :
92 : /* Return the rtx-label that corresponds to a LABEL_DECL,
93 : creating it if necessary. */
94 :
95 : rtx_insn *
96 2561847 : label_rtx (tree label)
97 : {
98 2561847 : gcc_assert (TREE_CODE (label) == LABEL_DECL);
99 :
100 2561847 : if (!DECL_RTL_SET_P (label))
101 : {
102 622783 : rtx_code_label *r = gen_label_rtx ();
103 622783 : SET_DECL_RTL (label, r);
104 622783 : if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
105 26407 : LABEL_PRESERVE_P (r) = 1;
106 : }
107 :
108 2561847 : return as_a <rtx_insn *> (DECL_RTL (label));
109 : }
110 :
111 : /* As above, but also put it on the forced-reference list of the
112 : function that contains it. */
113 : rtx_insn *
114 0 : force_label_rtx (tree label)
115 : {
116 0 : rtx_insn *ref = label_rtx (label);
117 0 : tree function = decl_function_context (label);
118 :
119 0 : gcc_assert (function);
120 :
121 0 : vec_safe_push (forced_labels, ref);
122 0 : return ref;
123 : }
124 :
125 : /* As label_rtx, but ensures (in check build), that returned value is
126 : an existing label (i.e. rtx with code CODE_LABEL). */
127 : rtx_code_label *
128 842397 : jump_target_rtx (tree label)
129 : {
130 842397 : return as_a <rtx_code_label *> (label_rtx (label));
131 : }
132 :
133 : /* Add an unconditional jump to LABEL as the next sequential instruction. */
134 :
135 : void
136 3152123 : emit_jump (rtx label)
137 : {
138 3152123 : do_pending_stack_adjust ();
139 3152123 : emit_jump_insn (targetm.gen_jump (label));
140 3152123 : emit_barrier ();
141 3152123 : }
142 :
143 : /* Handle goto statements and the labels that they can go to. */
144 :
145 : /* Specify the location in the RTL code of a label LABEL,
146 : which is a LABEL_DECL tree node.
147 :
148 : This is used for the kind of label that the user can jump to with a
149 : goto statement, and for alternatives of a switch or case statement.
150 : RTL labels generated for loops and conditionals don't go through here;
151 : they are generated directly at the RTL level, by other functions below.
152 :
153 : Note that this has nothing to do with defining label *names*.
154 : Languages vary in how they do that and what that even means. */
155 :
156 : void
157 622783 : expand_label (tree label)
158 : {
159 622783 : rtx_code_label *label_r = jump_target_rtx (label);
160 :
161 622783 : do_pending_stack_adjust ();
162 622783 : emit_label (label_r);
163 622783 : if (DECL_NAME (label))
164 115306 : LABEL_NAME (DECL_RTL (label)) = IDENTIFIER_POINTER (DECL_NAME (label));
165 :
166 622783 : if (DECL_NONLOCAL (label))
167 : {
168 504 : expand_builtin_setjmp_receiver (NULL);
169 504 : nonlocal_goto_handler_labels
170 504 : = gen_rtx_INSN_LIST (VOIDmode, label_r,
171 504 : nonlocal_goto_handler_labels);
172 : }
173 :
174 622783 : if (FORCED_LABEL (label))
175 25903 : vec_safe_push<rtx_insn *> (forced_labels, label_r);
176 :
177 1245062 : if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
178 26407 : maybe_set_first_label_num (label_r);
179 622783 : }
180 :
181 : /* Parse a hard register constraint and return its number or -1 in case of an
182 : error. BEGIN should point to a string of the form `{regname}`. For the
183 : sake of simplicity assume that a register name is not longer than 31
184 : characters, if not error out. */
185 :
186 : int
187 1784 : decode_hard_reg_constraint (const char *begin)
188 : {
189 1784 : if (*begin != '{')
190 : return -1;
191 1784 : ++begin;
192 1784 : const char *end = begin;
193 7124 : while (*end != '}' && *end != '\0')
194 5340 : ++end;
195 1784 : if (*end != '}' || end == begin)
196 : return -1;
197 1782 : ptrdiff_t len = end - begin;
198 1782 : if (len >= 31)
199 : return -1;
200 1782 : char regname[32];
201 1782 : memcpy (regname, begin, len);
202 1782 : regname[len] = '\0';
203 1782 : int regno = decode_reg_name (regname);
204 1782 : return regno;
205 : }
206 :
207 : static bool
208 0 : eliminable_regno_p (int regnum)
209 : {
210 0 : static const struct
211 : {
212 : const int from;
213 : const int to;
214 : } eliminables[] = ELIMINABLE_REGS;
215 0 : for (size_t i = 0; i < ARRAY_SIZE (eliminables); i++)
216 0 : if (regnum == eliminables[i].from)
217 : return true;
218 : return false;
219 : }
220 :
221 : /* Perform a similar check as done in make_decl_rtl(). */
222 :
223 : static bool
224 189 : hardreg_ok_p (int reg_number, machine_mode mode, int operand_num)
225 : {
226 189 : if (mode == BLKmode)
227 1 : error ("data type isn%'t suitable for register %s of operand %i",
228 : reg_names[reg_number], operand_num);
229 188 : else if (!in_hard_reg_set_p (accessible_reg_set, mode, reg_number))
230 0 : error ("register %s for operand %i cannot be accessed"
231 : " by the current target", reg_names[reg_number], operand_num);
232 188 : else if (!in_hard_reg_set_p (operand_reg_set, mode, reg_number))
233 0 : error ("register %s for operand %i is not general enough"
234 : " to be used as a register variable", reg_names[reg_number], operand_num);
235 188 : else if (!targetm.hard_regno_mode_ok (reg_number, mode))
236 0 : error ("register %s for operand %i isn%'t suitable for data type",
237 : reg_names[reg_number], operand_num);
238 188 : else if (reg_number != HARD_FRAME_POINTER_REGNUM
239 188 : && (reg_number == FRAME_POINTER_REGNUM
240 : #ifdef RETURN_ADDRESS_POINTER_REGNUM
241 : || reg_number == RETURN_ADDRESS_POINTER_REGNUM
242 : #endif
243 188 : || reg_number == ARG_POINTER_REGNUM)
244 188 : && eliminable_regno_p (reg_number))
245 0 : error ("register for operand %i is an internal GCC "
246 : "implementation detail", operand_num);
247 : else
248 : return true;
249 : return false;
250 : }
251 :
252 : /* Parse the output constraint pointed to by *CONSTRAINT_P. It is the
253 : OPERAND_NUMth output operand, indexed from zero. There are NINPUTS
254 : inputs and NOUTPUTS outputs to this extended-asm. Upon return,
255 : *ALLOWS_MEM will be TRUE iff the constraint allows the use of a
256 : memory operand. Similarly, *ALLOWS_REG will be TRUE iff the
257 : constraint allows the use of a register operand. And, *IS_INOUT
258 : will be true if the operand is read-write, i.e., if it is used as
259 : an input as well as an output. If *CONSTRAINT_P is not in
260 : canonical form, it will be made canonical. (Note that `+' will be
261 : replaced with `=' as part of this process.)
262 :
263 : Returns TRUE if all went well; FALSE if an error occurred. */
264 :
265 : bool
266 33438787 : parse_output_constraint (const char **constraint_p, int operand_num,
267 : int ninputs, int noutputs, bool *allows_mem,
268 : bool *allows_reg, bool *is_inout,
269 : gimplify_reg_info *reg_info)
270 : {
271 33438787 : const char *constraint = *constraint_p;
272 33438787 : const char *p;
273 :
274 : /* Assume the constraint doesn't allow the use of either a register
275 : or memory. */
276 33438787 : *allows_mem = false;
277 33438787 : *allows_reg = false;
278 :
279 : /* Allow the `=' or `+' to not be at the beginning of the string,
280 : since it wasn't explicitly documented that way, and there is a
281 : large body of code that puts it last. Swap the character to
282 : the front, so as not to uglify any place else. */
283 33438787 : p = strchr (constraint, '=');
284 33438787 : if (!p)
285 17359 : p = strchr (constraint, '+');
286 :
287 : /* If the string doesn't contain an `=', issue an error
288 : message. */
289 17359 : if (!p)
290 : {
291 9 : error ("output operand constraint lacks %<=%>");
292 9 : return false;
293 : }
294 :
295 : /* If the constraint begins with `+', then the operand is both read
296 : from and written to. */
297 33438778 : *is_inout = (*p == '+');
298 :
299 : /* Canonicalize the output constraint so that it begins with `='. */
300 33438778 : if (p != constraint || *is_inout)
301 : {
302 17358 : char *buf;
303 17358 : size_t c_len = strlen (constraint);
304 :
305 17358 : if (p != constraint)
306 8 : warning (0, "output constraint %qc for operand %d "
307 : "is not at the beginning",
308 8 : *p, operand_num);
309 :
310 : /* Make a copy of the constraint. */
311 17358 : buf = XALLOCAVEC (char, c_len + 1);
312 17358 : strcpy (buf, constraint);
313 : /* Swap the first character and the `=' or `+'. */
314 17358 : buf[p - constraint] = buf[0];
315 : /* Make sure the first character is an `='. (Until we do this,
316 : it might be a `+'.) */
317 17358 : buf[0] = '=';
318 : /* Replace the constraint with the canonicalized string. */
319 17358 : *constraint_p = ggc_alloc_string (buf, c_len);
320 17358 : constraint = *constraint_p;
321 : }
322 :
323 33438778 : unsigned int alt = 0;
324 33438778 : bool early_clobbered = false;
325 : /* Currently, multiple hard register constraints in one alternative are not
326 : supported. A combination of hard register constraints and regular
327 : register constraints is also not supported. */
328 33438778 : bool alt_has_hard_reg_cstr = false;
329 33438778 : bool alt_has_reg_cstr = false;
330 :
331 : /* Loop through the constraint string. */
332 67704121 : for (p = constraint + 1; *p; )
333 : {
334 34265362 : switch (*p)
335 : {
336 0 : case '+':
337 0 : case '=':
338 0 : error ("operand constraint contains incorrectly positioned "
339 : "%<+%> or %<=%>");
340 0 : return false;
341 :
342 8 : case '%':
343 8 : if (operand_num + 1 == ninputs + noutputs)
344 : {
345 0 : error ("%<%%%> constraint used with last operand");
346 0 : return false;
347 : }
348 : break;
349 :
350 : case '&':
351 34265343 : early_clobbered = true;
352 : break;
353 :
354 : case '?': case '!': case '*': case '#':
355 : case '$': case '^':
356 : case 'E': case 'F': case 'G': case 'H':
357 : case 's': case 'i': case 'n':
358 : case 'I': case 'J': case 'K': case 'L': case 'M':
359 : case 'N': case 'O': case 'P': case '-':
360 : break;
361 :
362 86867 : case ',':
363 86867 : ++alt;
364 86867 : early_clobbered = false;
365 86867 : alt_has_hard_reg_cstr = false;
366 86867 : alt_has_reg_cstr = false;
367 86867 : break;
368 :
369 0 : case '0': case '1': case '2': case '3': case '4':
370 0 : case '5': case '6': case '7': case '8': case '9':
371 0 : case '[':
372 0 : error ("matching constraint not valid in output operand");
373 0 : return false;
374 :
375 8 : case ':':
376 8 : error ("%<:%> constraint used for output operand");
377 8 : return false;
378 :
379 0 : case '<': case '>':
380 : /* ??? Before flow, auto inc/dec insns are not supposed to exist,
381 : excepting those that expand_call created. So match memory
382 : and hope. */
383 0 : *allows_mem = true;
384 0 : break;
385 :
386 2029523 : case 'g': case 'X':
387 2029523 : *allows_reg = true;
388 2029523 : *allows_mem = true;
389 2029523 : break;
390 :
391 25736 : case '{':
392 25736 : {
393 25736 : if (!targetm.lra_p ())
394 : {
395 0 : error ("hard register constraints are only supported while using LRA");
396 0 : return false;
397 : }
398 25736 : if (reg_info)
399 : {
400 103 : if (alt_has_reg_cstr)
401 : {
402 1 : error (
403 : "hard register constraints and regular register "
404 : "constraints in one alternative are not supported");
405 1 : return false;
406 : }
407 102 : if (alt_has_hard_reg_cstr)
408 : {
409 2 : error (
410 : "multiple hard register constraints in one "
411 : "alternative are not supported");
412 2 : return false;
413 : }
414 100 : alt_has_hard_reg_cstr = true;
415 100 : int regno = decode_hard_reg_constraint (p);
416 100 : if (regno < 0)
417 : {
418 0 : error ("invalid output constraint: %s", p);
419 0 : return false;
420 : }
421 100 : int overlap_regno = reg_info->test_alt_output (alt, regno);
422 100 : if (overlap_regno < 0)
423 99 : overlap_regno = reg_info->test_reg_asm_output (regno);
424 99 : if (overlap_regno >= 0)
425 : {
426 1 : error ("multiple outputs to hard register: %s",
427 : reg_names[overlap_regno]);
428 1 : return false;
429 : }
430 99 : reg_info->set_output (alt, regno);
431 99 : if (early_clobbered)
432 16 : reg_info->set_early_clobbered (alt, operand_num, regno);
433 99 : if (reg_info->is_clobbered (regno))
434 : {
435 1 : error ("hard register constraint for output %i conflicts "
436 : "with %<asm%> clobber list", operand_num);
437 1 : return false;
438 : }
439 98 : if (VAR_P (reg_info->operand)
440 98 : && DECL_HARD_REGISTER (reg_info->operand))
441 : {
442 2 : tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
443 2 : const char *asmspec = IDENTIFIER_POINTER (id) + 1;
444 2 : int regno_op = decode_reg_name (asmspec);
445 2 : if (regno != regno_op)
446 : {
447 1 : error ("constraint and register %<asm%> for output "
448 : "operand %i are unsatisfiable", operand_num);
449 1 : return false;
450 : }
451 : }
452 97 : machine_mode mode = TYPE_MODE (TREE_TYPE (reg_info->operand));
453 97 : if (!hardreg_ok_p (regno, mode, operand_num))
454 : return false;
455 : }
456 25730 : *allows_reg = true;
457 25730 : break;
458 : }
459 :
460 31576531 : default:
461 31576531 : if (!ISALPHA (*p))
462 : break;
463 31556972 : enum constraint_num cn = lookup_constraint (p);
464 31556972 : if (reg_class_for_constraint (cn) != NO_REGS
465 31556972 : || insn_extra_address_constraint (cn))
466 : {
467 29464232 : if (alt_has_hard_reg_cstr)
468 : {
469 1 : error (
470 : "hard register constraints and regular register "
471 : "constraints in one alternative are not supported");
472 1 : return false;
473 : }
474 29464231 : alt_has_reg_cstr = true;
475 29464231 : *allows_reg = true;
476 : }
477 : else if (insn_extra_memory_constraint (cn))
478 2084508 : *allows_mem = true;
479 : else
480 : insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
481 54559 : if (reg_info && *allows_reg
482 52871 : && VAR_P (reg_info->operand)
483 31590087 : && DECL_HARD_REGISTER (reg_info->operand))
484 : {
485 949 : tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
486 949 : const char *asmspec = IDENTIFIER_POINTER (id) + 1;
487 949 : int regno = decode_reg_name (asmspec);
488 949 : if (regno < 0)
489 : {
490 4 : location_t loc = DECL_SOURCE_LOCATION (reg_info->operand);
491 4 : error_at (loc, "invalid register name for %q+D",
492 : reg_info->operand);
493 4 : return false;
494 : }
495 945 : int overlap_regno = reg_info->test_alt_output (alt, regno);
496 945 : if (overlap_regno >= 0)
497 : {
498 0 : error ("multiple outputs to hard register: %s",
499 : reg_names[overlap_regno]);
500 0 : return false;
501 : }
502 945 : reg_info->set_reg_asm_output (regno);
503 945 : if (early_clobbered)
504 10 : reg_info->set_early_clobbered (alt, operand_num, regno);
505 : }
506 : break;
507 : }
508 :
509 68648572 : for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++)
510 34383675 : if (*p == '\0')
511 : break;
512 : }
513 :
514 : return true;
515 : }
516 :
517 : /* Similar, but for input constraints. */
518 :
519 : bool
520 21834468 : parse_input_constraint (const char **constraint_p, int input_num,
521 : int ninputs, int noutputs, int ninout,
522 : const char * const * constraints,
523 : bool *allows_mem, bool *allows_reg,
524 : gimplify_reg_info *reg_info)
525 : {
526 21834468 : const char *constraint = *constraint_p;
527 21834468 : const char *orig_constraint = constraint;
528 21834468 : size_t c_len = strlen (constraint);
529 21834468 : size_t j;
530 21834468 : bool saw_match = false;
531 21834468 : bool at_checked = false;
532 :
533 : /* Assume the constraint doesn't allow the use of either
534 : a register or memory. */
535 21834468 : *allows_mem = false;
536 21834468 : *allows_reg = false;
537 :
538 21834468 : bool alt_has_hard_reg_cstr = false;
539 21834468 : bool alt_has_reg_cstr = false;
540 :
541 : /* Make sure constraint has neither `=', `+', nor '&'. */
542 :
543 21834468 : unsigned int alt = 0;
544 21834468 : unsigned long match = 0;
545 :
546 34383220 : repeat:
547 70481607 : for (j = 0; j < c_len; j += CONSTRAINT_LEN (constraint[j], constraint+j))
548 48647198 : switch (constraint[j])
549 : {
550 13024075 : case '+': case '=': case '&':
551 13024075 : if (constraint == orig_constraint)
552 : {
553 0 : error ("input operand constraint contains %qc", constraint[j]);
554 0 : return false;
555 : }
556 : break;
557 :
558 377677 : case '%':
559 377677 : if (constraint == orig_constraint
560 377677 : && input_num + 1 == ninputs - ninout)
561 : {
562 0 : error ("%<%%%> constraint used with last operand");
563 0 : return false;
564 : }
565 : break;
566 :
567 : case '<': case '>':
568 : case '?': case '!': case '*': case '#':
569 : case '$': case '^':
570 : case 'E': case 'F': case 'G': case 'H':
571 : case 's': case 'i': case 'n':
572 : case 'I': case 'J': case 'K': case 'L': case 'M':
573 : case 'N': case 'O': case 'P': case '-':
574 : break;
575 :
576 166 : case ':':
577 : /* Verify that if : is used, it is just ":" or say ":,:" but not
578 : mixed with other constraints or say ",:,," etc. */
579 166 : if (!at_checked)
580 : {
581 312 : for (size_t k = 0; k < c_len; ++k)
582 336 : if (constraint[k] != ((k & 1) ? ',' : ':') || (c_len & 1) == 0)
583 : {
584 20 : error ("%<:%> constraint mixed with other constraints");
585 20 : return false;
586 : }
587 : at_checked = true;
588 : }
589 : break;
590 :
591 84539 : case ',':
592 84539 : ++alt;
593 84539 : alt_has_hard_reg_cstr = false;
594 84539 : alt_has_reg_cstr = false;
595 84539 : break;
596 :
597 : /* Whether or not a numeric constraint allows a register is
598 : decided by the matching constraint, and so there is no need
599 : to do anything special with them. We must handle them in
600 : the default case, so that we don't unnecessarily force
601 : operands to memory. */
602 12624120 : case '0': case '1': case '2': case '3': case '4':
603 12624120 : case '5': case '6': case '7': case '8': case '9':
604 12624120 : {
605 12624120 : char *end;
606 :
607 12624120 : saw_match = true;
608 :
609 12624120 : match = strtoul (constraint + j, &end, 10);
610 12624120 : if (match >= (unsigned long) noutputs)
611 : {
612 4 : error ("matching constraint references invalid operand number");
613 4 : return false;
614 : }
615 :
616 : /* Try and find the real constraint for this dup. Only do this
617 : if the matching constraint is the only alternative. */
618 12624116 : if (*end == '\0'
619 12560046 : && (j == 0 || (j == 1 && constraint[0] == '%')))
620 : {
621 12548752 : constraint = constraints[match];
622 12548752 : *constraint_p = constraint;
623 12548752 : c_len = strlen (constraint);
624 12548752 : goto repeat;
625 : }
626 : else
627 75364 : j = end - constraint;
628 : /* Anticipate increment at end of loop. */
629 75364 : j--;
630 : }
631 : /* Fall through. */
632 :
633 3025190 : case 'g': case 'X':
634 3025190 : *allows_reg = true;
635 3025190 : *allows_mem = true;
636 3025190 : break;
637 :
638 20950 : case '{':
639 20950 : {
640 20950 : if (!targetm.lra_p ())
641 : {
642 0 : error ("hard register constraints are only supported while using LRA");
643 0 : return false;
644 : }
645 20950 : if (reg_info)
646 : {
647 110 : if (alt_has_reg_cstr)
648 : {
649 1 : error (
650 : "hard register constraints and regular register "
651 : "constraints in one alternative are not supported");
652 1 : return false;
653 : }
654 109 : if (alt_has_hard_reg_cstr)
655 : {
656 2 : error (
657 : "multiple hard register constraints in one "
658 : "alternative are not supported");
659 2 : return false;
660 : }
661 107 : alt_has_hard_reg_cstr = true;
662 107 : int regno = decode_hard_reg_constraint (constraint + j);
663 107 : if (regno < 0)
664 : {
665 3 : error ("invalid input constraint: %s", constraint + j);
666 3 : return false;
667 : }
668 104 : int overlap_regno = reg_info->test_alt_input (alt, regno);
669 104 : if (overlap_regno < 0)
670 99 : overlap_regno = reg_info->test_reg_asm_input (regno);
671 99 : if (overlap_regno >= 0)
672 : {
673 6 : error ("multiple inputs to hard register: %s",
674 : reg_names[overlap_regno]);
675 6 : return false;
676 : }
677 98 : reg_info->set_input (alt, regno);
678 98 : if (reg_info->is_clobbered (regno))
679 : {
680 1 : error ("hard register constraint for input %i conflicts "
681 : "with %<asm%> clobber list", input_num);
682 1 : return false;
683 : }
684 97 : if (constraint == orig_constraint
685 97 : && reg_info->test_early_clobbered_alt (alt, regno))
686 : {
687 3 : error ("invalid hard register usage between earlyclobber "
688 : "operand and input operand");
689 3 : return false;
690 : }
691 94 : if (VAR_P (reg_info->operand)
692 94 : && DECL_HARD_REGISTER (reg_info->operand))
693 : {
694 4 : tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
695 4 : const char *asmspec = IDENTIFIER_POINTER (id) + 1;
696 4 : int regno_op = decode_reg_name (asmspec);
697 4 : if (regno != regno_op)
698 : {
699 2 : error ("constraint and register %<asm%> for input "
700 : "operand %i are unsatisfiable", input_num);
701 2 : return false;
702 : }
703 : }
704 92 : machine_mode mode = TYPE_MODE (TREE_TYPE (reg_info->operand));
705 92 : if (!hardreg_ok_p (regno, mode, input_num))
706 : return false;
707 : }
708 20931 : *allows_reg = true;
709 20931 : break;
710 : }
711 :
712 18902579 : default:
713 18902579 : if (! ISALPHA (constraint[j]))
714 : {
715 5 : error ("invalid punctuation %qc in constraint", constraint[j]);
716 5 : return false;
717 : }
718 18902574 : enum constraint_num cn = lookup_constraint (constraint + j);
719 18902574 : if (reg_class_for_constraint (cn) != NO_REGS
720 18902574 : || insn_extra_address_constraint (cn))
721 : {
722 15977998 : if (alt_has_hard_reg_cstr)
723 : {
724 1 : error (
725 : "hard register constraints and regular register "
726 : "constraints in one alternative are not supported");
727 1 : return false;
728 : }
729 15977997 : alt_has_reg_cstr = true;
730 15977997 : *allows_reg = true;
731 : }
732 : else if (insn_extra_memory_constraint (cn)
733 : || insn_extra_special_memory_constraint (cn)
734 : || insn_extra_relaxed_memory_constraint (cn))
735 2689760 : *allows_mem = true;
736 : else
737 : insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
738 34640 : if (reg_info && *allows_reg
739 32598 : && VAR_P (reg_info->operand)
740 18907388 : && DECL_HARD_REGISTER (reg_info->operand))
741 : {
742 873 : tree id = DECL_ASSEMBLER_NAME (reg_info->operand);
743 873 : const char *asmspec = IDENTIFIER_POINTER (id) + 1;
744 873 : int regno = decode_reg_name (asmspec);
745 873 : if (regno < 0)
746 : {
747 5 : location_t loc = DECL_SOURCE_LOCATION (reg_info->operand);
748 5 : error_at (loc, "invalid register name for %q+D",
749 : reg_info->operand);
750 5 : return false;
751 : }
752 868 : int overlap_regno = reg_info->test_alt_input (alt, regno);
753 868 : if (overlap_regno >= 0)
754 : {
755 1 : error ("multiple inputs to hard register: %s",
756 : reg_names[overlap_regno]);
757 1 : return false;
758 : }
759 867 : reg_info->set_reg_asm_input (regno);
760 867 : if ((constraint == orig_constraint
761 200 : && reg_info->test_early_clobbered_alt (alt, regno))
762 1065 : || (constraint != orig_constraint
763 667 : && reg_info->is_early_clobbered_in_any_output_unequal
764 667 : (match, regno)))
765 : {
766 4 : error ("invalid hard register usage between earlyclobber "
767 : "operand and input operand");
768 4 : return false;
769 : }
770 : }
771 : break;
772 : }
773 :
774 21834409 : if (saw_match && !*allows_reg)
775 4 : warning (0, "matching constraint does not allow a register");
776 :
777 : return true;
778 : }
779 :
780 : /* Return DECL iff there's an overlap between *REGS and DECL, where DECL
781 : can be an asm-declared register. Called via walk_tree. */
782 :
783 : static tree
784 148699 : decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
785 : void *data)
786 : {
787 148699 : tree decl = *declp;
788 148699 : const HARD_REG_SET *const regs = (const HARD_REG_SET *) data;
789 :
790 148699 : if (VAR_P (decl))
791 : {
792 21935 : if (DECL_HARD_REGISTER (decl)
793 1837 : && REG_P (DECL_RTL (decl))
794 23772 : && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER)
795 : {
796 1837 : rtx reg = DECL_RTL (decl);
797 :
798 1837 : if (overlaps_hard_reg_set_p (*regs, GET_MODE (reg), REGNO (reg)))
799 : return decl;
800 : }
801 : walk_subtrees = 0;
802 : }
803 : else if (TYPE_P (decl) || TREE_CODE (decl) == PARM_DECL)
804 148699 : walk_subtrees = 0;
805 : return NULL_TREE;
806 : }
807 :
808 : /* If there is an overlap between *REGS and DECL, return the first overlap
809 : found. */
810 : tree
811 129873 : tree_overlaps_hard_reg_set (tree decl, HARD_REG_SET *regs)
812 : {
813 129873 : return walk_tree (&decl, decl_overlaps_hard_reg_set_p, regs, NULL);
814 : }
815 :
816 :
817 : /* A subroutine of expand_asm_operands. Check that all operand names
818 : are unique. Return true if so. We rely on the fact that these names
819 : are identifiers, and so have been canonicalized by get_identifier,
820 : so all we need are pointer comparisons. */
821 :
822 : static bool
823 217308 : check_unique_operand_names (tree outputs, tree inputs, tree labels)
824 : {
825 217308 : tree i, j, i_name = NULL_TREE;
826 :
827 584136 : for (i = outputs; i ; i = TREE_CHAIN (i))
828 : {
829 366828 : i_name = TREE_PURPOSE (TREE_PURPOSE (i));
830 366828 : if (! i_name)
831 366414 : continue;
832 :
833 2333 : for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
834 1919 : if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
835 0 : goto failure;
836 : }
837 :
838 597875 : for (i = inputs; i ; i = TREE_CHAIN (i))
839 : {
840 380572 : i_name = TREE_PURPOSE (TREE_PURPOSE (i));
841 380572 : if (! i_name)
842 379948 : continue;
843 :
844 1190 : for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
845 566 : if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
846 0 : goto failure;
847 1042 : for (j = outputs; j ; j = TREE_CHAIN (j))
848 423 : if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
849 5 : goto failure;
850 : }
851 :
852 218177 : for (i = labels; i ; i = TREE_CHAIN (i))
853 : {
854 882 : i_name = TREE_PURPOSE (i);
855 882 : if (! i_name)
856 0 : continue;
857 :
858 2252 : for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
859 1374 : if (simple_cst_equal (i_name, TREE_PURPOSE (j)))
860 4 : goto failure;
861 1209 : for (j = inputs; j ; j = TREE_CHAIN (j))
862 335 : if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
863 4 : goto failure;
864 : }
865 :
866 : return true;
867 :
868 13 : failure:
869 13 : error ("duplicate %<asm%> operand name %qs", TREE_STRING_POINTER (i_name));
870 13 : return false;
871 : }
872 :
873 : /* Resolve the names of the operands in *POUTPUTS and *PINPUTS to numbers,
874 : and replace the name expansions in STRING and in the constraints to
875 : those numbers. This is generally done in the front end while creating
876 : the ASM_EXPR generic tree that eventually becomes the GIMPLE_ASM. */
877 :
878 : tree
879 217308 : resolve_asm_operand_names (tree string, tree outputs, tree inputs, tree labels)
880 : {
881 217308 : char *buffer;
882 217308 : char *p;
883 217308 : const char *c;
884 217308 : tree t;
885 :
886 217308 : check_unique_operand_names (outputs, inputs, labels);
887 :
888 : /* Substitute [<name>] in input constraint strings. There should be no
889 : named operands in output constraints. */
890 815188 : for (t = inputs; t ; t = TREE_CHAIN (t))
891 : {
892 380572 : c = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
893 380572 : if (strchr (c, '[') != NULL)
894 : {
895 179 : p = buffer = xstrdup (c);
896 537 : while ((p = strchr (p, '[')) != NULL)
897 179 : p = resolve_operand_name_1 (p, outputs, inputs, NULL);
898 179 : TREE_VALUE (TREE_PURPOSE (t))
899 179 : = build_string (strlen (buffer), buffer);
900 179 : free (buffer);
901 : }
902 : }
903 :
904 : /* Now check for any needed substitutions in the template. */
905 217308 : c = TREE_STRING_POINTER (string);
906 257869 : while ((c = strchr (c, '%')) != NULL)
907 : {
908 40981 : if (c[1] == '[')
909 : break;
910 40880 : else if (ISALPHA (c[1])
911 2115 : && (c[2] == '[' || (ISALPHA (c[2]) && c[3] == '[')))
912 : break;
913 : else
914 : {
915 40561 : c += 1 + (c[1] == '%');
916 40561 : continue;
917 : }
918 : }
919 :
920 217308 : if (c)
921 : {
922 : /* OK, we need to make a copy so we can perform the substitutions.
923 : Assume that we will not need extra space--we get to remove '['
924 : and ']', which means we cannot have a problem until we have more
925 : than 999 operands. */
926 420 : buffer = xstrdup (TREE_STRING_POINTER (string));
927 420 : p = buffer + (c - TREE_STRING_POINTER (string));
928 :
929 2278 : while ((p = strchr (p, '%')) != NULL)
930 : {
931 1858 : if (p[1] == '[')
932 183 : p += 1;
933 1675 : else if (ISALPHA (p[1]) && p[2] == '[')
934 990 : p += 2;
935 685 : else if (ISALPHA (p[1]) && ISALPHA (p[2]) && p[3] == '[')
936 24 : p += 3;
937 : else
938 : {
939 661 : p += 1 + (p[1] == '%');
940 661 : continue;
941 : }
942 :
943 1197 : p = resolve_operand_name_1 (p, outputs, inputs, labels);
944 : }
945 :
946 420 : string = build_string (strlen (buffer), buffer);
947 420 : free (buffer);
948 : }
949 :
950 217308 : return string;
951 : }
952 :
953 : /* A subroutine of resolve_operand_names. P points to the '[' for a
954 : potential named operand of the form [<name>]. In place, replace
955 : the name and brackets with a number. Return a pointer to the
956 : balance of the string after substitution. */
957 :
958 : static char *
959 1376 : resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
960 : {
961 1376 : char *q;
962 1376 : int op, op_inout;
963 1376 : tree t;
964 :
965 : /* Collect the operand name. */
966 1376 : q = strchr (++p, ']');
967 1376 : if (!q)
968 : {
969 0 : error ("missing close brace for named operand");
970 0 : return strchr (p, '\0');
971 : }
972 1376 : *q = '\0';
973 :
974 : /* Resolve the name to a number. */
975 2848 : for (op_inout = op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
976 : {
977 1710 : tree name = TREE_PURPOSE (TREE_PURPOSE (t));
978 2972 : if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
979 238 : goto found;
980 1472 : tree constraint = TREE_VALUE (TREE_PURPOSE (t));
981 2944 : if (constraint && strchr (TREE_STRING_POINTER (constraint), '+') != NULL)
982 64 : op_inout++;
983 : }
984 2369 : for (t = inputs; t ; t = TREE_CHAIN (t), op++)
985 : {
986 2264 : tree name = TREE_PURPOSE (TREE_PURPOSE (t));
987 3968 : if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
988 1033 : goto found;
989 : }
990 105 : op += op_inout;
991 114 : for (t = labels; t ; t = TREE_CHAIN (t), op++)
992 : {
993 111 : tree name = TREE_PURPOSE (t);
994 222 : if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
995 102 : goto found;
996 : }
997 :
998 3 : error ("undefined named operand %qs", identifier_to_locale (p));
999 3 : op = 0;
1000 :
1001 1376 : found:
1002 : /* Replace the name with the number. Unfortunately, not all libraries
1003 : get the return value of sprintf correct, so search for the end of the
1004 : generated string by hand. */
1005 1376 : sprintf (--p, "%d", op);
1006 1376 : p = strchr (p, '\0');
1007 :
1008 : /* Verify the no extra buffer space assumption. */
1009 1376 : gcc_assert (p <= q);
1010 :
1011 : /* Shift the rest of the buffer down to fill the gap. */
1012 1376 : memmove (p, q + 1, strlen (q + 1) + 1);
1013 :
1014 1376 : return p;
1015 : }
1016 :
1017 :
1018 : /* Generate RTL to return directly from the current function.
1019 : (That is, we bypass any return value.) */
1020 :
1021 : void
1022 379 : expand_naked_return (void)
1023 : {
1024 379 : rtx_code_label *end_label;
1025 :
1026 379 : clear_pending_stack_adjust ();
1027 379 : do_pending_stack_adjust ();
1028 :
1029 379 : end_label = naked_return_label;
1030 379 : if (end_label == 0)
1031 379 : end_label = naked_return_label = gen_label_rtx ();
1032 :
1033 379 : emit_jump (end_label);
1034 379 : }
1035 :
1036 : /* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. PROB
1037 : is the probability of jumping to LABEL. */
1038 : static void
1039 0 : do_jump_if_equal (machine_mode mode, rtx op0, rtx op1, rtx_code_label *label,
1040 : int unsignedp, profile_probability prob)
1041 : {
1042 0 : do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode,
1043 : NULL_RTX, NULL, label, prob);
1044 0 : }
1045 :
1046 : /* Return the sum of probabilities of outgoing edges of basic block BB. */
1047 :
1048 : static profile_probability
1049 8028 : get_outgoing_edge_probs (basic_block bb)
1050 : {
1051 8028 : edge e;
1052 8028 : edge_iterator ei;
1053 8028 : profile_probability prob_sum = profile_probability::never ();
1054 8028 : if (!bb)
1055 0 : return profile_probability::never ();
1056 84649 : FOR_EACH_EDGE (e, ei, bb->succs)
1057 76621 : prob_sum += e->probability;
1058 8028 : return prob_sum;
1059 : }
1060 :
1061 : /* Computes the conditional probability of jumping to a target if the branch
1062 : instruction is executed.
1063 : TARGET_PROB is the estimated probability of jumping to a target relative
1064 : to some basic block BB.
1065 : BASE_PROB is the probability of reaching the branch instruction relative
1066 : to the same basic block BB. */
1067 :
1068 : static inline profile_probability
1069 11720 : conditional_probability (profile_probability target_prob,
1070 : profile_probability base_prob)
1071 : {
1072 11720 : return target_prob / base_prob;
1073 : }
1074 :
1075 : /* Generate a dispatch tabler, switching on INDEX_EXPR and jumping to
1076 : one of the labels in CASE_LIST or to the DEFAULT_LABEL.
1077 : MINVAL, MAXVAL, and RANGE are the extrema and range of the case
1078 : labels in CASE_LIST. STMT_BB is the basic block containing the statement.
1079 :
1080 : First, a jump insn is emitted. First we try "casesi". If that
1081 : fails, try "tablejump". A target *must* have one of them (or both).
1082 :
1083 : Then, a table with the target labels is emitted.
1084 :
1085 : The process is unaware of the CFG. The caller has to fix up
1086 : the CFG itself. This is done in cfgexpand.cc. */
1087 :
1088 : static void
1089 8028 : emit_case_dispatch_table (tree index_expr, tree index_type,
1090 : auto_vec<simple_case_node> &case_list,
1091 : rtx default_label,
1092 : edge default_edge, tree minval, tree maxval,
1093 : tree range, basic_block stmt_bb)
1094 : {
1095 8028 : int i, ncases;
1096 8028 : auto_vec<rtx> labelvec;
1097 8028 : rtx_insn *fallback_label = label_rtx (case_list[0].m_code_label);
1098 8028 : rtx_code_label *table_label = gen_label_rtx ();
1099 8028 : bool has_gaps = false;
1100 8028 : profile_probability default_prob = default_edge ? default_edge->probability
1101 8028 : : profile_probability::never ();
1102 8028 : profile_probability base = get_outgoing_edge_probs (stmt_bb);
1103 8028 : bool try_with_tablejump = false;
1104 :
1105 8028 : profile_probability new_default_prob = conditional_probability (default_prob,
1106 : base);
1107 :
1108 8028 : if (! try_casesi (index_type, index_expr, minval, range,
1109 : table_label, default_label, fallback_label,
1110 : new_default_prob))
1111 : {
1112 : /* Index jumptables from zero for suitable values of minval to avoid
1113 : a subtraction. For the rationale see:
1114 : "http://gcc.gnu.org/ml/gcc-patches/2001-10/msg01234.html". */
1115 8028 : if (optimize_insn_for_speed_p ()
1116 7801 : && compare_tree_int (minval, 0) > 0
1117 11032 : && compare_tree_int (minval, 3) < 0)
1118 : {
1119 957 : minval = build_int_cst (index_type, 0);
1120 957 : range = maxval;
1121 957 : has_gaps = true;
1122 : }
1123 : try_with_tablejump = true;
1124 : }
1125 :
1126 : /* Get table of labels to jump to, in order of case index. */
1127 :
1128 8028 : ncases = tree_to_shwi (range) + 1;
1129 8028 : labelvec.safe_grow_cleared (ncases);
1130 :
1131 87080 : for (unsigned j = 0; j < case_list.length (); j++)
1132 : {
1133 79052 : simple_case_node *n = &case_list[j];
1134 : /* Compute the low and high bounds relative to the minimum
1135 : value since that should fit in a HOST_WIDE_INT while the
1136 : actual values may not. */
1137 79052 : HOST_WIDE_INT i_low
1138 79052 : = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
1139 79052 : n->m_low, minval));
1140 79052 : HOST_WIDE_INT i_high
1141 79052 : = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
1142 79052 : n->m_high, minval));
1143 79052 : HOST_WIDE_INT i;
1144 :
1145 168896 : for (i = i_low; i <= i_high; i ++)
1146 269532 : labelvec[i]
1147 101269 : = gen_rtx_LABEL_REF (Pmode, label_rtx (n->m_code_label));
1148 : }
1149 :
1150 : /* The dispatch table may contain gaps, including at the beginning of
1151 : the table if we tried to avoid the minval subtraction. We fill the
1152 : dispatch table slots associated with the gaps with the default case label.
1153 : However, in the event the default case is unreachable, we then use
1154 : any label from one of the case statements. */
1155 8028 : rtx gap_label = (default_label) ? default_label : fallback_label;
1156 :
1157 170456 : for (i = 0; i < ncases; i++)
1158 162428 : if (labelvec[i] == 0)
1159 : {
1160 72584 : has_gaps = true;
1161 84619 : labelvec[i] = gen_rtx_LABEL_REF (Pmode, gap_label);
1162 : }
1163 :
1164 8028 : if (has_gaps && default_label)
1165 : {
1166 : /* There is at least one entry in the jump table that jumps
1167 : to default label. The default label can either be reached
1168 : through the indirect jump or the direct conditional jump
1169 : before that. Split the probability of reaching the
1170 : default label among these two jumps. */
1171 3692 : new_default_prob = conditional_probability (default_prob / 2, base);
1172 3692 : default_prob /= 2;
1173 3692 : base -= default_prob;
1174 : }
1175 : else
1176 : {
1177 4336 : base -= default_prob;
1178 4336 : default_prob = profile_probability::never ();
1179 : }
1180 :
1181 8028 : if (default_edge)
1182 4725 : default_edge->probability = default_prob;
1183 :
1184 : /* We have altered the probability of the default edge. So the probabilities
1185 : of all other edges need to be adjusted so that it sums up to
1186 : REG_BR_PROB_BASE. */
1187 8028 : if (base > profile_probability::never ())
1188 : {
1189 8024 : edge e;
1190 8024 : edge_iterator ei;
1191 84513 : FOR_EACH_EDGE (e, ei, stmt_bb->succs)
1192 76489 : e->probability /= base;
1193 : }
1194 :
1195 8028 : if (try_with_tablejump)
1196 : {
1197 8028 : bool ok = try_tablejump (index_type, index_expr, minval, range,
1198 : table_label, default_label, new_default_prob);
1199 8028 : gcc_assert (ok);
1200 : }
1201 : /* Output the table. */
1202 8028 : emit_label (table_label);
1203 :
1204 8028 : if (CASE_VECTOR_PC_RELATIVE
1205 8028 : || (flag_pic && targetm.asm_out.generate_pic_addr_diff_vec ()))
1206 3411 : emit_jump_table_data (gen_rtx_ADDR_DIFF_VEC (CASE_VECTOR_MODE,
1207 : gen_rtx_LABEL_REF (Pmode,
1208 : table_label),
1209 : gen_rtvec_v (ncases, labelvec.address ()),
1210 : const0_rtx, const0_rtx));
1211 : else
1212 14595 : emit_jump_table_data (gen_rtx_ADDR_VEC (CASE_VECTOR_MODE,
1213 : gen_rtvec_v (ncases, labelvec.address ())));
1214 :
1215 : /* Record no drop-through after the table. */
1216 8028 : emit_barrier ();
1217 8028 : }
1218 :
1219 : /* Terminate a case Ada or switch (C) statement
1220 : in which ORIG_INDEX is the expression to be tested.
1221 : If ORIG_TYPE is not NULL, it is the original ORIG_INDEX
1222 : type as given in the source before any compiler conversions.
1223 : Generate the code to test it and jump to the right place. */
1224 :
1225 : void
1226 8028 : expand_case (gswitch *stmt)
1227 : {
1228 8028 : tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
1229 8028 : rtx_code_label *default_label;
1230 8028 : unsigned int count;
1231 8028 : int i;
1232 8028 : int ncases = gimple_switch_num_labels (stmt);
1233 8028 : tree index_expr = gimple_switch_index (stmt);
1234 8028 : tree index_type = TREE_TYPE (index_expr);
1235 8028 : tree elt;
1236 8028 : basic_block bb = gimple_bb (stmt);
1237 8028 : gimple *def_stmt;
1238 :
1239 8028 : auto_vec<simple_case_node> case_list;
1240 :
1241 : /* An ERROR_MARK occurs for various reasons including invalid data type.
1242 : ??? Can this still happen, with GIMPLE and all? */
1243 8028 : if (index_type == error_mark_node)
1244 0 : return;
1245 :
1246 : /* cleanup_tree_cfg removes all SWITCH_EXPR with their index
1247 : expressions being INTEGER_CST. */
1248 8028 : gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
1249 :
1250 : /* Optimization of switch statements with only one label has already
1251 : occurred, so we should never see them at this point. */
1252 8028 : gcc_assert (ncases > 1);
1253 :
1254 8028 : do_pending_stack_adjust ();
1255 :
1256 : /* Find the default case target label. */
1257 8028 : tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
1258 8028 : default_label = jump_target_rtx (default_lab);
1259 8028 : basic_block default_bb = label_to_block (cfun, default_lab);
1260 8028 : edge default_edge = find_edge (bb, default_bb);
1261 :
1262 : /* Get upper and lower bounds of case values. */
1263 8028 : elt = gimple_switch_label (stmt, 1);
1264 8028 : minval = fold_convert (index_type, CASE_LOW (elt));
1265 8028 : elt = gimple_switch_label (stmt, ncases - 1);
1266 8028 : if (CASE_HIGH (elt))
1267 1801 : maxval = fold_convert (index_type, CASE_HIGH (elt));
1268 : else
1269 6227 : maxval = fold_convert (index_type, CASE_LOW (elt));
1270 :
1271 : /* Try to narrow the index type if it's larger than a word.
1272 : That is mainly for -O0 where an equivalent optimization
1273 : done by forward propagation is not run and is aimed at
1274 : avoiding a call to a comparison routine of libgcc. */
1275 8028 : if (TYPE_PRECISION (index_type) > BITS_PER_WORD
1276 6 : && TREE_CODE (index_expr) == SSA_NAME
1277 6 : && (def_stmt = SSA_NAME_DEF_STMT (index_expr))
1278 6 : && is_gimple_assign (def_stmt)
1279 8031 : && gimple_assign_rhs_code (def_stmt) == NOP_EXPR)
1280 : {
1281 0 : tree inner_index_expr = gimple_assign_rhs1 (def_stmt);
1282 0 : tree inner_index_type = TREE_TYPE (inner_index_expr);
1283 :
1284 0 : if (INTEGRAL_TYPE_P (inner_index_type)
1285 0 : && TYPE_PRECISION (inner_index_type) <= BITS_PER_WORD
1286 0 : && int_fits_type_p (minval, inner_index_type)
1287 0 : && int_fits_type_p (maxval, inner_index_type))
1288 : {
1289 0 : index_expr = inner_index_expr;
1290 0 : index_type = inner_index_type;
1291 0 : minval = fold_convert (index_type, minval);
1292 0 : maxval = fold_convert (index_type, maxval);
1293 : }
1294 : }
1295 :
1296 : /* Compute span of values. */
1297 8028 : range = fold_build2 (MINUS_EXPR, index_type, maxval, minval);
1298 :
1299 : /* Listify the labels queue and gather some numbers to decide
1300 : how to expand this switch(). */
1301 8028 : count = 0;
1302 :
1303 87080 : for (i = ncases - 1; i >= 1; --i)
1304 : {
1305 79052 : elt = gimple_switch_label (stmt, i);
1306 79052 : tree low = CASE_LOW (elt);
1307 79052 : gcc_assert (low);
1308 79052 : tree high = CASE_HIGH (elt);
1309 79052 : gcc_assert (! high || tree_int_cst_lt (low, high));
1310 79052 : tree lab = CASE_LABEL (elt);
1311 :
1312 : /* Count the elements.
1313 : A range counts double, since it requires two compares. */
1314 79052 : count++;
1315 79052 : if (high)
1316 5554 : count++;
1317 :
1318 : /* The bounds on the case range, LOW and HIGH, have to be converted
1319 : to case's index type TYPE. Note that the original type of the
1320 : case index in the source code is usually "lost" during
1321 : gimplification due to type promotion, but the case labels retain the
1322 : original type. Make sure to drop overflow flags. */
1323 79052 : low = fold_convert (index_type, low);
1324 79052 : if (TREE_OVERFLOW (low))
1325 0 : low = wide_int_to_tree (index_type, wi::to_wide (low));
1326 :
1327 : /* The canonical from of a case label in GIMPLE is that a simple case
1328 : has an empty CASE_HIGH. For the casesi and tablejump expanders,
1329 : the back ends want simple cases to have high == low. */
1330 79052 : if (! high)
1331 73498 : high = low;
1332 79052 : high = fold_convert (index_type, high);
1333 79052 : if (TREE_OVERFLOW (high))
1334 0 : high = wide_int_to_tree (index_type, wi::to_wide (high));
1335 :
1336 79052 : case_list.safe_push (simple_case_node (low, high, lab));
1337 : }
1338 :
1339 : /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
1340 : destination, such as one with a default case only.
1341 : It also removes cases that are out of range for the switch
1342 : type, so we should never get a zero here. */
1343 8028 : gcc_assert (count > 0);
1344 :
1345 8028 : rtx_insn *before_case = get_last_insn ();
1346 :
1347 : /* If the default case is unreachable, then set default_label to NULL
1348 : so that we omit the range check when generating the dispatch table.
1349 : We also remove the edge to the unreachable default case. The block
1350 : itself will be automatically removed later. */
1351 8028 : if (EDGE_COUNT (default_edge->dest->succs) == 0
1352 12090 : && gimple_seq_unreachable_p (bb_seq (default_edge->dest)))
1353 : {
1354 3303 : default_label = NULL;
1355 3303 : expand_remove_edge (default_edge);
1356 3303 : default_edge = NULL;
1357 : }
1358 :
1359 8028 : emit_case_dispatch_table (index_expr, index_type,
1360 : case_list, default_label, default_edge,
1361 : minval, maxval, range, bb);
1362 :
1363 8028 : reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
1364 :
1365 8028 : free_temp_slots ();
1366 8028 : }
1367 :
1368 : /* Expand the dispatch to a short decrement chain if there are few cases
1369 : to dispatch to. Likewise if neither casesi nor tablejump is available,
1370 : or if flag_jump_tables is set. Otherwise, expand as a casesi or a
1371 : tablejump. The index mode is always the mode of integer_type_node.
1372 : Trap if no case matches the index.
1373 :
1374 : DISPATCH_INDEX is the index expression to switch on. It should be a
1375 : memory or register operand.
1376 :
1377 : DISPATCH_TABLE is a set of case labels. The set should be sorted in
1378 : ascending order, be contiguous, starting with value 0, and contain only
1379 : single-valued case labels. */
1380 :
1381 : void
1382 0 : expand_sjlj_dispatch_table (rtx dispatch_index,
1383 : vec<tree> dispatch_table)
1384 : {
1385 0 : tree index_type = integer_type_node;
1386 0 : machine_mode index_mode = TYPE_MODE (index_type);
1387 :
1388 0 : int ncases = dispatch_table.length ();
1389 :
1390 0 : do_pending_stack_adjust ();
1391 0 : rtx_insn *before_case = get_last_insn ();
1392 :
1393 : /* Expand as a decrement-chain if there are 5 or fewer dispatch
1394 : labels. This covers more than 98% of the cases in libjava,
1395 : and seems to be a reasonable compromise between the "old way"
1396 : of expanding as a decision tree or dispatch table vs. the "new
1397 : way" with decrement chain or dispatch table. */
1398 0 : if (dispatch_table.length () <= 5
1399 0 : || (!targetm.have_casesi () && !targetm.have_tablejump ())
1400 0 : || !flag_jump_tables)
1401 : {
1402 : /* Expand the dispatch as a decrement chain:
1403 :
1404 : "switch(index) {case 0: do_0; case 1: do_1; ...; case N: do_N;}"
1405 :
1406 : ==>
1407 :
1408 : if (index == 0) do_0; else index--;
1409 : if (index == 0) do_1; else index--;
1410 : ...
1411 : if (index == 0) do_N; else index--;
1412 :
1413 : This is more efficient than a dispatch table on most machines.
1414 : The last "index--" is redundant but the code is trivially dead
1415 : and will be cleaned up by later passes. */
1416 0 : rtx index = copy_to_mode_reg (index_mode, dispatch_index);
1417 0 : rtx zero = CONST0_RTX (index_mode);
1418 0 : for (int i = 0; i < ncases; i++)
1419 : {
1420 0 : tree elt = dispatch_table[i];
1421 0 : rtx_code_label *lab = jump_target_rtx (CASE_LABEL (elt));
1422 0 : do_jump_if_equal (index_mode, index, zero, lab, 0,
1423 : profile_probability::uninitialized ());
1424 0 : force_expand_binop (index_mode, sub_optab,
1425 : index, CONST1_RTX (index_mode),
1426 : index, 0, OPTAB_DIRECT);
1427 : }
1428 : }
1429 : else
1430 : {
1431 : /* Similar to expand_case, but much simpler. */
1432 0 : auto_vec<simple_case_node> case_list;
1433 0 : tree index_expr = make_tree (index_type, dispatch_index);
1434 0 : tree minval = build_int_cst (index_type, 0);
1435 0 : tree maxval = CASE_LOW (dispatch_table.last ());
1436 0 : tree range = maxval;
1437 0 : rtx_code_label *default_label = gen_label_rtx ();
1438 :
1439 0 : for (int i = ncases - 1; i >= 0; --i)
1440 : {
1441 0 : tree elt = dispatch_table[i];
1442 0 : tree high = CASE_HIGH (elt);
1443 0 : if (high == NULL_TREE)
1444 0 : high = CASE_LOW (elt);
1445 0 : case_list.safe_push (simple_case_node (CASE_LOW (elt), high,
1446 0 : CASE_LABEL (elt)));
1447 : }
1448 :
1449 0 : emit_case_dispatch_table (index_expr, index_type,
1450 : case_list, default_label, NULL,
1451 : minval, maxval, range,
1452 0 : BLOCK_FOR_INSN (before_case));
1453 0 : emit_label (default_label);
1454 0 : }
1455 :
1456 : /* Dispatching something not handled? Trap! */
1457 0 : expand_builtin_trap ();
1458 :
1459 0 : reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
1460 :
1461 0 : free_temp_slots ();
1462 0 : }
1463 :
1464 :
|