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