jit.exp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. # Test code for libgccjit.so
  2. #
  3. # We will compile each of jit.dg/test-*.c into an executable
  4. # dynamically linked against libgccjit.so, and then run each
  5. # such executable.
  6. #
  7. # These executables call into the libgccjit.so API to create
  8. # code, compile it, and run it, verifying that the results
  9. # are as expected. See harness.h for shared code used by all
  10. # such executables.
  11. #
  12. # The executables call into DejaGnu's unit testing C API to
  13. # report PASS/FAIL results, which this script gathers back
  14. # up into the Tcl world, reporting a summary of all results
  15. # across all of the executables.
  16. # Kludge alert:
  17. # We need g++_init so that it can find the stdlib include path.
  18. #
  19. # g++_init (in lib/g++.exp) uses g++_maybe_build_wrapper,
  20. # which normally comes from the definition of
  21. # ${tool}_maybe_build_wrapper within lib/wrapper.exp.
  22. #
  23. # However, for us, ${tool} is "jit".
  24. # Hence we load wrapper.exp with tool == "g++", so that
  25. # g++_maybe_build_wrapper is defined.
  26. set tool g++
  27. load_lib wrapper.exp
  28. set tool jit
  29. load_lib dg.exp
  30. load_lib prune.exp
  31. load_lib target-supports.exp
  32. load_lib gcc-defs.exp
  33. load_lib timeout.exp
  34. load_lib target-libpath.exp
  35. load_lib gcc.exp
  36. load_lib g++.exp
  37. load_lib dejagnu.exp
  38. # Look for lines of the form:
  39. # definitely lost: 11,316 bytes in 235 blocks
  40. # indirectly lost: 352 bytes in 4 blocks
  41. # Ideally these would report zero bytes lost (which is a PASS);
  42. # for now, report non-zero leaks as XFAILs.
  43. proc report_leak {kind name logfile line} {
  44. set match [regexp "$kind lost: .*" $line result]
  45. if $match {
  46. verbose "Saw \"$result\" within \"$line\"" 4
  47. # Extract bytes and blocks.
  48. # These can contain commas as well as numerals,
  49. # but we only care about whether we have zero.
  50. regexp "$kind lost: (.+) bytes in (.+) blocks" \
  51. $result -> bytes blocks
  52. verbose "bytes: '$bytes'" 4
  53. verbose "blocks: '$blocks'" 4
  54. if { $bytes == 0 } {
  55. pass "$name: $logfile: $result"
  56. } else {
  57. xfail "$name: $logfile: $result"
  58. }
  59. }
  60. }
  61. proc parse_valgrind_logfile {name logfile} {
  62. verbose "parse_valgrind_logfile: $logfile" 2
  63. if [catch {set f [open $logfile]}] {
  64. fail "$name: unable to read $logfile"
  65. return
  66. }
  67. while { [gets $f line] >= 0 } {
  68. # Strip off the PID prefix e.g. ==7675==
  69. set line [regsub "==\[0-9\]*== " $line ""]
  70. verbose $line 2
  71. report_leak "definitely" $name $logfile $line
  72. report_leak "indirectly" $name $logfile $line
  73. }
  74. close $f
  75. }
  76. # Given WRES, the result from "wait", issue a PASS
  77. # if the spawnee exited cleanly, or a FAIL for various kinds of
  78. # unexpected exits.
  79. proc verify_exit_status { executable wres } {
  80. lassign $wres pid spawnid os_error_flag value
  81. verbose "pid: $pid" 3
  82. verbose "spawnid: $spawnid" 3
  83. verbose "os_error_flag: $os_error_flag" 3
  84. verbose "value: $value" 3
  85. # Detect segfaults etc:
  86. if { [llength $wres] > 4 } {
  87. if { [lindex $wres 4] == "CHILDKILLED" } {
  88. fail "$executable killed: $wres"
  89. return
  90. }
  91. }
  92. if { $os_error_flag != 0 } {
  93. fail "$executable: OS error: $wres"
  94. return
  95. }
  96. if { $value != 0 } {
  97. fail "$executable: non-zero exit code: $wres"
  98. return
  99. }
  100. pass "$executable exited cleanly"
  101. }
  102. # This is host_execute from dejagnu.exp commit
  103. # 126a089777158a7891ff975473939f08c0e31a1c
  104. # with the following patch applied, and renaming to "fixed_host_execute".
  105. # See the discussion at
  106. # http://lists.gnu.org/archive/html/dejagnu/2014-10/msg00000.html
  107. #
  108. # --- /usr/share/dejagnu/dejagnu.exp.old 2014-10-08 13:38:57.274068541 -0400
  109. # +++ /usr/share/dejagnu/dejagnu.exp 2014-10-10 12:27:51.113813659 -0400
  110. # @@ -113,8 +113,6 @@ proc host_execute {args} {
  111. # set timetol 0
  112. # set arguments ""
  113. #
  114. # - expect_before buffer_full { perror "Buffer full" }
  115. # -
  116. # if { [llength $args] == 0} {
  117. # set executable $args
  118. # } else {
  119. # Execute the executable file, and anaylyse the output for the
  120. # test state keywords.
  121. # Returns:
  122. # A "" (empty) string if everything worked, or an error message
  123. # if there was a problem.
  124. #
  125. proc fixed_host_execute {args} {
  126. global env
  127. global text
  128. global spawn_id
  129. verbose "fixed_host_execute: $args"
  130. set timeoutmsg "Timed out: Never got started, "
  131. set timeout 100
  132. set file all
  133. set timetol 0
  134. set arguments ""
  135. if { [llength $args] == 0} {
  136. set executable $args
  137. } else {
  138. set executable [lindex $args 0]
  139. set params [lindex $args 1]
  140. }
  141. verbose "The executable is $executable" 2
  142. if {![file exists ${executable}]} {
  143. perror "The executable, \"$executable\" is missing" 0
  144. return "No source file found"
  145. }
  146. verbose "params: $params" 2
  147. # spawn the executable and look for the DejaGnu output messages from the
  148. # test case.
  149. # spawn -noecho -open [open "|./${executable}" "r"]
  150. # Run under valgrind if RUN_UNDER_VALGRIND is present in the environment.
  151. # Note that it's best to configure gcc with --enable-valgrind-annotations
  152. # when testing under valgrind.
  153. set run_under_valgrind [info exists env(RUN_UNDER_VALGRIND)]
  154. if $run_under_valgrind {
  155. set valgrind_logfile "${executable}.valgrind.txt"
  156. set valgrind_params {"valgrind"}
  157. lappend valgrind_params "--leak-check=full"
  158. lappend valgrind_params "--log-file=${valgrind_logfile}"
  159. } else {
  160. set valgrind_params {}
  161. }
  162. verbose "valgrind_params: $valgrind_params" 2
  163. set args ${valgrind_params}
  164. lappend args "./${executable}"
  165. set args [concat $args ${params}]
  166. verbose "args: $args" 2
  167. eval spawn -noecho $args
  168. expect_after full_buffer { error "got full_buffer" }
  169. set prefix "\[^\r\n\]*"
  170. expect {
  171. -re "^$prefix\[0-9\]\[0-9\]:..:..:${text}*\r\n" {
  172. regsub "\[\n\r\t\]*NOTE: $text\r\n" $expect_out(0,string) "" output
  173. verbose "$output" 3
  174. set timetol 0
  175. exp_continue
  176. }
  177. -re "^$prefix\tNOTE:${text}*" {
  178. regsub "\[\n\r\t\]*NOTE: $text\r\n" $expect_out(0,string) "" output
  179. set output [string range $output 6 end]
  180. verbose "$output" 2
  181. set timetol 0
  182. exp_continue
  183. }
  184. -re "^$prefix\tPASSED:${text}*" {
  185. regsub "\[\n\r\t\]*PASSED: $text\r\n" $expect_out(0,string) "" output
  186. set output [string range $output 8 end]
  187. pass "$output"
  188. set timetol 0
  189. exp_continue
  190. }
  191. -re "^$prefix\tFAILED:${text}*" {
  192. regsub "\[\n\r\t\]*FAILED: $text\r\n" $expect_out(0,string) "" output
  193. set output [string range $output 8 end]
  194. fail "$output"
  195. set timetol 0
  196. exp_continue
  197. }
  198. -re "^$prefix\tUNTESTED:${text}*" {
  199. regsub "\[\n\r\t\]*TESTED: $text\r\n" $expect_out(0,string) "" output
  200. set output [string range $output 8 end]
  201. untested "$output"
  202. set timetol 0
  203. exp_continue
  204. }
  205. -re "^$prefix\tUNRESOLVED:${text}*" {
  206. regsub "\[\n\r\t\]*UNRESOLVED: $text\r\n" $expect_out(0,string) "" output
  207. set output [string range $output 8 end]
  208. unresolved "$output"
  209. set timetol 0
  210. exp_continue
  211. }
  212. -re "^Totals" {
  213. verbose "All done" 2
  214. }
  215. eof {
  216. # unresolved "${executable} died prematurely"
  217. # catch close
  218. # return "${executable} died prematurely"
  219. }
  220. timeout {
  221. warning "Timed out executing test case"
  222. if { $timetol <= 2 } {
  223. incr timetol
  224. exp_continue
  225. } else {
  226. catch close
  227. return "Timed out executing test case"
  228. }
  229. }
  230. -re "^$prefix\r\n" {
  231. exp_continue
  232. }
  233. }
  234. # Use "wait" before "close": valgrind might not have finished
  235. # writing the log out before we parse it, so we need to wait for
  236. # the spawnee to finish.
  237. catch wait wres
  238. verbose "wres: $wres" 2
  239. verify_exit_status $executable $wres
  240. if $run_under_valgrind {
  241. upvar 2 name name
  242. parse_valgrind_logfile $name $valgrind_logfile
  243. }
  244. # force a close of the executable to be safe.
  245. catch close
  246. return ""
  247. }
  248. # (end of code from dejagnu.exp)
  249. # GCC_UNDER_TEST is needed by gcc_target_compile
  250. global GCC_UNDER_TEST
  251. if ![info exists GCC_UNDER_TEST] {
  252. set GCC_UNDER_TEST "[find_gcc]"
  253. }
  254. g++_init
  255. # Initialize dg.
  256. dg-init
  257. # Gather a list of all tests.
  258. # C tests within the testsuite: gcc/testsuite/jit.dg/test-*.c
  259. set tests [find $srcdir/$subdir test-*.c]
  260. # C++ tests within the testsuite: gcc/testsuite/jit.dg/test-*.cc
  261. set tests [concat $tests [find $srcdir/$subdir test-*.cc]]
  262. # We also test the examples within the documentation, to ensure that
  263. # they compile:
  264. set tests [concat $tests [find $srcdir/../jit/docs/examples *.c]]
  265. set tests [concat $tests [find $srcdir/../jit/docs/examples *.cc]]
  266. set tests [lsort $tests]
  267. verbose "tests: $tests"
  268. # Is testcase NAME meant to generate a reproducer?
  269. proc is_testcase_meant_to_generate_a_reproducer {name} {
  270. # We expect most testcases to generate a reproducer.
  271. # The exceptions are the tutorials (which don't have a "test-"
  272. # prefix), and test-threads.c and test-benchmark.c (which are each
  273. # unique).
  274. verbose "is_testcase_meant_to_generate_a_reproducer: $name"
  275. if { [string match "*test-*" $name] } {
  276. if { [string match "*test-threads.c" $name] } {
  277. return 0
  278. }
  279. if { [string match "*test-benchmark.c" $name] } {
  280. return 0
  281. }
  282. return 1
  283. }
  284. return 0
  285. }
  286. # libgloss has found the driver (as "xgcc" or "gcc) and stored
  287. # its full path as GCC_UNDER_TEST.
  288. proc get_path_of_driver {} {
  289. global GCC_UNDER_TEST
  290. verbose "GCC_UNDER_TEST: $GCC_UNDER_TEST"
  291. set binary [lindex $GCC_UNDER_TEST 0]
  292. verbose "binary: $binary"
  293. return [file dirname $binary]
  294. }
  295. # Expand "SRCDIR" within ARG to the location of the top-level
  296. # src directory
  297. proc jit-expand-vars {arg} {
  298. verbose "jit-expand-vars: $arg"
  299. global srcdir
  300. verbose " srcdir: $srcdir"
  301. # "srcdir" is that of the gcc/testsuite directory, so
  302. # we need to go up two levels.
  303. set arg [string map [list "SRCDIR" $srcdir/../..] $arg]
  304. verbose " new arg: $arg"
  305. return $arg
  306. }
  307. # Parameters used when invoking the executables built from the test cases.
  308. global jit-exe-params
  309. set jit-exe-params {}
  310. # Set "jit-exe-params", expanding "SRCDIR" in each arg to the location of
  311. # the top-level srcdir.
  312. proc dg-jit-set-exe-params { args } {
  313. verbose "dg-jit-set-exe-params: $args"
  314. global jit-exe-params
  315. set jit-exe-params {}
  316. # Skip initial arg (line number)
  317. foreach arg [lrange $args 1 [llength $args] ] {
  318. lappend jit-exe-params [jit-expand-vars $arg]
  319. }
  320. }
  321. proc jit-dg-test { prog do_what extra_tool_flags } {
  322. verbose "within jit-dg-test..."
  323. verbose " prog: $prog"
  324. verbose " do_what: $do_what"
  325. verbose " extra_tool_flags: $extra_tool_flags"
  326. # test-threads.c needs to be linked against pthreads
  327. if {[string match "*test-threads.c" $prog]} {
  328. append extra_tool_flags " -lpthread"
  329. }
  330. # Any test case that uses jit-verify-output-file-was-created
  331. # needs to call jit-setup-compile-to-file here.
  332. # (is there a better way to handle setup/finish pairs in dg?)
  333. set tmp [grep $prog "jit-verify-output-file-was-created"]
  334. if {![string match "" $tmp]} {
  335. jit-setup-compile-to-file $prog
  336. }
  337. # Determine what to name the built executable.
  338. #
  339. # We simply append .exe to the filename, e.g.
  340. # "test-foo.c.exe"
  341. # since some testcases exist in both
  342. # "test-foo.c" and
  343. # "test-foo.cc"
  344. # variants, and we don't want them to clobber each other's
  345. # executables.
  346. #
  347. # This also ensures that the source name makes it into the
  348. # pass/fail output, so that we can distinguish e.g. which test-foo
  349. # is failing.
  350. set output_file "[file tail $prog].exe"
  351. verbose "output_file: $output_file"
  352. # Create the test executable:
  353. set extension [file extension $prog]
  354. if {$extension == ".cc"} {
  355. set compilation_function "g++_target_compile"
  356. set options "{additional_flags=$extra_tool_flags}"
  357. } else {
  358. set compilation_function "gcc_target_compile"
  359. # Until recently, <dejagnu.h> assumed -fgnu89-inline
  360. # Ideally we should fixincludes it (PR other/63613), but
  361. # for now add -fgnu89-inline when compiling C JIT testcases.
  362. # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63613
  363. # and http://lists.gnu.org/archive/html/dejagnu/2014-10/msg00011.html
  364. set options "{additional_flags=$extra_tool_flags -fgnu89-inline}"
  365. }
  366. verbose "compilation_function=$compilation_function"
  367. verbose "options=$options"
  368. set comp_output [$compilation_function $prog $output_file \
  369. "executable" $options]
  370. upvar 1 name name
  371. if ![jit_check_compile "$name" "initial compilation" \
  372. $output_file $comp_output] then {
  373. return
  374. }
  375. # Most of the test cases use gcc_jit_context_dump_reproducer_to_file
  376. # as they run to write out a .c file that reproduces their behavior,
  377. # exercising that API.
  378. set generated_reproducer "${output_file}.reproducer.c"
  379. # Delete any such generated .c file from a previous run.
  380. catch "exec rm -f $generated_reproducer"
  381. # Run the test executable, capturing the PASS/FAIL textual output
  382. # from the C API, converting it into the Tcl API.
  383. # We need to set LD_LIBRARY_PATH so that the test files can find
  384. # libgccjit.so
  385. # Do this using set_ld_library_path_env_vars from target-libpath.exp
  386. # We will restore the old value later using
  387. # restore_ld_library_path_env_vars.
  388. # Unfortunately this API only supports a single saved value, rather
  389. # than a stack, and g++_init has already called into this API,
  390. # injecting the appropriate value for LD_LIBRARY_PATH for finding
  391. # the built copy of libstdc++.
  392. # Hence the call to restore_ld_library_path_env_vars would restore
  393. # the *initial* value of LD_LIBRARY_PATH, and attempts to run
  394. # a C++ testcase after running any prior testcases would thus look
  395. # in the wrong place for libstdc++. This led to failures at startup
  396. # of the form:
  397. # ./tut01-hello-world.cc.exe: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./tut01-hello-world.cc.exe)
  398. # when the built libstdc++ is more recent that the system libstdc++.
  399. #
  400. # As a workaround, reset the variable "orig_environment_saved" within
  401. # target-libpath.exp, so that the {set|restore}_ld_library_path_env_vars
  402. # API saves/restores the current value of LD_LIBRARY_PATH (as set up
  403. # by g++_init).
  404. global orig_environment_saved
  405. set orig_environment_saved 0
  406. global ld_library_path
  407. global base_dir
  408. set ld_library_path "$base_dir/../../"
  409. set_ld_library_path_env_vars
  410. # libgccjit uses the driver to convert .s files to .so libraries
  411. # via its *installed* name, FULL_DRIVER_NAME
  412. # ${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}
  413. # e.g. "x86_64-unknown-linux-gnu-gcc-5.0.0"
  414. # looking for it on PATH. Hence we need to prepend the location of
  415. # that executable to PATH when running the tests
  416. set dir_containing_driver [get_path_of_driver ]
  417. verbose "dir_containing_driver: $dir_containing_driver"
  418. global env
  419. set old_path $env(PATH)
  420. setenv "PATH" $dir_containing_driver:$old_path
  421. verbose -log "PATH=[getenv PATH]"
  422. # We have:
  423. # test-executables
  424. # linked to -> libgccjit.so
  425. # -> invokes driver:
  426. # -> invokes the assembler
  427. # -> invokes the linker
  428. # We want to be able to run this from the builddir without installing
  429. # but the linker needs to be able to locate various libraries, or we
  430. # get:
  431. # ld: cannot find crtbeginS.o: No such file or directory
  432. # ld: cannot find -lgcc
  433. # ld: cannot find -lgcc_s
  434. # These can be found in the "gcc" subdir of the build.
  435. # Hence to be able to run the testsuite without installing, we need
  436. # to set or prepend the "gcc" subdir of the build to LIBRARY_PATH:
  437. if { [info exists env(LIBRARY_PATH) ] } {
  438. set old_library_path $env(LIBRARY_PATH)
  439. setenv "LIBRARY_PATH" $dir_containing_driver:$old_library_path
  440. } else {
  441. setenv "LIBRARY_PATH" $dir_containing_driver
  442. }
  443. verbose -log "LIBRARY_PATH=[getenv LIBRARY_PATH]"
  444. # dejagnu.exp's host_execute has code to scrape out test results
  445. # from the DejaGnu C API and bring back into the tcl world, so we
  446. # use that to invoke the built code.
  447. # However, it appears to be buggy; see:
  448. # http://lists.gnu.org/archive/html/dejagnu/2014-10/msg00000.html
  449. # We instead call a patched local copy, "fixed_host_execute", defined
  450. # above.
  451. global jit-exe-params
  452. set args ${jit-exe-params}
  453. set jit-exe-params {}
  454. set result [fixed_host_execute $output_file $args ]
  455. verbose "result: $result"
  456. # Restore PATH
  457. setenv "PATH" $old_path
  458. # Restore LIBRARY_PATH
  459. if { [info exists old_library_path] } {
  460. setenv "LIBRARY_PATH" $old_library_path
  461. } else {
  462. unsetenv "LIBRARY_PATH"
  463. }
  464. restore_ld_library_path_env_vars
  465. # Most of the test cases use gcc_jit_context_dump_reproducer_to_file
  466. # as they run to write out a .c file that reproduces their behavior,
  467. # exercising that API.
  468. if { [is_testcase_meant_to_generate_a_reproducer $name] } {
  469. verbose "$name is meant to generate a reproducer"
  470. # Verify that a reproducer was generated
  471. if { [file exists $generated_reproducer] == 1} {
  472. pass "found generated reproducer: $generated_reproducer"
  473. set output_file "${generated_reproducer}.exe"
  474. # (this overwrites output_file)
  475. # Try to compile the generated reproducer
  476. verbose "compilation_function=$compilation_function"
  477. # The .c file written by gcc_jit_context_dump_reproducer_to_file
  478. # assigns the result of each API call to a unique variable, and not
  479. # all are necessarily used, so we need -Wno-unused-variable.
  480. set options \
  481. "{additional_flags=$extra_tool_flags -Wno-unused-variable}"
  482. verbose "options=$options"
  483. set comp_output2 [$compilation_function $generated_reproducer \
  484. $output_file "executable" $options]
  485. if ![jit_check_compile "generated reproducer from $name" "initial compilation" \
  486. $output_file $comp_output2] then {
  487. return
  488. }
  489. # The caller, dg-test, will verify comp_output, which contains
  490. # the output from compiling the testcase and will issue a fail
  491. # if it's non-empty (e.g. containing warnings, the
  492. # "test for excess errors").
  493. #
  494. # Append the output from compiling the reproducer, so that this is also
  495. # verified:
  496. append comp_output $comp_output2
  497. # TODO: we should try to run the built executable
  498. # It's not quite a quine, since it embeds ptrs which could change
  499. # from run to run.
  500. } else {
  501. fail "did not find a generated reproducer: $generated_reproducer"
  502. }
  503. } else {
  504. verbose "$name is not meant to generate a reproducer"
  505. }
  506. return [list $comp_output $output_file]
  507. }
  508. # Given source file PROG, scrape out the value of
  509. # #define OUTPUT_FILENAME
  510. # failing if it's not found.
  511. proc jit-get-output-filename {prog} {
  512. set tmp [grep $prog "#define OUTPUT_FILENAME (.*)"]
  513. if {![string match "" $tmp]} {
  514. foreach i $tmp {
  515. verbose "i: $i"
  516. if {[regexp "^\#define OUTPUT_FILENAME\[ \t\]\+\"(.*)\"$" $i i group] } {
  517. verbose "group: '$group'"
  518. return $group
  519. } else {
  520. fail "Unable to parse line: $i"
  521. }
  522. }
  523. }
  524. fail "Unable to locate OUTPUT_FILENAME"
  525. return ""
  526. }
  527. # For testcases that use jit-verify-output-file-was-created
  528. # delete OUTPUT_FILENAME beforehand, to ensure that the
  529. # testcase is indeed creating it.
  530. proc jit-setup-compile-to-file { prog } {
  531. verbose "jit-setup-compile-to-file: $prog"
  532. set output_filename [jit-get-output-filename $prog]
  533. verbose " output_filename: $output_filename"
  534. if {![string match "" $output_filename]} {
  535. verbose " deleting any $output_filename"
  536. catch "exec rm -f $output_filename"
  537. }
  538. }
  539. proc jit-verify-output-file-was-created { args } {
  540. verbose "jit-verify-output-file-was-created: $args"
  541. upvar 2 prog prog
  542. verbose "prog: $prog"
  543. set output_filename [jit-get-output-filename $prog]
  544. verbose " output_filename: $output_filename"
  545. # Verify that the expected file was written out
  546. if { [file exists $output_filename] == 1} {
  547. pass "$output_filename exists"
  548. } else {
  549. fail "$output_filename does not exist"
  550. }
  551. }
  552. # Verify that the given file exists, and is executable.
  553. # Attempt to execute it, and verify that its stdout matches
  554. # the given regex.
  555. proc jit-run-executable { args } {
  556. verbose "jit-run-executable: $args"
  557. set executable-name [lindex $args 0]
  558. verbose "executable-name: ${executable-name}"
  559. set dg-output-text [lindex $args 1]
  560. verbose "dg-output-text: ${dg-output-text}"
  561. if { [file executable ${executable-name}] } {
  562. pass "${executable-name} has executable bit set"
  563. } else {
  564. fail "${executable-name} does not have executable bit set"
  565. }
  566. # Attempt to run the executable; adapted from dg.exp's dg-test
  567. set status -1
  568. set result [jit_load ./${executable-name}]
  569. set status [lindex $result 0]
  570. set output [lindex $result 1]
  571. verbose " status: $status"
  572. verbose " output: $output"
  573. # send_user "After exec, status: $status\n"
  574. if { "$status" == "pass" } {
  575. pass "${executable-name} execution test"
  576. verbose "Exec succeeded." 3
  577. set texttmp ${dg-output-text}
  578. if { ![regexp $texttmp ${output}] } {
  579. fail "${executable-name} output pattern test, is ${output}, should match $texttmp"
  580. verbose "Failed test for output pattern $texttmp" 3
  581. } else {
  582. pass "${executable-name} output pattern test, $texttmp"
  583. verbose "Passed test for output pattern $texttmp" 3
  584. }
  585. unset texttmp
  586. } elseif { "$status" == "fail" } {
  587. # It would be nice to get some info out of errorCode.
  588. if {[info exists errorCode]} {
  589. verbose "Exec failed, errorCode: $errorCode" 3
  590. } else {
  591. verbose "Exec failed, errorCode not defined!" 3
  592. }
  593. fail "${executable-name} execution test"
  594. } else {
  595. $status "${executable-name} execution test"
  596. }
  597. }
  598. # Assuming that a .s file has been written out named
  599. # OUTPUT_FILENAME, invoke the driver to try to turn it into
  600. # an executable, and try to run the result.
  601. # For use by the test-compile-to-assembler.c testcase.
  602. proc jit-verify-assembler { args } {
  603. verbose "jit-verify-assembler: $args"
  604. set dg-output-text [lindex $args 0]
  605. verbose "dg-output-text: ${dg-output-text}"
  606. upvar 2 name name
  607. verbose "name: $name"
  608. upvar 2 prog prog
  609. verbose "prog: $prog"
  610. set asm_filename [jit-get-output-filename $prog]
  611. verbose " asm_filename: ${asm_filename}"
  612. # Name the built executable as OUTPUT_FILENAME with
  613. # ".exe" appended.
  614. set executable_from_asm ${asm_filename}.exe
  615. verbose " executable_from_asm: ${executable_from_asm}"
  616. # Invoke the driver to assemble/link the .s file to the .exe
  617. set comp_output [gcc_target_compile \
  618. ${asm_filename} \
  619. ${executable_from_asm} \
  620. "executable" \
  621. "{}"]
  622. if ![jit_check_compile \
  623. "$name" \
  624. "assemble/link of ${asm_filename}" \
  625. ${executable_from_asm} \
  626. $comp_output] then {
  627. return
  628. }
  629. # Verify that the executable was created.
  630. if { [file exists $executable_from_asm] == 1} {
  631. pass "$executable_from_asm exists"
  632. } else {
  633. fail "$executable_from_asm does not exist"
  634. }
  635. # Run it and verify that the output matches the regex.
  636. jit-run-executable ${executable_from_asm} ${dg-output-text}
  637. }
  638. # Assuming that a .o file has been written out named
  639. # OUTPUT_FILENAME, invoke the driver to try to turn it into
  640. # an executable, and try to run the result.
  641. # For use by the test-compile-to-object.c testcase.
  642. proc jit-verify-object { args } {
  643. verbose "jit-verify-object: $args"
  644. set dg-output-text [lindex $args 0]
  645. verbose "dg-output-text: ${dg-output-text}"
  646. upvar 2 name name
  647. verbose "name: $name"
  648. upvar 2 prog prog
  649. verbose "prog: $prog"
  650. set obj_filename [jit-get-output-filename $prog]
  651. verbose " obj_filename: ${obj_filename}"
  652. # Name the linked executable as OUTPUT_FILENAME with
  653. # ".exe" appended.
  654. set executable_from_obj ${obj_filename}.exe
  655. verbose " executable_from_obj: ${executable_from_obj}"
  656. # Invoke the driver to link the .o file to the .exe
  657. set comp_output [gcc_target_compile \
  658. ${obj_filename} \
  659. ${executable_from_obj} \
  660. "executable" \
  661. "{}"]
  662. if ![jit_check_compile \
  663. "$name" \
  664. "link of ${obj_filename}" \
  665. ${executable_from_obj} \
  666. $comp_output] then {
  667. return
  668. }
  669. # Verify that the executable was created.
  670. if { [file exists $executable_from_obj] == 1} {
  671. pass "$executable_from_obj exists"
  672. } else {
  673. fail "$executable_from_obj does not exist"
  674. }
  675. # Run it and verify that the output matches the regex.
  676. jit-run-executable ${executable_from_obj} ${dg-output-text}
  677. }
  678. # Assuming that a .so file has been written out named
  679. # OUTPUT_FILENAME, build a test executable to use it,
  680. # and try to run the result.
  681. # For use by the test-compile-to-dynamic-library.c testcase.
  682. proc jit-verify-dynamic-library { args } {
  683. verbose "jit-verify-object: $args"
  684. global srcdir
  685. global subdir
  686. set dg-output-text [lindex $args 0]
  687. verbose "dg-output-text: ${dg-output-text}"
  688. upvar 2 name name
  689. verbose "name: $name"
  690. upvar 2 prog prog
  691. verbose "prog: $prog"
  692. set obj_filename [jit-get-output-filename $prog]
  693. verbose " obj_filename: ${obj_filename}"
  694. # Build a test executable from
  695. # verify-dynamic-library.c
  696. set test_src "verify-dynamic-library.c"
  697. set test_executable ${test_src}.exe
  698. verbose " test_executable: ${test_executable}"
  699. # Invoke the driver to build the test executable
  700. set comp_output [gcc_target_compile \
  701. $srcdir/$subdir/${test_src} \
  702. ${test_executable} \
  703. "executable" \
  704. "{additional_flags=-ldl}"]
  705. if ![jit_check_compile \
  706. "$name" \
  707. "build of ${test_executable}" \
  708. ${test_executable} \
  709. $comp_output] then {
  710. return
  711. }
  712. # Verify that the test executable was created.
  713. if { [file exists $test_executable] == 1} {
  714. pass "$test_executable exists"
  715. } else {
  716. fail "$test_executable does not exist"
  717. }
  718. # Run it and verify that the output matches the regex.
  719. jit-run-executable ${test_executable} ${dg-output-text}
  720. }
  721. # A way to invoke "jit-run-executable" with the given regex,
  722. # using OUTPUT_FILENAME within the testcase to determine
  723. # the name of the executable to run.
  724. # For use by the test-compile-to-executable.c testcase.
  725. proc jit-verify-executable { args } {
  726. verbose "jit-verify-executable: $args"
  727. set dg-output-text [lindex $args 0]
  728. verbose "dg-output-text: ${dg-output-text}"
  729. upvar 2 name name
  730. verbose "name: $name"
  731. upvar 2 prog prog
  732. verbose "prog: $prog"
  733. set output_filename [jit-get-output-filename $prog]
  734. verbose " output_filename: $output_filename"
  735. jit-run-executable $output_filename ${dg-output-text}
  736. }
  737. # We need to link with --export-dynamic for test-calling-external-function.c
  738. # so that the JIT-built code can call into functions from the main program.
  739. set DEFAULT_CFLAGS "-I$srcdir/../jit -lgccjit -g -Wall -Werror -Wl,--export-dynamic"
  740. # Main loop. This will invoke jig-dg-test on each test-*.c file.
  741. dg-runtest $tests "" $DEFAULT_CFLAGS
  742. # All done.
  743. dg-finish