gcc80: Handle TZ specific "%+" format in strftime.
[dragonfly.git] / contrib / gcc-8.0 / gcc / read-rtl-function.c
1 /* read-rtl-function.c - Reader for RTL function dumps
2    Copyright (C) 2016-2018 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 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "target.h"
24 #include "tree.h"
25 #include "diagnostic.h"
26 #include "read-md.h"
27 #include "rtl.h"
28 #include "cfghooks.h"
29 #include "stringpool.h"
30 #include "function.h"
31 #include "tree-cfg.h"
32 #include "cfg.h"
33 #include "basic-block.h"
34 #include "cfgrtl.h"
35 #include "memmodel.h"
36 #include "emit-rtl.h"
37 #include "cgraph.h"
38 #include "tree-pass.h"
39 #include "toplev.h"
40 #include "varasm.h"
41 #include "read-rtl-function.h"
42 #include "selftest.h"
43 #include "selftest-rtl.h"
44
45 /* Forward decls.  */
46 class function_reader;
47 class fixup;
48
49 /* Edges are recorded when parsing the "insn-chain" directive,
50    and created at the end when all the blocks ought to exist.
51    This struct records an "edge-from" or "edge-to" directive seen
52    at LOC, which will be turned into an actual CFG edge once
53    the "insn-chain" is fully parsed.  */
54
55 struct deferred_edge
56 {
57   deferred_edge (file_location loc, int src_bb_idx, int dest_bb_idx, int flags)
58   : m_loc (loc), m_src_bb_idx (src_bb_idx), m_dest_bb_idx (dest_bb_idx),
59     m_flags (flags)
60   {}
61
62   file_location m_loc;
63   int m_src_bb_idx;
64   int m_dest_bb_idx;
65   int m_flags;
66 };
67
68 /* Subclass of rtx_reader for reading function dumps.  */
69
70 class function_reader : public rtx_reader
71 {
72  public:
73   function_reader ();
74   ~function_reader ();
75
76   /* Overridden vfuncs of class md_reader.  */
77   void handle_unknown_directive (file_location, const char *) FINAL OVERRIDE;
78
79   /* Overridden vfuncs of class rtx_reader.  */
80   rtx read_rtx_operand (rtx x, int idx) FINAL OVERRIDE;
81   void handle_any_trailing_information (rtx x) FINAL OVERRIDE;
82   rtx postprocess (rtx) FINAL OVERRIDE;
83   const char *finalize_string (char *stringbuf) FINAL OVERRIDE;
84
85   rtx_insn **get_insn_by_uid (int uid);
86   tree parse_mem_expr (const char *desc);
87
88  private:
89   void parse_function ();
90   void create_function ();
91   void parse_param ();
92   void parse_insn_chain ();
93   void parse_block ();
94   int parse_bb_idx ();
95   void parse_edge (basic_block block, bool from);
96   rtx_insn *parse_insn (file_location loc, const char *name);
97   void parse_cfg (file_location loc);
98   void parse_crtl (file_location loc);
99   void create_edges ();
100
101   int parse_enum_value (int num_values, const char *const *strings);
102
103   void read_rtx_operand_u (rtx x, int idx);
104   void read_rtx_operand_i_or_n (rtx x, int idx, char format_char);
105   rtx read_rtx_operand_r (rtx x);
106   rtx extra_parsing_for_operand_code_0 (rtx x, int idx);
107
108   void add_fixup_insn_uid (file_location loc, rtx insn, int operand_idx,
109                            int insn_uid);
110
111   void add_fixup_note_insn_basic_block (file_location loc, rtx insn,
112                                         int operand_idx, int bb_idx);
113
114   void add_fixup_source_location (file_location loc, rtx_insn *insn,
115                                   const char *filename, int lineno);
116
117   void add_fixup_expr (file_location loc, rtx x,
118                        const char *desc);
119
120   rtx consolidate_singletons (rtx x);
121   rtx parse_rtx ();
122   void maybe_read_location (rtx_insn *insn);
123
124   void handle_insn_uids ();
125   void apply_fixups ();
126
127  private:
128   struct uid_hash : int_hash <int, -1, -2> {};
129   hash_map<uid_hash, rtx_insn *> m_insns_by_uid;
130   auto_vec<fixup *> m_fixups;
131   rtx_insn *m_first_insn;
132   auto_vec<tree> m_fake_scope;
133   char *m_name;
134   bool m_have_crtl_directive;
135   basic_block m_bb_to_insert_after;
136   auto_vec <deferred_edge> m_deferred_edges;
137   int m_highest_bb_idx;
138 };
139
140 /* Abstract base class for recording post-processing steps that must be
141    done after reading a .rtl file.  */
142
143 class fixup
144 {
145  public:
146   /* Constructor for a fixup at LOC affecting X.  */
147   fixup (file_location loc, rtx x)
148     : m_loc (loc), m_rtx (x)
149   {}
150   virtual ~fixup () {}
151
152   virtual void apply (function_reader *reader) const = 0;
153
154  protected:
155   file_location m_loc;
156   rtx m_rtx;
157 };
158
159 /* An abstract subclass of fixup for post-processing steps that
160    act on a specific operand of a specific instruction.  */
161
162 class operand_fixup : public fixup
163 {
164  public:
165   /* Constructor for a fixup at LOC affecting INSN's operand
166      with index OPERAND_IDX.  */
167   operand_fixup (file_location loc, rtx insn, int operand_idx)
168     : fixup (loc, insn), m_operand_idx (operand_idx)
169   {}
170
171  protected:
172   int m_operand_idx;
173 };
174
175 /* A concrete subclass of operand_fixup: fixup an rtx_insn *
176    field based on an integer UID.  */
177
178 class fixup_insn_uid : public operand_fixup
179 {
180  public:
181   /* Constructor for a fixup at LOC affecting INSN's operand
182      with index OPERAND_IDX.  Record INSN_UID as the uid.  */
183   fixup_insn_uid (file_location loc, rtx insn, int operand_idx, int insn_uid)
184     : operand_fixup (loc, insn, operand_idx),
185       m_insn_uid (insn_uid)
186   {}
187
188   void apply (function_reader *reader) const;
189
190  private:
191   int m_insn_uid;
192 };
193
194 /* A concrete subclass of operand_fixup: fix up a
195    NOTE_INSN_BASIC_BLOCK based on an integer block ID.  */
196
197 class fixup_note_insn_basic_block : public operand_fixup
198 {
199  public:
200   fixup_note_insn_basic_block (file_location loc, rtx insn, int operand_idx,
201                                int bb_idx)
202     : operand_fixup (loc, insn, operand_idx),
203       m_bb_idx (bb_idx)
204   {}
205
206   void apply (function_reader *reader) const;
207
208  private:
209   int m_bb_idx;
210 };
211
212 /* A concrete subclass of fixup (not operand_fixup): fix up
213    the expr of an rtx (REG or MEM) based on a textual dump.  */
214
215 class fixup_expr : public fixup
216 {
217  public:
218   fixup_expr (file_location loc, rtx x, const char *desc)
219     : fixup (loc, x),
220       m_desc (xstrdup (desc))
221   {}
222
223   ~fixup_expr () { free (m_desc); }
224
225   void apply (function_reader *reader) const;
226
227  private:
228   char *m_desc;
229 };
230
231 /* Return a textual description of the operand of INSN with
232    index OPERAND_IDX.  */
233
234 static const char *
235 get_operand_name (rtx insn, int operand_idx)
236 {
237   gcc_assert (is_a <rtx_insn *> (insn));
238   switch (operand_idx)
239     {
240     case 0:
241       return "PREV_INSN";
242     case 1:
243       return "NEXT_INSN";
244     default:
245       return NULL;
246     }
247 }
248
249 /* Fixup an rtx_insn * field based on an integer UID, as read by READER.  */
250
251 void
252 fixup_insn_uid::apply (function_reader *reader) const
253 {
254   rtx_insn **insn_from_uid = reader->get_insn_by_uid (m_insn_uid);
255   if (insn_from_uid)
256     XEXP (m_rtx, m_operand_idx) = *insn_from_uid;
257   else
258     {
259       const char *op_name = get_operand_name (m_rtx, m_operand_idx);
260       if (op_name)
261         error_at (m_loc,
262                   "insn with UID %i not found for operand %i (`%s') of insn %i",
263                   m_insn_uid, m_operand_idx, op_name, INSN_UID (m_rtx));
264       else
265         error_at (m_loc,
266                   "insn with UID %i not found for operand %i of insn %i",
267                   m_insn_uid, m_operand_idx, INSN_UID (m_rtx));
268     }
269 }
270
271 /* Fix up a NOTE_INSN_BASIC_BLOCK based on an integer block ID.  */
272
273 void
274 fixup_note_insn_basic_block::apply (function_reader *) const
275 {
276   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, m_bb_idx);
277   gcc_assert (bb);
278   NOTE_BASIC_BLOCK (m_rtx) = bb;
279 }
280
281 /* Fix up the expr of an rtx (REG or MEM) based on a textual dump
282    read by READER.  */
283
284 void
285 fixup_expr::apply (function_reader *reader) const
286 {
287   tree expr = reader->parse_mem_expr (m_desc);
288   switch (GET_CODE (m_rtx))
289     {
290     case REG:
291       set_reg_attrs_for_decl_rtl (expr, m_rtx);
292       break;
293     case MEM:
294       set_mem_expr (m_rtx, expr);
295       break;
296     default:
297       gcc_unreachable ();
298     }
299 }
300
301 /* Strip trailing whitespace from DESC.  */
302
303 static void
304 strip_trailing_whitespace (char *desc)
305 {
306   char *terminator = desc + strlen (desc);
307   while (desc < terminator)
308     {
309       terminator--;
310       if (ISSPACE (*terminator))
311         *terminator = '\0';
312       else
313         break;
314     }
315 }
316
317 /* Return the numeric value n for GET_NOTE_INSN_NAME (n) for STRING,
318    or fail if STRING isn't recognized.  */
319
320 static int
321 parse_note_insn_name (const char *string)
322 {
323   for (int i = 0; i < NOTE_INSN_MAX; i++)
324     if (strcmp (string, GET_NOTE_INSN_NAME (i)) == 0)
325       return i;
326   fatal_with_file_and_line ("unrecognized NOTE_INSN name: `%s'", string);
327 }
328
329 /* Return the register number for NAME, or return -1 if it isn't
330    recognized.  */
331
332 static int
333 lookup_reg_by_dump_name (const char *name)
334 {
335   for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
336     if (reg_names[i][0]
337         && ! strcmp (name, reg_names[i]))
338       return i;
339
340   /* Also lookup virtuals.  */
341   if (!strcmp (name, "virtual-incoming-args"))
342     return VIRTUAL_INCOMING_ARGS_REGNUM;
343   if (!strcmp (name, "virtual-stack-vars"))
344     return VIRTUAL_STACK_VARS_REGNUM;
345   if (!strcmp (name, "virtual-stack-dynamic"))
346     return VIRTUAL_STACK_DYNAMIC_REGNUM;
347   if (!strcmp (name, "virtual-outgoing-args"))
348     return VIRTUAL_OUTGOING_ARGS_REGNUM;
349   if (!strcmp (name, "virtual-cfa"))
350     return VIRTUAL_CFA_REGNUM;
351   if (!strcmp (name, "virtual-preferred-stack-boundary"))
352     return VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM;
353   /* TODO: handle "virtual-reg-%d".  */
354
355   /* In compact mode, pseudos are printed with '< and '>' wrapping the regno,
356      offseting it by (LAST_VIRTUAL_REGISTER + 1), so that the
357      first non-virtual pseudo is dumped as "<0>".  */
358   if (name[0] == '<' && name[strlen (name) - 1] == '>')
359     {
360       int dump_num = atoi (name + 1);
361       return dump_num + LAST_VIRTUAL_REGISTER + 1;
362     }
363
364   /* Not found.  */
365   return -1;
366 }
367
368 /* class function_reader : public rtx_reader */
369
370 /* function_reader's constructor.  */
371
372 function_reader::function_reader ()
373 : rtx_reader (true),
374   m_first_insn (NULL),
375   m_name (NULL),
376   m_have_crtl_directive (false),
377   m_bb_to_insert_after (NULL),
378   m_highest_bb_idx (EXIT_BLOCK)
379 {
380 }
381
382 /* function_reader's destructor.  */
383
384 function_reader::~function_reader ()
385 {
386   int i;
387   fixup *f;
388   FOR_EACH_VEC_ELT (m_fixups, i, f)
389     delete f;
390
391   free (m_name);
392 }
393
394 /* Implementation of rtx_reader::handle_unknown_directive,
395    for parsing the remainder of a directive with name NAME
396    seen at START_LOC.
397
398    Require a top-level "function" directive, as emitted by
399    print_rtx_function, and parse it.  */
400
401 void
402 function_reader::handle_unknown_directive (file_location start_loc,
403                                            const char *name)
404 {
405   if (strcmp (name, "function"))
406     fatal_at (start_loc, "expected 'function'");
407
408   if (flag_lto)
409     error ("%<__RTL%> function cannot be compiled with %<-flto%>");
410
411   parse_function ();
412 }
413
414 /* Parse the output of print_rtx_function (or hand-written data in the
415    same format), having already parsed the "(function" heading, and
416    finishing immediately before the final ")".
417
418    The "param" and "crtl" clauses are optional.  */
419
420 void
421 function_reader::parse_function ()
422 {
423   m_name = xstrdup (read_string (0));
424
425   create_function ();
426
427   while (1)
428     {
429       int c = read_skip_spaces ();
430       if (c == ')')
431         {
432           unread_char (c);
433           break;
434         }
435       unread_char (c);
436       require_char ('(');
437       file_location loc = get_current_location ();
438       struct md_name directive;
439       read_name (&directive);
440       if (strcmp (directive.string, "param") == 0)
441         parse_param ();
442       else if (strcmp (directive.string, "insn-chain") == 0)
443         parse_insn_chain ();
444       else if (strcmp (directive.string, "crtl") == 0)
445         parse_crtl (loc);
446       else
447         fatal_with_file_and_line ("unrecognized directive: %s",
448                                   directive.string);
449     }
450
451   handle_insn_uids ();
452
453   apply_fixups ();
454
455   /* Rebuild the JUMP_LABEL field of any JUMP_INSNs in the chain, and the
456      LABEL_NUSES of any CODE_LABELs.
457
458      This has to happen after apply_fixups, since only after then do
459      LABEL_REFs have their label_ref_label set up.  */
460   rebuild_jump_labels (get_insns ());
461
462   crtl->init_stack_alignment ();
463 }
464
465 /* Set up state for the function *before* fixups are applied.
466
467    Create "cfun" and a decl for the function.
468    By default, every function decl is hardcoded as
469       int test_1 (int i, int j, int k);
470    Set up various other state:
471    - the cfg and basic blocks (edges are created later, *after* fixups
472    are applied).
473    - add the function to the callgraph.  */
474
475 void
476 function_reader::create_function ()
477 {
478   /* We start in cfgrtl mode, rather than cfglayout mode.  */
479   rtl_register_cfg_hooks ();
480
481   /* When run from selftests or "rtl1", cfun is NULL.
482      When run from "cc1" for a C function tagged with __RTL, cfun is the
483      tagged function.  */
484   if (!cfun)
485     {
486       tree fn_name = get_identifier (m_name ? m_name : "test_1");
487       tree int_type = integer_type_node;
488       tree return_type = int_type;
489       tree arg_types[3] = {int_type, int_type, int_type};
490       tree fn_type = build_function_type_array (return_type, 3, arg_types);
491       tree fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, fn_name, fn_type);
492       tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
493                                  return_type);
494       DECL_ARTIFICIAL (resdecl) = 1;
495       DECL_IGNORED_P (resdecl) = 1;
496       DECL_RESULT (fndecl) = resdecl;
497       allocate_struct_function (fndecl, false);
498       /* This sets cfun.  */
499       current_function_decl = fndecl;
500     }
501
502   gcc_assert (cfun);
503   gcc_assert (current_function_decl);
504   tree fndecl = current_function_decl;
505
506   /* Mark this function as being specified as __RTL.  */
507   cfun->curr_properties |= PROP_rtl;
508
509   /* cc1 normally inits DECL_INITIAL (fndecl) to be error_mark_node.
510      Create a dummy block for it.  */
511   DECL_INITIAL (fndecl) = make_node (BLOCK);
512
513   cfun->curr_properties = (PROP_cfg | PROP_rtl);
514
515   /* Do we need this to force cgraphunit.c to output the function? */
516   DECL_EXTERNAL (fndecl) = 0;
517   DECL_PRESERVE_P (fndecl) = 1;
518
519   /* Add to cgraph.  */
520   cgraph_node::finalize_function (fndecl, false);
521
522   /* Create bare-bones cfg.  This creates the entry and exit blocks.  */
523   init_empty_tree_cfg_for_function (cfun);
524   ENTRY_BLOCK_PTR_FOR_FN (cfun)->flags |= BB_RTL;
525   EXIT_BLOCK_PTR_FOR_FN (cfun)->flags |= BB_RTL;
526   init_rtl_bb_info (ENTRY_BLOCK_PTR_FOR_FN (cfun));
527   init_rtl_bb_info (EXIT_BLOCK_PTR_FOR_FN (cfun));
528   m_bb_to_insert_after = ENTRY_BLOCK_PTR_FOR_FN (cfun);
529
530 }
531
532 /* Look within the the params of FNDECL for a param named NAME.
533    Return NULL_TREE if one isn't found.  */
534
535 static tree
536 find_param_by_name (tree fndecl, const char *name)
537 {
538   for (tree arg = DECL_ARGUMENTS (fndecl); arg; arg = TREE_CHAIN (arg))
539     if (id_equal (DECL_NAME (arg), name))
540       return arg;
541   return NULL_TREE;
542 }
543
544 /* Parse the content of a "param" directive, having already parsed the
545    "(param".  Consume the trailing ')'.  */
546
547 void
548 function_reader::parse_param ()
549 {
550   require_char_ws ('"');
551   file_location loc = get_current_location ();
552   char *name = read_quoted_string ();
553
554   /* Lookup param by name.  */
555   tree t_param = find_param_by_name (cfun->decl, name);
556   if (!t_param)
557     fatal_at (loc, "param not found: %s", name);
558
559   /* Parse DECL_RTL.  */
560   require_char_ws ('(');
561   require_word_ws ("DECL_RTL");
562   DECL_WRTL_CHECK (t_param)->decl_with_rtl.rtl = parse_rtx ();
563   require_char_ws (')');
564
565   /* Parse DECL_RTL_INCOMING.  */
566   require_char_ws ('(');
567   require_word_ws ("DECL_RTL_INCOMING");
568   DECL_INCOMING_RTL (t_param) = parse_rtx ();
569   require_char_ws (')');
570
571   require_char_ws (')');
572 }
573
574 /* Parse zero or more child insn elements within an
575    "insn-chain" element.  Consume the trailing ')'.  */
576
577 void
578 function_reader::parse_insn_chain ()
579 {
580   while (1)
581     {
582       int c = read_skip_spaces ();
583       file_location loc = get_current_location ();
584       if (c == ')')
585         break;
586       else if (c == '(')
587         {
588           struct md_name directive;
589           read_name (&directive);
590           if (strcmp (directive.string, "block") == 0)
591             parse_block ();
592           else
593             parse_insn (loc, directive.string);
594         }
595       else
596         fatal_at (loc, "expected '(' or ')'");
597     }
598
599   create_edges ();
600 }
601
602 /* Parse zero or more child directives (edges and insns) within a
603    "block" directive, having already parsed the "(block " heading.
604    Consume the trailing ')'.  */
605
606 void
607 function_reader::parse_block ()
608 {
609   /* Parse the index value from the dump.  This will be an integer;
610      we don't support "entry" or "exit" here (unlike for edges).  */
611   struct md_name name;
612   read_name (&name);
613   int bb_idx = atoi (name.string);
614
615   /* The term "index" has two meanings for basic blocks in a CFG:
616      (a) the "index" field within struct basic_block_def.
617      (b) the index of a basic_block within the cfg's x_basic_block_info
618      vector, as accessed via BASIC_BLOCK_FOR_FN.
619
620      These can get out-of-sync when basic blocks are optimized away.
621      They get back in sync by "compact_blocks".
622      We reconstruct cfun->cfg->x_basic_block_info->m_vecdata with NULL
623      values in it for any missing basic blocks, so that (a) == (b) for
624      all of the blocks we create.  The doubly-linked list of basic
625      blocks (next_bb/prev_bb) skips over these "holes".  */
626
627   if (m_highest_bb_idx < bb_idx)
628     m_highest_bb_idx = bb_idx;
629
630   size_t new_size = m_highest_bb_idx + 1;
631   if (basic_block_info_for_fn (cfun)->length () < new_size)
632     vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size);
633
634   last_basic_block_for_fn (cfun) = new_size;
635
636   /* Create the basic block.
637
638      We can't call create_basic_block and use the regular RTL block-creation
639      hooks, since this creates NOTE_INSN_BASIC_BLOCK instances.  We don't
640      want to do that; we want to use the notes we were provided with.  */
641   basic_block bb = alloc_block ();
642   init_rtl_bb_info (bb);
643   bb->index = bb_idx;
644   bb->flags = BB_NEW | BB_RTL;
645   link_block (bb, m_bb_to_insert_after);
646   m_bb_to_insert_after = bb;
647
648   n_basic_blocks_for_fn (cfun)++;
649   SET_BASIC_BLOCK_FOR_FN (cfun, bb_idx, bb);
650   BB_SET_PARTITION (bb, BB_UNPARTITIONED);
651
652   /* Handle insns, edge-from and edge-to directives.  */
653   while (1)
654     {
655       int c = read_skip_spaces ();
656       file_location loc = get_current_location ();
657       if (c == ')')
658         break;
659       else if (c == '(')
660         {
661           struct md_name directive;
662           read_name (&directive);
663           if (strcmp (directive.string, "edge-from") == 0)
664             parse_edge (bb, true);
665           else if (strcmp (directive.string, "edge-to") == 0)
666             parse_edge (bb, false);
667           else
668             {
669               rtx_insn *insn = parse_insn (loc, directive.string);
670               set_block_for_insn (insn, bb);
671               if (!BB_HEAD (bb))
672                 BB_HEAD (bb) = insn;
673               BB_END (bb) = insn;
674             }
675         }
676       else
677         fatal_at (loc, "expected '(' or ')'");
678     }
679 }
680
681 /* Subroutine of function_reader::parse_edge.
682    Parse a basic block index, handling "entry" and "exit".  */
683
684 int
685 function_reader::parse_bb_idx ()
686 {
687   struct md_name name;
688   read_name (&name);
689   if (strcmp (name.string, "entry") == 0)
690     return ENTRY_BLOCK;
691   if (strcmp (name.string, "exit") == 0)
692     return EXIT_BLOCK;
693   return atoi (name.string);
694 }
695
696 /* Subroutine of parse_edge_flags.
697    Parse TOK, a token such as "FALLTHRU", converting to the flag value.
698    Issue an error if the token is unrecognized.  */
699
700 static int
701 parse_edge_flag_token (const char *tok)
702 {
703 #define DEF_EDGE_FLAG(NAME,IDX)         \
704   do {                                          \
705     if (strcmp (tok, #NAME) == 0)               \
706       return EDGE_##NAME; \
707   } while (0);
708 #include "cfg-flags.def"
709 #undef DEF_EDGE_FLAG
710   error ("unrecognized edge flag: '%s'", tok);
711   return 0;
712 }
713
714 /* Subroutine of function_reader::parse_edge.
715    Parse STR and convert to a flag value (or issue an error).
716    The parser uses strtok and hence modifiers STR in-place.  */
717
718 static int
719 parse_edge_flags (char *str)
720 {
721   int result = 0;
722
723   char *tok = strtok (str, "| ");
724   while (tok)
725     {
726       result |= parse_edge_flag_token (tok);
727       tok = strtok (NULL, "| ");
728     }
729
730   return result;
731 }
732
733 /* Parse an "edge-from" or "edge-to" directive within the "block"
734    directive for BLOCK, having already parsed the "(edge" heading.
735    Consume the final ")".  Record the edge within m_deferred_edges.
736    FROM is true for an "edge-from" directive, false for an "edge-to"
737    directive.  */
738
739 void
740 function_reader::parse_edge (basic_block block, bool from)
741 {
742   gcc_assert (block);
743   int this_bb_idx = block->index;
744   file_location loc = get_current_location ();
745   int other_bb_idx = parse_bb_idx ();
746
747   /* "(edge-from 2)" means src = 2, dest = this_bb_idx, whereas
748      "(edge-to 3)" means src = this_bb_idx, dest = 3.  */
749   int src_idx = from ? other_bb_idx : this_bb_idx;
750   int dest_idx = from ? this_bb_idx : other_bb_idx;
751
752   /* Optional "(flags)".  */
753   int flags = 0;
754   int c = read_skip_spaces ();
755   if (c == '(')
756     {
757       require_word_ws ("flags");
758       require_char_ws ('"');
759       char *str = read_quoted_string ();
760       flags = parse_edge_flags (str);
761       require_char_ws (')');
762     }
763   else
764     unread_char (c);
765
766   require_char_ws (')');
767
768   /* This BB already exists, but the other BB might not yet.
769      For now, save the edges, and create them at the end of insn-chain
770      processing. */
771   /* For now, only process the (edge-from) to this BB, and (edge-to)
772      that go to the exit block.
773      FIXME: we don't yet verify that the edge-from and edge-to directives
774      are consistent.  */
775   if (from || dest_idx == EXIT_BLOCK)
776     m_deferred_edges.safe_push (deferred_edge (loc, src_idx, dest_idx, flags));
777 }
778
779 /* Parse an rtx instruction, having parsed the opening and parenthesis, and
780    name NAME, seen at START_LOC, by calling read_rtx_code, calling
781    set_first_insn and set_last_insn as appropriate, and
782    adding the insn to the insn chain.
783    Consume the trailing ')'.  */
784
785 rtx_insn *
786 function_reader::parse_insn (file_location start_loc, const char *name)
787 {
788   rtx x = read_rtx_code (name);
789   if (!x)
790     fatal_at (start_loc, "expected insn type; got '%s'", name);
791   rtx_insn *insn = dyn_cast <rtx_insn *> (x);
792   if (!insn)
793     fatal_at (start_loc, "expected insn type; got '%s'", name);
794
795   /* Consume the trailing ')'.  */
796   require_char_ws (')');
797
798   rtx_insn *last_insn = get_last_insn ();
799
800   /* Add "insn" to the insn chain.  */
801   if (last_insn)
802     {
803       gcc_assert (NEXT_INSN (last_insn) == NULL);
804       SET_NEXT_INSN (last_insn) = insn;
805     }
806   SET_PREV_INSN (insn) = last_insn;
807
808   /* Add it to the sequence.  */
809   set_last_insn (insn);
810   if (!m_first_insn)
811     {
812       m_first_insn = insn;
813       set_first_insn (insn);
814     }
815
816   if (rtx_code_label *label = dyn_cast <rtx_code_label *> (insn))
817     maybe_set_max_label_num (label);
818
819   return insn;
820 }
821
822 /* Postprocessing subroutine for parse_insn_chain: all the basic blocks
823    should have been created by now; create the edges that were seen.  */
824
825 void
826 function_reader::create_edges ()
827 {
828   int i;
829   deferred_edge *de;
830   FOR_EACH_VEC_ELT (m_deferred_edges, i, de)
831     {
832       /* The BBs should already have been created by parse_block.  */
833       basic_block src = BASIC_BLOCK_FOR_FN (cfun, de->m_src_bb_idx);
834       if (!src)
835         fatal_at (de->m_loc, "error: block index %i not found",
836                   de->m_src_bb_idx);
837       basic_block dst = BASIC_BLOCK_FOR_FN (cfun, de->m_dest_bb_idx);
838       if (!dst)
839         fatal_at (de->m_loc, "error: block with index %i not found",
840                   de->m_dest_bb_idx);
841       unchecked_make_edge (src, dst, de->m_flags);
842     }
843 }
844
845 /* Parse a "crtl" directive, having already parsed the "(crtl" heading
846    at location LOC.
847    Consume the final ")".  */
848
849 void
850 function_reader::parse_crtl (file_location loc)
851 {
852   if (m_have_crtl_directive)
853     error_at (loc, "more than one 'crtl' directive");
854   m_have_crtl_directive = true;
855
856   /* return_rtx.  */
857   require_char_ws ('(');
858   require_word_ws ("return_rtx");
859   crtl->return_rtx = parse_rtx ();
860   require_char_ws (')');
861
862   require_char_ws (')');
863 }
864
865 /* Parse operand IDX of X, returning X, or an equivalent rtx
866    expression (for consolidating singletons).
867    This is an overridden implementation of rtx_reader::read_rtx_operand for
868    function_reader, handling various extra data printed by print_rtx,
869    and sometimes calling the base class implementation.  */
870
871 rtx
872 function_reader::read_rtx_operand (rtx x, int idx)
873 {
874   RTX_CODE code = GET_CODE (x);
875   const char *format_ptr = GET_RTX_FORMAT (code);
876   const char format_char = format_ptr[idx];
877   struct md_name name;
878
879   /* Override the regular parser for some format codes.  */
880   switch (format_char)
881     {
882     case 'e':
883       if (idx == 7 && CALL_P (x))
884         {
885           m_in_call_function_usage = true;
886           return rtx_reader::read_rtx_operand (x, idx);
887           m_in_call_function_usage = false;
888         }
889       else
890         return rtx_reader::read_rtx_operand (x, idx);
891       break;
892
893     case 'u':
894       read_rtx_operand_u (x, idx);
895       /* Don't run regular parser for 'u'.  */
896       return x;
897
898     case 'i':
899     case 'n':
900       read_rtx_operand_i_or_n (x, idx, format_char);
901       /* Don't run regular parser for these codes.  */
902       return x;
903
904     case 'B':
905       gcc_assert (is_compact ());
906       /* Compact mode doesn't store BBs.  */
907       /* Don't run regular parser.  */
908       return x;
909
910     case 'r':
911       /* Don't run regular parser for 'r'.  */
912       return read_rtx_operand_r (x);
913
914     default:
915       break;
916     }
917
918   /* Call base class implementation.  */
919   x = rtx_reader::read_rtx_operand (x, idx);
920
921   /* Handle any additional parsing needed to handle what the dump
922      could contain.  */
923   switch (format_char)
924     {
925     case '0':
926       x = extra_parsing_for_operand_code_0 (x, idx);
927       break;
928
929     case 'w':
930       if (!is_compact ())
931         {
932           /* Strip away the redundant hex dump of the value.  */
933           require_char_ws ('[');
934           read_name (&name);
935           require_char_ws (']');
936         }
937       break;
938
939     default:
940       break;
941     }
942
943   return x;
944 }
945
946 /* Parse operand IDX of X, of code 'u', when reading function dumps.
947
948    The RTL file recorded the ID of an insn (or 0 for NULL); we
949    must store this as a pointer, but the insn might not have
950    been loaded yet.  Store the ID away for now, via a fixup.  */
951
952 void
953 function_reader::read_rtx_operand_u (rtx x, int idx)
954 {
955   /* In compact mode, the PREV/NEXT insn uids are not dumped, so skip
956      the "uu" when reading. */
957   if (is_compact () && GET_CODE (x) != LABEL_REF)
958     return;
959
960   struct md_name name;
961   file_location loc = read_name (&name);
962   int insn_id = atoi (name.string);
963   if (insn_id)
964     add_fixup_insn_uid (loc, x, idx, insn_id);
965 }
966
967 /* Read a name, looking for a match against a string found in array
968    STRINGS of size NUM_VALUES.
969    Return the index of the the matched string, or emit an error.  */
970
971 int
972 function_reader::parse_enum_value (int num_values, const char *const *strings)
973 {
974   struct md_name name;
975   read_name (&name);
976   for (int i = 0; i < num_values; i++)
977     {
978       if (strcmp (name.string, strings[i]) == 0)
979         return i;
980     }
981   error ("unrecognized enum value: '%s'", name.string);
982   return 0;
983 }
984
985 /* Parse operand IDX of X, of code 'i' or 'n' (as specified by FORMAT_CHAR).
986    Special-cased handling of these, for reading function dumps.  */
987
988 void
989 function_reader::read_rtx_operand_i_or_n (rtx x, int idx,
990                                           char format_char)
991 {
992   /* Handle some of the extra information that print_rtx
993      can write out for these cases.  */
994   /* print_rtx only writes out operand 5 for notes
995      for NOTE_KIND values NOTE_INSN_DELETED_LABEL
996      and NOTE_INSN_DELETED_DEBUG_LABEL.  */
997   if (idx == 5 && NOTE_P (x))
998     return;
999
1000   if (idx == 4 && INSN_P (x))
1001     {
1002       maybe_read_location (as_a <rtx_insn *> (x));
1003       return;
1004     }
1005
1006   /* INSN_CODEs aren't printed in compact mode, so don't attempt to
1007      parse them.  */
1008   if (is_compact ()
1009       && INSN_P (x)
1010       && &INSN_CODE (x) == &XINT (x, idx))
1011     {
1012       INSN_CODE (x) = -1;
1013       return;
1014     }
1015
1016   /* Handle UNSPEC and UNSPEC_VOLATILE's operand 1.  */
1017 #if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
1018   if (idx == 1
1019       && GET_CODE (x) == UNSPEC_VOLATILE)
1020     {
1021       XINT (x, 1)
1022         = parse_enum_value (NUM_UNSPECV_VALUES, unspecv_strings);
1023       return;
1024     }
1025 #endif
1026 #if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
1027   if (idx == 1
1028       && (GET_CODE (x) == UNSPEC
1029           || GET_CODE (x) == UNSPEC_VOLATILE))
1030     {
1031       XINT (x, 1)
1032         = parse_enum_value (NUM_UNSPEC_VALUES, unspec_strings);
1033       return;
1034     }
1035 #endif
1036
1037   struct md_name name;
1038   read_name (&name);
1039   int value;
1040   if (format_char == 'n')
1041     value = parse_note_insn_name (name.string);
1042   else
1043     value = atoi (name.string);
1044   XINT (x, idx) = value;
1045 }
1046
1047 /* Parse the 'r' operand of X, returning X, or an equivalent rtx
1048    expression (for consolidating singletons).
1049    Special-cased handling of code 'r' for reading function dumps.  */
1050
1051 rtx
1052 function_reader::read_rtx_operand_r (rtx x)
1053 {
1054   struct md_name name;
1055   file_location loc = read_name (&name);
1056   int regno = lookup_reg_by_dump_name (name.string);
1057   if (regno == -1)
1058     fatal_at (loc, "unrecognized register: '%s'", name.string);
1059
1060   set_regno_raw (x, regno, 1);
1061
1062   /* Consolidate singletons.  */
1063   x = consolidate_singletons (x);
1064
1065   ORIGINAL_REGNO (x) = regno;
1066
1067   /* Parse extra stuff at end of 'r'.
1068      We may have zero, one, or two sections marked by square
1069      brackets.  */
1070   int ch = read_skip_spaces ();
1071   bool expect_original_regno = false;
1072   if (ch == '[')
1073     {
1074       file_location loc = get_current_location ();
1075       char *desc = read_until ("]", true);
1076       strip_trailing_whitespace (desc);
1077       const char *desc_start = desc;
1078       /* If ORIGINAL_REGNO (rtx) != regno, we will have:
1079          "orig:%i", ORIGINAL_REGNO (rtx).
1080          Consume it, we don't set ORIGINAL_REGNO, since we can
1081          get that from the 2nd copy later.  */
1082       if (strncmp (desc, "orig:", 5) == 0)
1083         {
1084           expect_original_regno = true;
1085           desc_start += 5;
1086           /* Skip to any whitespace following the integer.  */
1087           const char *space = strchr (desc_start, ' ');
1088           if (space)
1089             desc_start = space + 1;
1090         }
1091       /* Any remaining text may be the REG_EXPR.  Alternatively we have
1092          no REG_ATTRS, and instead we have ORIGINAL_REGNO.  */
1093       if (ISDIGIT (*desc_start))
1094         {
1095           /* Assume we have ORIGINAL_REGNO.  */
1096           ORIGINAL_REGNO (x) = atoi (desc_start);
1097         }
1098       else
1099         {
1100           /* Assume we have REG_EXPR.  */
1101           add_fixup_expr (loc, x, desc_start);
1102         }
1103       free (desc);
1104     }
1105   else
1106     unread_char (ch);
1107   if (expect_original_regno)
1108     {
1109       require_char_ws ('[');
1110       char *desc = read_until ("]", true);
1111       ORIGINAL_REGNO (x) = atoi (desc);
1112       free (desc);
1113     }
1114
1115   return x;
1116 }
1117
1118 /* Additional parsing for format code '0' in dumps, handling a variety
1119    of special-cases in print_rtx, when parsing operand IDX of X.
1120    Return X, or possibly a reallocated copy of X.  */
1121
1122 rtx
1123 function_reader::extra_parsing_for_operand_code_0 (rtx x, int idx)
1124 {
1125   RTX_CODE code = GET_CODE (x);
1126   int c;
1127   struct md_name name;
1128
1129   if (idx == 1 && code == SYMBOL_REF)
1130     {
1131       /* Possibly wrote " [flags %#x]", SYMBOL_REF_FLAGS (in_rtx).  */
1132       c = read_skip_spaces ();
1133       if (c == '[')
1134         {
1135           file_location loc = read_name (&name);
1136           if (strcmp (name.string, "flags"))
1137             error_at (loc, "was expecting `%s'", "flags");
1138           read_name (&name);
1139           SYMBOL_REF_FLAGS (x) = strtol (name.string, NULL, 16);
1140
1141           /* The standard RTX_CODE_SIZE (SYMBOL_REF) used when allocating
1142              x doesn't have space for the block_symbol information, so
1143              we must reallocate it if this flag is set.  */
1144           if (SYMBOL_REF_HAS_BLOCK_INFO_P (x))
1145             {
1146               /* Emulate the allocation normally done by
1147                  varasm.c:create_block_symbol.  */
1148               unsigned int size = RTX_HDR_SIZE + sizeof (struct block_symbol);
1149               rtx new_x = (rtx) ggc_internal_alloc (size);
1150
1151               /* Copy data over from the smaller SYMBOL_REF.  */
1152               memcpy (new_x, x, RTX_CODE_SIZE (SYMBOL_REF));
1153               x = new_x;
1154
1155               /* We can't reconstruct SYMBOL_REF_BLOCK; set it to NULL.  */
1156               SYMBOL_REF_BLOCK (x) = NULL;
1157
1158               /* Zero the offset.  */
1159               SYMBOL_REF_BLOCK_OFFSET (x) = 0;
1160             }
1161
1162           require_char (']');
1163         }
1164       else
1165         unread_char (c);
1166
1167       /* If X had a non-NULL SYMBOL_REF_DECL,
1168          rtx_writer::print_rtx_operand_code_0 would have dumped it
1169          using print_node_brief.
1170          Skip the content for now.  */
1171       c = read_skip_spaces ();
1172       if (c == '<')
1173         {
1174           while (1)
1175             {
1176               char ch = read_char ();
1177               if (ch == '>')
1178                 break;
1179             }
1180         }
1181       else
1182         unread_char (c);
1183     }
1184   else if (idx == 3 && code == NOTE)
1185     {
1186       /* Note-specific data appears for operand 3, which annoyingly
1187          is before the enum specifying which kind of note we have
1188          (operand 4).  */
1189       c = read_skip_spaces ();
1190       if (c == '[')
1191         {
1192           /* Possibly data for a NOTE_INSN_BASIC_BLOCK, of the form:
1193              [bb %d].  */
1194           file_location bb_loc = read_name (&name);
1195           if (strcmp (name.string, "bb"))
1196             error_at (bb_loc, "was expecting `%s'", "bb");
1197           read_name (&name);
1198           int bb_idx = atoi (name.string);
1199           add_fixup_note_insn_basic_block (bb_loc, x, idx,
1200                                            bb_idx);
1201           require_char_ws (']');
1202         }
1203       else
1204         unread_char (c);
1205     }
1206
1207   return x;
1208 }
1209
1210 /* Implementation of rtx_reader::handle_any_trailing_information.
1211    Handle the various additional information that print-rtl.c can
1212    write after the regular fields, when parsing X.  */
1213
1214 void
1215 function_reader::handle_any_trailing_information (rtx x)
1216 {
1217   struct md_name name;
1218
1219   switch (GET_CODE (x))
1220     {
1221       case MEM:
1222         {
1223           int ch;
1224           require_char_ws ('[');
1225           read_name (&name);
1226           set_mem_alias_set (x, atoi (name.string));
1227           /* We have either a MEM_EXPR, or a space.  */
1228           if (peek_char () != ' ')
1229             {
1230               file_location loc = get_current_location ();
1231               char *desc = read_until (" +", false);
1232               add_fixup_expr (loc, consolidate_singletons (x), desc);
1233               free (desc);
1234             }
1235           else
1236             read_char ();
1237
1238           /* We may optionally have '+' for MEM_OFFSET_KNOWN_P.  */
1239           ch = read_skip_spaces ();
1240           if (ch == '+')
1241             {
1242               read_name (&name);
1243               set_mem_offset (x, atoi (name.string));
1244             }
1245           else
1246             unread_char (ch);
1247
1248           /* Handle optional " S" for MEM_SIZE.  */
1249           ch = read_skip_spaces ();
1250           if (ch == 'S')
1251             {
1252               read_name (&name);
1253               set_mem_size (x, atoi (name.string));
1254             }
1255           else
1256             unread_char (ch);
1257
1258           /* Handle optional " A" for MEM_ALIGN.  */
1259           ch = read_skip_spaces ();
1260           if (ch == 'A' && peek_char () != 'S')
1261             {
1262               read_name (&name);
1263               set_mem_align (x, atoi (name.string));
1264             }
1265           else
1266             unread_char (ch);
1267
1268           /* Handle optional " AS" for MEM_ADDR_SPACE.  */
1269           ch = read_skip_spaces ();
1270           if (ch == 'A' && peek_char () == 'S')
1271             {
1272               read_char ();
1273               read_name (&name);
1274               set_mem_addr_space (x, atoi (name.string));
1275             }
1276           else
1277             unread_char (ch);
1278
1279           require_char (']');
1280         }
1281         break;
1282
1283       case CODE_LABEL:
1284         /* Assume that LABEL_NUSES was not dumped.  */
1285         /* TODO: parse LABEL_KIND.  */
1286         /* For now, skip until closing ')'.  */
1287         do
1288           {
1289             char ch = read_char ();
1290             if (ch == ')')
1291               {
1292                 unread_char (ch);
1293                 break;
1294               }
1295           }
1296         while (1);
1297         break;
1298
1299       default:
1300         break;
1301     }
1302 }
1303
1304 /* Parse a tree dump for a MEM_EXPR in DESC and turn it back into a tree.
1305    We handle "<retval>" and param names within cfun, but for anything else
1306    we "cheat" by building a global VAR_DECL of type "int" with that name
1307    (returning the same global for a name if we see the same name more
1308    than once).  */
1309
1310 tree
1311 function_reader::parse_mem_expr (const char *desc)
1312 {
1313   tree fndecl = cfun->decl;
1314
1315   if (strcmp (desc, "<retval>") == 0)
1316     return DECL_RESULT (fndecl);
1317
1318   tree param = find_param_by_name (fndecl, desc);
1319   if (param)
1320     return param;
1321
1322   /* Search within decls we already created.
1323      FIXME: use a hash rather than linear search.  */
1324   int i;
1325   tree t;
1326   FOR_EACH_VEC_ELT (m_fake_scope, i, t)
1327     if (id_equal (DECL_NAME (t), desc))
1328       return t;
1329
1330   /* Not found?  Create it.
1331      This allows mimicking of real data but avoids having to specify
1332      e.g. names of locals, params etc.
1333      Though this way we don't know if we have a PARM_DECL vs a VAR_DECL,
1334      and we don't know the types.  Fake it by making everything be
1335      a VAR_DECL of "int" type.  */
1336   t = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1337                   get_identifier (desc),
1338                   integer_type_node);
1339   m_fake_scope.safe_push (t);
1340   return t;
1341 }
1342
1343 /* Record that at LOC we saw an insn uid INSN_UID for the operand with index
1344    OPERAND_IDX within INSN, so that the pointer value can be fixed up in
1345    later post-processing.  */
1346
1347 void
1348 function_reader::add_fixup_insn_uid (file_location loc, rtx insn, int operand_idx,
1349                                      int insn_uid)
1350 {
1351   m_fixups.safe_push (new fixup_insn_uid (loc, insn, operand_idx, insn_uid));
1352 }
1353
1354 /* Record that at LOC we saw an basic block index BB_IDX for the operand with index
1355    OPERAND_IDX within INSN, so that the pointer value can be fixed up in
1356    later post-processing.  */
1357
1358 void
1359 function_reader::add_fixup_note_insn_basic_block (file_location loc, rtx insn,
1360                                                   int operand_idx, int bb_idx)
1361 {
1362   m_fixups.safe_push (new fixup_note_insn_basic_block (loc, insn, operand_idx,
1363                                                        bb_idx));
1364 }
1365
1366 /* Placeholder hook for recording source location information seen in a dump.
1367    This is empty for now.  */
1368
1369 void
1370 function_reader::add_fixup_source_location (file_location, rtx_insn *,
1371                                             const char *, int)
1372 {
1373 }
1374
1375 /* Record that at LOC we saw textual description DESC of the MEM_EXPR or REG_EXPR
1376    of INSN, so that the fields can be fixed up in later post-processing.  */
1377
1378 void
1379 function_reader::add_fixup_expr (file_location loc, rtx insn,
1380                                  const char *desc)
1381 {
1382   gcc_assert (desc);
1383   /* Fail early if the RTL reader erroneously hands us an int.  */
1384   gcc_assert (!ISDIGIT (desc[0]));
1385
1386   m_fixups.safe_push (new fixup_expr (loc, insn, desc));
1387 }
1388
1389 /* Helper function for consolidate_reg.  Return the global rtx for
1390    the register with regno REGNO.  */
1391
1392 static rtx
1393 lookup_global_register (int regno)
1394 {
1395   /* We can't use a switch here, as some of the REGNUMs might not be constants
1396      for some targets.  */
1397   if (regno == STACK_POINTER_REGNUM)
1398       return stack_pointer_rtx;
1399   else if (regno ==  FRAME_POINTER_REGNUM)
1400     return frame_pointer_rtx;
1401   else if (regno == HARD_FRAME_POINTER_REGNUM)
1402     return hard_frame_pointer_rtx;
1403   else if (regno == ARG_POINTER_REGNUM)
1404     return arg_pointer_rtx;
1405   else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
1406     return virtual_incoming_args_rtx;
1407   else if (regno == VIRTUAL_STACK_VARS_REGNUM)
1408     return virtual_stack_vars_rtx;
1409   else if (regno == VIRTUAL_STACK_DYNAMIC_REGNUM)
1410     return virtual_stack_dynamic_rtx;
1411   else if (regno == VIRTUAL_OUTGOING_ARGS_REGNUM)
1412     return virtual_outgoing_args_rtx;
1413   else if (regno == VIRTUAL_CFA_REGNUM)
1414     return virtual_cfa_rtx;
1415   else if (regno == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
1416     return virtual_preferred_stack_boundary_rtx;
1417 #ifdef return_ADDRESS_POINTER_REGNUM
1418   else if (regno == RETURN_ADDRESS_POINTER_REGNUM)
1419     return return_address_pointer_rtx;
1420 #endif
1421
1422   return NULL;
1423 }
1424
1425 /* Ensure that the backend can cope with a REG with regno REGNO.
1426    Normally REG instances are created by gen_reg_rtx which updates
1427    regno_reg_rtx, growing it as necessary.
1428    The REG instances created from the dumpfile weren't created this
1429    way, so we need to manually update regno_reg_rtx.  */
1430
1431 static void
1432 ensure_regno (int regno)
1433 {
1434   if (reg_rtx_no < regno + 1)
1435     reg_rtx_no = regno + 1;
1436
1437   crtl->emit.ensure_regno_capacity ();
1438   gcc_assert (regno < crtl->emit.regno_pointer_align_length);
1439 }
1440
1441 /* Helper function for consolidate_singletons, for handling REG instances.
1442    Given REG instance X of some regno, return the singleton rtx for that
1443    regno, if it exists, or X.  */
1444
1445 static rtx
1446 consolidate_reg (rtx x)
1447 {
1448   gcc_assert (GET_CODE (x) == REG);
1449
1450   unsigned int regno = REGNO (x);
1451
1452   ensure_regno (regno);
1453
1454   /* Some register numbers have their rtx created in init_emit_regs
1455      e.g. stack_pointer_rtx for STACK_POINTER_REGNUM.
1456      Consolidate on this.  */
1457   rtx global_reg = lookup_global_register (regno);
1458   if (global_reg)
1459     return global_reg;
1460
1461   /* Populate regno_reg_rtx if necessary.  */
1462   if (regno_reg_rtx[regno] == NULL)
1463     regno_reg_rtx[regno] = x;
1464   /* Use it.  */
1465   gcc_assert (GET_CODE (regno_reg_rtx[regno]) == REG);
1466   gcc_assert (REGNO (regno_reg_rtx[regno]) == regno);
1467   if (GET_MODE (x) == GET_MODE (regno_reg_rtx[regno]))
1468     return regno_reg_rtx[regno];
1469
1470   return x;
1471 }
1472
1473 /* When reading RTL function dumps, we must consolidate some
1474    rtx so that we use singletons where singletons are expected
1475    (e.g. we don't want multiple "(const_int 0 [0])" rtx, since
1476    these are tested via pointer equality against const0_rtx.
1477
1478    Return the equivalent singleton rtx for X, if any, otherwise X.  */
1479
1480 rtx
1481 function_reader::consolidate_singletons (rtx x)
1482 {
1483   if (!x)
1484     return x;
1485
1486   switch (GET_CODE (x))
1487     {
1488     case PC: return pc_rtx;
1489     case RETURN: return ret_rtx;
1490     case SIMPLE_RETURN: return simple_return_rtx;
1491     case CC0: return cc0_rtx;
1492
1493     case REG:
1494       return consolidate_reg (x);
1495
1496     case CONST_INT:
1497       return gen_rtx_CONST_INT (GET_MODE (x), INTVAL (x));
1498
1499     default:
1500       break;
1501     }
1502
1503   return x;
1504 }
1505
1506 /* Parse an rtx directive, including both the opening/closing parentheses,
1507    and the name.  */
1508
1509 rtx
1510 function_reader::parse_rtx ()
1511 {
1512   require_char_ws ('(');
1513   struct md_name directive;
1514   read_name (&directive);
1515   rtx result
1516     = consolidate_singletons (read_rtx_code (directive.string));
1517   require_char_ws (')');
1518
1519   return result;
1520 }
1521
1522 /* Implementation of rtx_reader::postprocess for reading function dumps.
1523    Return the equivalent singleton rtx for X, if any, otherwise X.  */
1524
1525 rtx
1526 function_reader::postprocess (rtx x)
1527 {
1528   return consolidate_singletons (x);
1529 }
1530
1531 /* Implementation of rtx_reader::finalize_string for reading function dumps.
1532    Make a GC-managed copy of STRINGBUF.  */
1533
1534 const char *
1535 function_reader::finalize_string (char *stringbuf)
1536 {
1537   return ggc_strdup (stringbuf);
1538 }
1539
1540 /* Attempt to parse optional location information for insn INSN, as
1541    potentially written out by rtx_writer::print_rtx_operand_code_i.
1542    We look for a quoted string followed by a colon.  */
1543
1544 void
1545 function_reader::maybe_read_location (rtx_insn *insn)
1546 {
1547   file_location loc = get_current_location ();
1548
1549   /* Attempt to parse a quoted string.  */
1550   int ch = read_skip_spaces ();
1551   if (ch == '"')
1552     {
1553       char *filename = read_quoted_string ();
1554       require_char (':');
1555       struct md_name line_num;
1556       read_name (&line_num);
1557       add_fixup_source_location (loc, insn, filename, atoi (line_num.string));
1558     }
1559   else
1560     unread_char (ch);
1561 }
1562
1563 /* Postprocessing subroutine of function_reader::parse_function.
1564    Populate m_insns_by_uid.  */
1565
1566 void
1567 function_reader::handle_insn_uids ()
1568 {
1569   /* Locate the currently assigned INSN_UID values, storing
1570      them in m_insns_by_uid.  */
1571   int max_uid = 0;
1572   for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
1573     {
1574       if (m_insns_by_uid.get (INSN_UID (insn)))
1575         error ("duplicate insn UID: %i", INSN_UID (insn));
1576       m_insns_by_uid.put (INSN_UID (insn), insn);
1577       if (INSN_UID (insn) > max_uid)
1578         max_uid = INSN_UID (insn);
1579     }
1580
1581   /* Ensure x_cur_insn_uid is 1 more than the biggest insn UID seen.
1582      This is normally updated by the various make_*insn_raw functions.  */
1583   crtl->emit.x_cur_insn_uid = max_uid + 1;
1584 }
1585
1586 /* Apply all of the recorded fixups.  */
1587
1588 void
1589 function_reader::apply_fixups ()
1590 {
1591   int i;
1592   fixup *f;
1593   FOR_EACH_VEC_ELT (m_fixups, i, f)
1594     f->apply (this);
1595 }
1596
1597 /* Given a UID value, try to locate a pointer to the corresponding
1598    rtx_insn *, or NULL if if can't be found.  */
1599
1600 rtx_insn **
1601 function_reader::get_insn_by_uid (int uid)
1602 {
1603   return m_insns_by_uid.get (uid);
1604 }
1605
1606 /* Run the RTL dump parser, parsing a dump located at PATH.
1607    Return true iff the file was successfully parsed.  */
1608
1609 bool
1610 read_rtl_function_body (const char *path)
1611 {
1612   initialize_rtl ();
1613   init_emit ();
1614   init_varasm_status ();
1615
1616   function_reader reader;
1617   if (!reader.read_file (path))
1618     return false;
1619
1620   return true;
1621 }
1622
1623 /* Run the RTL dump parser on the range of lines between START_LOC and
1624    END_LOC (including those lines).  */
1625
1626 bool
1627 read_rtl_function_body_from_file_range (location_t start_loc,
1628                                         location_t end_loc)
1629 {
1630   expanded_location exploc_start = expand_location (start_loc);
1631   expanded_location exploc_end = expand_location (end_loc);
1632
1633   if (exploc_start.file != exploc_end.file)
1634     {
1635       error_at (end_loc, "start/end of RTL fragment are in different files");
1636       return false;
1637     }
1638   if (exploc_start.line >= exploc_end.line)
1639     {
1640       error_at (end_loc,
1641                 "start of RTL fragment must be on an earlier line than end");
1642       return false;
1643     }
1644
1645   initialize_rtl ();
1646   init_emit ();
1647   init_varasm_status ();
1648
1649   function_reader reader;
1650   if (!reader.read_file_fragment (exploc_start.file, exploc_start.line,
1651                                   exploc_end.line - 1))
1652     return false;
1653
1654   return true;
1655 }
1656
1657 #if CHECKING_P
1658
1659 namespace selftest {
1660
1661 /* Verify that parse_edge_flags works.  */
1662
1663 static void
1664 test_edge_flags ()
1665 {
1666   /* parse_edge_flags modifies its input (due to strtok), so we must make
1667      a copy of the literals.  */
1668 #define ASSERT_PARSE_EDGE_FLAGS(EXPECTED, STR) \
1669   do { \
1670     char *str = xstrdup (STR); \
1671     ASSERT_EQ (EXPECTED, parse_edge_flags (str)); \
1672     free (str); \
1673   } while (0)
1674
1675   ASSERT_PARSE_EDGE_FLAGS (0, "");
1676   ASSERT_PARSE_EDGE_FLAGS (EDGE_FALLTHRU, "FALLTHRU");
1677   ASSERT_PARSE_EDGE_FLAGS (EDGE_ABNORMAL_CALL, "ABNORMAL_CALL");
1678   ASSERT_PARSE_EDGE_FLAGS (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL,
1679                            "ABNORMAL | ABNORMAL_CALL");
1680
1681 #undef  ASSERT_PARSE_EDGE_FLAGS
1682 }
1683
1684 /* Verify that lookup_reg_by_dump_name works.  */
1685
1686 static void
1687 test_parsing_regnos ()
1688 {
1689   ASSERT_EQ (-1, lookup_reg_by_dump_name ("this is not a register"));
1690
1691   /* Verify lookup of virtual registers.  */
1692   ASSERT_EQ (VIRTUAL_INCOMING_ARGS_REGNUM,
1693     lookup_reg_by_dump_name ("virtual-incoming-args"));
1694   ASSERT_EQ (VIRTUAL_STACK_VARS_REGNUM,
1695     lookup_reg_by_dump_name ("virtual-stack-vars"));
1696   ASSERT_EQ (VIRTUAL_STACK_DYNAMIC_REGNUM,
1697     lookup_reg_by_dump_name ("virtual-stack-dynamic"));
1698   ASSERT_EQ (VIRTUAL_OUTGOING_ARGS_REGNUM,
1699     lookup_reg_by_dump_name ("virtual-outgoing-args"));
1700   ASSERT_EQ (VIRTUAL_CFA_REGNUM,
1701     lookup_reg_by_dump_name ("virtual-cfa"));
1702   ASSERT_EQ (VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM,
1703     lookup_reg_by_dump_name ("virtual-preferred-stack-boundary"));
1704
1705   /* Verify lookup of non-virtual pseudos.  */
1706   ASSERT_EQ (LAST_VIRTUAL_REGISTER + 1, lookup_reg_by_dump_name ("<0>"));
1707   ASSERT_EQ (LAST_VIRTUAL_REGISTER + 2, lookup_reg_by_dump_name ("<1>"));
1708 }
1709
1710 /* Verify that edge E is as expected, with the src and dest basic blocks
1711    having indices EXPECTED_SRC_IDX and EXPECTED_DEST_IDX respectively, and
1712    the edge having flags equal to EXPECTED_FLAGS.
1713    Use LOC as the effective location when reporting failures.  */
1714
1715 static void
1716 assert_edge_at (const location &loc, edge e, int expected_src_idx,
1717                 int expected_dest_idx, int expected_flags)
1718 {
1719   ASSERT_EQ_AT (loc, expected_src_idx, e->src->index);
1720   ASSERT_EQ_AT (loc, expected_dest_idx, e->dest->index);
1721   ASSERT_EQ_AT (loc, expected_flags, e->flags);
1722 }
1723
1724 /* Verify that edge EDGE is as expected, with the src and dest basic blocks
1725    having indices EXPECTED_SRC_IDX and EXPECTED_DEST_IDX respectively, and
1726    the edge having flags equal to EXPECTED_FLAGS.  */
1727
1728 #define ASSERT_EDGE(EDGE, EXPECTED_SRC_IDX, EXPECTED_DEST_IDX,          \
1729                     EXPECTED_FLAGS)                                     \
1730   assert_edge_at (SELFTEST_LOCATION, EDGE, EXPECTED_SRC_IDX, \
1731                   EXPECTED_DEST_IDX, EXPECTED_FLAGS)
1732
1733 /* Verify that we can load RTL dumps.  */
1734
1735 static void
1736 test_loading_dump_fragment_1 ()
1737 {
1738   // TODO: filter on target?
1739   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("asr_div1.rtl"));
1740
1741   /* Verify that the insns were loaded correctly.  */
1742   rtx_insn *insn_1 = get_insns ();
1743   ASSERT_TRUE (insn_1);
1744   ASSERT_EQ (1, INSN_UID (insn_1));
1745   ASSERT_EQ (INSN, GET_CODE (insn_1));
1746   ASSERT_EQ (SET, GET_CODE (PATTERN (insn_1)));
1747   ASSERT_EQ (NULL, PREV_INSN (insn_1));
1748
1749   rtx_insn *insn_2 = NEXT_INSN (insn_1);
1750   ASSERT_TRUE (insn_2);
1751   ASSERT_EQ (2, INSN_UID (insn_2));
1752   ASSERT_EQ (INSN, GET_CODE (insn_2));
1753   ASSERT_EQ (insn_1, PREV_INSN (insn_2));
1754   ASSERT_EQ (NULL, NEXT_INSN (insn_2));
1755
1756   /* Verify that registers were loaded correctly.  */
1757   rtx insn_1_dest = SET_DEST (PATTERN (insn_1));
1758   ASSERT_EQ (REG, GET_CODE (insn_1_dest));
1759   ASSERT_EQ ((LAST_VIRTUAL_REGISTER + 1) + 2, REGNO (insn_1_dest));
1760   rtx insn_1_src = SET_SRC (PATTERN (insn_1));
1761   ASSERT_EQ (LSHIFTRT, GET_CODE (insn_1_src));
1762   rtx reg = XEXP (insn_1_src, 0);
1763   ASSERT_EQ (REG, GET_CODE (reg));
1764   ASSERT_EQ (LAST_VIRTUAL_REGISTER + 1, REGNO (reg));
1765
1766   /* Verify that get_insn_by_uid works.  */
1767   ASSERT_EQ (insn_1, get_insn_by_uid (1));
1768   ASSERT_EQ (insn_2, get_insn_by_uid (2));
1769
1770   /* Verify that basic blocks were created.  */
1771   ASSERT_EQ (2, BLOCK_FOR_INSN (insn_1)->index);
1772   ASSERT_EQ (2, BLOCK_FOR_INSN (insn_2)->index);
1773
1774   /* Verify that the CFG was recreated.  */
1775   ASSERT_TRUE (cfun);
1776   verify_three_block_rtl_cfg (cfun);
1777   basic_block bb2 = BASIC_BLOCK_FOR_FN (cfun, 2);
1778   ASSERT_TRUE (bb2 != NULL);
1779   ASSERT_EQ (BB_RTL, bb2->flags & BB_RTL);
1780   ASSERT_EQ (2, bb2->index);
1781   ASSERT_EQ (insn_1, BB_HEAD (bb2));
1782   ASSERT_EQ (insn_2, BB_END (bb2));
1783 }
1784
1785 /* Verify loading another RTL dump.  */
1786
1787 static void
1788 test_loading_dump_fragment_2 ()
1789 {
1790   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("simple-cse.rtl"));
1791
1792   rtx_insn *insn_1 = get_insn_by_uid (1);
1793   rtx_insn *insn_2 = get_insn_by_uid (2);
1794   rtx_insn *insn_3 = get_insn_by_uid (3);
1795
1796   rtx set1 = single_set (insn_1);
1797   ASSERT_NE (NULL, set1);
1798   rtx set2 = single_set (insn_2);
1799   ASSERT_NE (NULL, set2);
1800   rtx set3 = single_set (insn_3);
1801   ASSERT_NE (NULL, set3);
1802
1803   rtx src1 = SET_SRC (set1);
1804   ASSERT_EQ (PLUS, GET_CODE (src1));
1805
1806   rtx src2 = SET_SRC (set2);
1807   ASSERT_EQ (PLUS, GET_CODE (src2));
1808
1809   /* Both src1 and src2 refer to "(reg:SI %0)".
1810      Verify that we have pointer equality.  */
1811   rtx lhs1 = XEXP (src1, 0);
1812   rtx lhs2 = XEXP (src2, 0);
1813   ASSERT_EQ (lhs1, lhs2);
1814
1815   /* Verify that the CFG was recreated. */
1816   ASSERT_TRUE (cfun);
1817   verify_three_block_rtl_cfg (cfun);
1818 }
1819
1820 /* Verify that CODE_LABEL insns are loaded correctly.  */
1821
1822 static void
1823 test_loading_labels ()
1824 {
1825   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("example-labels.rtl"));
1826
1827   rtx_insn *insn_100 = get_insn_by_uid (100);
1828   ASSERT_EQ (CODE_LABEL, GET_CODE (insn_100));
1829   ASSERT_EQ (100, INSN_UID (insn_100));
1830   ASSERT_EQ (NULL, LABEL_NAME (insn_100));
1831   ASSERT_EQ (0, LABEL_NUSES (insn_100));
1832   ASSERT_EQ (30, CODE_LABEL_NUMBER (insn_100));
1833
1834   rtx_insn *insn_200 = get_insn_by_uid (200);
1835   ASSERT_EQ (CODE_LABEL, GET_CODE (insn_200));
1836   ASSERT_EQ (200, INSN_UID (insn_200));
1837   ASSERT_STREQ ("some_label_name", LABEL_NAME (insn_200));
1838   ASSERT_EQ (0, LABEL_NUSES (insn_200));
1839   ASSERT_EQ (40, CODE_LABEL_NUMBER (insn_200));
1840
1841   /* Ensure that the presence of CODE_LABEL_NUMBER == 40
1842      means that the next label num to be handed out will be 41.  */
1843   ASSERT_EQ (41, max_label_num ());
1844
1845   /* Ensure that label names read from a dump are GC-managed
1846      and are found through the insn.  */
1847   forcibly_ggc_collect ();
1848   ASSERT_TRUE (ggc_marked_p (insn_200));
1849   ASSERT_TRUE (ggc_marked_p (LABEL_NAME (insn_200)));
1850 }
1851
1852 /* Verify that the loader copes with an insn with a mode.  */
1853
1854 static void
1855 test_loading_insn_with_mode ()
1856 {
1857   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("insn-with-mode.rtl"));
1858   rtx_insn *insn = get_insns ();
1859   ASSERT_EQ (INSN, GET_CODE (insn));
1860
1861   /* Verify that the "TI" mode was set from "insn:TI".  */
1862   ASSERT_EQ (TImode, GET_MODE (insn));
1863 }
1864
1865 /* Verify that the loader copes with a jump_insn to a label_ref.  */
1866
1867 static void
1868 test_loading_jump_to_label_ref ()
1869 {
1870   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("jump-to-label-ref.rtl"));
1871
1872   rtx_insn *jump_insn = get_insn_by_uid (1);
1873   ASSERT_EQ (JUMP_INSN, GET_CODE (jump_insn));
1874
1875   rtx_insn *barrier = get_insn_by_uid (2);
1876   ASSERT_EQ (BARRIER, GET_CODE (barrier));
1877
1878   rtx_insn *code_label = get_insn_by_uid (100);
1879   ASSERT_EQ (CODE_LABEL, GET_CODE (code_label));
1880
1881   /* Verify the jump_insn. */
1882   ASSERT_EQ (4, BLOCK_FOR_INSN (jump_insn)->index);
1883   ASSERT_EQ (SET, GET_CODE (PATTERN (jump_insn)));
1884   /* Ensure that the "(pc)" is using the global singleton.  */
1885   ASSERT_RTX_PTR_EQ (pc_rtx, SET_DEST (PATTERN (jump_insn)));
1886   rtx label_ref = SET_SRC (PATTERN (jump_insn));
1887   ASSERT_EQ (LABEL_REF, GET_CODE (label_ref));
1888   ASSERT_EQ (code_label, label_ref_label (label_ref));
1889   ASSERT_EQ (code_label, JUMP_LABEL (jump_insn));
1890
1891   /* Verify the code_label. */
1892   ASSERT_EQ (5, BLOCK_FOR_INSN (code_label)->index);
1893   ASSERT_EQ (NULL, LABEL_NAME (code_label));
1894   ASSERT_EQ (1, LABEL_NUSES (code_label));
1895
1896   /* Verify the generated CFG.  */
1897
1898   /* Locate blocks.  */
1899   basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
1900   ASSERT_TRUE (entry != NULL);
1901   ASSERT_EQ (ENTRY_BLOCK, entry->index);
1902
1903   basic_block exit = EXIT_BLOCK_PTR_FOR_FN (cfun);
1904   ASSERT_TRUE (exit != NULL);
1905   ASSERT_EQ (EXIT_BLOCK, exit->index);
1906
1907   basic_block bb4 = (*cfun->cfg->x_basic_block_info)[4];
1908   basic_block bb5 = (*cfun->cfg->x_basic_block_info)[5];
1909   ASSERT_EQ (4, bb4->index);
1910   ASSERT_EQ (5, bb5->index);
1911
1912   /* Entry block.  */
1913   ASSERT_EQ (NULL, entry->preds);
1914   ASSERT_EQ (1, entry->succs->length ());
1915   ASSERT_EDGE ((*entry->succs)[0], 0, 4, EDGE_FALLTHRU);
1916
1917   /* bb4.  */
1918   ASSERT_EQ (1, bb4->preds->length ());
1919   ASSERT_EDGE ((*bb4->preds)[0], 0, 4, EDGE_FALLTHRU);
1920   ASSERT_EQ (1, bb4->succs->length ());
1921   ASSERT_EDGE ((*bb4->succs)[0], 4, 5, 0x0);
1922
1923   /* bb5.  */
1924   ASSERT_EQ (1, bb5->preds->length ());
1925   ASSERT_EDGE ((*bb5->preds)[0], 4, 5, 0x0);
1926   ASSERT_EQ (1, bb5->succs->length ());
1927   ASSERT_EDGE ((*bb5->succs)[0], 5, 1, EDGE_FALLTHRU);
1928
1929   /* Exit block.  */
1930   ASSERT_EQ (1, exit->preds->length ());
1931   ASSERT_EDGE ((*exit->preds)[0], 5, 1, EDGE_FALLTHRU);
1932   ASSERT_EQ (NULL, exit->succs);
1933 }
1934
1935 /* Verify that the loader copes with a jump_insn to a label_ref
1936    marked "return".  */
1937
1938 static void
1939 test_loading_jump_to_return ()
1940 {
1941   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("jump-to-return.rtl"));
1942
1943   rtx_insn *jump_insn = get_insn_by_uid (1);
1944   ASSERT_EQ (JUMP_INSN, GET_CODE (jump_insn));
1945   ASSERT_RTX_PTR_EQ (ret_rtx, JUMP_LABEL (jump_insn));
1946 }
1947
1948 /* Verify that the loader copes with a jump_insn to a label_ref
1949    marked "simple_return".  */
1950
1951 static void
1952 test_loading_jump_to_simple_return ()
1953 {
1954   rtl_dump_test t (SELFTEST_LOCATION,
1955                    locate_file ("jump-to-simple-return.rtl"));
1956
1957   rtx_insn *jump_insn = get_insn_by_uid (1);
1958   ASSERT_EQ (JUMP_INSN, GET_CODE (jump_insn));
1959   ASSERT_RTX_PTR_EQ (simple_return_rtx, JUMP_LABEL (jump_insn));
1960 }
1961
1962 /* Verify that the loader copes with a NOTE_INSN_BASIC_BLOCK.  */
1963
1964 static void
1965 test_loading_note_insn_basic_block ()
1966 {
1967   rtl_dump_test t (SELFTEST_LOCATION,
1968                    locate_file ("note_insn_basic_block.rtl"));
1969
1970   rtx_insn *note = get_insn_by_uid (1);
1971   ASSERT_EQ (NOTE, GET_CODE (note));
1972   ASSERT_EQ (2, BLOCK_FOR_INSN (note)->index);
1973
1974   ASSERT_EQ (NOTE_INSN_BASIC_BLOCK, NOTE_KIND (note));
1975   ASSERT_EQ (2, NOTE_BASIC_BLOCK (note)->index);
1976   ASSERT_EQ (BASIC_BLOCK_FOR_FN (cfun, 2), NOTE_BASIC_BLOCK (note));
1977 }
1978
1979 /* Verify that the loader copes with a NOTE_INSN_DELETED.  */
1980
1981 static void
1982 test_loading_note_insn_deleted ()
1983 {
1984   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("note-insn-deleted.rtl"));
1985
1986   rtx_insn *note = get_insn_by_uid (1);
1987   ASSERT_EQ (NOTE, GET_CODE (note));
1988   ASSERT_EQ (NOTE_INSN_DELETED, NOTE_KIND (note));
1989 }
1990
1991 /* Verify that the const_int values are consolidated, since
1992    pointer equality corresponds to value equality.
1993    TODO: do this for all in CASE_CONST_UNIQUE.  */
1994
1995 static void
1996 test_loading_const_int ()
1997 {
1998   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("const-int.rtl"));
1999
2000   /* Verify that const_int values below MAX_SAVED_CONST_INT use
2001      the global values.  */
2002   ASSERT_EQ (const0_rtx, SET_SRC (PATTERN (get_insn_by_uid (1))));
2003   ASSERT_EQ (const1_rtx, SET_SRC (PATTERN (get_insn_by_uid (2))));
2004   ASSERT_EQ (constm1_rtx, SET_SRC (PATTERN (get_insn_by_uid (3))));
2005
2006   /* Verify that other const_int values are consolidated. */
2007   rtx int256 = gen_rtx_CONST_INT (SImode, 256);
2008   ASSERT_EQ (int256, SET_SRC (PATTERN (get_insn_by_uid (4))));
2009 }
2010
2011 /* Verify that the loader copes with a SYMBOL_REF.  */
2012
2013 static void
2014 test_loading_symbol_ref ()
2015 {
2016   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("symbol-ref.rtl"));
2017
2018   rtx_insn *insn = get_insns ();
2019
2020   rtx high = SET_SRC (PATTERN (insn));
2021   ASSERT_EQ (HIGH, GET_CODE (high));
2022
2023   rtx symbol_ref = XEXP (high, 0);
2024   ASSERT_EQ (SYMBOL_REF, GET_CODE (symbol_ref));
2025
2026   /* Verify that "[flags 0xc0]" was parsed.  */
2027   ASSERT_EQ (0xc0, SYMBOL_REF_FLAGS (symbol_ref));
2028   /* TODO: we don't yet load SYMBOL_REF_DECL.  */
2029 }
2030
2031 /* Verify that the loader can rebuild a CFG.  */
2032
2033 static void
2034 test_loading_cfg ()
2035 {
2036   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("cfg-test.rtl"));
2037
2038   ASSERT_STREQ ("cfg_test", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
2039
2040   ASSERT_TRUE (cfun);
2041
2042   ASSERT_TRUE (cfun->cfg != NULL);
2043   ASSERT_EQ (6, n_basic_blocks_for_fn (cfun));
2044   ASSERT_EQ (6, n_edges_for_fn (cfun));
2045
2046   /* The "fake" basic blocks.  */
2047   basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
2048   ASSERT_TRUE (entry != NULL);
2049   ASSERT_EQ (ENTRY_BLOCK, entry->index);
2050
2051   basic_block exit = EXIT_BLOCK_PTR_FOR_FN (cfun);
2052   ASSERT_TRUE (exit != NULL);
2053   ASSERT_EQ (EXIT_BLOCK, exit->index);
2054
2055   /* The "real" basic blocks.  */
2056   basic_block bb2 = (*cfun->cfg->x_basic_block_info)[2];
2057   basic_block bb3 = (*cfun->cfg->x_basic_block_info)[3];
2058   basic_block bb4 = (*cfun->cfg->x_basic_block_info)[4];
2059   basic_block bb5 = (*cfun->cfg->x_basic_block_info)[5];
2060
2061   ASSERT_EQ (2, bb2->index);
2062   ASSERT_EQ (3, bb3->index);
2063   ASSERT_EQ (4, bb4->index);
2064   ASSERT_EQ (5, bb5->index);
2065
2066   /* Verify connectivity.  */
2067
2068   /* Entry block.  */
2069   ASSERT_EQ (NULL, entry->preds);
2070   ASSERT_EQ (1, entry->succs->length ());
2071   ASSERT_EDGE ((*entry->succs)[0], 0, 2, EDGE_FALLTHRU);
2072
2073   /* bb2.  */
2074   ASSERT_EQ (1, bb2->preds->length ());
2075   ASSERT_EDGE ((*bb2->preds)[0], 0, 2, EDGE_FALLTHRU);
2076   ASSERT_EQ (2, bb2->succs->length ());
2077   ASSERT_EDGE ((*bb2->succs)[0], 2, 3, EDGE_TRUE_VALUE);
2078   ASSERT_EDGE ((*bb2->succs)[1], 2, 4, EDGE_FALSE_VALUE);
2079
2080   /* bb3.  */
2081   ASSERT_EQ (1, bb3->preds->length ());
2082   ASSERT_EDGE ((*bb3->preds)[0], 2, 3, EDGE_TRUE_VALUE);
2083   ASSERT_EQ (1, bb3->succs->length ());
2084   ASSERT_EDGE ((*bb3->succs)[0], 3, 5, EDGE_FALLTHRU);
2085
2086   /* bb4.  */
2087   ASSERT_EQ (1, bb4->preds->length ());
2088   ASSERT_EDGE ((*bb4->preds)[0], 2, 4, EDGE_FALSE_VALUE);
2089   ASSERT_EQ (1, bb4->succs->length ());
2090   ASSERT_EDGE ((*bb4->succs)[0], 4, 5, EDGE_FALLTHRU);
2091
2092   /* bb5.  */
2093   ASSERT_EQ (2, bb5->preds->length ());
2094   ASSERT_EDGE ((*bb5->preds)[0], 3, 5, EDGE_FALLTHRU);
2095   ASSERT_EDGE ((*bb5->preds)[1], 4, 5, EDGE_FALLTHRU);
2096   ASSERT_EQ (1, bb5->succs->length ());
2097   ASSERT_EDGE ((*bb5->succs)[0], 5, 1, EDGE_FALLTHRU);
2098
2099   /* Exit block.  */
2100   ASSERT_EQ (1, exit->preds->length ());
2101   ASSERT_EDGE ((*exit->preds)[0], 5, 1, EDGE_FALLTHRU);
2102   ASSERT_EQ (NULL, exit->succs);
2103 }
2104
2105 /* Verify that the loader copes with sparse block indices.
2106    This testcase loads a file with a "(block 42)".  */
2107
2108 static void
2109 test_loading_bb_index ()
2110 {
2111   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("bb-index.rtl"));
2112
2113   ASSERT_STREQ ("test_bb_index", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
2114
2115   ASSERT_TRUE (cfun);
2116
2117   ASSERT_TRUE (cfun->cfg != NULL);
2118   ASSERT_EQ (3, n_basic_blocks_for_fn (cfun));
2119   ASSERT_EQ (43, basic_block_info_for_fn (cfun)->length ());
2120   ASSERT_EQ (2, n_edges_for_fn (cfun));
2121
2122   ASSERT_EQ (NULL, (*cfun->cfg->x_basic_block_info)[41]);
2123   basic_block bb42 = (*cfun->cfg->x_basic_block_info)[42];
2124   ASSERT_NE (NULL, bb42);
2125   ASSERT_EQ (42, bb42->index);
2126 }
2127
2128 /* Verify that function_reader::handle_any_trailing_information correctly
2129    parses all the possible items emitted for a MEM.  */
2130
2131 static void
2132 test_loading_mem ()
2133 {
2134   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("mem.rtl"));
2135
2136   ASSERT_STREQ ("test_mem", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
2137   ASSERT_TRUE (cfun);
2138
2139   /* Verify parsing of "[42 i+17 S8 A128 AS5]".  */
2140   rtx_insn *insn_1 = get_insn_by_uid (1);
2141   rtx set1 = single_set (insn_1);
2142   rtx mem1 = SET_DEST (set1);
2143   ASSERT_EQ (42, MEM_ALIAS_SET (mem1));
2144   /* "+17".  */
2145   ASSERT_TRUE (MEM_OFFSET_KNOWN_P (mem1));
2146   ASSERT_KNOWN_EQ (17, MEM_OFFSET (mem1));
2147   /* "S8".  */
2148   ASSERT_KNOWN_EQ (8, MEM_SIZE (mem1));
2149   /* "A128.  */
2150   ASSERT_EQ (128, MEM_ALIGN (mem1));
2151   /* "AS5.  */
2152   ASSERT_EQ (5, MEM_ADDR_SPACE (mem1));
2153
2154   /* Verify parsing of "43 i+18 S9 AS6"
2155      (an address space without an alignment).  */
2156   rtx_insn *insn_2 = get_insn_by_uid (2);
2157   rtx set2 = single_set (insn_2);
2158   rtx mem2 = SET_DEST (set2);
2159   ASSERT_EQ (43, MEM_ALIAS_SET (mem2));
2160   /* "+18".  */
2161   ASSERT_TRUE (MEM_OFFSET_KNOWN_P (mem2));
2162   ASSERT_KNOWN_EQ (18, MEM_OFFSET (mem2));
2163   /* "S9".  */
2164   ASSERT_KNOWN_EQ (9, MEM_SIZE (mem2));
2165   /* "AS6.  */
2166   ASSERT_EQ (6, MEM_ADDR_SPACE (mem2));
2167 }
2168
2169 /* Run all of the selftests within this file.  */
2170
2171 void
2172 read_rtl_function_c_tests ()
2173 {
2174   test_edge_flags ();
2175   test_parsing_regnos ();
2176   test_loading_dump_fragment_1 ();
2177   test_loading_dump_fragment_2 ();
2178   test_loading_labels ();
2179   test_loading_insn_with_mode ();
2180   test_loading_jump_to_label_ref ();
2181   test_loading_jump_to_return ();
2182   test_loading_jump_to_simple_return ();
2183   test_loading_note_insn_basic_block ();
2184   test_loading_note_insn_deleted ();
2185   test_loading_const_int ();
2186   test_loading_symbol_ref ();
2187   test_loading_cfg ();
2188   test_loading_bb_index ();
2189   test_loading_mem ();
2190 }
2191
2192 } // namespace selftest
2193
2194 #endif /* #if CHECKING_P */