1 /* Unit tests for function-handling.
2 Copyright (C) 2015-2016 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
22 #include "coretypes.h"
27 #include "fixed-value.h"
31 #include "tree-core.h"
32 #include "stor-layout.h"
34 #include "stringpool.h"
35 #include "stor-layout.h"
42 #include "hard-reg-set.h"
45 #include "dominance.h"
48 #include "basic-block.h"
49 #include "tree-ssa-alias.h"
50 #include "internal-fn.h"
51 #include "gimple-fold.h"
52 #include "gimple-expr.h"
54 #include "print-tree.h"
55 #include "tree-iterator.h"
58 #include "basic-block.h"
59 #include "double-int.h"
65 #include "fold-const.h"
66 #include "stor-layout.h"
68 #include "hash-table.h"
69 #include "tree-ssa-alias.h"
70 #include "internal-fn.h"
71 #include "gimple-expr.h"
74 #include "tree-pass.h"
77 #include "plugin-api.h"
86 /* Helper function for selftests of function-creation. */
89 make_fndecl (tree return_type
,
91 vec
<tree
> ¶m_types
,
92 bool is_variadic
= false)
96 fn_type
= build_varargs_function_type_array (return_type
,
97 param_types
.length (),
98 param_types
.address ());
100 fn_type
= build_function_type_array (return_type
,
101 param_types
.length (),
102 param_types
.address ());
103 /* FIXME: this uses input_location: */
104 tree fndecl
= build_fn_decl (name
, fn_type
);
109 /* Verify creating a function declaration equivalent to the following
110 int test_fndecl_int_void (void);
114 test_fndecl_int_void ()
116 auto_vec
<tree
> param_types
;
117 const char *name
= "test_fndecl_int_void";
118 tree fndecl
= make_fndecl (integer_type_node
,
121 ASSERT_TRUE (fndecl
!= NULL
);
123 /* Verify name of decl. */
124 tree declname
= DECL_NAME (fndecl
);
125 ASSERT_TRUE (declname
!= NULL
);
126 ASSERT_EQ (IDENTIFIER_NODE
, TREE_CODE (declname
));
127 /* We expect it to use a *copy* of the string we passed in. */
128 const char *identifier_ptr
= IDENTIFIER_POINTER (declname
);
129 ASSERT_NE (name
, identifier_ptr
);
130 ASSERT_EQ (0, strcmp ("test_fndecl_int_void", identifier_ptr
));
132 /* Verify type of fndecl. */
133 ASSERT_EQ (FUNCTION_DECL
, TREE_CODE (fndecl
));
134 tree fntype
= TREE_TYPE (fndecl
);
135 ASSERT_EQ (FUNCTION_TYPE
, TREE_CODE (fntype
));
137 /* Verify return type. */
138 ASSERT_EQ (integer_type_node
, TREE_TYPE (fntype
));
140 /* Verify "void" args. */
141 tree argtypes
= TYPE_ARG_TYPES (fntype
);
142 ASSERT_EQ (TREE_LIST
, TREE_CODE (argtypes
));
143 ASSERT_EQ (void_type_node
, TREE_VALUE (argtypes
));
144 ASSERT_EQ (NULL
, TREE_CHAIN (argtypes
));
147 /* Verify creating a function declaration equivalent to the following
148 float test_fndecl_float_intchar (int, char);
152 test_fndecl_float_intchar ()
154 auto_vec
<tree
> param_types
;
155 param_types
.safe_push (integer_type_node
);
156 param_types
.safe_push (char_type_node
);
157 const char *name
= "test_fndecl_float_intchar";
158 tree fndecl
= make_fndecl (float_type_node
,
161 ASSERT_TRUE (fndecl
!= NULL
);
163 /* Verify name of decl. */
164 tree declname
= DECL_NAME (fndecl
);
165 ASSERT_TRUE (declname
!= NULL
);
166 ASSERT_EQ (IDENTIFIER_NODE
, TREE_CODE (declname
));
167 /* We expect it to use a *copy* of the string we passed in. */
168 const char *identifier_ptr
= IDENTIFIER_POINTER (declname
);
169 ASSERT_NE (name
, identifier_ptr
);
170 ASSERT_EQ (0, strcmp (name
, identifier_ptr
));
172 /* Verify type of fndecl. */
173 ASSERT_EQ (FUNCTION_DECL
, TREE_CODE (fndecl
));
174 tree fntype
= TREE_TYPE (fndecl
);
175 ASSERT_EQ (FUNCTION_TYPE
, TREE_CODE (fntype
));
177 /* Verify return type. */
178 ASSERT_EQ (float_type_node
, TREE_TYPE (fntype
));
180 /* Verify "(int, char)" args. */
181 tree arg0
= TYPE_ARG_TYPES (fntype
);
182 ASSERT_EQ (TREE_LIST
, TREE_CODE (arg0
));
183 ASSERT_EQ (integer_type_node
, TREE_VALUE (arg0
));
184 tree arg1
= TREE_CHAIN (arg0
);
185 ASSERT_TRUE (arg1
!= NULL
);
186 ASSERT_EQ (TREE_LIST
, TREE_CODE (arg1
));
187 ASSERT_EQ (char_type_node
, TREE_VALUE (arg1
));
188 tree argterm
= TREE_CHAIN (arg1
);
189 ASSERT_TRUE (argterm
!= NULL
);
190 ASSERT_EQ (TREE_LIST
, TREE_CODE (argterm
));
191 ASSERT_EQ (void_type_node
, TREE_VALUE (argterm
));
192 ASSERT_EQ (NULL
, TREE_CHAIN (argterm
));
195 /* The test cases using these helper functions take a trivial function:
197 int test_fn (void) { return 42; }
199 and test various conversions done to it:
202 - construction of the CFG
203 - conversion to SSA form
204 - expansion to RTL form
206 In avoid having one overlong test case, this is broken
207 up into separate test cases for each stage, with helper functions
208 to minimize code duplication.
210 Another approach would be to attempt to directly construct a function
211 in the appropriate representation at each stage, though presumably
212 that would exhibit different kinds of failure compared to this
215 /* Construct this function:
216 int test_fn (void) { return 42; }
217 in generic tree form. Return the fndecl. */
220 build_trivial_generic_function ()
222 auto_vec
<tree
> param_types
;
223 tree fndecl
= make_fndecl (integer_type_node
,
226 ASSERT_TRUE (fndecl
!= NULL
);
228 /* Populate the function. */
229 tree retval
= build_decl (UNKNOWN_LOCATION
, RESULT_DECL
,
230 NULL_TREE
, integer_type_node
);
231 DECL_ARTIFICIAL (retval
) = 1;
232 DECL_IGNORED_P (retval
) = 1;
233 DECL_RESULT (fndecl
) = retval
;
235 /* Create a BIND_EXPR, and within it, a statement list. */
236 tree stmt_list
= alloc_stmt_list ();
237 tree_stmt_iterator stmt_iter
= tsi_start (stmt_list
);
238 tree block
= make_node (BLOCK
);
240 = build3 (BIND_EXPR
, void_type_node
, NULL
, stmt_list
, block
);
242 tree modify_retval
= build2 (MODIFY_EXPR
,
245 build_int_cst (integer_type_node
, 42));
246 tree return_stmt
= build1 (RETURN_EXPR
,
249 tsi_link_after (&stmt_iter
, return_stmt
, TSI_CONTINUE_LINKING
);
251 DECL_INITIAL (fndecl
) = block
;
253 /* how to add to function? the following appears to be how to
254 set the body of a fndecl: */
255 DECL_SAVED_TREE(fndecl
) = bind_expr
;
257 /* Ensure that locals appear in the debuginfo. */
258 BLOCK_VARS (block
) = BIND_EXPR_VARS (bind_expr
);
263 /* Construct this function:
264 int test_fn (void) { return 42; }
265 in "high gimple" form. Return the fndecl. */
268 build_trivial_high_gimple_function ()
270 /* Construct a trivial function, and gimplify it: */
271 tree fndecl
= build_trivial_generic_function ();
272 gimplify_function_tree (fndecl
);
276 /* Build a CFG for a function in gimple form. */
279 build_cfg (tree fndecl
)
281 function
*fun
= DECL_STRUCT_FUNCTION (fndecl
);
282 ASSERT_TRUE (fun
!= NULL
);
283 ASSERT_EQ (fndecl
, fun
->decl
);
285 /* We first have to lower control flow; for our trivial test function
295 gimple_opt_pass
*lower_cf_pass
= make_pass_lower_cf (g
);
297 lower_cf_pass
->execute (fun
);
300 /* We can now convert to CFG form; for our trivial test function this
309 gimple_opt_pass
*build_cfg_pass
= make_pass_build_cfg (g
);
311 build_cfg_pass
->execute (fun
);
315 /* Convert a gimple+CFG function to SSA form. */
318 convert_to_ssa (tree fndecl
)
320 function
*fun
= DECL_STRUCT_FUNCTION (fndecl
);
321 ASSERT_TRUE (fun
!= NULL
);
322 ASSERT_EQ (fndecl
, fun
->decl
);
324 gimple_opt_pass
*build_ssa_pass
= make_pass_build_ssa (g
);
326 build_ssa_pass
->execute (fun
);
330 /* Assuming we have a simple 3-block CFG like this:
331 [ENTRY] -> [block2] -> [EXIT]
332 get the "real" basic block (block 2). */
335 get_real_block (function
*fun
)
337 ASSERT_TRUE (fun
->cfg
!= NULL
);
338 ASSERT_EQ (3, n_basic_blocks_for_fn (fun
));
339 basic_block bb2
= (*fun
->cfg
->x_basic_block_info
)[2];
340 ASSERT_TRUE (bb2
!= NULL
);
344 /* Verify that we have a simple 3-block CFG: the two "fake" ones, and
346 [ENTRY] -> [block2] -> [EXIT]. */
349 verify_three_block_cfg (function
*fun
)
351 ASSERT_TRUE (fun
->cfg
!= NULL
);
352 ASSERT_EQ (3, n_basic_blocks_for_fn (fun
));
353 ASSERT_EQ (2, n_edges_for_fn (fun
));
355 /* The "fake" basic blocks. */
356 basic_block entry
= ENTRY_BLOCK_PTR_FOR_FN (fun
);
357 ASSERT_TRUE (entry
!= NULL
);
358 ASSERT_EQ (ENTRY_BLOCK
, entry
->index
);
360 basic_block exit
= EXIT_BLOCK_PTR_FOR_FN (fun
);
361 ASSERT_TRUE (exit
!= NULL
);
362 ASSERT_EQ (EXIT_BLOCK
, exit
->index
);
364 /* The "real" basic block. */
365 basic_block bb2
= get_real_block (fun
);
366 ASSERT_TRUE (bb2
!= NULL
);
367 ASSERT_EQ (2, bb2
->index
);
369 /* Verify connectivity. */
370 ASSERT_EQ (NULL
, entry
->preds
);
371 ASSERT_EQ (1, entry
->succs
->length ());
373 edge from_entry_to_bb2
= (*entry
->succs
)[0];
374 ASSERT_EQ (entry
, from_entry_to_bb2
->src
);
375 ASSERT_EQ (bb2
, from_entry_to_bb2
->dest
);
377 ASSERT_EQ (1, bb2
->preds
->length ());
378 ASSERT_EQ (from_entry_to_bb2
, (*bb2
->preds
)[0]);
379 ASSERT_EQ (1, bb2
->succs
->length ());
381 edge from_bb2_to_exit
= (*bb2
->succs
)[0];
382 ASSERT_EQ (bb2
, from_bb2_to_exit
->src
);
383 ASSERT_EQ (exit
, from_bb2_to_exit
->dest
);
385 ASSERT_EQ (1, exit
->preds
->length ());
386 ASSERT_EQ (from_bb2_to_exit
, (*exit
->preds
)[0]);
387 ASSERT_EQ (NULL
, exit
->succs
);
390 /* As above, but additionally verify the gimple statements are sane. */
393 verify_three_block_gimple_cfg (function
*fun
)
395 verify_three_block_cfg (fun
);
397 /* The "fake" basic blocks should be flagged as gimple, but with have no
399 basic_block entry
= ENTRY_BLOCK_PTR_FOR_FN (fun
);
400 ASSERT_TRUE (entry
!= NULL
);
401 ASSERT_EQ (0, entry
->flags
& BB_RTL
);
402 ASSERT_EQ (NULL
, bb_seq (entry
));
404 basic_block exit
= EXIT_BLOCK_PTR_FOR_FN (fun
);
405 ASSERT_TRUE (exit
!= NULL
);
406 ASSERT_EQ (0, entry
->flags
& BB_RTL
);
407 ASSERT_EQ (NULL
, bb_seq (exit
));
409 /* The "real" basic block should be flagged as gimple, and have one
410 or more statements. */
411 basic_block bb2
= get_real_block (fun
);
412 ASSERT_TRUE (bb2
!= NULL
);
413 ASSERT_EQ (0, entry
->flags
& BB_RTL
);
414 ASSERT_TRUE (bb_seq (bb2
) != NULL
);
417 /* As above, but additionally verify the RTL insns are sane. */
420 verify_three_block_rtl_cfg (function
*fun
)
422 verify_three_block_cfg (fun
);
424 /* The "fake" basic blocks should be flagged as RTL, but with no
426 basic_block entry
= ENTRY_BLOCK_PTR_FOR_FN (fun
);
427 ASSERT_TRUE (entry
!= NULL
);
428 ASSERT_EQ (BB_RTL
, entry
->flags
& BB_RTL
);
429 ASSERT_EQ (NULL
, BB_HEAD (entry
));
431 basic_block exit
= EXIT_BLOCK_PTR_FOR_FN (fun
);
432 ASSERT_TRUE (exit
!= NULL
);
433 ASSERT_EQ (BB_RTL
, entry
->flags
& BB_RTL
);
434 ASSERT_EQ (NULL
, BB_HEAD (exit
));
436 /* The "real" basic block should be flagged as RTL, and have one
438 basic_block bb2
= get_real_block (fun
);
439 ASSERT_TRUE (bb2
!= NULL
);
440 ASSERT_EQ (BB_RTL
, entry
->flags
& BB_RTL
);
441 ASSERT_TRUE (BB_HEAD (bb2
) != NULL
);
444 /* Test converting our trivial function:
445 int test_fn (void) { return 42; }
449 test_gimplification ()
451 tree fndecl
= build_trivial_generic_function ();
453 /* Convert to gimple: */
454 gimplify_function_tree (fndecl
);
456 /* Verify that we got gimple out of it. */
458 /* The function is now in GIMPLE form but the CFG has not been
461 /* We should have a struct function for the decl. */
462 function
*fun
= DECL_STRUCT_FUNCTION (fndecl
);
463 ASSERT_TRUE (fun
!= NULL
);
464 ASSERT_EQ (fndecl
, fun
->decl
);
466 /* We expect a GIMPLE_BIND, with two gimple statements within it:
470 gimple_seq seq_fn_body
= gimple_body (fndecl
);
471 ASSERT_TRUE (seq_fn_body
!= NULL
);
472 gimple
*bind_stmt
= gimple_seq_first_stmt (seq_fn_body
);
473 ASSERT_EQ (GIMPLE_BIND
, gimple_code (bind_stmt
));
474 ASSERT_EQ (NULL
, bind_stmt
->next
);
476 gimple_seq seq_bind_body
= gimple_bind_body (as_a
<gbind
*> (bind_stmt
));
478 /* Verify that we have the 2 statements we expect. */
479 ASSERT_TRUE (seq_bind_body
!= NULL
);
480 gimple
*stmt1
= gimple_seq_first_stmt (seq_bind_body
);
481 ASSERT_TRUE (stmt1
!= NULL
);
482 ASSERT_EQ (GIMPLE_ASSIGN
, gimple_code (stmt1
));
483 gimple
*stmt2
= stmt1
->next
;
484 ASSERT_TRUE (stmt2
!= NULL
);
485 ASSERT_EQ (stmt1
, stmt2
->prev
);
486 ASSERT_EQ (GIMPLE_RETURN
, gimple_code (stmt2
));
489 /* Test of building a CFG for a function in high gimple form. */
494 /* Construct a trivial function, and gimplify it: */
495 tree fndecl
= build_trivial_high_gimple_function ();
496 function
*fun
= DECL_STRUCT_FUNCTION (fndecl
);
497 ASSERT_TRUE (fun
!= NULL
);
502 /* The CFG-building code constructs a 4-block cfg (with
512 and then ought to merge blocks 2 and 3 in cleanup_tree_cfg.
514 Hence we should end up with a simple 3-block cfg, the two "fake" ones,
516 [ENTRY] -> [block2] -> [EXIT]
525 verify_three_block_gimple_cfg (fun
);
527 /* Verify the statements within the "real" block. */
528 basic_block bb2
= get_real_block (fun
);
529 gimple
*stmt_a
= gimple_seq_first_stmt (bb_seq (bb2
));
530 ASSERT_EQ (GIMPLE_ASSIGN
, gimple_code (stmt_a
));
531 gimple
*stmt_b
= stmt_a
->next
;
532 ASSERT_EQ (GIMPLE_RETURN
, gimple_code (stmt_b
));
533 ASSERT_EQ (NULL
, stmt_b
->next
);
536 /* Test of conversion of gimple to SSA form. */
539 test_conversion_to_ssa ()
541 /* As above, construct a trivial function, gimplify it, and build a CFG: */
542 tree fndecl
= build_trivial_high_gimple_function ();
543 function
*fun
= DECL_STRUCT_FUNCTION (fndecl
);
544 ASSERT_TRUE (fun
!= NULL
);
547 convert_to_ssa (fndecl
);
549 verify_three_block_gimple_cfg (fun
);
551 /* For out trivial test function we should now have something like
560 basic_block bb2
= get_real_block (fun
);
561 gimple
*stmt_a
= gimple_seq_first_stmt (bb_seq (bb2
));
562 ASSERT_EQ (GIMPLE_ASSIGN
, gimple_code (stmt_a
));
564 gimple
*stmt_b
= stmt_a
->next
;
565 ASSERT_EQ (GIMPLE_RETURN
, gimple_code (stmt_b
));
566 ASSERT_EQ (NULL
, stmt_b
->next
);
568 greturn
*return_stmt
= as_a
<greturn
*> (stmt_b
);
569 ASSERT_EQ (SSA_NAME
, TREE_CODE (gimple_return_retval (return_stmt
)));
572 /* Test of expansion from gimple-ssa to RTL. */
575 test_expansion_to_rtl ()
577 /* As above, construct a trivial function, gimplify it, build a CFG,
578 and convert to SSA: */
579 tree fndecl
= build_trivial_high_gimple_function ();
580 function
*fun
= DECL_STRUCT_FUNCTION (fndecl
);
581 ASSERT_TRUE (fun
!= NULL
);
583 convert_to_ssa (fndecl
);
585 /* We need a cgraph_node for it. */
586 cgraph_node::get_create (fndecl
);
587 /* Normally, cgraph_node::expand () would call
588 init_function_start (and a bunch of other stuff),
589 and invoke the expand pass, but it also runs
590 all of the other passes. So just do the minimum
591 needed to get from gimple-SSA to RTL. */
592 rtl_opt_pass
*expand_pass
= make_pass_expand (g
);
594 init_function_start (fndecl
);
595 expand_pass
->execute (fun
);
598 /* On x86_64, I get this:
599 (note 3 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
600 (note 2 3 5 2 NOTE_INSN_FUNCTION_BEG)
601 (insn 5 2 6 2 (set (reg:SI 87 [ D.59 ])
602 (const_int 42 [0x2a])) -1 (nil))
603 (insn 6 5 10 2 (set (reg:SI 88 [ <retval> ])
604 (reg:SI 87 [ D.59 ])) -1 (nil))
605 (insn 10 6 11 2 (set (reg/i:SI 0 ax)
606 (reg:SI 88 [ <retval> ])) -1 (nil))
607 (insn 11 10 0 2 (use (reg/i:SI 0 ax)) -1 (nil))
609 On cr16-elf I get this:
610 (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
611 (insn 2 4 3 2 (set (reg:SI 24)
612 (reg/f:SI 16 virtual-incoming-args)) -1
614 (note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)
615 (insn 6 3 7 2 (set (reg:HI 22 [ _1 ])
616 (const_int 42 [0x2a])) -1
618 (insn 7 6 11 2 (set (reg:HI 23 [ <retval> ])
619 (reg:HI 22 [ _1 ])) -1
621 (insn 11 7 12 2 (set (reg/i:HI 0 r0)
622 (reg:HI 23 [ <retval> ])) -1
624 (insn 12 11 0 2 (use (reg/i:HI 0 r0)) -1
626 verify_three_block_rtl_cfg (fun
);
628 /* Verify as much of the RTL as we can whilst avoiding
629 target-specific behavior. */
630 basic_block bb2
= get_real_block (fun
);
632 /* Expect a NOTE_INSN_BASIC_BLOCK... */
633 rtx_insn
*insn
= BB_HEAD (bb2
);
634 ASSERT_TRUE (insn
!= NULL
);
635 ASSERT_EQ (NOTE
, insn
->code
);
636 ASSERT_EQ (NOTE_INSN_BASIC_BLOCK
, NOTE_KIND (insn
));
637 ASSERT_EQ (bb2
, NOTE_BASIC_BLOCK (insn
));
639 /* ...etc; any further checks are likely to over-specify things
640 and run us into target dependencies. */
643 /* Run all of the selftests within this file. */
646 function_tests_c_tests ()
648 test_fndecl_int_void ();
649 test_fndecl_float_intchar ();
650 test_gimplification ();
651 test_building_cfg ();
652 test_conversion_to_ssa ();
653 test_expansion_to_rtl ();
656 } // namespace selftest
658 #endif /* #if CHECKING_P */