OSDN Git Service

* doc/invoke.texi (-fwhopr): Merge into -flto section.
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / lib / lto.exp
1 # Copyright (C) 2009, 2010 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with GCC; see the file COPYING3.  If not see
15 # <http://www.gnu.org/licenses/>.
16
17 # Contributed by Diego Novillo <dnovillo@google.com>
18
19 # Prune messages that aren't useful.
20
21 proc lto_prune_warns { text } {
22
23     verbose "lto_prune_warns: entry: $text" 2
24
25     # Many tests that use visibility will still pass on platforms that don't support it.
26     regsub -all "(^|\n)\[^\n\]*: warning: visibility attribute not supported in this configuration; ignored\[^\n\]*" $text "" text
27
28     # And any stray location lines.
29     regsub -all "(^|\n)\[^\n\]*: In function \[^\n\]*" $text "" text
30     regsub -all "(^|\n)In file included from \[^\n\]*" $text "" text
31     regsub -all "(^|\n)\[ \t\]*from \[^\n\]*" $text "" text
32
33     # Sun ld warns about common symbols with differing sizes.  Unlike GNU ld
34     # --warn-common (off by default), they cannot be disabled.
35     regsub -all "(^|\n)ld: warning: symbol \[`'\]\[^\n\]*' has differing sizes:" $text "" text
36     regsub -all "(^|\n)\[ \t\]*\[\(\]file \[^\n\]* value=\[^\n\]*; file \[^\n\]* value=\[^\n\]*\[)\];" $text "" text
37     regsub -all "(^|\n)\[ \t\]*\[^\n\]* definition taken" $text "" text
38
39     verbose "lto_prune_warns: exit: $text" 2
40
41     return $text
42 }
43
44 # lto_init -- called at the start of each subdir of tests
45
46 proc lto_init { args } {
47     global LTO_OPTIONS
48
49     if {[info exists args] && $args == "no-mathlib"} {
50         global board_info
51         global saved_mathlib
52
53         set dest [target_info name]
54         if [board_info $dest exists mathlib] {
55             set saved_mathlib [board_info $dest mathlib]
56         }
57         set board_info($dest,mathlib) " "
58     }
59
60     # Each test is run with the compiler options from this list.
61     # The default option lists can be overridden by LTO_OPTIONS="[list
62     # {opts_1} {opts_2}... {opts_n}]" where opts_i are lists of options.
63     # You can put this in the environment before site.exp is written or
64     # add it to site.exp directly.
65     if ![info exists LTO_OPTIONS] {
66         set LTO_OPTIONS [list   \
67             {-O0 -flto -flto-partition=none } \
68             {-O2 -flto -flto-partition=none } \
69             {-O0 -flto -flto-partition=1to1 } \
70             {-O2 -flto -flto-partition=1to1 } \
71             {-O0 -flto}         \
72             {-O2 -flto}         \
73         ]
74     }
75 }
76
77 #
78 # lto_finish -- called at the end of each subdir of tests if mathlib is
79 #               changed.
80 #
81
82 proc lto_finish { } {
83     global board_info
84     global saved_mathlib
85
86     set dest [target_info name]
87     if [info exists saved_mathlib] {
88         set board_info($dest,mathlib) $saved_mathlib
89     } elseif [board_info $dest exists mathlib] {
90         unset board_info($dest,mathlib)
91     }
92 }
93
94 # Subsets of tests can be selectively disabled by members of this list:
95 #  - ATTRIBUTE: disable all tests using the __attribute__ extension,
96 #  - COMPLEX: disable all tests using the complex types feature,
97 #  - COMPLEX_INT: disable all tests using the complex integral types extension,
98 #  - VA: disable all tests using the variable number of arguments feature,
99 #  - VLA_IN_STRUCT: disable all tests using the variable-length arrays as
100 #    structure members extension,
101 #  - ZERO_ARRAY: disable all tests using the zero-sized arrays extension.
102 # The default skip lists can be overriden by
103 # LTO_SKIPS="[list {skip_1}...{skip_n}]"
104 # where skip_i are skip identifiers.  You can put this in the environment
105 # before site.exp is written or add it to site.exp directly.
106 if ![info exists LTO_SKIPS] {
107     set LTO_SKIPS [list {}]
108 }
109
110 global lto_skip_list
111 set lto_skip_list $LTO_SKIPS
112
113 load_lib dg.exp
114 load_lib gcc-dg.exp
115 load_lib gcc.exp
116
117 # lto-obj -- compile to an object file
118 #
119 # SOURCE is the source file
120 # DEST is the object file
121 # OPTALL is the list of compiler options to use with all tests
122 # OPTFILE is the list of compiler options to use with this file
123 # OPTSTR is the options to print with test messages
124 # XFAILDATA is the xfail data to be passed to the compiler
125 proc lto-obj { source dest optall optfile optstr xfaildata } {
126     global testcase
127     global tool
128     global compiler_conditional_xfail_data
129     global lto_skip_list
130
131     # Add the skip specifiers.
132     foreach skip $lto_skip_list {
133         if { ![string match $skip ""] } {
134             lappend optall "-DSKIP_$skip"
135         }
136     }
137
138     # Set up the options for compiling this file.
139     set options ""
140     lappend options "additional_flags=$optall $optfile"
141
142     set compiler_conditional_xfail_data $xfaildata
143
144     # Allow C source files to mix freely with other languages
145     if [ string match "*.c" $source ] then {
146       set comp_output [gcc_target_compile "$source" "$dest" object $options]
147     } else {
148       set comp_output [${tool}_target_compile "$source" "$dest" object $options]
149     }
150     # Prune unimportant visibility warnings before checking output.
151     set comp_output [lto_prune_warns $comp_output]
152     ${tool}_check_compile "$testcase $dest assemble" $optstr $dest $comp_output
153 }
154
155 # lto-link-and-maybe-run -- link the object files and run the executable
156 # if compile_type is set to "run"
157 #
158 # TESTNAME is the mixture of object files to link
159 # OBJLIST is the list of object files to link
160 # DEST is the name of the executable
161 # OPTALL is a list of compiler and linker options to use for all tests
162 # OPTFILE is a list of compiler and linker options to use for this test
163 # OPTSTR is the list of options to list in messages
164 proc lto-link-and-maybe-run { testname objlist dest optall optfile optstr } {
165     global testcase
166     global tool
167     global compile_type
168     global board_info
169
170     # Check that all of the objects were built successfully.
171     foreach obj [split $objlist] {
172         if ![file_on_host exists $obj] then {
173             unresolved "$testcase $testname link $optstr"
174             unresolved "$testcase $testname execute $optstr"
175             return
176         }
177     }
178
179     # Set up the options for linking this test.
180     set options ""
181     lappend options "additional_flags=$optall $optfile"
182
183     set target_board [target_info name]
184     set relocatable 0
185
186     # Some LTO tests do relocatable linking. Some target boards set
187     # a linker script which can't be used for relocatable linking.
188     # Use the default linker script instead.
189     if { [lsearch -exact [split "$optall $optfile"] "-r"] >= 0 } {
190         set relocatable 1
191     }
192
193     if { $relocatable } {
194         set saved_ldscript [board_info $target_board ldscript]
195         set board_info($target_board,ldscript) ""
196     }
197
198     # Link the objects into an executable.
199     set comp_output [${tool}_target_compile "$objlist" $dest executable \
200                      "$options"]
201
202     if { $relocatable } {
203         set board_info($target_board,ldscript) $saved_ldscript
204     }
205
206     # Prune unimportant visibility warnings before checking output.
207     set comp_output [lto_prune_warns $comp_output]
208
209     if ![${tool}_check_compile "$testcase $testname link" $optstr \
210          $dest $comp_output] then {
211         unresolved "$testcase $testname execute $optstr"
212         return
213     }
214
215     # Return if we only needed to link.
216     if { ![string compare "link" $compile_type] } {
217         return
218     }
219
220     # Run the self-checking executable.
221     if ![string match "*/*" $dest] then {
222         set dest "./$dest"
223     }
224     set result [${tool}_load $dest "" ""]
225     set status [lindex $result 0]
226     if { $status == "pass" } then {
227         file_on_host delete $dest
228     }
229     $status "$testcase $testname execute $optstr"
230 }
231
232 # lto-get-options-main -- get target requirements for a test and
233 # options for the primary source file and the test as a whole
234 #
235 # SRC is the full pathname of the primary source file.
236 proc lto-get-options-main { src } {
237     global compile_type
238     global dg-extra-ld-options
239     global dg-suppress-ld-options
240
241     set dg-extra-ld-options ""
242     set dg-suppress-ld-options ""
243
244     # dg-options sets a variable called dg-extra-tool-flags.
245     set dg-extra-tool-flags ""
246
247     # dg-options sets a variable called tool_flags.
248     set tool_flags ""
249
250     # dg-require-* sets dg-do-what.
251     upvar dg-do-what dg-do-what 
252     upvar dg-final-code dg-final-code
253     set dg-final-code ""
254
255     set tmp [dg-get-options $src]
256     verbose "getting options for $src: $tmp"
257     foreach op $tmp {
258         set cmd [lindex $op 0]
259         verbose "cmd is $cmd"
260         if { [string match "dg-skip-if" $cmd] \
261              || [string match "dg-require-*" $cmd] } {
262             set status [catch "$op" errmsg]
263             if { $status != 0 } {
264                 perror "src: $errmsg for \"$op\"\n"
265                 unresolved "$src: $errmsg for \"$op\""
266                 return
267             }
268         } elseif { [string match "dg-lto-options" $cmd] } {
269             set op [lreplace $op 0 0 "dg-options"]
270             set status [catch "$op" errmsg]
271             if { $status != 0 } {
272                 perror "src: $errmsg for \"$op\"\n"
273                 unresolved "$src: $errmsg for \"$op\""
274                 return
275             }
276         } elseif { ![string compare "dg-xfail-if" $cmd] \
277                    || ![string compare "dg-options" $cmd] } {
278             warning "lto.exp does not support $cmd in primary source file"
279         } elseif { ![string compare "dg-lto-do" $cmd] } {
280             if { [llength $op] > 3 } {
281                 set kw [lindex [lindex $op 3] 0]
282                 if [string match "target" $kw] {
283                     perror "$src: dg-lto-do does not support \"target\""
284                 } elseif [string match "xfail" $kw] {
285                     perror "$src: dg-lto-do does not support \"xfail\""
286                 } else {
287                     perror "$src: dg-lto-do takes a single argument"
288                 }
289             }
290             set dgdo [lindex $op 2]
291             verbose "dg-lto-do command for \"$op\" is $dgdo"
292             if { ![string compare "assemble" $dgdo] } {
293                 set compile_type "assemble"
294             } elseif { ![string compare "run" $dgdo] } {
295                 set compile_type "run"
296             } elseif { ![string compare "link" $dgdo] } {
297                 set compile_type "link"
298             } else {
299                 warning "lto.exp does not support dg-lto-do $dgdo"
300             }
301         } elseif { ![string compare "dg-extra-ld-options" $cmd] } {
302             if { [llength $op] > 4 } {
303                 error "[lindex $op 0]: too many arguments"
304             } else {
305                 if { [llength $op] == 3
306                      || ([llength $op] > 3
307                          && [dg-process-target [lindex $op 3]] == "S") } {
308                     set dg-extra-ld-options [lindex $op 2]
309                     verbose \
310                         "dg-extra-ld-options for main is ${dg-extra-ld-options}"
311                 }
312             }
313         } elseif { ![string compare "dg-suppress-ld-options" $cmd] } {
314             if { [llength $op] > 4 } {
315                 error "[lindex $op 0]: too many arguments"
316             } else {
317                 if { [llength $op] == 3
318                      || ([llength $op] > 3
319                          && [dg-process-target [lindex $op 3]] == "S") } {
320                     set dg-suppress-ld-options [lindex $op 2]
321                     verbose \
322                         "dg-suppress-ld-options for main is ${dg-suppress-ld-options}"
323                 }
324             }
325         } elseif { ![string compare "dg-final" $cmd] } {
326             if { [llength $op] > 3 } {
327                 error "[lindex $op 0]: too many arguments"
328             } else {
329                 append dg-final-code "[lindex $op 2]\n"
330             }
331         } else {
332             # Ignore unrecognized dg- commands, but warn about them.
333             warning "lto.exp does not support $cmd"
334         }
335     }
336
337     # Return flags to use for compiling the primary source file and for
338     # linking.
339     verbose "dg-extra-tool-flags for main is ${dg-extra-tool-flags}"
340     return ${dg-extra-tool-flags}
341 }
342
343
344 # lto-get-options -- get special tool flags to use for a secondary
345 # source file
346 #
347 # SRC is the full pathname of the source file.
348 # The result is a list of options to use.
349 #
350 # This code is copied from proc dg-test in dg.exp from DejaGNU.
351 proc lto-get-options { src } {
352     # dg-options sets a variable called dg-extra-tool-flags.
353     set dg-extra-tool-flags ""
354
355     # dg-xfail-if sets compiler_conditional_xfail_data.
356     global compiler_conditional_xfail_data
357     set compiler_conditional_xfail_data ""
358
359     # dg-xfail-if needs access to dg-do-what.
360     upvar dg-do-what dg-do-what 
361
362     set tmp [dg-get-options $src]
363     foreach op $tmp {
364         set cmd [lindex $op 0]
365         if { ![string compare "dg-options" $cmd] \
366              || ![string compare "dg-xfail-if" $cmd] } {
367             set status [catch "$op" errmsg]
368             if { $status != 0 } {
369                 perror "src: $errmsg for \"$op\"\n"
370                 unresolved "$src: $errmsg for \"$op\""
371                 return
372             }
373         } elseif { [string match "dg-require-*" $cmd] } {
374             warning "lto.exp does not support $cmd in secondary source files"
375         } else {
376             # Ignore unrecognized dg- commands, but warn about them.
377             warning "lto.exp does not support $cmd in secondary source files"
378         }
379     }
380
381     return ${dg-extra-tool-flags}
382 }
383
384 # lto-execute -- compile multi-file tests
385 #
386 # SRC1 is the full pathname of the main file of the testcase.
387 # SID identifies a test suite in the names of temporary files.
388 proc lto-execute { src1 sid } {
389     global srcdir tmpdir
390     global lto_option_list
391     global tool
392     global verbose
393     global testcase
394     global gluefile
395     global compiler_conditional_xfail_data
396     global dg-do-what-default
397     global compile_type
398     global dg-extra-ld-options
399     global dg-suppress-ld-options
400     global LTO_OPTIONS
401     global dg-final-code
402
403     # Get extra flags for this test from the primary source file, and
404     # process other dg-* options that this suite supports.  Warn about
405     # unsupported flags.
406     verbose "lto-execute: $src1" 1
407     set compile_type "run"
408     set dg-do-what [list ${dg-do-what-default} "" P]
409     set extra_flags(0) [lto-get-options-main $src1]
410     set compile_xfail(0) "" 
411
412     # If the main file defines dg-options, those flags are used to
413     # overwrite the default lto_option_list taken from LTO_OPTIONS.
414     if { [string length $extra_flags(0)] > 0 } {
415         set lto_option_list $extra_flags(0)
416         set extra_flags(0) ""
417     } else {
418         set lto_option_list $LTO_OPTIONS
419     }
420
421     # Check whether this test is supported for this target.
422     if { [lindex ${dg-do-what} 1 ] == "N" } {
423         unsupported "$src1"
424         verbose "$src1 not supported on this target, skipping it" 3
425         return
426     }
427
428     # Set up the names of the other source files.
429     set dir [file dirname $src1]
430     set base [file rootname $src1]
431     set base [string range $base [string length $dir] end]
432     regsub "_0" $base "" base
433     regsub "/" $base "" base
434     set src_list $src1
435     set i 1
436     set done 0
437     while { !$done } {
438         set names [glob -nocomplain -types f -- "${dir}/${base}_${i}.*"]
439         if { [llength ${names}] > 1 } {
440             warning "lto-execute: more than one file matched ${dir}/${base}_${i}.*"
441         }
442         if { [llength ${names}] == 1 } {
443             lappend src_list [lindex ${names} 0]
444             incr i
445         } else {
446             set num_srcs ${i}
447             set done 1
448         }
449     }
450
451     # Use the dg-options mechanism to specify extra flags for each
452     # of the secondary files.
453     # The extra flags in each file are used to compile that file, and the
454     # extra flags in *_0.* are also used for linking.
455     verbose "\tsrc_list is: $src_list"
456     for {set i 1} {$i < $num_srcs} {incr i} {
457         set extra_flags($i) [lto-get-options [lindex $src_list $i]]
458         set compile_xfail($i) $compiler_conditional_xfail_data
459     }
460
461     # Define the names of the object files.
462     set obj_list ""
463     for {set i 0} {$i < $num_srcs} {incr i} {
464         lappend obj_list "${sid}_${base}_${i}.o"
465     }
466
467     # Get the base name of this test, for use in messages.
468     set testcase [lindex ${src_list} 0]
469
470     # Remove the $srcdir and $tmpdir prefixes from $src1.  (It would
471     # be possible to use "regsub" here, if we were careful to escape
472     # all regular expression characters in $srcdir and $tmpdir, but
473     # that would be more complicated that this approach.) 
474     if {[string first "$srcdir/" "${testcase}"] == 0} {
475         set testcase [string range "${testcase}" [string length "$srcdir/"] end]
476     }
477     if {[string first "$tmpdir/" "$testcase"] == 0} {
478         set testcase [string range "$testcase" [string length "$tmpdir/"] end]
479         set testcase "tmpdir-$testcase"
480     }
481     regsub "_0.*" $testcase "" testcase
482
483     # Set up the base name of executable files so they'll be unique.
484     regsub -all "\[./\]" $testcase "-" execbase
485
486     # If we couldn't rip $srcdir out of `src1' then just do the best we can.
487     # The point is to reduce the unnecessary noise in the logs.  Don't strip
488     # out too much because different testcases with the same name can confuse
489     # `test-tool'.
490     if [string match "/*" $testcase] then {
491         set testcase "[file tail [file dirname $src1]]/[file tail $src1]"
492     }
493
494     # Loop through all of the option lists used for this test.
495     set count 0
496     foreach option $lto_option_list {
497         verbose "Testing $testcase, $option"
498
499         # There's a unique name for each executable we generate.
500         set execname "${execbase}-${count}1"
501         incr count
502
503         file_on_host delete $execname
504
505         # Compile pieces with the compiler under test.
506         set i 0
507         foreach src $src_list obj $obj_list {
508             lto-obj $src $obj $option $extra_flags($i) $option \
509                     $compile_xfail($i)
510             incr i
511         }
512
513         # Link (using the compiler under test), run, and clean up tests.
514         if { ![string compare "run" $compile_type] \
515              || ![string compare "link" $compile_type] } {
516
517             # Filter out any link options we were asked to suppress.
518             set reduced {}
519             foreach x [split $option] {
520               if {[lsearch ${dg-suppress-ld-options} $x] == -1} {
521                 lappend reduced $x
522               }
523             }
524             set filtered [join $reduced " "]
525
526             lto-link-and-maybe-run \
527                     "[lindex $obj_list 0]-[lindex $obj_list end]" \
528                     $obj_list $execname $filtered ${dg-extra-ld-options} \
529                     $filtered
530         }
531
532
533         # Are there any further tests to perform?
534         # Note that if the program has special run-time requirements, running
535         # of the program can be delayed until here.  Ditto for other situations.
536         # It would be a bit cumbersome though.
537
538         if ![string match ${dg-final-code} ""] {
539             regsub -all "\\\\(\[{}\])" ${dg-final-code} "\\1" dg-final-code
540             # Note that the use of `args' here makes this a varargs proc.
541             proc dg-final-proc { args } ${dg-final-code}
542             verbose "Running dg-final tests." 3
543             verbose "dg-final-proc:\n[info body dg-final-proc]" 4
544             if [catch "dg-final-proc $src1" errmsg] {
545                 perror "$name: error executing dg-final: $errmsg"
546                 # ??? The call to unresolved here is necessary to clear
547                 # `errcnt'.  What we really need is a proc like perror that
548                 # doesn't set errcnt.  It should also set exit_status to 1.
549                 unresolved "$name: error executing dg-final: $errmsg"
550             }
551         }
552
553         # Clean up object files.
554         set files [glob -nocomplain ${sid}_*.o]
555         if { $files != "" } {
556             foreach objfile $files {
557                 if { ![info exists gluefile] || $objfile != $gluefile } {
558                     eval "file_on_host delete $objfile"
559                 }
560             }
561         }
562
563         if { ![string compare "run" $compile_type] \
564              || ![string compare "link" $compile_type] } {
565             file_on_host delete $execname
566         }
567     }
568 }
569
570 # Utility for scanning a symbol in the final executable, invoked via dg-final.
571 # Call pass if pattern is present, otherwise fail.
572 #
573 # Argument 0 is the regexp to match.
574 # Argument 1 handles expected failures and the like
575 proc scan-symbol { args } {
576     global nm
577     global base_dir
578     upvar 2 execname execname
579
580     if { [llength $args] >= 2 } {
581         switch [dg-process-target [lindex $args 1]] {
582             "S" { }
583             "N" { return }
584             "F" { setup_xfail "*-*-*" }
585             "P" { }
586         }
587     }
588
589     # Find nm like we find g++ in g++.exp.
590     if ![info exists nm]  {
591         set nm [findfile $base_dir/../../../binutils/nm \
592                 $base_dir/../../../binutils/nm \
593                 [findfile $base_dir/../../nm $base_dir/../../nm \
594                       [findfile $base_dir/nm $base_dir/nm \
595                        [transform nm]]]]
596         verbose -log "nm is $nm"
597     }
598
599     set output_file "[glob -nocomplain $execname]"
600     if { $output_file == "" } {
601         fail "scan-symbol $args: dump file does not exist"
602         return
603     }
604
605     set fd [open "| $nm $output_file" r]
606     set text [read $fd]
607     close $fd
608
609     if [regexp -- [lindex $args 0] $text] {
610         pass "scan-symbol $args"
611     } else {
612         fail "scan-symbol $args"
613     }
614 }