libgccjit.texi revision 1.3
1\input texinfo @c -*-texinfo-*- 2@c %**start of header 3@setfilename libgccjit.info 4@documentencoding UTF-8 5@ifinfo 6@*Generated by Sphinx 1.1.3.@* 7@end ifinfo 8@settitle libgccjit Documentation 9@defindex ge 10@paragraphindent 2 11@exampleindent 4 12@afourlatex 13@dircategory Miscellaneous 14@direntry 15* libgccjit: (libgccjit.info). One line description of project. 16@end direntry 17 18@c %**end of header 19 20@copying 21@quotation 22libgccjit 7.0.0 (experimental 20160517), May 17, 2016 23 24David Malcolm 25 26Copyright @copyright{} 2014-2017 Free Software Foundation, Inc. 27@end quotation 28 29@end copying 30 31@titlepage 32@title libgccjit Documentation 33@insertcopying 34@end titlepage 35@contents 36 37@c %** start of user preamble 38 39@c %** end of user preamble 40 41@ifnottex 42@node Top 43@top libgccjit Documentation 44@insertcopying 45@end ifnottex 46 47@c %**start of body 48@anchor{index doc}@anchor{0} 49@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 50@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 51@c 52@c This is free software: you can redistribute it and/or modify it 53@c under the terms of the GNU General Public License as published by 54@c the Free Software Foundation, either version 3 of the License, or 55@c (at your option) any later version. 56@c 57@c This program is distributed in the hope that it will be useful, but 58@c WITHOUT ANY WARRANTY; without even the implied warranty of 59@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 60@c General Public License for more details. 61@c 62@c You should have received a copy of the GNU General Public License 63@c along with this program. If not, see 64@c <http://www.gnu.org/licenses/>. 65 66This document describes libgccjit@footnote{http://gcc.gnu.org/wiki/JIT}, an API 67for embedding GCC inside programs and libraries. 68 69Note that libgccjit is currently of "Alpha" quality; 70the APIs are not yet set in stone, and they shouldn't be used in 71production yet. 72 73There are actually two APIs for the library: 74 75 76@itemize * 77 78@item 79a pure C API: @code{libgccjit.h} 80 81@item 82a C++ wrapper API: @code{libgccjit++.h}. This is a collection of "thin" 83wrapper classes around the C API, to save typing. 84@end itemize 85 86Contents: 87 88@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 89@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 90@c 91@c This is free software: you can redistribute it and/or modify it 92@c under the terms of the GNU General Public License as published by 93@c the Free Software Foundation, either version 3 of the License, or 94@c (at your option) any later version. 95@c 96@c This program is distributed in the hope that it will be useful, but 97@c WITHOUT ANY WARRANTY; without even the implied warranty of 98@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 99@c General Public License for more details. 100@c 101@c You should have received a copy of the GNU General Public License 102@c along with this program. If not, see 103@c <http://www.gnu.org/licenses/>. 104 105@menu 106* Tutorial:: 107* Topic Reference:: 108* C++ bindings for libgccjit:: 109* Internals:: 110* Indices and tables:: 111* Index:: 112 113@detailmenu 114 --- The Detailed Node Listing --- 115 116Tutorial 117 118* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world". 119* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function. 120* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables. 121* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter. 122* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler. 123 124Tutorial part 2: Creating a trivial machine code function 125 126* Error-handling:: 127* Options:: 128* Full example:: 129 130Tutorial part 3: Loops and variables 131 132* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. 133* Control flow:: 134* Visualizing the control flow graph:: 135* Full example: Full example<2>. 136 137Tutorial part 4: Adding JIT-compilation to a toy interpreter 138 139* Our toy interpreter:: 140* Compiling to machine code:: 141* Setting things up:: 142* Populating the function:: 143* Verifying the control flow graph:: 144* Compiling the context:: 145* Single-stepping through the generated code:: 146* Examining the generated code:: 147* Putting it all together:: 148* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?. 149 150Behind the curtain: How does our code get optimized? 151 152* Optimizing away stack manipulation:: 153* Elimination of tail recursion:: 154 155Tutorial part 5: Implementing an Ahead-of-Time compiler 156 157* The "brainf" language:: 158* Converting a brainf script to libgccjit IR:: 159* Compiling a context to a file:: 160* Other forms of ahead-of-time-compilation:: 161 162Topic Reference 163 164* Compilation contexts:: 165* Objects:: 166* Types:: 167* Expressions:: 168* Creating and using functions:: 169* Source Locations:: 170* Compiling a context:: 171* ABI and API compatibility:: 172* Performance:: 173 174Compilation contexts 175 176* Lifetime-management:: 177* Thread-safety:: 178* Error-handling: Error-handling<2>. 179* Debugging:: 180* Options: Options<2>. 181 182Options 183 184* String Options:: 185* Boolean options:: 186* Integer options:: 187* Additional command-line options:: 188 189Types 190 191* Standard types:: 192* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 193* Structures and unions:: 194 195Expressions 196 197* Rvalues:: 198* Lvalues:: 199* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 200 201Rvalues 202 203* Simple expressions:: 204* Unary Operations:: 205* Binary Operations:: 206* Comparisons:: 207* Function calls:: 208* Type-coercion:: 209 210Lvalues 211 212* Global variables:: 213 214Creating and using functions 215 216* Params:: 217* Functions:: 218* Blocks:: 219* Statements:: 220 221Source Locations 222 223* Faking it:: 224 225Compiling a context 226 227* In-memory compilation:: 228* Ahead-of-time compilation:: 229 230ABI and API compatibility 231 232* ABI symbol tags:: 233 234ABI symbol tags 235 236* LIBGCCJIT_ABI_0:: 237* LIBGCCJIT_ABI_1:: 238* LIBGCCJIT_ABI_2:: 239* LIBGCCJIT_ABI_3:: 240* LIBGCCJIT_ABI_4:: 241* LIBGCCJIT_ABI_5:: 242 243Performance 244 245* The timing API:: 246 247C++ bindings for libgccjit 248 249* Tutorial: Tutorial<2>. 250* Topic Reference: Topic Reference<2>. 251 252Tutorial 253 254* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 255* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 256* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 257* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 258 259Tutorial part 2: Creating a trivial machine code function 260 261* Options: Options<3>. 262* Full example: Full example<3>. 263 264Tutorial part 3: Loops and variables 265 266* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 267* Control flow: Control flow<2>. 268* Visualizing the control flow graph: Visualizing the control flow graph<2>. 269* Full example: Full example<4>. 270 271Tutorial part 4: Adding JIT-compilation to a toy interpreter 272 273* Our toy interpreter: Our toy interpreter<2>. 274* Compiling to machine code: Compiling to machine code<2>. 275* Setting things up: Setting things up<2>. 276* Populating the function: Populating the function<2>. 277* Verifying the control flow graph: Verifying the control flow graph<2>. 278* Compiling the context: Compiling the context<2>. 279* Single-stepping through the generated code: Single-stepping through the generated code<2>. 280* Examining the generated code: Examining the generated code<2>. 281* Putting it all together: Putting it all together<2>. 282* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 283 284Behind the curtain: How does our code get optimized? 285 286* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 287* Elimination of tail recursion: Elimination of tail recursion<2>. 288 289Topic Reference 290 291* Compilation contexts: Compilation contexts<2>. 292* Objects: Objects<2>. 293* Types: Types<2>. 294* Expressions: Expressions<2>. 295* Creating and using functions: Creating and using functions<2>. 296* Source Locations: Source Locations<2>. 297* Compiling a context: Compiling a context<2>. 298 299Compilation contexts 300 301* Lifetime-management: Lifetime-management<2>. 302* Thread-safety: Thread-safety<2>. 303* Error-handling: Error-handling<3>. 304* Debugging: Debugging<2>. 305* Options: Options<4>. 306 307Options 308 309* String Options: String Options<2>. 310* Boolean options: Boolean options<2>. 311* Integer options: Integer options<2>. 312* Additional command-line options: Additional command-line options<2>. 313 314Types 315 316* Standard types: Standard types<2>. 317* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 318* Structures and unions: Structures and unions<2>. 319 320Expressions 321 322* Rvalues: Rvalues<2>. 323* Lvalues: Lvalues<2>. 324* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 325 326Rvalues 327 328* Simple expressions: Simple expressions<2>. 329* Unary Operations: Unary Operations<2>. 330* Binary Operations: Binary Operations<2>. 331* Comparisons: Comparisons<2>. 332* Function calls: Function calls<2>. 333* Type-coercion: Type-coercion<2>. 334 335Lvalues 336 337* Global variables: Global variables<2>. 338 339Creating and using functions 340 341* Params: Params<2>. 342* Functions: Functions<2>. 343* Blocks: Blocks<2>. 344* Statements: Statements<2>. 345 346Source Locations 347 348* Faking it: Faking it<2>. 349 350Compiling a context 351 352* In-memory compilation: In-memory compilation<2>. 353* Ahead-of-time compilation: Ahead-of-time compilation<2>. 354 355Internals 356 357* Working on the JIT library:: 358* Running the test suite:: 359* Environment variables:: 360* Packaging notes:: 361* Overview of code structure:: 362* Design notes:: 363* Submitting patches:: 364 365Running the test suite 366 367* Running under valgrind:: 368 369@end detailmenu 370@end menu 371 372 373@node Tutorial,Topic Reference,Top,Top 374@anchor{intro/index libgccjit}@anchor{1}@anchor{intro/index doc}@anchor{2}@anchor{intro/index tutorial}@anchor{3} 375@chapter Tutorial 376 377 378@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 379@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 380@c 381@c This is free software: you can redistribute it and/or modify it 382@c under the terms of the GNU General Public License as published by 383@c the Free Software Foundation, either version 3 of the License, or 384@c (at your option) any later version. 385@c 386@c This program is distributed in the hope that it will be useful, but 387@c WITHOUT ANY WARRANTY; without even the implied warranty of 388@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 389@c General Public License for more details. 390@c 391@c You should have received a copy of the GNU General Public License 392@c along with this program. If not, see 393@c <http://www.gnu.org/licenses/>. 394 395@menu 396* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world". 397* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function. 398* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables. 399* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter. 400* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler. 401 402@end menu 403 404@node Tutorial part 1 "Hello world",Tutorial part 2 Creating a trivial machine code function,,Tutorial 405@anchor{intro/tutorial01 doc}@anchor{4}@anchor{intro/tutorial01 tutorial-part-1-hello-world}@anchor{5} 406@section Tutorial part 1: "Hello world" 407 408 409Before we look at the details of the API, let's look at building and 410running programs that use the library. 411 412Here's a toy "hello world" program that uses the library to synthesize 413a call to @cite{printf} and uses it to write a message to stdout. 414 415Don't worry about the content of the program for now; we'll cover 416the details in later parts of this tutorial. 417 418@quotation 419 420@example 421/* Smoketest example for libgccjit.so 422 Copyright (C) 2014-2017 Free Software Foundation, Inc. 423 424This file is part of GCC. 425 426GCC is free software; you can redistribute it and/or modify it 427under the terms of the GNU General Public License as published by 428the Free Software Foundation; either version 3, or (at your option) 429any later version. 430 431GCC is distributed in the hope that it will be useful, but 432WITHOUT ANY WARRANTY; without even the implied warranty of 433MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 434General Public License for more details. 435 436You should have received a copy of the GNU General Public License 437along with GCC; see the file COPYING3. If not see 438<http://www.gnu.org/licenses/>. */ 439 440#include <libgccjit.h> 441 442#include <stdlib.h> 443#include <stdio.h> 444 445static void 446create_code (gcc_jit_context *ctxt) 447@{ 448 /* Let's try to inject the equivalent of: 449 void 450 greet (const char *name) 451 @{ 452 printf ("hello %s\n", name); 453 @} 454 */ 455 gcc_jit_type *void_type = 456 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); 457 gcc_jit_type *const_char_ptr_type = 458 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); 459 gcc_jit_param *param_name = 460 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); 461 gcc_jit_function *func = 462 gcc_jit_context_new_function (ctxt, NULL, 463 GCC_JIT_FUNCTION_EXPORTED, 464 void_type, 465 "greet", 466 1, ¶m_name, 467 0); 468 469 gcc_jit_param *param_format = 470 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); 471 gcc_jit_function *printf_func = 472 gcc_jit_context_new_function (ctxt, NULL, 473 GCC_JIT_FUNCTION_IMPORTED, 474 gcc_jit_context_get_type ( 475 ctxt, GCC_JIT_TYPE_INT), 476 "printf", 477 1, ¶m_format, 478 1); 479 gcc_jit_rvalue *args[2]; 480 args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); 481 args[1] = gcc_jit_param_as_rvalue (param_name); 482 483 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 484 485 gcc_jit_block_add_eval ( 486 block, NULL, 487 gcc_jit_context_new_call (ctxt, 488 NULL, 489 printf_func, 490 2, args)); 491 gcc_jit_block_end_with_void_return (block, NULL); 492@} 493 494int 495main (int argc, char **argv) 496@{ 497 gcc_jit_context *ctxt; 498 gcc_jit_result *result; 499 500 /* Get a "context" object for working with the library. */ 501 ctxt = gcc_jit_context_acquire (); 502 if (!ctxt) 503 @{ 504 fprintf (stderr, "NULL ctxt"); 505 exit (1); 506 @} 507 508 /* Set some options on the context. 509 Let's see the code being generated, in assembler form. */ 510 gcc_jit_context_set_bool_option ( 511 ctxt, 512 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 513 0); 514 515 /* Populate the context. */ 516 create_code (ctxt); 517 518 /* Compile the code. */ 519 result = gcc_jit_context_compile (ctxt); 520 if (!result) 521 @{ 522 fprintf (stderr, "NULL result"); 523 exit (1); 524 @} 525 526 /* Extract the generated code from "result". */ 527 typedef void (*fn_type) (const char *); 528 fn_type greet = 529 (fn_type)gcc_jit_result_get_code (result, "greet"); 530 if (!greet) 531 @{ 532 fprintf (stderr, "NULL greet"); 533 exit (1); 534 @} 535 536 /* Now call the generated function: */ 537 greet ("world"); 538 fflush (stdout); 539 540 gcc_jit_context_release (ctxt); 541 gcc_jit_result_release (result); 542 return 0; 543@} 544 545@end example 546 547@noindent 548@end quotation 549 550Copy the above to @cite{tut01-hello-world.c}. 551 552Assuming you have the jit library installed, build the test program 553using: 554 555@example 556$ gcc \ 557 tut01-hello-world.c \ 558 -o tut01-hello-world \ 559 -lgccjit 560@end example 561 562@noindent 563 564You should then be able to run the built program: 565 566@example 567$ ./tut01-hello-world 568hello world 569@end example 570 571@noindent 572 573@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 574@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 575@c 576@c This is free software: you can redistribute it and/or modify it 577@c under the terms of the GNU General Public License as published by 578@c the Free Software Foundation, either version 3 of the License, or 579@c (at your option) any later version. 580@c 581@c This program is distributed in the hope that it will be useful, but 582@c WITHOUT ANY WARRANTY; without even the implied warranty of 583@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 584@c General Public License for more details. 585@c 586@c You should have received a copy of the GNU General Public License 587@c along with this program. If not, see 588@c <http://www.gnu.org/licenses/>. 589 590@node Tutorial part 2 Creating a trivial machine code function,Tutorial part 3 Loops and variables,Tutorial part 1 "Hello world",Tutorial 591@anchor{intro/tutorial02 doc}@anchor{6}@anchor{intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{7} 592@section Tutorial part 2: Creating a trivial machine code function 593 594 595Consider this C function: 596 597@example 598int square (int i) 599@{ 600 return i * i; 601@} 602@end example 603 604@noindent 605 606How can we construct this at run-time using libgccjit? 607 608First we need to include the relevant header: 609 610@example 611#include <libgccjit.h> 612@end example 613 614@noindent 615 616All state associated with compilation is associated with a 617@pxref{8,,gcc_jit_context *}. 618 619Create one using @pxref{9,,gcc_jit_context_acquire()}: 620 621@example 622gcc_jit_context *ctxt; 623ctxt = gcc_jit_context_acquire (); 624@end example 625 626@noindent 627 628The JIT library has a system of types. It is statically-typed: every 629expression is of a specific type, fixed at compile-time. In our example, 630all of the expressions are of the C @cite{int} type, so let's obtain this from 631the context, as a @pxref{a,,gcc_jit_type *}, using 632@pxref{b,,gcc_jit_context_get_type()}: 633 634@example 635gcc_jit_type *int_type = 636 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 637@end example 638 639@noindent 640 641@pxref{a,,gcc_jit_type *} is an example of a "contextual" object: every 642entity in the API is associated with a @pxref{8,,gcc_jit_context *}. 643 644Memory management is easy: all such "contextual" objects are automatically 645cleaned up for you when the context is released, using 646@pxref{c,,gcc_jit_context_release()}: 647 648@example 649gcc_jit_context_release (ctxt); 650@end example 651 652@noindent 653 654so you don't need to manually track and cleanup all objects, just the 655contexts. 656 657Although the API is C-based, there is a form of class hierarchy, which 658looks like this: 659 660@example 661+- gcc_jit_object 662 +- gcc_jit_location 663 +- gcc_jit_type 664 +- gcc_jit_struct 665 +- gcc_jit_field 666 +- gcc_jit_function 667 +- gcc_jit_block 668 +- gcc_jit_rvalue 669 +- gcc_jit_lvalue 670 +- gcc_jit_param 671@end example 672 673@noindent 674 675There are casting methods for upcasting from subclasses to parent classes. 676For example, @pxref{d,,gcc_jit_type_as_object()}: 677 678@example 679gcc_jit_object *obj = gcc_jit_type_as_object (int_type); 680@end example 681 682@noindent 683 684One thing you can do with a @pxref{e,,gcc_jit_object *} is 685to ask it for a human-readable description, using 686@pxref{f,,gcc_jit_object_get_debug_string()}: 687 688@example 689printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); 690@end example 691 692@noindent 693 694giving this text on stdout: 695 696@example 697obj: int 698@end example 699 700@noindent 701 702This is invaluable when debugging. 703 704Let's create the function. To do so, we first need to construct 705its single parameter, specifying its type and giving it a name, 706using @pxref{10,,gcc_jit_context_new_param()}: 707 708@example 709gcc_jit_param *param_i = 710 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 711@end example 712 713@noindent 714 715Now we can create the function, using 716@pxref{11,,gcc_jit_context_new_function()}: 717 718@example 719gcc_jit_function *func = 720 gcc_jit_context_new_function (ctxt, NULL, 721 GCC_JIT_FUNCTION_EXPORTED, 722 int_type, 723 "square", 724 1, ¶m_i, 725 0); 726@end example 727 728@noindent 729 730To define the code within the function, we must create basic blocks 731containing statements. 732 733Every basic block contains a list of statements, eventually terminated 734by a statement that either returns, or jumps to another basic block. 735 736Our function has no control-flow, so we just need one basic block: 737 738@example 739gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 740@end example 741 742@noindent 743 744Our basic block is relatively simple: it immediately terminates by 745returning the value of an expression. 746 747We can build the expression using @pxref{12,,gcc_jit_context_new_binary_op()}: 748 749@example 750gcc_jit_rvalue *expr = 751 gcc_jit_context_new_binary_op ( 752 ctxt, NULL, 753 GCC_JIT_BINARY_OP_MULT, int_type, 754 gcc_jit_param_as_rvalue (param_i), 755 gcc_jit_param_as_rvalue (param_i)); 756@end example 757 758@noindent 759 760A @pxref{13,,gcc_jit_rvalue *} is another example of a 761@pxref{e,,gcc_jit_object *} subclass. We can upcast it using 762@pxref{14,,gcc_jit_rvalue_as_object()} and as before print it with 763@pxref{f,,gcc_jit_object_get_debug_string()}. 764 765@example 766printf ("expr: %s\n", 767 gcc_jit_object_get_debug_string ( 768 gcc_jit_rvalue_as_object (expr))); 769@end example 770 771@noindent 772 773giving this output: 774 775@example 776expr: i * i 777@end example 778 779@noindent 780 781Creating the expression in itself doesn't do anything; we have to add 782this expression to a statement within the block. In this case, we use it 783to build a return statement, which terminates the basic block: 784 785@example 786gcc_jit_block_end_with_return (block, NULL, expr); 787@end example 788 789@noindent 790 791OK, we've populated the context. We can now compile it using 792@pxref{15,,gcc_jit_context_compile()}: 793 794@example 795gcc_jit_result *result; 796result = gcc_jit_context_compile (ctxt); 797@end example 798 799@noindent 800 801and get a @pxref{16,,gcc_jit_result *}. 802 803At this point we're done with the context; we can release it: 804 805@example 806gcc_jit_context_release (ctxt); 807@end example 808 809@noindent 810 811We can now use @pxref{17,,gcc_jit_result_get_code()} to look up a specific 812machine code routine within the result, in this case, the function we 813created above. 814 815@example 816void *fn_ptr = gcc_jit_result_get_code (result, "square"); 817if (!fn_ptr) 818 @{ 819 fprintf (stderr, "NULL fn_ptr"); 820 goto error; 821 @} 822@end example 823 824@noindent 825 826We can now cast the pointer to an appropriate function pointer type, and 827then call it: 828 829@example 830typedef int (*fn_type) (int); 831fn_type square = (fn_type)fn_ptr; 832printf ("result: %d", square (5)); 833@end example 834 835@noindent 836 837@example 838result: 25 839@end example 840 841@noindent 842 843Once we're done with the code, we can release the result: 844 845@example 846gcc_jit_result_release (result); 847@end example 848 849@noindent 850 851We can't call @code{square} anymore once we've released @code{result}. 852 853@menu 854* Error-handling:: 855* Options:: 856* Full example:: 857 858@end menu 859 860@node Error-handling,Options,,Tutorial part 2 Creating a trivial machine code function 861@anchor{intro/tutorial02 error-handling}@anchor{18} 862@subsection Error-handling 863 864 865Various kinds of errors are possible when using the API, such as 866mismatched types in an assignment. You can only compile and get code 867from a context if no errors occur. 868 869Errors are printed on stderr; they typically contain the name of the API 870entrypoint where the error occurred, and pertinent information on the 871problem: 872 873@example 874./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *) 875@end example 876 877@noindent 878 879The API is designed to cope with errors without crashing, so you can get 880away with having a single error-handling check in your code: 881 882@example 883void *fn_ptr = gcc_jit_result_get_code (result, "square"); 884if (!fn_ptr) 885 @{ 886 fprintf (stderr, "NULL fn_ptr"); 887 goto error; 888 @} 889@end example 890 891@noindent 892 893For more information, see the @pxref{19,,error-handling guide} 894within the Topic eference. 895 896@node Options,Full example,Error-handling,Tutorial part 2 Creating a trivial machine code function 897@anchor{intro/tutorial02 options}@anchor{1a} 898@subsection Options 899 900 901To get more information on what's going on, you can set debugging flags 902on the context using @pxref{1b,,gcc_jit_context_set_bool_option()}. 903 904@c (I'm deliberately not mentioning 905@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think 906@c it's probably more of use to implementors than to users) 907 908Setting @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a 909C-like representation to stderr when you compile (GCC's "GIMPLE" 910representation): 911 912@example 913gcc_jit_context_set_bool_option ( 914 ctxt, 915 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 916 1); 917result = gcc_jit_context_compile (ctxt); 918@end example 919 920@noindent 921 922@example 923square (signed int i) 924@{ 925 signed int D.260; 926 927 entry: 928 D.260 = i * i; 929 return D.260; 930@} 931@end example 932 933@noindent 934 935We can see the generated machine code in assembler form (on stderr) by 936setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context 937before compiling: 938 939@example 940gcc_jit_context_set_bool_option ( 941 ctxt, 942 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 943 1); 944result = gcc_jit_context_compile (ctxt); 945@end example 946 947@noindent 948 949@example 950 .file "fake.c" 951 .text 952 .globl square 953 .type square, @@function 954square: 955.LFB6: 956 .cfi_startproc 957 pushq %rbp 958 .cfi_def_cfa_offset 16 959 .cfi_offset 6, -16 960 movq %rsp, %rbp 961 .cfi_def_cfa_register 6 962 movl %edi, -4(%rbp) 963.L14: 964 movl -4(%rbp), %eax 965 imull -4(%rbp), %eax 966 popq %rbp 967 .cfi_def_cfa 7, 8 968 ret 969 .cfi_endproc 970.LFE6: 971 .size square, .-square 972 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 973 .section .note.GNU-stack,"",@@progbits 974@end example 975 976@noindent 977 978By default, no optimizations are performed, the equivalent of GCC's 979@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling 980@pxref{1e,,gcc_jit_context_set_int_option()} with 981@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 982 983@example 984gcc_jit_context_set_int_option ( 985 ctxt, 986 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 987 3); 988@end example 989 990@noindent 991 992@example 993 .file "fake.c" 994 .text 995 .p2align 4,,15 996 .globl square 997 .type square, @@function 998square: 999.LFB7: 1000 .cfi_startproc 1001.L16: 1002 movl %edi, %eax 1003 imull %edi, %eax 1004 ret 1005 .cfi_endproc 1006.LFE7: 1007 .size square, .-square 1008 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 1009 .section .note.GNU-stack,"",@@progbits 1010@end example 1011 1012@noindent 1013 1014Naturally this has only a small effect on such a trivial function. 1015 1016@node Full example,,Options,Tutorial part 2 Creating a trivial machine code function 1017@anchor{intro/tutorial02 full-example}@anchor{20} 1018@subsection Full example 1019 1020 1021Here's what the above looks like as a complete program: 1022 1023@quotation 1024 1025@example 1026/* Usage example for libgccjit.so 1027 Copyright (C) 2014-2017 Free Software Foundation, Inc. 1028 1029This file is part of GCC. 1030 1031GCC is free software; you can redistribute it and/or modify it 1032under the terms of the GNU General Public License as published by 1033the Free Software Foundation; either version 3, or (at your option) 1034any later version. 1035 1036GCC is distributed in the hope that it will be useful, but 1037WITHOUT ANY WARRANTY; without even the implied warranty of 1038MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1039General Public License for more details. 1040 1041You should have received a copy of the GNU General Public License 1042along with GCC; see the file COPYING3. If not see 1043<http://www.gnu.org/licenses/>. */ 1044 1045#include <libgccjit.h> 1046 1047#include <stdlib.h> 1048#include <stdio.h> 1049 1050void 1051create_code (gcc_jit_context *ctxt) 1052@{ 1053 /* Let's try to inject the equivalent of: 1054 1055 int square (int i) 1056 @{ 1057 return i * i; 1058 @} 1059 */ 1060 gcc_jit_type *int_type = 1061 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1062 gcc_jit_param *param_i = 1063 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 1064 gcc_jit_function *func = 1065 gcc_jit_context_new_function (ctxt, NULL, 1066 GCC_JIT_FUNCTION_EXPORTED, 1067 int_type, 1068 "square", 1069 1, ¶m_i, 1070 0); 1071 1072 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 1073 1074 gcc_jit_rvalue *expr = 1075 gcc_jit_context_new_binary_op ( 1076 ctxt, NULL, 1077 GCC_JIT_BINARY_OP_MULT, int_type, 1078 gcc_jit_param_as_rvalue (param_i), 1079 gcc_jit_param_as_rvalue (param_i)); 1080 1081 gcc_jit_block_end_with_return (block, NULL, expr); 1082@} 1083 1084int 1085main (int argc, char **argv) 1086@{ 1087 gcc_jit_context *ctxt = NULL; 1088 gcc_jit_result *result = NULL; 1089 1090 /* Get a "context" object for working with the library. */ 1091 ctxt = gcc_jit_context_acquire (); 1092 if (!ctxt) 1093 @{ 1094 fprintf (stderr, "NULL ctxt"); 1095 goto error; 1096 @} 1097 1098 /* Set some options on the context. 1099 Let's see the code being generated, in assembler form. */ 1100 gcc_jit_context_set_bool_option ( 1101 ctxt, 1102 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1103 0); 1104 1105 /* Populate the context. */ 1106 create_code (ctxt); 1107 1108 /* Compile the code. */ 1109 result = gcc_jit_context_compile (ctxt); 1110 if (!result) 1111 @{ 1112 fprintf (stderr, "NULL result"); 1113 goto error; 1114 @} 1115 1116 /* We're done with the context; we can release it: */ 1117 gcc_jit_context_release (ctxt); 1118 ctxt = NULL; 1119 1120 /* Extract the generated code from "result". */ 1121 void *fn_ptr = gcc_jit_result_get_code (result, "square"); 1122 if (!fn_ptr) 1123 @{ 1124 fprintf (stderr, "NULL fn_ptr"); 1125 goto error; 1126 @} 1127 1128 typedef int (*fn_type) (int); 1129 fn_type square = (fn_type)fn_ptr; 1130 printf ("result: %d\n", square (5)); 1131 1132 error: 1133 if (ctxt) 1134 gcc_jit_context_release (ctxt); 1135 if (result) 1136 gcc_jit_result_release (result); 1137 return 0; 1138@} 1139 1140@end example 1141 1142@noindent 1143@end quotation 1144 1145Building and running it: 1146 1147@example 1148$ gcc \ 1149 tut02-square.c \ 1150 -o tut02-square \ 1151 -lgccjit 1152 1153# Run the built program: 1154$ ./tut02-square 1155result: 25 1156@end example 1157 1158@noindent 1159 1160@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 1161@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 1162@c 1163@c This is free software: you can redistribute it and/or modify it 1164@c under the terms of the GNU General Public License as published by 1165@c the Free Software Foundation, either version 3 of the License, or 1166@c (at your option) any later version. 1167@c 1168@c This program is distributed in the hope that it will be useful, but 1169@c WITHOUT ANY WARRANTY; without even the implied warranty of 1170@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1171@c General Public License for more details. 1172@c 1173@c You should have received a copy of the GNU General Public License 1174@c along with this program. If not, see 1175@c <http://www.gnu.org/licenses/>. 1176 1177@node Tutorial part 3 Loops and variables,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial part 2 Creating a trivial machine code function,Tutorial 1178@anchor{intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{21}@anchor{intro/tutorial03 doc}@anchor{22} 1179@section Tutorial part 3: Loops and variables 1180 1181 1182Consider this C function: 1183 1184@quotation 1185 1186@example 1187int loop_test (int n) 1188@{ 1189 int sum = 0; 1190 for (int i = 0; i < n; i++) 1191 sum += i * i; 1192 return sum; 1193@} 1194@end example 1195 1196@noindent 1197@end quotation 1198 1199This example demonstrates some more features of libgccjit, with local 1200variables and a loop. 1201 1202To break this down into libgccjit terms, it's usually easier to reword 1203the @cite{for} loop as a @cite{while} loop, giving: 1204 1205@quotation 1206 1207@example 1208int loop_test (int n) 1209@{ 1210 int sum = 0; 1211 int i = 0; 1212 while (i < n) 1213 @{ 1214 sum += i * i; 1215 i++; 1216 @} 1217 return sum; 1218@} 1219@end example 1220 1221@noindent 1222@end quotation 1223 1224Here's what the final control flow graph will look like: 1225 1226@quotation 1227 1228 1229@float Figure 1230 1231@image{sum-of-squares1,,,image of a control flow graph,png} 1232 1233@end float 1234 1235@end quotation 1236 1237As before, we include the libgccjit header and make a 1238@pxref{8,,gcc_jit_context *}. 1239 1240@example 1241#include <libgccjit.h> 1242 1243void test (void) 1244@{ 1245 gcc_jit_context *ctxt; 1246 ctxt = gcc_jit_context_acquire (); 1247@end example 1248 1249@noindent 1250 1251The function works with the C @cite{int} type: 1252 1253@example 1254gcc_jit_type *the_type = 1255 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1256gcc_jit_type *return_type = the_type; 1257@end example 1258 1259@noindent 1260 1261though we could equally well make it work on, say, @cite{double}: 1262 1263@example 1264gcc_jit_type *the_type = 1265 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE); 1266@end example 1267 1268@noindent 1269 1270Let's build the function: 1271 1272@example 1273gcc_jit_param *n = 1274 gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); 1275gcc_jit_param *params[1] = @{n@}; 1276gcc_jit_function *func = 1277 gcc_jit_context_new_function (ctxt, NULL, 1278 GCC_JIT_FUNCTION_EXPORTED, 1279 return_type, 1280 "loop_test", 1281 1, params, 0); 1282@end example 1283 1284@noindent 1285 1286@menu 1287* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. 1288* Control flow:: 1289* Visualizing the control flow graph:: 1290* Full example: Full example<2>. 1291 1292@end menu 1293 1294@node Expressions lvalues and rvalues,Control flow,,Tutorial part 3 Loops and variables 1295@anchor{intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{23} 1296@subsection Expressions: lvalues and rvalues 1297 1298 1299The base class of expression is the @pxref{13,,gcc_jit_rvalue *}, 1300representing an expression that can be on the @emph{right}-hand side of 1301an assignment: a value that can be computed somehow, and assigned 1302@emph{to} a storage area (such as a variable). It has a specific 1303@pxref{a,,gcc_jit_type *}. 1304 1305Anothe important class is @pxref{24,,gcc_jit_lvalue *}. 1306A @pxref{24,,gcc_jit_lvalue *}. is something that can of the @emph{left}-hand 1307side of an assignment: a storage area (such as a variable). 1308 1309In other words, every assignment can be thought of as: 1310 1311@example 1312LVALUE = RVALUE; 1313@end example 1314 1315@noindent 1316 1317Note that @pxref{24,,gcc_jit_lvalue *} is a subclass of 1318@pxref{13,,gcc_jit_rvalue *}, where in an assignment of the form: 1319 1320@example 1321LVALUE_A = LVALUE_B; 1322@end example 1323 1324@noindent 1325 1326the @cite{LVALUE_B} implies reading the current value of that storage 1327area, assigning it into the @cite{LVALUE_A}. 1328 1329So far the only expressions we've seen are @cite{i * i}: 1330 1331@example 1332gcc_jit_rvalue *expr = 1333 gcc_jit_context_new_binary_op ( 1334 ctxt, NULL, 1335 GCC_JIT_BINARY_OP_MULT, int_type, 1336 gcc_jit_param_as_rvalue (param_i), 1337 gcc_jit_param_as_rvalue (param_i)); 1338@end example 1339 1340@noindent 1341 1342which is a @pxref{13,,gcc_jit_rvalue *}, and the various function 1343parameters: @cite{param_i} and @cite{param_n}, instances of 1344@pxref{25,,gcc_jit_param *}, which is a subclass of 1345@pxref{24,,gcc_jit_lvalue *} (and, in turn, of @pxref{13,,gcc_jit_rvalue *}): 1346we can both read from and write to function parameters within the 1347body of a function. 1348 1349Our new example has a couple of local variables. We create them by 1350calling @pxref{26,,gcc_jit_function_new_local()}, supplying a type and a 1351name: 1352 1353@example 1354/* Build locals: */ 1355gcc_jit_lvalue *i = 1356 gcc_jit_function_new_local (func, NULL, the_type, "i"); 1357gcc_jit_lvalue *sum = 1358 gcc_jit_function_new_local (func, NULL, the_type, "sum"); 1359@end example 1360 1361@noindent 1362 1363These are instances of @pxref{24,,gcc_jit_lvalue *} - they can be read from 1364and written to. 1365 1366Note that there is no precanned way to create @emph{and} initialize a variable 1367like in C: 1368 1369@example 1370int i = 0; 1371@end example 1372 1373@noindent 1374 1375Instead, having added the local to the function, we have to separately add 1376an assignment of @cite{0} to @cite{local_i} at the beginning of the function. 1377 1378@node Control flow,Visualizing the control flow graph,Expressions lvalues and rvalues,Tutorial part 3 Loops and variables 1379@anchor{intro/tutorial03 control-flow}@anchor{27} 1380@subsection Control flow 1381 1382 1383This function has a loop, so we need to build some basic blocks to 1384handle the control flow. In this case, we need 4 blocks: 1385 1386 1387@enumerate 1388 1389@item 1390before the loop (initializing the locals) 1391 1392@item 1393the conditional at the top of the loop (comparing @cite{i < n}) 1394 1395@item 1396the body of the loop 1397 1398@item 1399after the loop terminates (@cite{return sum}) 1400@end enumerate 1401 1402so we create these as @pxref{28,,gcc_jit_block *} instances within the 1403@pxref{29,,gcc_jit_function *}: 1404 1405@example 1406gcc_jit_block *b_initial = 1407 gcc_jit_function_new_block (func, "initial"); 1408gcc_jit_block *b_loop_cond = 1409 gcc_jit_function_new_block (func, "loop_cond"); 1410gcc_jit_block *b_loop_body = 1411 gcc_jit_function_new_block (func, "loop_body"); 1412gcc_jit_block *b_after_loop = 1413 gcc_jit_function_new_block (func, "after_loop"); 1414@end example 1415 1416@noindent 1417 1418We now populate each block with statements. 1419 1420The entry block @cite{b_initial} consists of initializations followed by a jump 1421to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using 1422@pxref{2a,,gcc_jit_block_add_assignment()} to add 1423an assignment statement, and using @pxref{2b,,gcc_jit_context_zero()} to get 1424the constant value @cite{0} for the relevant type for the right-hand side of 1425the assignment: 1426 1427@example 1428/* sum = 0; */ 1429gcc_jit_block_add_assignment ( 1430 b_initial, NULL, 1431 sum, 1432 gcc_jit_context_zero (ctxt, the_type)); 1433 1434/* i = 0; */ 1435gcc_jit_block_add_assignment ( 1436 b_initial, NULL, 1437 i, 1438 gcc_jit_context_zero (ctxt, the_type)); 1439@end example 1440 1441@noindent 1442 1443We can then terminate the entry block by jumping to the conditional: 1444 1445@example 1446gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); 1447@end example 1448 1449@noindent 1450 1451The conditional block is equivalent to the line @cite{while (i < n)} from our 1452C example. It contains a single statement: a conditional, which jumps to 1453one of two destination blocks depending on a boolean 1454@pxref{13,,gcc_jit_rvalue *}, in this case the comparison of @cite{i} and @cite{n}. 1455We build the comparison using @pxref{2c,,gcc_jit_context_new_comparison()}: 1456 1457@example 1458/* (i >= n) */ 1459 gcc_jit_rvalue *guard = 1460 gcc_jit_context_new_comparison ( 1461 ctxt, NULL, 1462 GCC_JIT_COMPARISON_GE, 1463 gcc_jit_lvalue_as_rvalue (i), 1464 gcc_jit_param_as_rvalue (n)); 1465@end example 1466 1467@noindent 1468 1469and can then use this to add @cite{b_loop_cond}'s sole statement, via 1470@pxref{2d,,gcc_jit_block_end_with_conditional()}: 1471 1472@example 1473/* Equivalent to: 1474 if (guard) 1475 goto after_loop; 1476 else 1477 goto loop_body; */ 1478gcc_jit_block_end_with_conditional ( 1479 b_loop_cond, NULL, 1480 guard, 1481 b_after_loop, /* on_true */ 1482 b_loop_body); /* on_false */ 1483@end example 1484 1485@noindent 1486 1487Next, we populate the body of the loop. 1488 1489The C statement @cite{sum += i * i;} is an assignment operation, where an 1490lvalue is modified "in-place". We use 1491@pxref{2e,,gcc_jit_block_add_assignment_op()} to handle these operations: 1492 1493@example 1494/* sum += i * i */ 1495gcc_jit_block_add_assignment_op ( 1496 b_loop_body, NULL, 1497 sum, 1498 GCC_JIT_BINARY_OP_PLUS, 1499 gcc_jit_context_new_binary_op ( 1500 ctxt, NULL, 1501 GCC_JIT_BINARY_OP_MULT, the_type, 1502 gcc_jit_lvalue_as_rvalue (i), 1503 gcc_jit_lvalue_as_rvalue (i))); 1504@end example 1505 1506@noindent 1507 1508The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in 1509a similar way. We use @pxref{2f,,gcc_jit_context_one()} to get the constant 1510value @cite{1} (for the relevant type) for the right-hand side 1511of the assignment. 1512 1513@example 1514/* i++ */ 1515gcc_jit_block_add_assignment_op ( 1516 b_loop_body, NULL, 1517 i, 1518 GCC_JIT_BINARY_OP_PLUS, 1519 gcc_jit_context_one (ctxt, the_type)); 1520@end example 1521 1522@noindent 1523 1524@cartouche 1525@quotation Note 1526For numeric constants other than 0 or 1, we could use 1527@pxref{30,,gcc_jit_context_new_rvalue_from_int()} and 1528@pxref{31,,gcc_jit_context_new_rvalue_from_double()}. 1529@end quotation 1530@end cartouche 1531 1532The loop body completes by jumping back to the conditional: 1533 1534@example 1535gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); 1536@end example 1537 1538@noindent 1539 1540Finally, we populate the @cite{b_after_loop} block, reached when the loop 1541conditional is false. We want to generate the equivalent of: 1542 1543@example 1544return sum; 1545@end example 1546 1547@noindent 1548 1549so the block is just one statement: 1550 1551@example 1552/* return sum */ 1553gcc_jit_block_end_with_return ( 1554 b_after_loop, 1555 NULL, 1556 gcc_jit_lvalue_as_rvalue (sum)); 1557@end example 1558 1559@noindent 1560 1561@cartouche 1562@quotation Note 1563You can intermingle block creation with statement creation, 1564but given that the terminator statements generally include references 1565to other blocks, I find it's clearer to create all the blocks, 1566@emph{then} all the statements. 1567@end quotation 1568@end cartouche 1569 1570We've finished populating the function. As before, we can now compile it 1571to machine code: 1572 1573@example 1574gcc_jit_result *result; 1575result = gcc_jit_context_compile (ctxt); 1576 1577typedef int (*loop_test_fn_type) (int); 1578loop_test_fn_type loop_test = 1579 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 1580if (!loop_test) 1581 goto error; 1582printf ("result: %d", loop_test (10)); 1583@end example 1584 1585@noindent 1586 1587@example 1588result: 285 1589@end example 1590 1591@noindent 1592 1593@node Visualizing the control flow graph,Full example<2>,Control flow,Tutorial part 3 Loops and variables 1594@anchor{intro/tutorial03 visualizing-the-control-flow-graph}@anchor{32} 1595@subsection Visualizing the control flow graph 1596 1597 1598You can see the control flow graph of a function using 1599@pxref{33,,gcc_jit_function_dump_to_dot()}: 1600 1601@example 1602gcc_jit_function_dump_to_dot (func, "/tmp/sum-of-squares.dot"); 1603@end example 1604 1605@noindent 1606 1607giving a .dot file in GraphViz format. 1608 1609You can convert this to an image using @cite{dot}: 1610 1611@example 1612$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png 1613@end example 1614 1615@noindent 1616 1617or use a viewer (my preferred one is xdot.py; see 1618@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can 1619install it with @cite{yum install python-xdot}): 1620 1621@quotation 1622 1623 1624@float Figure 1625 1626@image{sum-of-squares1,,,image of a control flow graph,png} 1627 1628@end float 1629 1630@end quotation 1631 1632@node Full example<2>,,Visualizing the control flow graph,Tutorial part 3 Loops and variables 1633@anchor{intro/tutorial03 full-example}@anchor{34} 1634@subsection Full example 1635 1636 1637@quotation 1638 1639@example 1640/* Usage example for libgccjit.so 1641 Copyright (C) 2014-2017 Free Software Foundation, Inc. 1642 1643This file is part of GCC. 1644 1645GCC is free software; you can redistribute it and/or modify it 1646under the terms of the GNU General Public License as published by 1647the Free Software Foundation; either version 3, or (at your option) 1648any later version. 1649 1650GCC is distributed in the hope that it will be useful, but 1651WITHOUT ANY WARRANTY; without even the implied warranty of 1652MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1653General Public License for more details. 1654 1655You should have received a copy of the GNU General Public License 1656along with GCC; see the file COPYING3. If not see 1657<http://www.gnu.org/licenses/>. */ 1658 1659#include <libgccjit.h> 1660 1661#include <stdlib.h> 1662#include <stdio.h> 1663 1664void 1665create_code (gcc_jit_context *ctxt) 1666@{ 1667 /* 1668 Simple sum-of-squares, to test conditionals and looping 1669 1670 int loop_test (int n) 1671 @{ 1672 int i; 1673 int sum = 0; 1674 for (i = 0; i < n ; i ++) 1675 @{ 1676 sum += i * i; 1677 @} 1678 return sum; 1679 */ 1680 gcc_jit_type *the_type = 1681 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1682 gcc_jit_type *return_type = the_type; 1683 1684 gcc_jit_param *n = 1685 gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); 1686 gcc_jit_param *params[1] = @{n@}; 1687 gcc_jit_function *func = 1688 gcc_jit_context_new_function (ctxt, NULL, 1689 GCC_JIT_FUNCTION_EXPORTED, 1690 return_type, 1691 "loop_test", 1692 1, params, 0); 1693 1694 /* Build locals: */ 1695 gcc_jit_lvalue *i = 1696 gcc_jit_function_new_local (func, NULL, the_type, "i"); 1697 gcc_jit_lvalue *sum = 1698 gcc_jit_function_new_local (func, NULL, the_type, "sum"); 1699 1700 gcc_jit_block *b_initial = 1701 gcc_jit_function_new_block (func, "initial"); 1702 gcc_jit_block *b_loop_cond = 1703 gcc_jit_function_new_block (func, "loop_cond"); 1704 gcc_jit_block *b_loop_body = 1705 gcc_jit_function_new_block (func, "loop_body"); 1706 gcc_jit_block *b_after_loop = 1707 gcc_jit_function_new_block (func, "after_loop"); 1708 1709 /* sum = 0; */ 1710 gcc_jit_block_add_assignment ( 1711 b_initial, NULL, 1712 sum, 1713 gcc_jit_context_zero (ctxt, the_type)); 1714 1715 /* i = 0; */ 1716 gcc_jit_block_add_assignment ( 1717 b_initial, NULL, 1718 i, 1719 gcc_jit_context_zero (ctxt, the_type)); 1720 1721 gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); 1722 1723 /* if (i >= n) */ 1724 gcc_jit_block_end_with_conditional ( 1725 b_loop_cond, NULL, 1726 gcc_jit_context_new_comparison ( 1727 ctxt, NULL, 1728 GCC_JIT_COMPARISON_GE, 1729 gcc_jit_lvalue_as_rvalue (i), 1730 gcc_jit_param_as_rvalue (n)), 1731 b_after_loop, 1732 b_loop_body); 1733 1734 /* sum += i * i */ 1735 gcc_jit_block_add_assignment_op ( 1736 b_loop_body, NULL, 1737 sum, 1738 GCC_JIT_BINARY_OP_PLUS, 1739 gcc_jit_context_new_binary_op ( 1740 ctxt, NULL, 1741 GCC_JIT_BINARY_OP_MULT, the_type, 1742 gcc_jit_lvalue_as_rvalue (i), 1743 gcc_jit_lvalue_as_rvalue (i))); 1744 1745 /* i++ */ 1746 gcc_jit_block_add_assignment_op ( 1747 b_loop_body, NULL, 1748 i, 1749 GCC_JIT_BINARY_OP_PLUS, 1750 gcc_jit_context_one (ctxt, the_type)); 1751 1752 gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); 1753 1754 /* return sum */ 1755 gcc_jit_block_end_with_return ( 1756 b_after_loop, 1757 NULL, 1758 gcc_jit_lvalue_as_rvalue (sum)); 1759@} 1760 1761int 1762main (int argc, char **argv) 1763@{ 1764 gcc_jit_context *ctxt = NULL; 1765 gcc_jit_result *result = NULL; 1766 1767 /* Get a "context" object for working with the library. */ 1768 ctxt = gcc_jit_context_acquire (); 1769 if (!ctxt) 1770 @{ 1771 fprintf (stderr, "NULL ctxt"); 1772 goto error; 1773 @} 1774 1775 /* Set some options on the context. 1776 Let's see the code being generated, in assembler form. */ 1777 gcc_jit_context_set_bool_option ( 1778 ctxt, 1779 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1780 0); 1781 1782 /* Populate the context. */ 1783 create_code (ctxt); 1784 1785 /* Compile the code. */ 1786 result = gcc_jit_context_compile (ctxt); 1787 if (!result) 1788 @{ 1789 fprintf (stderr, "NULL result"); 1790 goto error; 1791 @} 1792 1793 /* Extract the generated code from "result". */ 1794 typedef int (*loop_test_fn_type) (int); 1795 loop_test_fn_type loop_test = 1796 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 1797 if (!loop_test) 1798 @{ 1799 fprintf (stderr, "NULL loop_test"); 1800 goto error; 1801 @} 1802 1803 /* Run the generated code. */ 1804 int val = loop_test (10); 1805 printf("loop_test returned: %d\n", val); 1806 1807 error: 1808 gcc_jit_context_release (ctxt); 1809 gcc_jit_result_release (result); 1810 return 0; 1811@} 1812 1813@end example 1814 1815@noindent 1816@end quotation 1817 1818Building and running it: 1819 1820@example 1821$ gcc \ 1822 tut03-sum-of-squares.c \ 1823 -o tut03-sum-of-squares \ 1824 -lgccjit 1825 1826# Run the built program: 1827$ ./tut03-sum-of-squares 1828loop_test returned: 285 1829@end example 1830 1831@noindent 1832 1833@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 1834@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 1835@c 1836@c This is free software: you can redistribute it and/or modify it 1837@c under the terms of the GNU General Public License as published by 1838@c the Free Software Foundation, either version 3 of the License, or 1839@c (at your option) any later version. 1840@c 1841@c This program is distributed in the hope that it will be useful, but 1842@c WITHOUT ANY WARRANTY; without even the implied warranty of 1843@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1844@c General Public License for more details. 1845@c 1846@c You should have received a copy of the GNU General Public License 1847@c along with this program. If not, see 1848@c <http://www.gnu.org/licenses/>. 1849 1850@node Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial part 5 Implementing an Ahead-of-Time compiler,Tutorial part 3 Loops and variables,Tutorial 1851@anchor{intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{35}@anchor{intro/tutorial04 doc}@anchor{36} 1852@section Tutorial part 4: Adding JIT-compilation to a toy interpreter 1853 1854 1855In this example we construct a "toy" interpreter, and add JIT-compilation 1856to it. 1857 1858@menu 1859* Our toy interpreter:: 1860* Compiling to machine code:: 1861* Setting things up:: 1862* Populating the function:: 1863* Verifying the control flow graph:: 1864* Compiling the context:: 1865* Single-stepping through the generated code:: 1866* Examining the generated code:: 1867* Putting it all together:: 1868* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?. 1869 1870@end menu 1871 1872@node Our toy interpreter,Compiling to machine code,,Tutorial part 4 Adding JIT-compilation to a toy interpreter 1873@anchor{intro/tutorial04 our-toy-interpreter}@anchor{37} 1874@subsection Our toy interpreter 1875 1876 1877It's a stack-based interpreter, and is intended as a (very simple) example 1878of the kind of bytecode interpreter seen in dynamic languages such as 1879Python, Ruby etc. 1880 1881For the sake of simplicity, our toy virtual machine is very limited: 1882 1883@quotation 1884 1885 1886@itemize * 1887 1888@item 1889The only data type is @cite{int} 1890 1891@item 1892It can only work on one function at a time (so that the only 1893function call that can be made is to recurse). 1894 1895@item 1896Functions can only take one parameter. 1897 1898@item 1899Functions have a stack of @cite{int} values. 1900 1901@item 1902We'll implement function call within the interpreter by calling a 1903function in our implementation, rather than implementing our own 1904frame stack. 1905 1906@item 1907The parser is only good enough to get the examples to work. 1908@end itemize 1909@end quotation 1910 1911Naturally, a real interpreter would be much more complicated that this. 1912 1913The following operations are supported: 1914 1915 1916@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx} 1917@headitem 1918 1919Operation 1920 1921@tab 1922 1923Meaning 1924 1925@tab 1926 1927Old Stack 1928 1929@tab 1930 1931New Stack 1932 1933@item 1934 1935DUP 1936 1937@tab 1938 1939Duplicate top of stack. 1940 1941@tab 1942 1943@code{[..., x]} 1944 1945@tab 1946 1947@code{[..., x, x]} 1948 1949@item 1950 1951ROT 1952 1953@tab 1954 1955Swap top two elements 1956of stack. 1957 1958@tab 1959 1960@code{[..., x, y]} 1961 1962@tab 1963 1964@code{[..., y, x]} 1965 1966@item 1967 1968BINARY_ADD 1969 1970@tab 1971 1972Add the top two elements 1973on the stack. 1974 1975@tab 1976 1977@code{[..., x, y]} 1978 1979@tab 1980 1981@code{[..., (x+y)]} 1982 1983@item 1984 1985BINARY_SUBTRACT 1986 1987@tab 1988 1989Likewise, but subtract. 1990 1991@tab 1992 1993@code{[..., x, y]} 1994 1995@tab 1996 1997@code{[..., (x-y)]} 1998 1999@item 2000 2001BINARY_MULT 2002 2003@tab 2004 2005Likewise, but multiply. 2006 2007@tab 2008 2009@code{[..., x, y]} 2010 2011@tab 2012 2013@code{[..., (x*y)]} 2014 2015@item 2016 2017BINARY_COMPARE_LT 2018 2019@tab 2020 2021Compare the top two 2022elements on the stack 2023and push a nonzero/zero 2024if (x<y). 2025 2026@tab 2027 2028@code{[..., x, y]} 2029 2030@tab 2031 2032@code{[..., (x<y)]} 2033 2034@item 2035 2036RECURSE 2037 2038@tab 2039 2040Recurse, passing the top 2041of the stack, and 2042popping the result. 2043 2044@tab 2045 2046@code{[..., x]} 2047 2048@tab 2049 2050@code{[..., fn(x)]} 2051 2052@item 2053 2054RETURN 2055 2056@tab 2057 2058Return the top of the 2059stack. 2060 2061@tab 2062 2063@code{[x]} 2064 2065@tab 2066 2067@code{[]} 2068 2069@item 2070 2071PUSH_CONST @cite{arg} 2072 2073@tab 2074 2075Push an int const. 2076 2077@tab 2078 2079@code{[...]} 2080 2081@tab 2082 2083@code{[..., arg]} 2084 2085@item 2086 2087JUMP_ABS_IF_TRUE @cite{arg} 2088 2089@tab 2090 2091Pop; if top of stack was 2092nonzero, jump to 2093@code{arg}. 2094 2095@tab 2096 2097@code{[..., x]} 2098 2099@tab 2100 2101@code{[...]} 2102 2103@end multitable 2104 2105 2106Programs can be interpreted, disassembled, and compiled to machine code. 2107 2108The interpreter reads @code{.toy} scripts. Here's what a simple recursive 2109factorial program looks like, the script @code{factorial.toy}. 2110The parser ignores lines beginning with a @cite{#}. 2111 2112@quotation 2113 2114@example 2115# Simple recursive factorial implementation, roughly equivalent to: 2116# 2117# int factorial (int arg) 2118# @{ 2119# if (arg < 2) 2120# return arg 2121# return arg * factorial (arg - 1) 2122# @} 2123 2124# Initial state: 2125# stack: [arg] 2126 2127# 0: 2128DUP 2129# stack: [arg, arg] 2130 2131# 1: 2132PUSH_CONST 2 2133# stack: [arg, arg, 2] 2134 2135# 2: 2136BINARY_COMPARE_LT 2137# stack: [arg, (arg < 2)] 2138 2139# 3: 2140JUMP_ABS_IF_TRUE 9 2141# stack: [arg] 2142 2143# 4: 2144DUP 2145# stack: [arg, arg] 2146 2147# 5: 2148PUSH_CONST 1 2149# stack: [arg, arg, 1] 2150 2151# 6: 2152BINARY_SUBTRACT 2153# stack: [arg, (arg - 1) 2154 2155# 7: 2156RECURSE 2157# stack: [arg, factorial(arg - 1)] 2158 2159# 8: 2160BINARY_MULT 2161# stack: [arg * factorial(arg - 1)] 2162 2163# 9: 2164RETURN 2165 2166@end example 2167 2168@noindent 2169@end quotation 2170 2171The interpreter is a simple infinite loop with a big @code{switch} statement 2172based on what the next opcode is: 2173 2174@quotation 2175 2176@example 2177 2178static int 2179toyvm_function_interpret (toyvm_function *fn, int arg, FILE *trace) 2180@{ 2181 toyvm_frame frame; 2182#define PUSH(ARG) (toyvm_frame_push (&frame, (ARG))) 2183#define POP(ARG) (toyvm_frame_pop (&frame)) 2184 2185 frame.frm_function = fn; 2186 frame.frm_pc = 0; 2187 frame.frm_cur_depth = 0; 2188 2189 PUSH (arg); 2190 2191 while (1) 2192 @{ 2193 toyvm_op *op; 2194 int x, y; 2195 assert (frame.frm_pc < fn->fn_num_ops); 2196 op = &fn->fn_ops[frame.frm_pc++]; 2197 2198 if (trace) 2199 @{ 2200 toyvm_frame_dump_stack (&frame, trace); 2201 toyvm_function_disassemble_op (fn, op, frame.frm_pc, trace); 2202 @} 2203 2204 switch (op->op_opcode) 2205 @{ 2206 /* Ops taking no operand. */ 2207 case DUP: 2208 x = POP (); 2209 PUSH (x); 2210 PUSH (x); 2211 break; 2212 2213 case ROT: 2214 y = POP (); 2215 x = POP (); 2216 PUSH (y); 2217 PUSH (x); 2218 break; 2219 2220 case BINARY_ADD: 2221 y = POP (); 2222 x = POP (); 2223 PUSH (x + y); 2224 break; 2225 2226 case BINARY_SUBTRACT: 2227 y = POP (); 2228 x = POP (); 2229 PUSH (x - y); 2230 break; 2231 2232 case BINARY_MULT: 2233 y = POP (); 2234 x = POP (); 2235 PUSH (x * y); 2236 break; 2237 2238 case BINARY_COMPARE_LT: 2239 y = POP (); 2240 x = POP (); 2241 PUSH (x < y); 2242 break; 2243 2244 case RECURSE: 2245 x = POP (); 2246 x = toyvm_function_interpret (fn, x, trace); 2247 PUSH (x); 2248 break; 2249 2250 case RETURN: 2251 return POP (); 2252 2253 /* Ops taking an operand. */ 2254 case PUSH_CONST: 2255 PUSH (op->op_operand); 2256 break; 2257 2258 case JUMP_ABS_IF_TRUE: 2259 x = POP (); 2260 if (x) 2261 frame.frm_pc = op->op_operand; 2262 break; 2263 2264 default: 2265 assert (0); /* unknown opcode */ 2266 2267 @} /* end of switch on opcode */ 2268 @} /* end of while loop */ 2269 2270#undef PUSH 2271#undef POP 2272@} 2273 2274 2275@end example 2276 2277@noindent 2278@end quotation 2279 2280@node Compiling to machine code,Setting things up,Our toy interpreter,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2281@anchor{intro/tutorial04 compiling-to-machine-code}@anchor{38} 2282@subsection Compiling to machine code 2283 2284 2285We want to generate machine code that can be cast to this type and 2286then directly executed in-process: 2287 2288@quotation 2289 2290@example 2291typedef int (*toyvm_compiled_code) (int); 2292 2293 2294@end example 2295 2296@noindent 2297@end quotation 2298 2299The lifetime of the code is tied to that of a @pxref{16,,gcc_jit_result *}. 2300We'll handle this by bundling them up in a structure, so that we can 2301clean them up together by calling @pxref{39,,gcc_jit_result_release()}: 2302 2303@quotation 2304 2305@example 2306 2307struct toyvm_compiled_function 2308@{ 2309 gcc_jit_result *cf_jit_result; 2310 toyvm_compiled_code cf_code; 2311@}; 2312 2313 2314@end example 2315 2316@noindent 2317@end quotation 2318 2319Our compiler isn't very sophisticated; it takes the implementation of 2320each opcode above, and maps it directly to the operations supported by 2321the libgccjit API. 2322 2323How should we handle the stack? In theory we could calculate what the 2324stack depth will be at each opcode, and optimize away the stack 2325manipulation "by hand". We'll see below that libgccjit is able to do 2326this for us, so we'll implement stack manipulation 2327in a direct way, by creating a @code{stack} array and @code{stack_depth} 2328variables, local within the generated function, equivalent to this C code: 2329 2330@example 2331int stack_depth; 2332int stack[MAX_STACK_DEPTH]; 2333@end example 2334 2335@noindent 2336 2337We'll also have local variables @code{x} and @code{y} for use when implementing 2338the opcodes, equivalent to this: 2339 2340@example 2341int x; 2342int y; 2343@end example 2344 2345@noindent 2346 2347This means our compiler has the following state: 2348 2349@quotation 2350 2351@example 2352 2353struct compilation_state 2354@{ 2355 gcc_jit_context *ctxt; 2356 2357 gcc_jit_type *int_type; 2358 gcc_jit_type *bool_type; 2359 gcc_jit_type *stack_type; /* int[MAX_STACK_DEPTH] */ 2360 2361 gcc_jit_rvalue *const_one; 2362 2363 gcc_jit_function *fn; 2364 gcc_jit_param *param_arg; 2365 gcc_jit_lvalue *stack; 2366 gcc_jit_lvalue *stack_depth; 2367 gcc_jit_lvalue *x; 2368 gcc_jit_lvalue *y; 2369 2370 gcc_jit_location *op_locs[MAX_OPS]; 2371 gcc_jit_block *initial_block; 2372 gcc_jit_block *op_blocks[MAX_OPS]; 2373 2374@}; 2375 2376 2377@end example 2378 2379@noindent 2380@end quotation 2381 2382@node Setting things up,Populating the function,Compiling to machine code,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2383@anchor{intro/tutorial04 setting-things-up}@anchor{3a} 2384@subsection Setting things up 2385 2386 2387First we create our types: 2388 2389@quotation 2390 2391@example 2392 state.int_type = 2393 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_INT); 2394 state.bool_type = 2395 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_BOOL); 2396 state.stack_type = 2397 gcc_jit_context_new_array_type (state.ctxt, NULL, 2398 state.int_type, MAX_STACK_DEPTH); 2399 2400 2401@end example 2402 2403@noindent 2404@end quotation 2405 2406along with extracting a useful @cite{int} constant: 2407 2408@quotation 2409 2410@example 2411 state.const_one = gcc_jit_context_one (state.ctxt, state.int_type); 2412 2413 2414@end example 2415 2416@noindent 2417@end quotation 2418 2419We'll implement push and pop in terms of the @code{stack} array and 2420@code{stack_depth}. Here are helper functions for adding statements to 2421a block, implementing pushing and popping values: 2422 2423@quotation 2424 2425@example 2426 2427static void 2428add_push (compilation_state *state, 2429 gcc_jit_block *block, 2430 gcc_jit_rvalue *rvalue, 2431 gcc_jit_location *loc) 2432@{ 2433 /* stack[stack_depth] = RVALUE */ 2434 gcc_jit_block_add_assignment ( 2435 block, 2436 loc, 2437 /* stack[stack_depth] */ 2438 gcc_jit_context_new_array_access ( 2439 state->ctxt, 2440 loc, 2441 gcc_jit_lvalue_as_rvalue (state->stack), 2442 gcc_jit_lvalue_as_rvalue (state->stack_depth)), 2443 rvalue); 2444 2445 /* "stack_depth++;". */ 2446 gcc_jit_block_add_assignment_op ( 2447 block, 2448 loc, 2449 state->stack_depth, 2450 GCC_JIT_BINARY_OP_PLUS, 2451 state->const_one); 2452@} 2453 2454static void 2455add_pop (compilation_state *state, 2456 gcc_jit_block *block, 2457 gcc_jit_lvalue *lvalue, 2458 gcc_jit_location *loc) 2459@{ 2460 /* "--stack_depth;". */ 2461 gcc_jit_block_add_assignment_op ( 2462 block, 2463 loc, 2464 state->stack_depth, 2465 GCC_JIT_BINARY_OP_MINUS, 2466 state->const_one); 2467 2468 /* "LVALUE = stack[stack_depth];". */ 2469 gcc_jit_block_add_assignment ( 2470 block, 2471 loc, 2472 lvalue, 2473 /* stack[stack_depth] */ 2474 gcc_jit_lvalue_as_rvalue ( 2475 gcc_jit_context_new_array_access ( 2476 state->ctxt, 2477 loc, 2478 gcc_jit_lvalue_as_rvalue (state->stack), 2479 gcc_jit_lvalue_as_rvalue (state->stack_depth)))); 2480@} 2481 2482 2483@end example 2484 2485@noindent 2486@end quotation 2487 2488We will support single-stepping through the generated code in the 2489debugger, so we need to create @pxref{3b,,gcc_jit_location} instances, one 2490per operation in the source code. These will reference the lines of 2491e.g. @code{factorial.toy}. 2492 2493@quotation 2494 2495@example 2496 for (pc = 0; pc < fn->fn_num_ops; pc++) 2497 @{ 2498 toyvm_op *op = &fn->fn_ops[pc]; 2499 2500 state.op_locs[pc] = gcc_jit_context_new_location (state.ctxt, 2501 fn->fn_filename, 2502 op->op_linenum, 2503 0); /* column */ 2504 @} 2505 2506 2507@end example 2508 2509@noindent 2510@end quotation 2511 2512Let's create the function itself. As usual, we create its parameter 2513first, then use the parameter to create the function: 2514 2515@quotation 2516 2517@example 2518 state.param_arg = 2519 gcc_jit_context_new_param (state.ctxt, state.op_locs[0], 2520 state.int_type, "arg"); 2521 state.fn = 2522 gcc_jit_context_new_function (state.ctxt, 2523 state.op_locs[0], 2524 GCC_JIT_FUNCTION_EXPORTED, 2525 state.int_type, 2526 funcname, 2527 1, &state.param_arg, 0); 2528 2529 2530@end example 2531 2532@noindent 2533@end quotation 2534 2535We create the locals within the function. 2536 2537@quotation 2538 2539@example 2540 state.stack = 2541 gcc_jit_function_new_local (state.fn, NULL, 2542 state.stack_type, "stack"); 2543 state.stack_depth = 2544 gcc_jit_function_new_local (state.fn, NULL, 2545 state.int_type, "stack_depth"); 2546 state.x = 2547 gcc_jit_function_new_local (state.fn, NULL, 2548 state.int_type, "x"); 2549 state.y = 2550 gcc_jit_function_new_local (state.fn, NULL, 2551 state.int_type, "y"); 2552 2553 2554@end example 2555 2556@noindent 2557@end quotation 2558 2559@node Populating the function,Verifying the control flow graph,Setting things up,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2560@anchor{intro/tutorial04 populating-the-function}@anchor{3c} 2561@subsection Populating the function 2562 2563 2564There's some one-time initialization, and the API treats the first block 2565you create as the entrypoint of the function, so we need to create that 2566block first: 2567 2568@quotation 2569 2570@example 2571 state.initial_block = gcc_jit_function_new_block (state.fn, "initial"); 2572 2573 2574@end example 2575 2576@noindent 2577@end quotation 2578 2579We can now create blocks for each of the operations. Most of these will 2580be consolidated into larger blocks when the optimizer runs. 2581 2582@quotation 2583 2584@example 2585 for (pc = 0; pc < fn->fn_num_ops; pc++) 2586 @{ 2587 char buf[16]; 2588 sprintf (buf, "instr%i", pc); 2589 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); 2590 @} 2591 2592 2593@end example 2594 2595@noindent 2596@end quotation 2597 2598Now that we have a block it can jump to when it's done, we can populate 2599the initial block: 2600 2601@quotation 2602 2603@example 2604 2605 /* "stack_depth = 0;". */ 2606 gcc_jit_block_add_assignment ( 2607 state.initial_block, 2608 state.op_locs[0], 2609 state.stack_depth, 2610 gcc_jit_context_zero (state.ctxt, state.int_type)); 2611 2612 /* "PUSH (arg);". */ 2613 add_push (&state, 2614 state.initial_block, 2615 gcc_jit_param_as_rvalue (state.param_arg), 2616 state.op_locs[0]); 2617 2618 /* ...and jump to insn 0. */ 2619 gcc_jit_block_end_with_jump (state.initial_block, 2620 state.op_locs[0], 2621 state.op_blocks[0]); 2622 2623 2624@end example 2625 2626@noindent 2627@end quotation 2628 2629We can now populate the blocks for the individual operations. We loop 2630through them, adding instructions to their blocks: 2631 2632@quotation 2633 2634@example 2635 for (pc = 0; pc < fn->fn_num_ops; pc++) 2636 @{ 2637 gcc_jit_location *loc = state.op_locs[pc]; 2638 2639 gcc_jit_block *block = state.op_blocks[pc]; 2640 gcc_jit_block *next_block = (pc < fn->fn_num_ops 2641 ? state.op_blocks[pc + 1] 2642 : NULL); 2643 2644 toyvm_op *op; 2645 op = &fn->fn_ops[pc]; 2646 2647 2648@end example 2649 2650@noindent 2651@end quotation 2652 2653We're going to have another big @code{switch} statement for implementing 2654the opcodes, this time for compiling them, rather than interpreting 2655them. It's helpful to have macros for implementing push and pop, so that 2656we can make the @code{switch} statement that's coming up look as much as 2657possible like the one above within the interpreter: 2658 2659@example 2660 2661#define X_EQUALS_POP()\ 2662 add_pop (&state, block, state.x, loc) 2663#define Y_EQUALS_POP()\ 2664 add_pop (&state, block, state.y, loc) 2665#define PUSH_RVALUE(RVALUE)\ 2666 add_push (&state, block, (RVALUE), loc) 2667#define PUSH_X()\ 2668 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.x)) 2669#define PUSH_Y() \ 2670 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.y)) 2671 2672 2673@end example 2674 2675@noindent 2676 2677@cartouche 2678@quotation Note 2679A particularly clever implementation would have an @emph{identical} 2680@code{switch} statement shared by the interpreter and the compiler, with 2681some preprocessor "magic". We're not doing that here, for the sake 2682of simplicity. 2683@end quotation 2684@end cartouche 2685 2686When I first implemented this compiler, I accidentally missed an edit 2687when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the 2688stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y} 2689uninitialized. 2690 2691To track this kind of thing down, we can use 2692@pxref{3d,,gcc_jit_block_add_comment()} to add descriptive comments 2693to the internal representation. This is invaluable when looking through 2694the generated IR for, say @code{factorial}: 2695 2696@quotation 2697 2698@example 2699 2700 gcc_jit_block_add_comment (block, loc, opcode_names[op->op_opcode]); 2701 2702 2703@end example 2704 2705@noindent 2706@end quotation 2707 2708We can now write the big @code{switch} statement that implements the 2709individual opcodes, populating the relevant block with statements: 2710 2711@quotation 2712 2713@example 2714 2715 switch (op->op_opcode) 2716 @{ 2717 case DUP: 2718 X_EQUALS_POP (); 2719 PUSH_X (); 2720 PUSH_X (); 2721 break; 2722 2723 case ROT: 2724 Y_EQUALS_POP (); 2725 X_EQUALS_POP (); 2726 PUSH_Y (); 2727 PUSH_X (); 2728 break; 2729 2730 case BINARY_ADD: 2731 Y_EQUALS_POP (); 2732 X_EQUALS_POP (); 2733 PUSH_RVALUE ( 2734 gcc_jit_context_new_binary_op ( 2735 state.ctxt, 2736 loc, 2737 GCC_JIT_BINARY_OP_PLUS, 2738 state.int_type, 2739 gcc_jit_lvalue_as_rvalue (state.x), 2740 gcc_jit_lvalue_as_rvalue (state.y))); 2741 break; 2742 2743 case BINARY_SUBTRACT: 2744 Y_EQUALS_POP (); 2745 X_EQUALS_POP (); 2746 PUSH_RVALUE ( 2747 gcc_jit_context_new_binary_op ( 2748 state.ctxt, 2749 loc, 2750 GCC_JIT_BINARY_OP_MINUS, 2751 state.int_type, 2752 gcc_jit_lvalue_as_rvalue (state.x), 2753 gcc_jit_lvalue_as_rvalue (state.y))); 2754 break; 2755 2756 case BINARY_MULT: 2757 Y_EQUALS_POP (); 2758 X_EQUALS_POP (); 2759 PUSH_RVALUE ( 2760 gcc_jit_context_new_binary_op ( 2761 state.ctxt, 2762 loc, 2763 GCC_JIT_BINARY_OP_MULT, 2764 state.int_type, 2765 gcc_jit_lvalue_as_rvalue (state.x), 2766 gcc_jit_lvalue_as_rvalue (state.y))); 2767 break; 2768 2769 case BINARY_COMPARE_LT: 2770 Y_EQUALS_POP (); 2771 X_EQUALS_POP (); 2772 PUSH_RVALUE ( 2773 /* cast of bool to int */ 2774 gcc_jit_context_new_cast ( 2775 state.ctxt, 2776 loc, 2777 /* (x < y) as a bool */ 2778 gcc_jit_context_new_comparison ( 2779 state.ctxt, 2780 loc, 2781 GCC_JIT_COMPARISON_LT, 2782 gcc_jit_lvalue_as_rvalue (state.x), 2783 gcc_jit_lvalue_as_rvalue (state.y)), 2784 state.int_type)); 2785 break; 2786 2787 case RECURSE: 2788 @{ 2789 X_EQUALS_POP (); 2790 gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (state.x); 2791 PUSH_RVALUE ( 2792 gcc_jit_context_new_call ( 2793 state.ctxt, 2794 loc, 2795 state.fn, 2796 1, &arg)); 2797 break; 2798 @} 2799 2800 case RETURN: 2801 X_EQUALS_POP (); 2802 gcc_jit_block_end_with_return ( 2803 block, 2804 loc, 2805 gcc_jit_lvalue_as_rvalue (state.x)); 2806 break; 2807 2808 /* Ops taking an operand. */ 2809 case PUSH_CONST: 2810 PUSH_RVALUE ( 2811 gcc_jit_context_new_rvalue_from_int ( 2812 state.ctxt, 2813 state.int_type, 2814 op->op_operand)); 2815 break; 2816 2817 case JUMP_ABS_IF_TRUE: 2818 X_EQUALS_POP (); 2819 gcc_jit_block_end_with_conditional ( 2820 block, 2821 loc, 2822 /* "(bool)x". */ 2823 gcc_jit_context_new_cast ( 2824 state.ctxt, 2825 loc, 2826 gcc_jit_lvalue_as_rvalue (state.x), 2827 state.bool_type), 2828 state.op_blocks[op->op_operand], /* on_true */ 2829 next_block); /* on_false */ 2830 break; 2831 2832 default: 2833 assert(0); 2834 @} /* end of switch on opcode */ 2835 2836 2837@end example 2838 2839@noindent 2840@end quotation 2841 2842Every block must be terminated, via a call to one of the 2843@code{gcc_jit_block_end_with_} entrypoints. This has been done for two 2844of the opcodes, but we need to do it for the other ones, by jumping 2845to the next block. 2846 2847@quotation 2848 2849@example 2850 if (op->op_opcode != JUMP_ABS_IF_TRUE 2851 && op->op_opcode != RETURN) 2852 gcc_jit_block_end_with_jump ( 2853 block, 2854 loc, 2855 next_block); 2856 2857 2858@end example 2859 2860@noindent 2861@end quotation 2862 2863This is analogous to simply incrementing the program counter. 2864 2865@node Verifying the control flow graph,Compiling the context,Populating the function,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2866@anchor{intro/tutorial04 verifying-the-control-flow-graph}@anchor{3e} 2867@subsection Verifying the control flow graph 2868 2869 2870Having finished looping over the blocks, the context is complete. 2871 2872As before, we can verify that the control flow and statements are sane by 2873using @pxref{33,,gcc_jit_function_dump_to_dot()}: 2874 2875@example 2876gcc_jit_function_dump_to_dot (state.fn, "/tmp/factorial.dot"); 2877@end example 2878 2879@noindent 2880 2881and viewing the result. Note how the label names, comments, and 2882variable names show up in the dump, to make it easier to spot 2883errors in our compiler. 2884 2885@quotation 2886 2887 2888@float Figure 2889 2890@image{factorial1,,,image of a control flow graph,png} 2891 2892@end float 2893 2894@end quotation 2895 2896@node Compiling the context,Single-stepping through the generated code,Verifying the control flow graph,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2897@anchor{intro/tutorial04 compiling-the-context}@anchor{3f} 2898@subsection Compiling the context 2899 2900 2901Having finished looping over the blocks and populating them with 2902statements, the context is complete. 2903 2904We can now compile it, and extract machine code from the result: 2905 2906@quotation 2907 2908@example 2909 gcc_jit_result *jit_result = gcc_jit_context_compile (state.ctxt); 2910 gcc_jit_context_release (state.ctxt); 2911 2912 toyvm_compiled_function *toyvm_result = 2913 (toyvm_compiled_function *)calloc (1, sizeof (toyvm_compiled_function)); 2914 if (!toyvm_result) 2915 @{ 2916 fprintf (stderr, "out of memory allocating toyvm_compiled_function\n"); 2917 gcc_jit_result_release (jit_result); 2918 return NULL; 2919 @} 2920 2921 toyvm_result->cf_jit_result = jit_result; 2922 toyvm_result->cf_code = 2923 (toyvm_compiled_code)gcc_jit_result_get_code (jit_result, 2924 funcname); 2925 2926 free (funcname); 2927 2928 return toyvm_result; 2929@} 2930 2931char test[1024]; 2932 2933#define CHECK_NON_NULL(PTR) \ 2934 do @{ \ 2935 if ((PTR) != NULL) \ 2936 @{ \ 2937 pass ("%s: %s is non-null", test, #PTR); \ 2938 @} \ 2939 else \ 2940 @{ \ 2941 fail ("%s: %s is NULL", test, #PTR); \ 2942 abort (); \ 2943 @} \ 2944 @} while (0) 2945 2946#define CHECK_VALUE(ACTUAL, EXPECTED) \ 2947 do @{ \ 2948 if ((ACTUAL) == (EXPECTED)) \ 2949 @{ \ 2950 pass ("%s: actual: %s == expected: %s", test, #ACTUAL, #EXPECTED); \ 2951 @} \ 2952 else \ 2953 @{ \ 2954 fail ("%s: actual: %s != expected: %s", test, #ACTUAL, #EXPECTED); \ 2955 fprintf (stderr, "incorrect value\n"); \ 2956 abort (); \ 2957 @} \ 2958 @} while (0) 2959 2960static void 2961test_script (const char *scripts_dir, const char *script_name, int input, 2962 int expected_result) 2963@{ 2964 char *script_path; 2965 toyvm_function *fn; 2966 int interpreted_result; 2967 toyvm_compiled_function *compiled_fn; 2968 toyvm_compiled_code code; 2969 int compiled_result; 2970 2971 snprintf (test, sizeof (test), "toyvm.c: %s", script_name); 2972 2973 script_path = (char *)malloc (strlen (scripts_dir) 2974 + strlen (script_name) + 1); 2975 CHECK_NON_NULL (script_path); 2976 sprintf (script_path, "%s%s", scripts_dir, script_name); 2977 2978 fn = toyvm_function_parse (script_path, script_name); 2979 CHECK_NON_NULL (fn); 2980 2981 interpreted_result = toyvm_function_interpret (fn, input, NULL); 2982 CHECK_VALUE (interpreted_result, expected_result); 2983 2984 compiled_fn = toyvm_function_compile (fn); 2985 CHECK_NON_NULL (compiled_fn); 2986 2987 code = (toyvm_compiled_code)compiled_fn->cf_code; 2988 CHECK_NON_NULL (code); 2989 2990 compiled_result = code (input); 2991 CHECK_VALUE (compiled_result, expected_result); 2992 2993 gcc_jit_result_release (compiled_fn->cf_jit_result); 2994 free (compiled_fn); 2995 free (fn); 2996 free (script_path); 2997@} 2998 2999#define PATH_TO_SCRIPTS ("/jit/docs/examples/tut04-toyvm/") 3000 3001static void 3002test_suite (void) 3003@{ 3004 const char *srcdir; 3005 char *scripts_dir; 3006 3007 snprintf (test, sizeof (test), "toyvm.c"); 3008 3009 /* We need to locate the test scripts. 3010 Rely on "srcdir" being set in the environment. */ 3011 3012 srcdir = getenv ("srcdir"); 3013 CHECK_NON_NULL (srcdir); 3014 3015 scripts_dir = (char *)malloc (strlen (srcdir) + strlen(PATH_TO_SCRIPTS) 3016 + 1); 3017 CHECK_NON_NULL (scripts_dir); 3018 sprintf (scripts_dir, "%s%s", srcdir, PATH_TO_SCRIPTS); 3019 3020 test_script (scripts_dir, "factorial.toy", 10, 3628800); 3021 test_script (scripts_dir, "fibonacci.toy", 10, 55); 3022 3023 free (scripts_dir); 3024@} 3025 3026int 3027main (int argc, char **argv) 3028@{ 3029 const char *filename = NULL; 3030 toyvm_function *fn = NULL; 3031 3032 /* If called with no args, assume we're being run by the test suite. */ 3033 if (argc < 3) 3034 @{ 3035 test_suite (); 3036 return 0; 3037 @} 3038 3039 if (argc != 3) 3040 @{ 3041 fprintf (stdout, 3042 "%s FILENAME INPUT: Parse and run a .toy file\n", 3043 argv[0]); 3044 exit (1); 3045 @} 3046 3047 filename = argv[1]; 3048 fn = toyvm_function_parse (filename, filename); 3049 if (!fn) 3050 exit (1); 3051 3052 if (0) 3053 toyvm_function_disassemble (fn, stdout); 3054 3055 printf ("interpreter result: %d\n", 3056 toyvm_function_interpret (fn, atoi (argv[2]), NULL)); 3057 3058 /* JIT-compilation. */ 3059 toyvm_compiled_function *compiled_fn 3060 = toyvm_function_compile (fn); 3061 3062 toyvm_compiled_code code = compiled_fn->cf_code; 3063 printf ("compiler result: %d\n", 3064 code (atoi (argv[2]))); 3065 3066 gcc_jit_result_release (compiled_fn->cf_jit_result); 3067 free (compiled_fn); 3068 3069 return 0; 3070@} 3071 3072@end example 3073 3074@noindent 3075@end quotation 3076 3077We can now run the result: 3078 3079@quotation 3080 3081@example 3082 toyvm_compiled_function *compiled_fn 3083 = toyvm_function_compile (fn); 3084 3085 toyvm_compiled_code code = compiled_fn->cf_code; 3086 printf ("compiler result: %d\n", 3087 code (atoi (argv[2]))); 3088 3089 gcc_jit_result_release (compiled_fn->cf_jit_result); 3090 free (compiled_fn); 3091 3092 3093@end example 3094 3095@noindent 3096@end quotation 3097 3098@node Single-stepping through the generated code,Examining the generated code,Compiling the context,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3099@anchor{intro/tutorial04 single-stepping-through-the-generated-code}@anchor{40} 3100@subsection Single-stepping through the generated code 3101 3102 3103It's possible to debug the generated code. To do this we need to both: 3104 3105@quotation 3106 3107 3108@itemize * 3109 3110@item 3111Set up source code locations for our statements, so that we can 3112meaningfully step through the code. We did this above by 3113calling @pxref{41,,gcc_jit_context_new_location()} and using the 3114results. 3115 3116@item 3117Enable the generation of debugging information, by setting 3118@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 3119@pxref{8,,gcc_jit_context} via 3120@pxref{1b,,gcc_jit_context_set_bool_option()}: 3121 3122@example 3123gcc_jit_context_set_bool_option ( 3124 ctxt, 3125 GCC_JIT_BOOL_OPTION_DEBUGINFO, 3126 1); 3127@end example 3128 3129@noindent 3130@end itemize 3131@end quotation 3132 3133Having done this, we can put a breakpoint on the generated function: 3134 3135@example 3136$ gdb --args ./toyvm factorial.toy 10 3137(gdb) break factorial 3138Function "factorial" not defined. 3139Make breakpoint pending on future shared library load? (y or [n]) y 3140Breakpoint 1 (factorial) pending. 3141(gdb) run 3142Breakpoint 1, factorial (arg=10) at factorial.toy:14 314314 DUP 3144@end example 3145 3146@noindent 3147 3148We've set up location information, which references @code{factorial.toy}. 3149This allows us to use e.g. @code{list} to see where we are in the script: 3150 3151@example 3152(gdb) list 31539 315410 # Initial state: 315511 # stack: [arg] 315612 315713 # 0: 315814 DUP 315915 # stack: [arg, arg] 316016 316117 # 1: 316218 PUSH_CONST 2 3163@end example 3164 3165@noindent 3166 3167and to step through the function, examining the data: 3168 3169@example 3170(gdb) n 317118 PUSH_CONST 2 3172(gdb) n 317322 BINARY_COMPARE_LT 3174(gdb) print stack 3175$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@} 3176(gdb) print stack_depth 3177$6 = 3 3178@end example 3179 3180@noindent 3181 3182You'll see that the parts of the @code{stack} array that haven't been 3183touched yet are uninitialized. 3184 3185@cartouche 3186@quotation Note 3187Turning on optimizations may lead to unpredictable results when 3188stepping through the generated code: the execution may appear to 3189"jump around" the source code. This is analogous to turning up the 3190optimization level in a regular compiler. 3191@end quotation 3192@end cartouche 3193 3194@node Examining the generated code,Putting it all together,Single-stepping through the generated code,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3195@anchor{intro/tutorial04 examining-the-generated-code}@anchor{43} 3196@subsection Examining the generated code 3197 3198 3199How good is the optimized code? 3200 3201We can turn up optimizations, by calling 3202@pxref{1e,,gcc_jit_context_set_int_option()} with 3203@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 3204 3205@example 3206gcc_jit_context_set_int_option ( 3207 ctxt, 3208 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3209 3); 3210@end example 3211 3212@noindent 3213 3214One of GCC's internal representations is called "gimple". A dump of the 3215initial gimple representation of the code can be seen by setting: 3216 3217@example 3218gcc_jit_context_set_bool_option (ctxt, 3219 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 3220 1); 3221@end example 3222 3223@noindent 3224 3225With optimization on and source locations displayed, this gives: 3226 3227@c We'll use "c" for gimple dumps 3228 3229@example 3230factorial (signed int arg) 3231@{ 3232 <unnamed type> D.80; 3233 signed int D.81; 3234 signed int D.82; 3235 signed int D.83; 3236 signed int D.84; 3237 signed int D.85; 3238 signed int y; 3239 signed int x; 3240 signed int stack_depth; 3241 signed int stack[8]; 3242 3243 try 3244 @{ 3245 initial: 3246 stack_depth = 0; 3247 stack[stack_depth] = arg; 3248 stack_depth = stack_depth + 1; 3249 goto instr0; 3250 instr0: 3251 /* DUP */: 3252 stack_depth = stack_depth + -1; 3253 x = stack[stack_depth]; 3254 stack[stack_depth] = x; 3255 stack_depth = stack_depth + 1; 3256 stack[stack_depth] = x; 3257 stack_depth = stack_depth + 1; 3258 goto instr1; 3259 instr1: 3260 /* PUSH_CONST */: 3261 stack[stack_depth] = 2; 3262 stack_depth = stack_depth + 1; 3263 goto instr2; 3264 3265 /* etc */ 3266@end example 3267 3268@noindent 3269 3270You can see the generated machine code in assembly form via: 3271 3272@example 3273gcc_jit_context_set_bool_option ( 3274 ctxt, 3275 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 3276 1); 3277result = gcc_jit_context_compile (ctxt); 3278@end example 3279 3280@noindent 3281 3282which shows that (on this x86_64 box) the compiler has unrolled the loop 3283and is using MMX instructions to perform several multiplications 3284simultaneously: 3285 3286@example 3287 .file "fake.c" 3288 .text 3289.Ltext0: 3290 .p2align 4,,15 3291 .globl factorial 3292 .type factorial, @@function 3293factorial: 3294.LFB0: 3295 .file 1 "factorial.toy" 3296 .loc 1 14 0 3297 .cfi_startproc 3298.LVL0: 3299.L2: 3300 .loc 1 26 0 3301 cmpl $1, %edi 3302 jle .L13 3303 leal -1(%rdi), %edx 3304 movl %edx, %ecx 3305 shrl $2, %ecx 3306 leal 0(,%rcx,4), %esi 3307 testl %esi, %esi 3308 je .L14 3309 cmpl $9, %edx 3310 jbe .L14 3311 leal -2(%rdi), %eax 3312 movl %eax, -16(%rsp) 3313 leal -3(%rdi), %eax 3314 movd -16(%rsp), %xmm0 3315 movl %edi, -16(%rsp) 3316 movl %eax, -12(%rsp) 3317 movd -16(%rsp), %xmm1 3318 xorl %eax, %eax 3319 movl %edx, -16(%rsp) 3320 movd -12(%rsp), %xmm4 3321 movd -16(%rsp), %xmm6 3322 punpckldq %xmm4, %xmm0 3323 movdqa .LC1(%rip), %xmm4 3324 punpckldq %xmm6, %xmm1 3325 punpcklqdq %xmm0, %xmm1 3326 movdqa .LC0(%rip), %xmm0 3327 jmp .L5 3328 # etc - edited for brevity 3329@end example 3330 3331@noindent 3332 3333This is clearly overkill for a function that will likely overflow the 3334@code{int} type before the vectorization is worthwhile - but then again, this 3335is a toy example. 3336 3337Turning down the optimization level to 2: 3338 3339@example 3340gcc_jit_context_set_int_option ( 3341 ctxt, 3342 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3343 3); 3344@end example 3345 3346@noindent 3347 3348yields this code, which is simple enough to quote in its entirety: 3349 3350@example 3351 .file "fake.c" 3352 .text 3353 .p2align 4,,15 3354 .globl factorial 3355 .type factorial, @@function 3356factorial: 3357.LFB0: 3358 .cfi_startproc 3359.L2: 3360 cmpl $1, %edi 3361 jle .L8 3362 movl $1, %edx 3363 jmp .L4 3364 .p2align 4,,10 3365 .p2align 3 3366.L6: 3367 movl %eax, %edi 3368.L4: 3369.L5: 3370 leal -1(%rdi), %eax 3371 imull %edi, %edx 3372 cmpl $1, %eax 3373 jne .L6 3374.L3: 3375.L7: 3376 imull %edx, %eax 3377 ret 3378.L8: 3379 movl %edi, %eax 3380 movl $1, %edx 3381 jmp .L7 3382 .cfi_endproc 3383.LFE0: 3384 .size factorial, .-factorial 3385 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})" 3386 .section .note.GNU-stack,"",@@progbits 3387@end example 3388 3389@noindent 3390 3391Note that the stack pushing and popping have been eliminated, as has the 3392recursive call (in favor of an iteration). 3393 3394@node Putting it all together,Behind the curtain How does our code get optimized?,Examining the generated code,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3395@anchor{intro/tutorial04 putting-it-all-together}@anchor{44} 3396@subsection Putting it all together 3397 3398 3399The complete example can be seen in the source tree at 3400@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.c} 3401 3402along with a Makefile and a couple of sample .toy scripts: 3403 3404@example 3405$ ls -al 3406drwxrwxr-x. 2 david david 4096 Sep 19 17:46 . 3407drwxrwxr-x. 3 david david 4096 Sep 19 15:26 .. 3408-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy 3409-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy 3410-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile 3411-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.c 3412 3413$ make toyvm 3414g++ -Wall -g -o toyvm toyvm.c -lgccjit 3415 3416$ ./toyvm factorial.toy 10 3417interpreter result: 3628800 3418compiler result: 3628800 3419 3420$ ./toyvm fibonacci.toy 10 3421interpreter result: 55 3422compiler result: 55 3423@end example 3424 3425@noindent 3426 3427@node Behind the curtain How does our code get optimized?,,Putting it all together,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3428@anchor{intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{45} 3429@subsection Behind the curtain: How does our code get optimized? 3430 3431 3432Our example is done, but you may be wondering about exactly how the 3433compiler turned what we gave it into the machine code seen above. 3434 3435We can examine what the compiler is doing in detail by setting: 3436 3437@example 3438gcc_jit_context_set_bool_option (state.ctxt, 3439 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 3440 1); 3441gcc_jit_context_set_bool_option (state.ctxt, 3442 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 3443 1); 3444@end example 3445 3446@noindent 3447 3448This will dump detailed information about the compiler's state to a 3449directory under @code{/tmp}, and keep it from being cleaned up. 3450 3451The precise names and their formats of these files is subject to change. 3452Higher optimization levels lead to more files. 3453Here's what I saw (edited for brevity; there were almost 200 files): 3454 3455@example 3456intermediate files written to /tmp/libgccjit-KPQbGw 3457$ ls /tmp/libgccjit-KPQbGw/ 3458fake.c.000i.cgraph 3459fake.c.000i.type-inheritance 3460fake.c.004t.gimple 3461fake.c.007t.omplower 3462fake.c.008t.lower 3463fake.c.011t.eh 3464fake.c.012t.cfg 3465fake.c.014i.visibility 3466fake.c.015i.early_local_cleanups 3467fake.c.016t.ssa 3468# etc 3469@end example 3470 3471@noindent 3472 3473The gimple code is converted into Static Single Assignment form, 3474with annotations for use when generating the debuginfo: 3475 3476@example 3477$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa 3478@end example 3479 3480@noindent 3481 3482@example 3483;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3484 3485factorial (signed int arg) 3486@{ 3487 signed int stack[8]; 3488 signed int stack_depth; 3489 signed int x; 3490 signed int y; 3491 <unnamed type> _20; 3492 signed int _21; 3493 signed int _38; 3494 signed int _44; 3495 signed int _51; 3496 signed int _56; 3497 3498initial: 3499 stack_depth_3 = 0; 3500 # DEBUG stack_depth => stack_depth_3 3501 stack[stack_depth_3] = arg_5(D); 3502 stack_depth_7 = stack_depth_3 + 1; 3503 # DEBUG stack_depth => stack_depth_7 3504 # DEBUG instr0 => NULL 3505 # DEBUG /* DUP */ => NULL 3506 stack_depth_8 = stack_depth_7 + -1; 3507 # DEBUG stack_depth => stack_depth_8 3508 x_9 = stack[stack_depth_8]; 3509 # DEBUG x => x_9 3510 stack[stack_depth_8] = x_9; 3511 stack_depth_11 = stack_depth_8 + 1; 3512 # DEBUG stack_depth => stack_depth_11 3513 stack[stack_depth_11] = x_9; 3514 stack_depth_13 = stack_depth_11 + 1; 3515 # DEBUG stack_depth => stack_depth_13 3516 # DEBUG instr1 => NULL 3517 # DEBUG /* PUSH_CONST */ => NULL 3518 stack[stack_depth_13] = 2; 3519 3520 /* etc; edited for brevity */ 3521@end example 3522 3523@noindent 3524 3525We can perhaps better see the code by turning off 3526@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG} 3527statements, giving: 3528 3529@example 3530$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa 3531@end example 3532 3533@noindent 3534 3535@example 3536;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3537 3538factorial (signed int arg) 3539@{ 3540 signed int stack[8]; 3541 signed int stack_depth; 3542 signed int x; 3543 signed int y; 3544 <unnamed type> _20; 3545 signed int _21; 3546 signed int _38; 3547 signed int _44; 3548 signed int _51; 3549 signed int _56; 3550 3551initial: 3552 stack_depth_3 = 0; 3553 stack[stack_depth_3] = arg_5(D); 3554 stack_depth_7 = stack_depth_3 + 1; 3555 stack_depth_8 = stack_depth_7 + -1; 3556 x_9 = stack[stack_depth_8]; 3557 stack[stack_depth_8] = x_9; 3558 stack_depth_11 = stack_depth_8 + 1; 3559 stack[stack_depth_11] = x_9; 3560 stack_depth_13 = stack_depth_11 + 1; 3561 stack[stack_depth_13] = 2; 3562 stack_depth_15 = stack_depth_13 + 1; 3563 stack_depth_16 = stack_depth_15 + -1; 3564 y_17 = stack[stack_depth_16]; 3565 stack_depth_18 = stack_depth_16 + -1; 3566 x_19 = stack[stack_depth_18]; 3567 _20 = x_19 < y_17; 3568 _21 = (signed int) _20; 3569 stack[stack_depth_18] = _21; 3570 stack_depth_23 = stack_depth_18 + 1; 3571 stack_depth_24 = stack_depth_23 + -1; 3572 x_25 = stack[stack_depth_24]; 3573 if (x_25 != 0) 3574 goto <bb 4> (instr9); 3575 else 3576 goto <bb 3> (instr4); 3577 3578instr4: 3579/* DUP */: 3580 stack_depth_26 = stack_depth_24 + -1; 3581 x_27 = stack[stack_depth_26]; 3582 stack[stack_depth_26] = x_27; 3583 stack_depth_29 = stack_depth_26 + 1; 3584 stack[stack_depth_29] = x_27; 3585 stack_depth_31 = stack_depth_29 + 1; 3586 stack[stack_depth_31] = 1; 3587 stack_depth_33 = stack_depth_31 + 1; 3588 stack_depth_34 = stack_depth_33 + -1; 3589 y_35 = stack[stack_depth_34]; 3590 stack_depth_36 = stack_depth_34 + -1; 3591 x_37 = stack[stack_depth_36]; 3592 _38 = x_37 - y_35; 3593 stack[stack_depth_36] = _38; 3594 stack_depth_40 = stack_depth_36 + 1; 3595 stack_depth_41 = stack_depth_40 + -1; 3596 x_42 = stack[stack_depth_41]; 3597 _44 = factorial (x_42); 3598 stack[stack_depth_41] = _44; 3599 stack_depth_46 = stack_depth_41 + 1; 3600 stack_depth_47 = stack_depth_46 + -1; 3601 y_48 = stack[stack_depth_47]; 3602 stack_depth_49 = stack_depth_47 + -1; 3603 x_50 = stack[stack_depth_49]; 3604 _51 = x_50 * y_48; 3605 stack[stack_depth_49] = _51; 3606 stack_depth_53 = stack_depth_49 + 1; 3607 3608 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)> 3609instr9: 3610/* RETURN */: 3611 stack_depth_54 = stack_depth_1 + -1; 3612 x_55 = stack[stack_depth_54]; 3613 _56 = x_55; 3614 stack =@{v@} @{CLOBBER@}; 3615 return _56; 3616 3617@} 3618@end example 3619 3620@noindent 3621 3622Note in the above how all the @pxref{28,,gcc_jit_block} instances we 3623created have been consolidated into just 3 blocks in GCC's internal 3624representation: @code{initial}, @code{instr4} and @code{instr9}. 3625 3626@menu 3627* Optimizing away stack manipulation:: 3628* Elimination of tail recursion:: 3629 3630@end menu 3631 3632@node Optimizing away stack manipulation,Elimination of tail recursion,,Behind the curtain How does our code get optimized? 3633@anchor{intro/tutorial04 optimizing-away-stack-manipulation}@anchor{46} 3634@subsubsection Optimizing away stack manipulation 3635 3636 3637Recall our simple implementation of stack operations. Let's examine 3638how the stack operations are optimized away. 3639 3640After a pass of constant-propagation, the depth of the stack at each 3641opcode can be determined at compile-time: 3642 3643@example 3644$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1 3645@end example 3646 3647@noindent 3648 3649@example 3650;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3651 3652factorial (signed int arg) 3653@{ 3654 signed int stack[8]; 3655 signed int stack_depth; 3656 signed int x; 3657 signed int y; 3658 <unnamed type> _20; 3659 signed int _21; 3660 signed int _38; 3661 signed int _44; 3662 signed int _51; 3663 3664initial: 3665 stack[0] = arg_5(D); 3666 x_9 = stack[0]; 3667 stack[0] = x_9; 3668 stack[1] = x_9; 3669 stack[2] = 2; 3670 y_17 = stack[2]; 3671 x_19 = stack[1]; 3672 _20 = x_19 < y_17; 3673 _21 = (signed int) _20; 3674 stack[1] = _21; 3675 x_25 = stack[1]; 3676 if (x_25 != 0) 3677 goto <bb 4> (instr9); 3678 else 3679 goto <bb 3> (instr4); 3680 3681instr4: 3682/* DUP */: 3683 x_27 = stack[0]; 3684 stack[0] = x_27; 3685 stack[1] = x_27; 3686 stack[2] = 1; 3687 y_35 = stack[2]; 3688 x_37 = stack[1]; 3689 _38 = x_37 - y_35; 3690 stack[1] = _38; 3691 x_42 = stack[1]; 3692 _44 = factorial (x_42); 3693 stack[1] = _44; 3694 y_48 = stack[1]; 3695 x_50 = stack[0]; 3696 _51 = x_50 * y_48; 3697 stack[0] = _51; 3698 3699instr9: 3700/* RETURN */: 3701 x_55 = stack[0]; 3702 x_56 = x_55; 3703 stack =@{v@} @{CLOBBER@}; 3704 return x_56; 3705 3706@} 3707@end example 3708 3709@noindent 3710 3711Note how, in the above, all those @code{stack_depth} values are now just 3712constants: we're accessing specific stack locations at each opcode. 3713 3714The "esra" pass ("Early Scalar Replacement of Aggregates") breaks 3715out our "stack" array into individual elements: 3716 3717@example 3718$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra 3719@end example 3720 3721@noindent 3722 3723@example 3724;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3725 3726Created a replacement for stack offset: 0, size: 32: stack$0 3727Created a replacement for stack offset: 32, size: 32: stack$1 3728Created a replacement for stack offset: 64, size: 32: stack$2 3729 3730Symbols to be put in SSA form 3731@{ D.89 D.90 D.91 @} 3732Incremental SSA update started at block: 0 3733Number of blocks in CFG: 5 3734Number of blocks to update: 4 ( 80%) 3735 3736 3737factorial (signed int arg) 3738@{ 3739 signed int stack$2; 3740 signed int stack$1; 3741 signed int stack$0; 3742 signed int stack[8]; 3743 signed int stack_depth; 3744 signed int x; 3745 signed int y; 3746 <unnamed type> _20; 3747 signed int _21; 3748 signed int _38; 3749 signed int _44; 3750 signed int _51; 3751 3752initial: 3753 stack$0_45 = arg_5(D); 3754 x_9 = stack$0_45; 3755 stack$0_39 = x_9; 3756 stack$1_32 = x_9; 3757 stack$2_30 = 2; 3758 y_17 = stack$2_30; 3759 x_19 = stack$1_32; 3760 _20 = x_19 < y_17; 3761 _21 = (signed int) _20; 3762 stack$1_28 = _21; 3763 x_25 = stack$1_28; 3764 if (x_25 != 0) 3765 goto <bb 4> (instr9); 3766 else 3767 goto <bb 3> (instr4); 3768 3769instr4: 3770/* DUP */: 3771 x_27 = stack$0_39; 3772 stack$0_22 = x_27; 3773 stack$1_14 = x_27; 3774 stack$2_12 = 1; 3775 y_35 = stack$2_12; 3776 x_37 = stack$1_14; 3777 _38 = x_37 - y_35; 3778 stack$1_10 = _38; 3779 x_42 = stack$1_10; 3780 _44 = factorial (x_42); 3781 stack$1_6 = _44; 3782 y_48 = stack$1_6; 3783 x_50 = stack$0_22; 3784 _51 = x_50 * y_48; 3785 stack$0_1 = _51; 3786 3787 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)> 3788instr9: 3789/* RETURN */: 3790 x_55 = stack$0_52; 3791 x_56 = x_55; 3792 stack =@{v@} @{CLOBBER@}; 3793 return x_56; 3794 3795@} 3796@end example 3797 3798@noindent 3799 3800Hence at this point, all those pushes and pops of the stack are now 3801simply assignments to specific temporary variables. 3802 3803After some copy propagation, the stack manipulation has been completely 3804optimized away: 3805 3806@example 3807$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1 3808@end example 3809 3810@noindent 3811 3812@example 3813;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3814 3815factorial (signed int arg) 3816@{ 3817 signed int stack$2; 3818 signed int stack$1; 3819 signed int stack$0; 3820 signed int stack[8]; 3821 signed int stack_depth; 3822 signed int x; 3823 signed int y; 3824 <unnamed type> _20; 3825 signed int _21; 3826 signed int _38; 3827 signed int _44; 3828 signed int _51; 3829 3830initial: 3831 stack$0_39 = arg_5(D); 3832 _20 = arg_5(D) <= 1; 3833 _21 = (signed int) _20; 3834 if (_21 != 0) 3835 goto <bb 4> (instr9); 3836 else 3837 goto <bb 3> (instr4); 3838 3839instr4: 3840/* DUP */: 3841 _38 = arg_5(D) + -1; 3842 _44 = factorial (_38); 3843 _51 = arg_5(D) * _44; 3844 stack$0_1 = _51; 3845 3846 # stack$0_52 = PHI <arg_5(D)(2), _51(3)> 3847instr9: 3848/* RETURN */: 3849 stack =@{v@} @{CLOBBER@}; 3850 return stack$0_52; 3851 3852@} 3853@end example 3854 3855@noindent 3856 3857Later on, another pass finally eliminated @code{stack_depth} local and the 3858unused parts of the @cite{stack`} array altogether: 3859 3860@example 3861$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa 3862@end example 3863 3864@noindent 3865 3866@example 3867;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3868 3869Released 44 names, 314.29%, removed 44 holes 3870factorial (signed int arg) 3871@{ 3872 signed int stack$0; 3873 signed int mult_acc_1; 3874 <unnamed type> _5; 3875 signed int _6; 3876 signed int _7; 3877 signed int mul_tmp_10; 3878 signed int mult_acc_11; 3879 signed int mult_acc_13; 3880 3881 # arg_9 = PHI <arg_8(D)(0)> 3882 # mult_acc_13 = PHI <1(0)> 3883initial: 3884 3885 <bb 5>: 3886 # arg_4 = PHI <arg_9(2), _7(3)> 3887 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)> 3888 _5 = arg_4 <= 1; 3889 _6 = (signed int) _5; 3890 if (_6 != 0) 3891 goto <bb 4> (instr9); 3892 else 3893 goto <bb 3> (instr4); 3894 3895instr4: 3896/* DUP */: 3897 _7 = arg_4 + -1; 3898 mult_acc_11 = mult_acc_1 * arg_4; 3899 goto <bb 5>; 3900 3901 # stack$0_12 = PHI <arg_4(5)> 3902instr9: 3903/* RETURN */: 3904 mul_tmp_10 = mult_acc_1 * stack$0_12; 3905 return mul_tmp_10; 3906 3907@} 3908@end example 3909 3910@noindent 3911 3912@node Elimination of tail recursion,,Optimizing away stack manipulation,Behind the curtain How does our code get optimized? 3913@anchor{intro/tutorial04 elimination-of-tail-recursion}@anchor{47} 3914@subsubsection Elimination of tail recursion 3915 3916 3917Another significant optimization is the detection that the call to 3918@code{factorial} is tail recursion, which can be eliminated in favor of 3919an iteration: 3920 3921@example 3922$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1 3923@end example 3924 3925@noindent 3926 3927@example 3928;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3929 3930 3931Symbols to be put in SSA form 3932@{ D.88 @} 3933Incremental SSA update started at block: 0 3934Number of blocks in CFG: 5 3935Number of blocks to update: 4 ( 80%) 3936 3937 3938factorial (signed int arg) 3939@{ 3940 signed int stack$2; 3941 signed int stack$1; 3942 signed int stack$0; 3943 signed int stack[8]; 3944 signed int stack_depth; 3945 signed int x; 3946 signed int y; 3947 signed int mult_acc_1; 3948 <unnamed type> _20; 3949 signed int _21; 3950 signed int _38; 3951 signed int mul_tmp_44; 3952 signed int mult_acc_51; 3953 3954 # arg_5 = PHI <arg_39(D)(0), _38(3)> 3955 # mult_acc_1 = PHI <1(0), mult_acc_51(3)> 3956initial: 3957 _20 = arg_5 <= 1; 3958 _21 = (signed int) _20; 3959 if (_21 != 0) 3960 goto <bb 4> (instr9); 3961 else 3962 goto <bb 3> (instr4); 3963 3964instr4: 3965/* DUP */: 3966 _38 = arg_5 + -1; 3967 mult_acc_51 = mult_acc_1 * arg_5; 3968 goto <bb 2> (initial); 3969 3970 # stack$0_52 = PHI <arg_5(2)> 3971instr9: 3972/* RETURN */: 3973 stack =@{v@} @{CLOBBER@}; 3974 mul_tmp_44 = mult_acc_1 * stack$0_52; 3975 return mul_tmp_44; 3976 3977@} 3978@end example 3979 3980@noindent 3981 3982@c Copyright (C) 2015-2017 Free Software Foundation, Inc. 3983@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 3984@c 3985@c This is free software: you can redistribute it and/or modify it 3986@c under the terms of the GNU General Public License as published by 3987@c the Free Software Foundation, either version 3 of the License, or 3988@c (at your option) any later version. 3989@c 3990@c This program is distributed in the hope that it will be useful, but 3991@c WITHOUT ANY WARRANTY; without even the implied warranty of 3992@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 3993@c General Public License for more details. 3994@c 3995@c You should have received a copy of the GNU General Public License 3996@c along with this program. If not, see 3997@c <http://www.gnu.org/licenses/>. 3998 3999@node Tutorial part 5 Implementing an Ahead-of-Time compiler,,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial 4000@anchor{intro/tutorial05 doc}@anchor{48}@anchor{intro/tutorial05 tutorial-part-5-implementing-an-ahead-of-time-compiler}@anchor{49} 4001@section Tutorial part 5: Implementing an Ahead-of-Time compiler 4002 4003 4004If you have a pre-existing language frontend that's compatible with 4005libgccjit's license, it's possible to hook it up to libgccjit as a 4006backend. In the previous example we showed 4007how to do that for in-memory JIT-compilation, but libgccjit can also 4008compile code directly to a file, allowing you to implement a more 4009traditional ahead-of-time compiler ("JIT" is something of a misnomer 4010for this use-case). 4011 4012The essential difference is to compile the context using 4013@pxref{4a,,gcc_jit_context_compile_to_file()} rather than 4014@pxref{15,,gcc_jit_context_compile()}. 4015 4016@menu 4017* The "brainf" language:: 4018* Converting a brainf script to libgccjit IR:: 4019* Compiling a context to a file:: 4020* Other forms of ahead-of-time-compilation:: 4021 4022@end menu 4023 4024@node The "brainf" language,Converting a brainf script to libgccjit IR,,Tutorial part 5 Implementing an Ahead-of-Time compiler 4025@anchor{intro/tutorial05 the-brainf-language}@anchor{4b} 4026@subsection The "brainf" language 4027 4028 4029In this example we use libgccjit to construct an ahead-of-time compiler 4030for an esoteric programming language that we shall refer to as "brainf". 4031 4032brainf scripts operate on an array of bytes, with a notional data pointer 4033within the array. 4034 4035brainf is hard for humans to read, but it's trivial to write a parser for 4036it, as there is no lexing; just a stream of bytes. The operations are: 4037 4038 4039@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 4040@headitem 4041 4042Character 4043 4044@tab 4045 4046Meaning 4047 4048@item 4049 4050@code{>} 4051 4052@tab 4053 4054@code{idx += 1} 4055 4056@item 4057 4058@code{<} 4059 4060@tab 4061 4062@code{idx -= 1} 4063 4064@item 4065 4066@code{+} 4067 4068@tab 4069 4070@code{data[idx] += 1} 4071 4072@item 4073 4074@code{-} 4075 4076@tab 4077 4078@code{data[idx] -= 1} 4079 4080@item 4081 4082@code{.} 4083 4084@tab 4085 4086@code{output (data[idx])} 4087 4088@item 4089 4090@code{,} 4091 4092@tab 4093 4094@code{data[idx] = input ()} 4095 4096@item 4097 4098@code{[} 4099 4100@tab 4101 4102loop until @code{data[idx] == 0} 4103 4104@item 4105 4106@code{]} 4107 4108@tab 4109 4110end of loop 4111 4112@item 4113 4114Anything else 4115 4116@tab 4117 4118ignored 4119 4120@end multitable 4121 4122 4123Unlike the previous example, we'll implement an ahead-of-time compiler, 4124which reads @code{.bf} scripts and outputs executables (though it would 4125be trivial to have it run them JIT-compiled in-process). 4126 4127Here's what a simple @code{.bf} script looks like: 4128 4129@quotation 4130 4131@example 4132[ 4133 Emit the uppercase alphabet 4134] 4135 4136cell 0 = 26 4137++++++++++++++++++++++++++ 4138 4139cell 1 = 65 4140>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4141 4142while cell#0 != 0 4143[ 4144 > 4145 . emit cell#1 4146 + increment cell@@1 4147 <- decrement cell@@0 4148] 4149 4150@end example 4151 4152@noindent 4153@end quotation 4154 4155@cartouche 4156@quotation Note 4157This example makes use of whitespace and comments for legibility, but 4158could have been written as: 4159 4160@example 4161++++++++++++++++++++++++++ 4162>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4163[>.+<-] 4164@end example 4165 4166@noindent 4167 4168It's not a particularly useful language, except for providing 4169compiler-writers with a test case that's easy to parse. The point 4170is that you can use @pxref{4a,,gcc_jit_context_compile_to_file()} 4171to use libgccjit as a backend for a pre-existing language frontend 4172(provided that the pre-existing frontend is compatible with libgccjit's 4173license). 4174@end quotation 4175@end cartouche 4176 4177@node Converting a brainf script to libgccjit IR,Compiling a context to a file,The "brainf" language,Tutorial part 5 Implementing an Ahead-of-Time compiler 4178@anchor{intro/tutorial05 converting-a-brainf-script-to-libgccjit-ir}@anchor{4c} 4179@subsection Converting a brainf script to libgccjit IR 4180 4181 4182As before we write simple code to populate a @pxref{8,,gcc_jit_context *}. 4183 4184@quotation 4185 4186@example 4187 4188typedef struct bf_compiler 4189@{ 4190 const char *filename; 4191 int line; 4192 int column; 4193 4194 gcc_jit_context *ctxt; 4195 4196 gcc_jit_type *void_type; 4197 gcc_jit_type *int_type; 4198 gcc_jit_type *byte_type; 4199 gcc_jit_type *array_type; 4200 4201 gcc_jit_function *func_getchar; 4202 gcc_jit_function *func_putchar; 4203 4204 gcc_jit_function *func; 4205 gcc_jit_block *curblock; 4206 4207 gcc_jit_rvalue *int_zero; 4208 gcc_jit_rvalue *int_one; 4209 gcc_jit_rvalue *byte_zero; 4210 gcc_jit_rvalue *byte_one; 4211 gcc_jit_lvalue *data_cells; 4212 gcc_jit_lvalue *idx; 4213 4214 int num_open_parens; 4215 gcc_jit_block *paren_test[MAX_OPEN_PARENS]; 4216 gcc_jit_block *paren_body[MAX_OPEN_PARENS]; 4217 gcc_jit_block *paren_after[MAX_OPEN_PARENS]; 4218 4219@} bf_compiler; 4220 4221/* Bail out, with a message on stderr. */ 4222 4223static void 4224fatal_error (bf_compiler *bfc, const char *msg) 4225@{ 4226 fprintf (stderr, 4227 "%s:%i:%i: %s", 4228 bfc->filename, bfc->line, bfc->column, msg); 4229 abort (); 4230@} 4231 4232/* Get "data_cells[idx]" as an lvalue. */ 4233 4234static gcc_jit_lvalue * 4235bf_get_current_data (bf_compiler *bfc, gcc_jit_location *loc) 4236@{ 4237 return gcc_jit_context_new_array_access ( 4238 bfc->ctxt, 4239 loc, 4240 gcc_jit_lvalue_as_rvalue (bfc->data_cells), 4241 gcc_jit_lvalue_as_rvalue (bfc->idx)); 4242@} 4243 4244/* Get "data_cells[idx] == 0" as a boolean rvalue. */ 4245 4246static gcc_jit_rvalue * 4247bf_current_data_is_zero (bf_compiler *bfc, gcc_jit_location *loc) 4248@{ 4249 return gcc_jit_context_new_comparison ( 4250 bfc->ctxt, 4251 loc, 4252 GCC_JIT_COMPARISON_EQ, 4253 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)), 4254 bfc->byte_zero); 4255@} 4256 4257/* Compile one bf character. */ 4258 4259static void 4260bf_compile_char (bf_compiler *bfc, 4261 unsigned char ch) 4262@{ 4263 gcc_jit_location *loc = 4264 gcc_jit_context_new_location (bfc->ctxt, 4265 bfc->filename, 4266 bfc->line, 4267 bfc->column); 4268 4269 /* Turn this on to trace execution, by injecting putchar () 4270 of each source char. */ 4271 if (0) 4272 @{ 4273 gcc_jit_rvalue *arg = 4274 gcc_jit_context_new_rvalue_from_int ( 4275 bfc->ctxt, 4276 bfc->int_type, 4277 ch); 4278 gcc_jit_rvalue *call = 4279 gcc_jit_context_new_call (bfc->ctxt, 4280 loc, 4281 bfc->func_putchar, 4282 1, &arg); 4283 gcc_jit_block_add_eval (bfc->curblock, 4284 loc, 4285 call); 4286 @} 4287 4288 switch (ch) 4289 @{ 4290 case '>': 4291 gcc_jit_block_add_comment (bfc->curblock, 4292 loc, 4293 "'>': idx += 1;"); 4294 gcc_jit_block_add_assignment_op (bfc->curblock, 4295 loc, 4296 bfc->idx, 4297 GCC_JIT_BINARY_OP_PLUS, 4298 bfc->int_one); 4299 break; 4300 4301 case '<': 4302 gcc_jit_block_add_comment (bfc->curblock, 4303 loc, 4304 "'<': idx -= 1;"); 4305 gcc_jit_block_add_assignment_op (bfc->curblock, 4306 loc, 4307 bfc->idx, 4308 GCC_JIT_BINARY_OP_MINUS, 4309 bfc->int_one); 4310 break; 4311 4312 case '+': 4313 gcc_jit_block_add_comment (bfc->curblock, 4314 loc, 4315 "'+': data[idx] += 1;"); 4316 gcc_jit_block_add_assignment_op (bfc->curblock, 4317 loc, 4318 bf_get_current_data (bfc, loc), 4319 GCC_JIT_BINARY_OP_PLUS, 4320 bfc->byte_one); 4321 break; 4322 4323 case '-': 4324 gcc_jit_block_add_comment (bfc->curblock, 4325 loc, 4326 "'-': data[idx] -= 1;"); 4327 gcc_jit_block_add_assignment_op (bfc->curblock, 4328 loc, 4329 bf_get_current_data (bfc, loc), 4330 GCC_JIT_BINARY_OP_MINUS, 4331 bfc->byte_one); 4332 break; 4333 4334 case '.': 4335 @{ 4336 gcc_jit_rvalue *arg = 4337 gcc_jit_context_new_cast ( 4338 bfc->ctxt, 4339 loc, 4340 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)), 4341 bfc->int_type); 4342 gcc_jit_rvalue *call = 4343 gcc_jit_context_new_call (bfc->ctxt, 4344 loc, 4345 bfc->func_putchar, 4346 1, &arg); 4347 gcc_jit_block_add_comment (bfc->curblock, 4348 loc, 4349 "'.': putchar ((int)data[idx]);"); 4350 gcc_jit_block_add_eval (bfc->curblock, 4351 loc, 4352 call); 4353 @} 4354 break; 4355 4356 case ',': 4357 @{ 4358 gcc_jit_rvalue *call = 4359 gcc_jit_context_new_call (bfc->ctxt, 4360 loc, 4361 bfc->func_getchar, 4362 0, NULL); 4363 gcc_jit_block_add_comment ( 4364 bfc->curblock, 4365 loc, 4366 "',': data[idx] = (unsigned char)getchar ();"); 4367 gcc_jit_block_add_assignment (bfc->curblock, 4368 loc, 4369 bf_get_current_data (bfc, loc), 4370 gcc_jit_context_new_cast ( 4371 bfc->ctxt, 4372 loc, 4373 call, 4374 bfc->byte_type)); 4375 @} 4376 break; 4377 4378 case '[': 4379 @{ 4380 gcc_jit_block *loop_test = 4381 gcc_jit_function_new_block (bfc->func, NULL); 4382 gcc_jit_block *on_zero = 4383 gcc_jit_function_new_block (bfc->func, NULL); 4384 gcc_jit_block *on_non_zero = 4385 gcc_jit_function_new_block (bfc->func, NULL); 4386 4387 if (bfc->num_open_parens == MAX_OPEN_PARENS) 4388 fatal_error (bfc, "too many open parens"); 4389 4390 gcc_jit_block_end_with_jump ( 4391 bfc->curblock, 4392 loc, 4393 loop_test); 4394 4395 gcc_jit_block_add_comment ( 4396 loop_test, 4397 loc, 4398 "'['"); 4399 gcc_jit_block_end_with_conditional ( 4400 loop_test, 4401 loc, 4402 bf_current_data_is_zero (bfc, loc), 4403 on_zero, 4404 on_non_zero); 4405 bfc->paren_test[bfc->num_open_parens] = loop_test; 4406 bfc->paren_body[bfc->num_open_parens] = on_non_zero; 4407 bfc->paren_after[bfc->num_open_parens] = on_zero; 4408 bfc->num_open_parens += 1; 4409 bfc->curblock = on_non_zero; 4410 @} 4411 break; 4412 4413 case ']': 4414 @{ 4415 gcc_jit_block_add_comment ( 4416 bfc->curblock, 4417 loc, 4418 "']'"); 4419 4420 if (bfc->num_open_parens == 0) 4421 fatal_error (bfc, "mismatching parens"); 4422 bfc->num_open_parens -= 1; 4423 gcc_jit_block_end_with_jump ( 4424 bfc->curblock, 4425 loc, 4426 bfc->paren_test[bfc->num_open_parens]); 4427 bfc->curblock = bfc->paren_after[bfc->num_open_parens]; 4428 @} 4429 break; 4430 4431 case '\n': 4432 bfc->line +=1; 4433 bfc->column = 0; 4434 break; 4435 @} 4436 4437 if (ch != '\n') 4438 bfc->column += 1; 4439@} 4440 4441/* Compile the given .bf file into a gcc_jit_context, containing a 4442 single "main" function suitable for compiling into an executable. */ 4443 4444gcc_jit_context * 4445bf_compile (const char *filename) 4446@{ 4447 bf_compiler bfc; 4448 FILE *f_in; 4449 int ch; 4450 4451 memset (&bfc, 0, sizeof (bfc)); 4452 4453 bfc.filename = filename; 4454 f_in = fopen (filename, "r"); 4455 if (!f_in) 4456 fatal_error (&bfc, "unable to open file"); 4457 bfc.line = 1; 4458 4459 bfc.ctxt = gcc_jit_context_acquire (); 4460 4461 gcc_jit_context_set_int_option ( 4462 bfc.ctxt, 4463 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 4464 3); 4465 gcc_jit_context_set_bool_option ( 4466 bfc.ctxt, 4467 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 4468 0); 4469 gcc_jit_context_set_bool_option ( 4470 bfc.ctxt, 4471 GCC_JIT_BOOL_OPTION_DEBUGINFO, 4472 1); 4473 gcc_jit_context_set_bool_option ( 4474 bfc.ctxt, 4475 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 4476 0); 4477 gcc_jit_context_set_bool_option ( 4478 bfc.ctxt, 4479 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 4480 0); 4481 4482 bfc.void_type = 4483 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_VOID); 4484 bfc.int_type = 4485 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_INT); 4486 bfc.byte_type = 4487 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR); 4488 bfc.array_type = 4489 gcc_jit_context_new_array_type (bfc.ctxt, 4490 NULL, 4491 bfc.byte_type, 4492 30000); 4493 4494 bfc.func_getchar = 4495 gcc_jit_context_new_function (bfc.ctxt, NULL, 4496 GCC_JIT_FUNCTION_IMPORTED, 4497 bfc.int_type, 4498 "getchar", 4499 0, NULL, 4500 0); 4501 4502 gcc_jit_param *param_c = 4503 gcc_jit_context_new_param (bfc.ctxt, NULL, bfc.int_type, "c"); 4504 bfc.func_putchar = 4505 gcc_jit_context_new_function (bfc.ctxt, NULL, 4506 GCC_JIT_FUNCTION_IMPORTED, 4507 bfc.void_type, 4508 "putchar", 4509 1, ¶m_c, 4510 0); 4511 4512 bfc.func = make_main (bfc.ctxt); 4513 bfc.curblock = 4514 gcc_jit_function_new_block (bfc.func, "initial"); 4515 bfc.int_zero = gcc_jit_context_zero (bfc.ctxt, bfc.int_type); 4516 bfc.int_one = gcc_jit_context_one (bfc.ctxt, bfc.int_type); 4517 bfc.byte_zero = gcc_jit_context_zero (bfc.ctxt, bfc.byte_type); 4518 bfc.byte_one = gcc_jit_context_one (bfc.ctxt, bfc.byte_type); 4519 4520 bfc.data_cells = 4521 gcc_jit_context_new_global (bfc.ctxt, NULL, 4522 GCC_JIT_GLOBAL_INTERNAL, 4523 bfc.array_type, 4524 "data_cells"); 4525 bfc.idx = 4526 gcc_jit_function_new_local (bfc.func, NULL, 4527 bfc.int_type, 4528 "idx"); 4529 4530 gcc_jit_block_add_comment (bfc.curblock, 4531 NULL, 4532 "idx = 0;"); 4533 gcc_jit_block_add_assignment (bfc.curblock, 4534 NULL, 4535 bfc.idx, 4536 bfc.int_zero); 4537 4538 bfc.num_open_parens = 0; 4539 4540 while ( EOF != (ch = fgetc (f_in))) 4541 bf_compile_char (&bfc, (unsigned char)ch); 4542 4543 gcc_jit_block_end_with_return (bfc.curblock, NULL, bfc.int_zero); 4544 4545 fclose (f_in); 4546 4547 return bfc.ctxt; 4548@} 4549 4550 4551@end example 4552 4553@noindent 4554@end quotation 4555 4556@node Compiling a context to a file,Other forms of ahead-of-time-compilation,Converting a brainf script to libgccjit IR,Tutorial part 5 Implementing an Ahead-of-Time compiler 4557@anchor{intro/tutorial05 compiling-a-context-to-a-file}@anchor{4d} 4558@subsection Compiling a context to a file 4559 4560 4561Unlike the previous tutorial, this time we'll compile the context 4562directly to an executable, using @pxref{4a,,gcc_jit_context_compile_to_file()}: 4563 4564@example 4565gcc_jit_context_compile_to_file (ctxt, 4566 GCC_JIT_OUTPUT_KIND_EXECUTABLE, 4567 output_file); 4568@end example 4569 4570@noindent 4571 4572Here's the top-level of the compiler, which is what actually calls into 4573@pxref{4a,,gcc_jit_context_compile_to_file()}: 4574 4575@quotation 4576 4577@example 4578 4579int 4580main (int argc, char **argv) 4581@{ 4582 const char *input_file; 4583 const char *output_file; 4584 gcc_jit_context *ctxt; 4585 const char *err; 4586 4587 if (argc != 3) 4588 @{ 4589 fprintf (stderr, "%s: INPUT_FILE OUTPUT_FILE\n", argv[0]); 4590 return 1; 4591 @} 4592 4593 input_file = argv[1]; 4594 output_file = argv[2]; 4595 ctxt = bf_compile (input_file); 4596 4597 gcc_jit_context_compile_to_file (ctxt, 4598 GCC_JIT_OUTPUT_KIND_EXECUTABLE, 4599 output_file); 4600 4601 err = gcc_jit_context_get_first_error (ctxt); 4602 4603 if (err) 4604 @{ 4605 gcc_jit_context_release (ctxt); 4606 return 1; 4607 @} 4608 4609 gcc_jit_context_release (ctxt); 4610 return 0; 4611@} 4612 4613 4614@end example 4615 4616@noindent 4617@end quotation 4618 4619Note how once the context is populated you could trivially instead compile 4620it to memory using @pxref{15,,gcc_jit_context_compile()} and run it in-process 4621as in the previous tutorial. 4622 4623To create an executable, we need to export a @code{main} function. Here's 4624how to create one from the JIT API: 4625 4626@quotation 4627 4628@example 4629 4630/* Make "main" function: 4631 int 4632 main (int argc, char **argv) 4633 @{ 4634 ... 4635 @} 4636*/ 4637static gcc_jit_function * 4638make_main (gcc_jit_context *ctxt) 4639@{ 4640 gcc_jit_type *int_type = 4641 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 4642 gcc_jit_param *param_argc = 4643 gcc_jit_context_new_param (ctxt, NULL, int_type, "argc"); 4644 gcc_jit_type *char_ptr_ptr_type = 4645 gcc_jit_type_get_pointer ( 4646 gcc_jit_type_get_pointer ( 4647 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR))); 4648 gcc_jit_param *param_argv = 4649 gcc_jit_context_new_param (ctxt, NULL, char_ptr_ptr_type, "argv"); 4650 gcc_jit_param *params[2] = @{param_argc, param_argv@}; 4651 gcc_jit_function *func_main = 4652 gcc_jit_context_new_function (ctxt, NULL, 4653 GCC_JIT_FUNCTION_EXPORTED, 4654 int_type, 4655 "main", 4656 2, params, 4657 0); 4658 return func_main; 4659@} 4660 4661 4662@end example 4663 4664@noindent 4665@end quotation 4666 4667@cartouche 4668@quotation Note 4669The above implementation ignores @code{argc} and @code{argv}, but you could 4670make use of them by exposing @code{param_argc} and @code{param_argv} to the 4671caller. 4672@end quotation 4673@end cartouche 4674 4675Upon compiling this C code, we obtain a bf-to-machine-code compiler; 4676let's call it @code{bfc}: 4677 4678@example 4679$ gcc \ 4680 tut05-bf.c \ 4681 -o bfc \ 4682 -lgccjit 4683@end example 4684 4685@noindent 4686 4687We can now use @code{bfc} to compile .bf files into machine code executables: 4688 4689@example 4690$ ./bfc \ 4691 emit-alphabet.bf \ 4692 a.out 4693@end example 4694 4695@noindent 4696 4697which we can run directly: 4698 4699@example 4700$ ./a.out 4701ABCDEFGHIJKLMNOPQRSTUVWXYZ 4702@end example 4703 4704@noindent 4705 4706Success! 4707 4708We can also inspect the generated executable using standard tools: 4709 4710@example 4711$ objdump -d a.out |less 4712@end example 4713 4714@noindent 4715 4716which shows that libgccjit has managed to optimize the function 4717somewhat (for example, the runs of 26 and 65 increment operations 4718have become integer constants 0x1a and 0x41): 4719 4720@example 47210000000000400620 <main>: 4722 400620: 80 3d 39 0a 20 00 00 cmpb $0x0,0x200a39(%rip) # 601060 <data 4723 400627: 74 07 je 400630 <main 4724 400629: eb fe jmp 400629 <main+0x9> 4725 40062b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 4726 400630: 48 83 ec 08 sub $0x8,%rsp 4727 400634: 0f b6 05 26 0a 20 00 movzbl 0x200a26(%rip),%eax # 601061 <data_cells+0x1> 4728 40063b: c6 05 1e 0a 20 00 1a movb $0x1a,0x200a1e(%rip) # 601060 <data_cells> 4729 400642: 8d 78 41 lea 0x41(%rax),%edi 4730 400645: 40 88 3d 15 0a 20 00 mov %dil,0x200a15(%rip) # 601061 <data_cells+0x1> 4731 40064c: 0f 1f 40 00 nopl 0x0(%rax) 4732 400650: 40 0f b6 ff movzbl %dil,%edi 4733 400654: e8 87 fe ff ff callq 4004e0 <putchar@@plt> 4734 400659: 0f b6 05 01 0a 20 00 movzbl 0x200a01(%rip),%eax # 601061 <data_cells+0x1> 4735 400660: 80 2d f9 09 20 00 01 subb $0x1,0x2009f9(%rip) # 601060 <data_cells> 4736 400667: 8d 78 01 lea 0x1(%rax),%edi 4737 40066a: 40 88 3d f0 09 20 00 mov %dil,0x2009f0(%rip) # 601061 <data_cells+0x1> 4738 400671: 75 dd jne 400650 <main+0x30> 4739 400673: 31 c0 xor %eax,%eax 4740 400675: 48 83 c4 08 add $0x8,%rsp 4741 400679: c3 retq 4742 40067a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 4743@end example 4744 4745@noindent 4746 4747We also set up debugging information (via 4748@pxref{41,,gcc_jit_context_new_location()} and 4749@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO}), so it's possible to use @code{gdb} 4750to singlestep through the generated binary and inspect the internal 4751state @code{idx} and @code{data_cells}: 4752 4753@example 4754(gdb) break main 4755Breakpoint 1 at 0x400790 4756(gdb) run 4757Starting program: a.out 4758 4759Breakpoint 1, 0x0000000000400790 in main (argc=1, argv=0x7fffffffe448) 4760(gdb) stepi 47610x0000000000400797 in main (argc=1, argv=0x7fffffffe448) 4762(gdb) stepi 47630x00000000004007a0 in main (argc=1, argv=0x7fffffffe448) 4764(gdb) stepi 47659 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4766(gdb) list 47674 47685 cell 0 = 26 47696 ++++++++++++++++++++++++++ 47707 47718 cell 1 = 65 47729 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 477310 477411 while cell#0 != 0 477512 [ 477613 > 4777(gdb) n 47786 ++++++++++++++++++++++++++ 4779(gdb) n 47809 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4781(gdb) p idx 4782$1 = 1 4783(gdb) p data_cells 4784$2 = "\032", '\000' <repeats 29998 times> 4785(gdb) p data_cells[0] 4786$3 = 26 '\032' 4787(gdb) p data_cells[1] 4788$4 = 0 '\000' 4789(gdb) list 47904 47915 cell 0 = 26 47926 ++++++++++++++++++++++++++ 47937 47948 cell 1 = 65 47959 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 479610 479711 while cell#0 != 0 479812 [ 479913 > 4800@end example 4801 4802@noindent 4803 4804@node Other forms of ahead-of-time-compilation,,Compiling a context to a file,Tutorial part 5 Implementing an Ahead-of-Time compiler 4805@anchor{intro/tutorial05 other-forms-of-ahead-of-time-compilation}@anchor{4e} 4806@subsection Other forms of ahead-of-time-compilation 4807 4808 4809The above demonstrates compiling a @pxref{8,,gcc_jit_context *} directly 4810to an executable. It's also possible to compile it to an object file, 4811and to a dynamic library. See the documentation of 4812@pxref{4a,,gcc_jit_context_compile_to_file()} for more information. 4813 4814@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 4815@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 4816@c 4817@c This is free software: you can redistribute it and/or modify it 4818@c under the terms of the GNU General Public License as published by 4819@c the Free Software Foundation, either version 3 of the License, or 4820@c (at your option) any later version. 4821@c 4822@c This program is distributed in the hope that it will be useful, but 4823@c WITHOUT ANY WARRANTY; without even the implied warranty of 4824@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4825@c General Public License for more details. 4826@c 4827@c You should have received a copy of the GNU General Public License 4828@c along with this program. If not, see 4829@c <http://www.gnu.org/licenses/>. 4830 4831@node Topic Reference,C++ bindings for libgccjit,Tutorial,Top 4832@anchor{topics/index doc}@anchor{4f}@anchor{topics/index topic-reference}@anchor{50} 4833@chapter Topic Reference 4834 4835 4836@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 4837@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 4838@c 4839@c This is free software: you can redistribute it and/or modify it 4840@c under the terms of the GNU General Public License as published by 4841@c the Free Software Foundation, either version 3 of the License, or 4842@c (at your option) any later version. 4843@c 4844@c This program is distributed in the hope that it will be useful, but 4845@c WITHOUT ANY WARRANTY; without even the implied warranty of 4846@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4847@c General Public License for more details. 4848@c 4849@c You should have received a copy of the GNU General Public License 4850@c along with this program. If not, see 4851@c <http://www.gnu.org/licenses/>. 4852 4853@menu 4854* Compilation contexts:: 4855* Objects:: 4856* Types:: 4857* Expressions:: 4858* Creating and using functions:: 4859* Source Locations:: 4860* Compiling a context:: 4861* ABI and API compatibility:: 4862* Performance:: 4863 4864Compilation contexts 4865 4866* Lifetime-management:: 4867* Thread-safety:: 4868* Error-handling: Error-handling<2>. 4869* Debugging:: 4870* Options: Options<2>. 4871 4872Options 4873 4874* String Options:: 4875* Boolean options:: 4876* Integer options:: 4877* Additional command-line options:: 4878 4879Types 4880 4881* Standard types:: 4882* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 4883* Structures and unions:: 4884 4885Expressions 4886 4887* Rvalues:: 4888* Lvalues:: 4889* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 4890 4891Rvalues 4892 4893* Simple expressions:: 4894* Unary Operations:: 4895* Binary Operations:: 4896* Comparisons:: 4897* Function calls:: 4898* Type-coercion:: 4899 4900Lvalues 4901 4902* Global variables:: 4903 4904Creating and using functions 4905 4906* Params:: 4907* Functions:: 4908* Blocks:: 4909* Statements:: 4910 4911Source Locations 4912 4913* Faking it:: 4914 4915Compiling a context 4916 4917* In-memory compilation:: 4918* Ahead-of-time compilation:: 4919 4920ABI and API compatibility 4921 4922* ABI symbol tags:: 4923 4924ABI symbol tags 4925 4926* LIBGCCJIT_ABI_0:: 4927* LIBGCCJIT_ABI_1:: 4928* LIBGCCJIT_ABI_2:: 4929* LIBGCCJIT_ABI_3:: 4930* LIBGCCJIT_ABI_4:: 4931* LIBGCCJIT_ABI_5:: 4932 4933Performance 4934 4935* The timing API:: 4936 4937@end menu 4938 4939 4940@node Compilation contexts,Objects,,Topic Reference 4941@anchor{topics/contexts compilation-contexts}@anchor{51}@anchor{topics/contexts doc}@anchor{52} 4942@section Compilation contexts 4943 4944 4945@geindex gcc_jit_context (C type) 4946@anchor{topics/contexts gcc_jit_context}@anchor{8} 4947@deffn {C Type} gcc_jit_context 4948@end deffn 4949 4950The top-level of the API is the @pxref{8,,gcc_jit_context} type. 4951 4952A @pxref{8,,gcc_jit_context} instance encapsulates the state of a 4953compilation. 4954 4955You can set up options on it, and add types, functions and code. 4956Invoking @pxref{15,,gcc_jit_context_compile()} on it gives you a 4957@pxref{16,,gcc_jit_result}. 4958 4959@menu 4960* Lifetime-management:: 4961* Thread-safety:: 4962* Error-handling: Error-handling<2>. 4963* Debugging:: 4964* Options: Options<2>. 4965 4966@end menu 4967 4968@node Lifetime-management,Thread-safety,,Compilation contexts 4969@anchor{topics/contexts lifetime-management}@anchor{53} 4970@subsection Lifetime-management 4971 4972 4973Contexts are the unit of lifetime-management within the API: objects 4974have their lifetime bounded by the context they are created within, and 4975cleanup of such objects is done for you when the context is released. 4976 4977@geindex gcc_jit_context_acquire (C function) 4978@anchor{topics/contexts gcc_jit_context_acquire}@anchor{9} 4979@deffn {C Function} gcc_jit_context *gcc_jit_context_acquire (void) 4980 4981This function acquires a new @pxref{8,,gcc_jit_context *} instance, 4982which is independent of any others that may be present within this 4983process. 4984@end deffn 4985 4986@geindex gcc_jit_context_release (C function) 4987@anchor{topics/contexts gcc_jit_context_release}@anchor{c} 4988@deffn {C Function} void gcc_jit_context_release (gcc_jit_context@w{ }*ctxt) 4989 4990This function releases all resources associated with the given context. 4991Both the context itself and all of its @pxref{e,,gcc_jit_object *} 4992instances are cleaned up. It should be called exactly once on a given 4993context. 4994 4995It is invalid to use the context or any of its "contextual" objects 4996after calling this. 4997 4998@example 4999gcc_jit_context_release (ctxt); 5000@end example 5001 5002@noindent 5003@end deffn 5004 5005@geindex gcc_jit_context_new_child_context (C function) 5006@anchor{topics/contexts gcc_jit_context_new_child_context}@anchor{54} 5007@deffn {C Function} gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context@w{ }*parent_ctxt) 5008 5009Given an existing JIT context, create a child context. 5010 5011The child inherits a copy of all option-settings from the parent. 5012 5013The child can reference objects created within the parent, but not 5014vice-versa. 5015 5016The lifetime of the child context must be bounded by that of the 5017parent: you should release a child context before releasing the parent 5018context. 5019 5020If you use a function from a parent context within a child context, 5021you have to compile the parent context before you can compile the 5022child context, and the gcc_jit_result of the parent context must 5023outlive the gcc_jit_result of the child context. 5024 5025This allows caching of shared initializations. For example, you could 5026create types and declarations of global functions in a parent context 5027once within a process, and then create child contexts whenever a 5028function or loop becomes hot. Each such child context can be used for 5029JIT-compiling just one function or loop, but can reference types 5030and helper functions created within the parent context. 5031 5032Contexts can be arbitrarily nested, provided the above rules are 5033followed, but it's probably not worth going above 2 or 3 levels, and 5034there will likely be a performance hit for such nesting. 5035@end deffn 5036 5037@node Thread-safety,Error-handling<2>,Lifetime-management,Compilation contexts 5038@anchor{topics/contexts thread-safety}@anchor{55} 5039@subsection Thread-safety 5040 5041 5042Instances of @pxref{8,,gcc_jit_context *} created via 5043@pxref{9,,gcc_jit_context_acquire()} are independent from each other: 5044only one thread may use a given context at once, but multiple threads 5045could each have their own contexts without needing locks. 5046 5047Contexts created via @pxref{54,,gcc_jit_context_new_child_context()} are 5048related to their parent context. They can be partitioned by their 5049ultimate ancestor into independent "family trees". Only one thread 5050within a process may use a given "family tree" of such contexts at once, 5051and if you're using multiple threads you should provide your own locking 5052around entire such context partitions. 5053 5054@node Error-handling<2>,Debugging,Thread-safety,Compilation contexts 5055@anchor{topics/contexts error-handling}@anchor{19}@anchor{topics/contexts id1}@anchor{56} 5056@subsection Error-handling 5057 5058 5059Various kinds of errors are possible when using the API, such as 5060mismatched types in an assignment. You can only compile and get code from 5061a context if no errors occur. 5062 5063Errors are printed on stderr and can be queried using 5064@pxref{57,,gcc_jit_context_get_first_error()}. 5065 5066They typically contain the name of the API entrypoint where the error 5067occurred, and pertinent information on the problem: 5068 5069@example 5070./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *) 5071@end example 5072 5073@noindent 5074 5075In general, if an error occurs when using an API entrypoint, the 5076entrypoint returns NULL. You don't have to check everywhere for NULL 5077results, since the API handles a NULL being passed in for any 5078argument by issuing another error. This typically leads to a cascade of 5079followup error messages, but is safe (albeit verbose). The first error 5080message is usually the one to pay attention to, since it is likely to 5081be responsible for all of the rest: 5082 5083@geindex gcc_jit_context_get_first_error (C function) 5084@anchor{topics/contexts gcc_jit_context_get_first_error}@anchor{57} 5085@deffn {C Function} const char * gcc_jit_context_get_first_error (gcc_jit_context@w{ }*ctxt) 5086 5087Returns the first error message that occurred on the context. 5088 5089The returned string is valid for the rest of the lifetime of the 5090context. 5091 5092If no errors occurred, this will be NULL. 5093@end deffn 5094 5095If you are wrapping the C API for a higher-level language that supports 5096exception-handling, you may instead be interested in the last error that 5097occurred on the context, so that you can embed this in an exception: 5098 5099@geindex gcc_jit_context_get_last_error (C function) 5100@anchor{topics/contexts gcc_jit_context_get_last_error}@anchor{58} 5101@deffn {C Function} const char * gcc_jit_context_get_last_error (gcc_jit_context@w{ }*ctxt) 5102 5103Returns the last error message that occurred on the context. 5104 5105If no errors occurred, this will be NULL. 5106 5107If non-NULL, the returned string is only guaranteed to be valid until 5108the next call to libgccjit relating to this context. 5109@end deffn 5110 5111@node Debugging,Options<2>,Error-handling<2>,Compilation contexts 5112@anchor{topics/contexts debugging}@anchor{59} 5113@subsection Debugging 5114 5115 5116@geindex gcc_jit_context_dump_to_file (C function) 5117@anchor{topics/contexts gcc_jit_context_dump_to_file}@anchor{5a} 5118@deffn {C Function} void gcc_jit_context_dump_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path, int@w{ }update_locations) 5119 5120To help with debugging: dump a C-like representation to the given path, 5121describing what's been set up on the context. 5122 5123If "update_locations" is true, then also set up @pxref{3b,,gcc_jit_location} 5124information throughout the context, pointing at the dump file as if it 5125were a source file. This may be of use in conjunction with 5126@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to allow stepping through the 5127code in a debugger. 5128@end deffn 5129 5130@geindex gcc_jit_context_set_logfile (C function) 5131@anchor{topics/contexts gcc_jit_context_set_logfile}@anchor{5b} 5132@deffn {C Function} void gcc_jit_context_set_logfile (gcc_jit_context@w{ }*ctxt, FILE@w{ }*logfile, int@w{ }flags, int@w{ }verbosity) 5133 5134To help with debugging; enable ongoing logging of the context's 5135activity to the given file. 5136 5137For example, the following will enable logging to stderr. 5138 5139@example 5140gcc_jit_context_set_logfile (ctxt, stderr, 0, 0); 5141@end example 5142 5143@noindent 5144 5145Examples of information logged include: 5146 5147 5148@itemize * 5149 5150@item 5151API calls 5152 5153@item 5154the various steps involved within compilation 5155 5156@item 5157activity on any @pxref{16,,gcc_jit_result} instances created by 5158the context 5159 5160@item 5161activity within any child contexts 5162@end itemize 5163 5164An example of a log can be seen @pxref{5c,,here}, 5165though the precise format and kinds of information logged is subject 5166to change. 5167 5168The caller remains responsible for closing @cite{logfile}, and it must not 5169be closed until all users are released. In particular, note that 5170child contexts and @pxref{16,,gcc_jit_result} instances created by 5171the context will use the logfile. 5172 5173There may a performance cost for logging. 5174 5175You can turn off logging on @cite{ctxt} by passing @cite{NULL} for @cite{logfile}. 5176Doing so only affects the context; it does not affect child contexts 5177or @pxref{16,,gcc_jit_result} instances already created by 5178the context. 5179 5180The parameters "flags" and "verbosity" are reserved for future 5181expansion, and must be zero for now. 5182@end deffn 5183 5184To contrast the above: @pxref{5a,,gcc_jit_context_dump_to_file()} dumps the 5185current state of a context to the given path, whereas 5186@pxref{5b,,gcc_jit_context_set_logfile()} enables on-going logging of 5187future activies on a context to the given @cite{FILE *}. 5188 5189@geindex gcc_jit_context_dump_reproducer_to_file (C function) 5190@anchor{topics/contexts gcc_jit_context_dump_reproducer_to_file}@anchor{5d} 5191@deffn {C Function} void gcc_jit_context_dump_reproducer_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path) 5192 5193Write C source code into @cite{path} that can be compiled into a 5194self-contained executable (i.e. with libgccjit as the only dependency). 5195The generated code will attempt to replay the API calls that have been 5196made into the given context. 5197 5198This may be useful when debugging the library or client code, for 5199reducing a complicated recipe for reproducing a bug into a simpler 5200form. For example, consider client code that parses some source file 5201into some internal representation, and then walks this IR, calling into 5202libgccjit. If this encounters a bug, a call to 5203@cite{gcc_jit_context_dump_reproducer_to_file} will write out C code for 5204a much simpler executable that performs the equivalent calls into 5205libgccjit, without needing the client code and its data. 5206 5207Typically you need to supply @code{-Wno-unused-variable} when 5208compiling the generated file (since the result of each API call is 5209assigned to a unique variable within the generated C source, and not 5210all are necessarily then used). 5211@end deffn 5212 5213@geindex gcc_jit_context_enable_dump (C function) 5214@anchor{topics/contexts gcc_jit_context_enable_dump}@anchor{5e} 5215@deffn {C Function} void gcc_jit_context_enable_dump (gcc_jit_context@w{ }*ctxt, const char@w{ }*dumpname, char@w{ }**out_ptr) 5216 5217Enable the dumping of a specific set of internal state from the 5218compilation, capturing the result in-memory as a buffer. 5219 5220Parameter "dumpname" corresponds to the equivalent gcc command-line 5221option, without the "-fdump-" prefix. 5222For example, to get the equivalent of @code{-fdump-tree-vrp1}, 5223supply @code{"tree-vrp1"}: 5224 5225@example 5226static char *dump_vrp1; 5227 5228void 5229create_code (gcc_jit_context *ctxt) 5230@{ 5231 gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1); 5232 /* (other API calls omitted for brevity) */ 5233@} 5234@end example 5235 5236@noindent 5237 5238The context directly stores the dumpname as a @code{(const char *)}, so 5239the passed string must outlive the context. 5240 5241@pxref{15,,gcc_jit_context_compile()} will capture the dump as a 5242dynamically-allocated buffer, writing it to @code{*out_ptr}. 5243 5244The caller becomes responsible for calling: 5245 5246@example 5247free (*out_ptr) 5248@end example 5249 5250@noindent 5251 5252each time that @pxref{15,,gcc_jit_context_compile()} is called. 5253@code{*out_ptr} will be written to, either with the address of a buffer, 5254or with @code{NULL} if an error occurred. 5255 5256@cartouche 5257@quotation Warning 5258This API entrypoint is likely to be less stable than the others. 5259In particular, both the precise dumpnames, and the format and content 5260of the dumps are subject to change. 5261 5262It exists primarily for writing the library's own test suite. 5263@end quotation 5264@end cartouche 5265@end deffn 5266 5267@node Options<2>,,Debugging,Compilation contexts 5268@anchor{topics/contexts options}@anchor{5f} 5269@subsection Options 5270 5271 5272Options present in the initial release of libgccjit were handled using 5273enums, whereas those added subsequently have their own per-option API 5274entrypoints. 5275 5276Adding entrypoints for each new option means that client code that use 5277the new options can be identified directly from binary metadata, which 5278would not be possible if we instead extended the various 5279@code{enum gcc_jit_*_option}. 5280 5281@menu 5282* String Options:: 5283* Boolean options:: 5284* Integer options:: 5285* Additional command-line options:: 5286 5287@end menu 5288 5289@node String Options,Boolean options,,Options<2> 5290@anchor{topics/contexts string-options}@anchor{60} 5291@subsubsection String Options 5292 5293 5294@geindex gcc_jit_context_set_str_option (C function) 5295@anchor{topics/contexts gcc_jit_context_set_str_option}@anchor{61} 5296@deffn {C Function} void gcc_jit_context_set_str_option (gcc_jit_context@w{ }*ctxt, enum gcc_jit_str_option@w{ }opt, const char@w{ }*value) 5297 5298Set a string option of the context. 5299 5300@geindex gcc_jit_str_option (C type) 5301@anchor{topics/contexts gcc_jit_str_option}@anchor{62} 5302@deffn {C Type} enum gcc_jit_str_option 5303@end deffn 5304 5305The parameter @code{value} can be NULL. If non-NULL, the call takes a 5306copy of the underlying string, so it is valid to pass in a pointer to 5307an on-stack buffer. 5308 5309There is just one string option specified this way: 5310 5311@geindex GCC_JIT_STR_OPTION_PROGNAME (C macro) 5312@anchor{topics/contexts GCC_JIT_STR_OPTION_PROGNAME}@anchor{63} 5313@deffn {C Macro} GCC_JIT_STR_OPTION_PROGNAME 5314 5315The name of the program, for use as a prefix when printing error 5316messages to stderr. If @cite{NULL}, or default, "libgccjit.so" is used. 5317@end deffn 5318@end deffn 5319 5320@node Boolean options,Integer options,String Options,Options<2> 5321@anchor{topics/contexts boolean-options}@anchor{64} 5322@subsubsection Boolean options 5323 5324 5325@geindex gcc_jit_context_set_bool_option (C function) 5326@anchor{topics/contexts gcc_jit_context_set_bool_option}@anchor{1b} 5327@deffn {C Function} void gcc_jit_context_set_bool_option (gcc_jit_context@w{ }*ctxt, enum gcc_jit_bool_option@w{ }opt, int@w{ }value) 5328 5329Set a boolean option of the context. 5330Zero is "false" (the default), non-zero is "true". 5331 5332@geindex gcc_jit_bool_option (C type) 5333@anchor{topics/contexts gcc_jit_bool_option}@anchor{65} 5334@deffn {C Type} enum gcc_jit_bool_option 5335@end deffn 5336 5337@geindex GCC_JIT_BOOL_OPTION_DEBUGINFO (C macro) 5338@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DEBUGINFO}@anchor{42} 5339@deffn {C Macro} GCC_JIT_BOOL_OPTION_DEBUGINFO 5340 5341If true, @pxref{15,,gcc_jit_context_compile()} will attempt to do the right 5342thing so that if you attach a debugger to the process, it will 5343be able to inspect variables and step through your code. 5344 5345Note that you can't step through code unless you set up source 5346location information for the code (by creating and passing in 5347@pxref{3b,,gcc_jit_location} instances). 5348@end deffn 5349 5350@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE (C macro) 5351@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}@anchor{66} 5352@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE 5353 5354If true, @pxref{15,,gcc_jit_context_compile()} will dump its initial 5355"tree" representation of your code to stderr (before any 5356optimizations). 5357 5358Here's some sample output (from the @cite{square} example): 5359 5360@example 5361<statement_list 0x7f4875a62cc0 5362 type <void_type 0x7f4875a64bd0 VOID 5363 align 8 symtab 0 alias set -1 canonical type 0x7f4875a64bd0 5364 pointer_to_this <pointer_type 0x7f4875a64c78>> 5365 side-effects head 0x7f4875a761e0 tail 0x7f4875a761f8 stmts 0x7f4875a62d20 0x7f4875a62d00 5366 5367 stmt <label_expr 0x7f4875a62d20 type <void_type 0x7f4875a64bd0> 5368 side-effects 5369 arg 0 <label_decl 0x7f4875a79080 entry type <void_type 0x7f4875a64bd0> 5370 VOID file (null) line 0 col 0 5371 align 1 context <function_decl 0x7f4875a77500 square>>> 5372 stmt <return_expr 0x7f4875a62d00 5373 type <integer_type 0x7f4875a645e8 public SI 5374 size <integer_cst 0x7f4875a623a0 constant 32> 5375 unit size <integer_cst 0x7f4875a623c0 constant 4> 5376 align 32 symtab 0 alias set -1 canonical type 0x7f4875a645e8 precision 32 min <integer_cst 0x7f4875a62340 -2147483648> max <integer_cst 0x7f4875a62360 2147483647> 5377 pointer_to_this <pointer_type 0x7f4875a6b348>> 5378 side-effects 5379 arg 0 <modify_expr 0x7f4875a72a78 type <integer_type 0x7f4875a645e8> 5380 side-effects arg 0 <result_decl 0x7f4875a7a000 D.54> 5381 arg 1 <mult_expr 0x7f4875a72a50 type <integer_type 0x7f4875a645e8> 5382 arg 0 <parm_decl 0x7f4875a79000 i> arg 1 <parm_decl 0x7f4875a79000 i>>>>> 5383@end example 5384 5385@noindent 5386@end deffn 5387 5388@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE (C macro) 5389@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}@anchor{1c} 5390@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE 5391 5392If true, @pxref{15,,gcc_jit_context_compile()} will dump the "gimple" 5393representation of your code to stderr, before any optimizations 5394are performed. The dump resembles C code: 5395 5396@example 5397square (signed int i) 5398@{ 5399 signed int D.56; 5400 5401 entry: 5402 D.56 = i * i; 5403 return D.56; 5404@} 5405@end example 5406 5407@noindent 5408@end deffn 5409 5410@geindex GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE (C macro) 5411@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE}@anchor{1d} 5412@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE 5413 5414If true, @pxref{15,,gcc_jit_context_compile()} will dump the final 5415generated code to stderr, in the form of assembly language: 5416 5417@example 5418 .file "fake.c" 5419 .text 5420 .globl square 5421 .type square, @@function 5422square: 5423.LFB0: 5424 .cfi_startproc 5425 pushq %rbp 5426 .cfi_def_cfa_offset 16 5427 .cfi_offset 6, -16 5428 movq %rsp, %rbp 5429 .cfi_def_cfa_register 6 5430 movl %edi, -4(%rbp) 5431.L2: 5432 movl -4(%rbp), %eax 5433 imull -4(%rbp), %eax 5434 popq %rbp 5435 .cfi_def_cfa 7, 8 5436 ret 5437 .cfi_endproc 5438.LFE0: 5439 .size square, .-square 5440 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.1-%@{gcc_release@})" 5441 .section .note.GNU-stack,"",@@progbits 5442@end example 5443 5444@noindent 5445@end deffn 5446 5447@geindex GCC_JIT_BOOL_OPTION_DUMP_SUMMARY (C macro) 5448@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_SUMMARY}@anchor{67} 5449@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_SUMMARY 5450 5451If true, @pxref{15,,gcc_jit_context_compile()} will print information to stderr 5452on the actions it is performing. 5453@end deffn 5454 5455@geindex GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING (C macro) 5456@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING}@anchor{68} 5457@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING 5458 5459If true, @pxref{15,,gcc_jit_context_compile()} will dump copious 5460amount of information on what it's doing to various 5461files within a temporary directory. Use 5462@pxref{69,,GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES} (see below) to 5463see the results. The files are intended to be human-readable, 5464but the exact files and their formats are subject to change. 5465@end deffn 5466 5467@geindex GCC_JIT_BOOL_OPTION_SELFCHECK_GC (C macro) 5468@anchor{topics/contexts GCC_JIT_BOOL_OPTION_SELFCHECK_GC}@anchor{6a} 5469@deffn {C Macro} GCC_JIT_BOOL_OPTION_SELFCHECK_GC 5470 5471If true, libgccjit will aggressively run its garbage collector, to 5472shake out bugs (greatly slowing down the compile). This is likely 5473to only be of interest to developers @emph{of} the library. It is 5474used when running the selftest suite. 5475@end deffn 5476 5477@geindex GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES (C macro) 5478@anchor{topics/contexts GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES}@anchor{69} 5479@deffn {C Macro} GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES 5480 5481If true, the @pxref{8,,gcc_jit_context} will not clean up intermediate files 5482written to the filesystem, and will display their location on stderr. 5483@end deffn 5484@end deffn 5485 5486@geindex gcc_jit_context_set_bool_allow_unreachable_blocks (C function) 5487@anchor{topics/contexts gcc_jit_context_set_bool_allow_unreachable_blocks}@anchor{6b} 5488@deffn {C Function} void gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value) 5489 5490By default, libgccjit will issue an error about unreachable blocks 5491within a function. 5492 5493This entrypoint can be used to disable that error. 5494 5495This entrypoint was added in @pxref{6c,,LIBGCCJIT_ABI_2}; you can test for 5496its presence using 5497 5498@example 5499#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 5500@end example 5501 5502@noindent 5503@end deffn 5504 5505@geindex gcc_jit_context_set_bool_use_external_driver (C function) 5506@anchor{topics/contexts gcc_jit_context_set_bool_use_external_driver}@anchor{6d} 5507@deffn {C Function} void gcc_jit_context_set_bool_use_external_driver (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value) 5508 5509libgccjit internally generates assembler, and uses "driver" code 5510for converting it to other formats (e.g. shared libraries). 5511 5512By default, libgccjit will use an embedded copy of the driver 5513code. 5514 5515This option can be used to instead invoke an external driver executable 5516as a subprocess. 5517 5518This entrypoint was added in @pxref{6e,,LIBGCCJIT_ABI_5}; you can test for 5519its presence using 5520 5521@example 5522#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver 5523@end example 5524 5525@noindent 5526@end deffn 5527 5528@node Integer options,Additional command-line options,Boolean options,Options<2> 5529@anchor{topics/contexts integer-options}@anchor{6f} 5530@subsubsection Integer options 5531 5532 5533@geindex gcc_jit_context_set_int_option (C function) 5534@anchor{topics/contexts gcc_jit_context_set_int_option}@anchor{1e} 5535@deffn {C Function} void gcc_jit_context_set_int_option (gcc_jit_context@w{ }*ctxt, enum gcc_jit_int_option@w{ }opt, int@w{ }value) 5536 5537Set an integer option of the context. 5538 5539@geindex gcc_jit_int_option (C type) 5540@anchor{topics/contexts gcc_jit_int_option}@anchor{70} 5541@deffn {C Type} enum gcc_jit_int_option 5542@end deffn 5543 5544There is just one integer option specified this way: 5545 5546@geindex GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL (C macro) 5547@anchor{topics/contexts GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}@anchor{1f} 5548@deffn {C Macro} GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL 5549 5550How much to optimize the code. 5551 5552Valid values are 0-3, corresponding to GCC's command-line options 5553-O0 through -O3. 5554 5555The default value is 0 (unoptimized). 5556@end deffn 5557@end deffn 5558 5559@node Additional command-line options,,Integer options,Options<2> 5560@anchor{topics/contexts additional-command-line-options}@anchor{71} 5561@subsubsection Additional command-line options 5562 5563 5564@geindex gcc_jit_context_add_command_line_option (C function) 5565@anchor{topics/contexts gcc_jit_context_add_command_line_option}@anchor{72} 5566@deffn {C Function} void gcc_jit_context_add_command_line_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname) 5567 5568Add an arbitrary gcc command-line option to the context, for use 5569by @pxref{15,,gcc_jit_context_compile()} and 5570@pxref{4a,,gcc_jit_context_compile_to_file()}. 5571 5572The parameter @code{optname} must be non-NULL. The underlying buffer is 5573copied, so that it does not need to outlive the call. 5574 5575Extra options added by @cite{gcc_jit_context_add_command_line_option} are 5576applied @emph{after} the regular options above, potentially overriding them. 5577Options from parent contexts are inherited by child contexts; options 5578from the parent are applied @emph{before} those from the child. 5579 5580For example: 5581 5582@example 5583gcc_jit_context_add_command_line_option (ctxt, "-ffast-math"); 5584gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm"); 5585@end example 5586 5587@noindent 5588 5589Note that only some options are likely to be meaningful; there is no 5590"frontend" within libgccjit, so typically only those affecting 5591optimization and code-generation are likely to be useful. 5592 5593This entrypoint was added in @pxref{73,,LIBGCCJIT_ABI_1}; you can test for 5594its presence using 5595 5596@example 5597#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 5598@end example 5599 5600@noindent 5601@end deffn 5602 5603@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 5604@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 5605@c 5606@c This is free software: you can redistribute it and/or modify it 5607@c under the terms of the GNU General Public License as published by 5608@c the Free Software Foundation, either version 3 of the License, or 5609@c (at your option) any later version. 5610@c 5611@c This program is distributed in the hope that it will be useful, but 5612@c WITHOUT ANY WARRANTY; without even the implied warranty of 5613@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5614@c General Public License for more details. 5615@c 5616@c You should have received a copy of the GNU General Public License 5617@c along with this program. If not, see 5618@c <http://www.gnu.org/licenses/>. 5619 5620@node Objects,Types,Compilation contexts,Topic Reference 5621@anchor{topics/objects objects}@anchor{74}@anchor{topics/objects doc}@anchor{75} 5622@section Objects 5623 5624 5625@geindex gcc_jit_object (C type) 5626@anchor{topics/objects gcc_jit_object}@anchor{e} 5627@deffn {C Type} gcc_jit_object 5628@end deffn 5629 5630Almost every entity in the API (with the exception of 5631@pxref{8,,gcc_jit_context *} and @pxref{16,,gcc_jit_result *}) is a 5632"contextual" object, a @pxref{e,,gcc_jit_object *} 5633 5634A JIT object: 5635 5636@quotation 5637 5638 5639@itemize * 5640 5641@item 5642is associated with a @pxref{8,,gcc_jit_context *}. 5643 5644@item 5645is automatically cleaned up for you when its context is released so 5646you don't need to manually track and cleanup all objects, just the 5647contexts. 5648@end itemize 5649@end quotation 5650 5651Although the API is C-based, there is a form of class hierarchy, which 5652looks like this: 5653 5654@example 5655+- gcc_jit_object 5656 +- gcc_jit_location 5657 +- gcc_jit_type 5658 +- gcc_jit_struct 5659 +- gcc_jit_field 5660 +- gcc_jit_function 5661 +- gcc_jit_block 5662 +- gcc_jit_rvalue 5663 +- gcc_jit_lvalue 5664 +- gcc_jit_param 5665 +- gcc_jit_case 5666@end example 5667 5668@noindent 5669 5670There are casting methods for upcasting from subclasses to parent classes. 5671For example, @pxref{d,,gcc_jit_type_as_object()}: 5672 5673@example 5674gcc_jit_object *obj = gcc_jit_type_as_object (int_type); 5675@end example 5676 5677@noindent 5678 5679The object "base class" has the following operations: 5680 5681@geindex gcc_jit_object_get_context (C function) 5682@anchor{topics/objects gcc_jit_object_get_context}@anchor{76} 5683@deffn {C Function} gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object@w{ }*obj) 5684 5685Which context is "obj" within? 5686@end deffn 5687 5688@geindex gcc_jit_object_get_debug_string (C function) 5689@anchor{topics/objects gcc_jit_object_get_debug_string}@anchor{f} 5690@deffn {C Function} const char *gcc_jit_object_get_debug_string (gcc_jit_object@w{ }*obj) 5691 5692Generate a human-readable description for the given object. 5693 5694For example, 5695 5696@example 5697printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); 5698@end example 5699 5700@noindent 5701 5702might give this text on stdout: 5703 5704@example 5705obj: 4.0 * (float)i 5706@end example 5707 5708@noindent 5709 5710@cartouche 5711@quotation Note 5712If you call this on an object, the @cite{const char *} buffer is allocated 5713and generated on the first call for that object, and the buffer will 5714have the same lifetime as the object i.e. it will exist until the 5715object's context is released. 5716@end quotation 5717@end cartouche 5718@end deffn 5719 5720@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 5721@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 5722@c 5723@c This is free software: you can redistribute it and/or modify it 5724@c under the terms of the GNU General Public License as published by 5725@c the Free Software Foundation, either version 3 of the License, or 5726@c (at your option) any later version. 5727@c 5728@c This program is distributed in the hope that it will be useful, but 5729@c WITHOUT ANY WARRANTY; without even the implied warranty of 5730@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5731@c General Public License for more details. 5732@c 5733@c You should have received a copy of the GNU General Public License 5734@c along with this program. If not, see 5735@c <http://www.gnu.org/licenses/>. 5736 5737@node Types,Expressions,Objects,Topic Reference 5738@anchor{topics/types doc}@anchor{77}@anchor{topics/types types}@anchor{78} 5739@section Types 5740 5741 5742@geindex gcc_jit_type (C type) 5743@anchor{topics/types gcc_jit_type}@anchor{a} 5744@deffn {C Type} gcc_jit_type 5745 5746gcc_jit_type represents a type within the library. 5747@end deffn 5748 5749@geindex gcc_jit_type_as_object (C function) 5750@anchor{topics/types gcc_jit_type_as_object}@anchor{d} 5751@deffn {C Function} gcc_jit_object *gcc_jit_type_as_object (gcc_jit_type@w{ }*type) 5752 5753Upcast a type to an object. 5754@end deffn 5755 5756Types can be created in several ways: 5757 5758 5759@itemize * 5760 5761@item 5762fundamental types can be accessed using 5763@pxref{b,,gcc_jit_context_get_type()}: 5764 5765@example 5766gcc_jit_type *int_type = gcc_jit_context_get_type (GCC_JIT_TYPE_INT); 5767@end example 5768 5769@noindent 5770 5771See @pxref{b,,gcc_jit_context_get_type()} for the available types. 5772 5773@item 5774derived types can be accessed by using functions such as 5775@pxref{79,,gcc_jit_type_get_pointer()} and @pxref{7a,,gcc_jit_type_get_const()}: 5776 5777@example 5778gcc_jit_type *const_int_star = gcc_jit_type_get_pointer (gcc_jit_type_get_const (int_type)); 5779gcc_jit_type *int_const_star = gcc_jit_type_get_const (gcc_jit_type_get_pointer (int_type)); 5780@end example 5781 5782@noindent 5783 5784@item 5785by creating structures (see below). 5786@end itemize 5787 5788@menu 5789* Standard types:: 5790* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 5791* Structures and unions:: 5792 5793@end menu 5794 5795@node Standard types,Pointers const and volatile,,Types 5796@anchor{topics/types standard-types}@anchor{7b} 5797@subsection Standard types 5798 5799 5800@geindex gcc_jit_context_get_type (C function) 5801@anchor{topics/types gcc_jit_context_get_type}@anchor{b} 5802@deffn {C Function} gcc_jit_type *gcc_jit_context_get_type (gcc_jit_context@w{ }*ctxt, enum gcc_jit_types@w{ }type_) 5803 5804Access a specific type. The available types are: 5805 5806 5807@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 5808@headitem 5809 5810@cite{enum gcc_jit_types} value 5811 5812@tab 5813 5814Meaning 5815 5816@item 5817 5818@code{GCC_JIT_TYPE_VOID} 5819 5820@tab 5821 5822C's @code{void} type. 5823 5824@item 5825 5826@code{GCC_JIT_TYPE_VOID_PTR} 5827 5828@tab 5829 5830C's @code{void *}. 5831 5832@item 5833 5834@code{GCC_JIT_TYPE_BOOL} 5835 5836@tab 5837 5838C++'s @code{bool} type; also C99's 5839@code{_Bool} type, aka @code{bool} if 5840using stdbool.h. 5841 5842@item 5843 5844@code{GCC_JIT_TYPE_CHAR} 5845 5846@tab 5847 5848C's @code{char} (of some signedness) 5849 5850@item 5851 5852@code{GCC_JIT_TYPE_SIGNED_CHAR} 5853 5854@tab 5855 5856C's @code{signed char} 5857 5858@item 5859 5860@code{GCC_JIT_TYPE_UNSIGNED_CHAR} 5861 5862@tab 5863 5864C's @code{unsigned char} 5865 5866@item 5867 5868@code{GCC_JIT_TYPE_SHORT} 5869 5870@tab 5871 5872C's @code{short} (signed) 5873 5874@item 5875 5876@code{GCC_JIT_TYPE_UNSIGNED_SHORT} 5877 5878@tab 5879 5880C's @code{unsigned short} 5881 5882@item 5883 5884@code{GCC_JIT_TYPE_INT} 5885 5886@tab 5887 5888C's @code{int} (signed) 5889 5890@item 5891 5892@code{GCC_JIT_TYPE_UNSIGNED_INT} 5893 5894@tab 5895 5896C's @code{unsigned int} 5897 5898@item 5899 5900@code{GCC_JIT_TYPE_LONG} 5901 5902@tab 5903 5904C's @code{long} (signed) 5905 5906@item 5907 5908@code{GCC_JIT_TYPE_UNSIGNED_LONG} 5909 5910@tab 5911 5912C's @code{unsigned long} 5913 5914@item 5915 5916@code{GCC_JIT_TYPE_LONG_LONG} 5917 5918@tab 5919 5920C99's @code{long long} (signed) 5921 5922@item 5923 5924@code{GCC_JIT_TYPE_UNSIGNED_LONG_LONG} 5925 5926@tab 5927 5928C99's @code{unsigned long long} 5929 5930@item 5931 5932@code{GCC_JIT_TYPE_FLOAT} 5933 5934@tab 5935 5936@item 5937 5938@code{GCC_JIT_TYPE_DOUBLE} 5939 5940@tab 5941 5942@item 5943 5944@code{GCC_JIT_TYPE_LONG_DOUBLE} 5945 5946@tab 5947 5948@item 5949 5950@code{GCC_JIT_TYPE_CONST_CHAR_PTR} 5951 5952@tab 5953 5954C type: @code{(const char *)} 5955 5956@item 5957 5958@code{GCC_JIT_TYPE_SIZE_T} 5959 5960@tab 5961 5962C's @code{size_t} type 5963 5964@item 5965 5966@code{GCC_JIT_TYPE_FILE_PTR} 5967 5968@tab 5969 5970C type: @code{(FILE *)} 5971 5972@item 5973 5974@code{GCC_JIT_TYPE_COMPLEX_FLOAT} 5975 5976@tab 5977 5978C99's @code{_Complex float} 5979 5980@item 5981 5982@code{GCC_JIT_TYPE_COMPLEX_DOUBLE} 5983 5984@tab 5985 5986C99's @code{_Complex double} 5987 5988@item 5989 5990@code{GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE} 5991 5992@tab 5993 5994C99's @code{_Complex long double} 5995 5996@end multitable 5997 5998@end deffn 5999 6000@geindex gcc_jit_context_get_int_type (C function) 6001@anchor{topics/types gcc_jit_context_get_int_type}@anchor{7c} 6002@deffn {C Function} gcc_jit_type * gcc_jit_context_get_int_type (gcc_jit_context@w{ }*ctxt, int@w{ }num_bytes, int@w{ }is_signed) 6003 6004Access the integer type of the given size. 6005@end deffn 6006 6007@node Pointers const and volatile,Structures and unions,Standard types,Types 6008@anchor{topics/types pointers-const-and-volatile}@anchor{7d} 6009@subsection Pointers, @cite{const}, and @cite{volatile} 6010 6011 6012@geindex gcc_jit_type_get_pointer (C function) 6013@anchor{topics/types gcc_jit_type_get_pointer}@anchor{79} 6014@deffn {C Function} gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type@w{ }*type) 6015 6016Given type "T", get type "T*". 6017@end deffn 6018 6019@geindex gcc_jit_type_get_const (C function) 6020@anchor{topics/types gcc_jit_type_get_const}@anchor{7a} 6021@deffn {C Function} gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type@w{ }*type) 6022 6023Given type "T", get type "const T". 6024@end deffn 6025 6026@geindex gcc_jit_type_get_volatile (C function) 6027@anchor{topics/types gcc_jit_type_get_volatile}@anchor{7e} 6028@deffn {C Function} gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type@w{ }*type) 6029 6030Given type "T", get type "volatile T". 6031@end deffn 6032 6033@geindex gcc_jit_context_new_array_type (C function) 6034@anchor{topics/types gcc_jit_context_new_array_type}@anchor{7f} 6035@deffn {C Function} gcc_jit_type * gcc_jit_context_new_array_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*element_type, int@w{ }num_elements) 6036 6037Given type "T", get type "T[N]" (for a constant N). 6038@end deffn 6039 6040@node Structures and unions,,Pointers const and volatile,Types 6041@anchor{topics/types structures-and-unions}@anchor{80} 6042@subsection Structures and unions 6043 6044 6045@geindex gcc_jit_struct (C type) 6046@anchor{topics/types gcc_jit_struct}@anchor{81} 6047@deffn {C Type} gcc_jit_struct 6048@end deffn 6049 6050A compound type analagous to a C @cite{struct}. 6051 6052@geindex gcc_jit_field (C type) 6053@anchor{topics/types gcc_jit_field}@anchor{82} 6054@deffn {C Type} gcc_jit_field 6055@end deffn 6056 6057A field within a @pxref{81,,gcc_jit_struct}. 6058 6059You can model C @cite{struct} types by creating @pxref{81,,gcc_jit_struct *} and 6060@pxref{82,,gcc_jit_field} instances, in either order: 6061 6062 6063@itemize * 6064 6065@item 6066by creating the fields, then the structure. For example, to model: 6067 6068@example 6069struct coord @{double x; double y; @}; 6070@end example 6071 6072@noindent 6073 6074you could call: 6075 6076@example 6077gcc_jit_field *field_x = 6078 gcc_jit_context_new_field (ctxt, NULL, double_type, "x"); 6079gcc_jit_field *field_y = 6080 gcc_jit_context_new_field (ctxt, NULL, double_type, "y"); 6081gcc_jit_field *fields[2] = @{field_x, field_y@}; 6082gcc_jit_struct *coord = 6083 gcc_jit_context_new_struct_type (ctxt, NULL, "coord", 2, fields); 6084@end example 6085 6086@noindent 6087 6088@item 6089by creating the structure, then populating it with fields, typically 6090to allow modelling self-referential structs such as: 6091 6092@example 6093struct node @{ int m_hash; struct node *m_next; @}; 6094@end example 6095 6096@noindent 6097 6098like this: 6099 6100@example 6101gcc_jit_type *node = 6102 gcc_jit_context_new_opaque_struct (ctxt, NULL, "node"); 6103gcc_jit_type *node_ptr = 6104 gcc_jit_type_get_pointer (node); 6105gcc_jit_field *field_hash = 6106 gcc_jit_context_new_field (ctxt, NULL, int_type, "m_hash"); 6107gcc_jit_field *field_next = 6108 gcc_jit_context_new_field (ctxt, NULL, node_ptr, "m_next"); 6109gcc_jit_field *fields[2] = @{field_hash, field_next@}; 6110gcc_jit_struct_set_fields (node, NULL, 2, fields); 6111@end example 6112 6113@noindent 6114@end itemize 6115 6116@geindex gcc_jit_context_new_field (C function) 6117@anchor{topics/types gcc_jit_context_new_field}@anchor{83} 6118@deffn {C Function} gcc_jit_field * gcc_jit_context_new_field (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, const char@w{ }*name) 6119 6120Construct a new field, with the given type and name. 6121 6122The parameter @code{name} must be non-NULL. The call takes a copy of the 6123underlying string, so it is valid to pass in a pointer to an on-stack 6124buffer. 6125@end deffn 6126 6127@geindex gcc_jit_field_as_object (C function) 6128@anchor{topics/types gcc_jit_field_as_object}@anchor{84} 6129@deffn {C Function} gcc_jit_object * gcc_jit_field_as_object (gcc_jit_field@w{ }*field) 6130 6131Upcast from field to object. 6132@end deffn 6133 6134@geindex gcc_jit_context_new_struct_type (C function) 6135@anchor{topics/types gcc_jit_context_new_struct_type}@anchor{85} 6136@deffn {C Function} gcc_jit_struct *gcc_jit_context_new_struct_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name, int@w{ }num_fields, gcc_jit_field@w{ }**fields) 6137 6138@quotation 6139 6140Construct a new struct type, with the given name and fields. 6141 6142The parameter @code{name} must be non-NULL. The call takes a copy of 6143the underlying string, so it is valid to pass in a pointer to an 6144on-stack buffer. 6145@end quotation 6146@end deffn 6147 6148@geindex gcc_jit_context_new_opaque_struct (C function) 6149@anchor{topics/types gcc_jit_context_new_opaque_struct}@anchor{86} 6150@deffn {C Function} gcc_jit_struct * gcc_jit_context_new_opaque_struct (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name) 6151 6152Construct a new struct type, with the given name, but without 6153specifying the fields. The fields can be omitted (in which case the 6154size of the struct is not known), or later specified using 6155@pxref{87,,gcc_jit_struct_set_fields()}. 6156 6157The parameter @code{name} must be non-NULL. The call takes a copy of 6158the underlying string, so it is valid to pass in a pointer to an 6159on-stack buffer. 6160@end deffn 6161 6162@geindex gcc_jit_struct_as_type (C function) 6163@anchor{topics/types gcc_jit_struct_as_type}@anchor{88} 6164@deffn {C Function} gcc_jit_type * gcc_jit_struct_as_type (gcc_jit_struct@w{ }*struct_type) 6165 6166Upcast from struct to type. 6167@end deffn 6168 6169@geindex gcc_jit_struct_set_fields (C function) 6170@anchor{topics/types gcc_jit_struct_set_fields}@anchor{87} 6171@deffn {C Function} void gcc_jit_struct_set_fields (gcc_jit_struct@w{ }*struct_type, gcc_jit_location@w{ }*loc, int@w{ }num_fields, gcc_jit_field@w{ }**fields) 6172 6173Populate the fields of a formerly-opaque struct type. 6174 6175This can only be called once on a given struct type. 6176@end deffn 6177 6178@geindex gcc_jit_context_new_union_type (C function) 6179@anchor{topics/types gcc_jit_context_new_union_type}@anchor{89} 6180@deffn {C Function} gcc_jit_type * gcc_jit_context_new_union_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name, int@w{ }num_fields, gcc_jit_field@w{ }**fields) 6181 6182Construct a new union type, with the given name and fields. 6183 6184The parameter @code{name} must be non-NULL. It is copied, so the input 6185buffer does not need to outlive the call. 6186 6187Example of use: 6188 6189@example 6190 6191union int_or_float 6192@{ 6193 int as_int; 6194 float as_float; 6195@}; 6196 6197void 6198create_code (gcc_jit_context *ctxt, void *user_data) 6199@{ 6200 /* Let's try to inject the equivalent of: 6201 float 6202 test_union (int i) 6203 @{ 6204 union int_or_float u; 6205 u.as_int = i; 6206 return u.as_float; 6207 @} 6208 */ 6209 gcc_jit_type *int_type = 6210 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 6211 gcc_jit_type *float_type = 6212 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); 6213 gcc_jit_field *as_int = 6214 gcc_jit_context_new_field (ctxt, 6215 NULL, 6216 int_type, 6217 "as_int"); 6218 gcc_jit_field *as_float = 6219 gcc_jit_context_new_field (ctxt, 6220 NULL, 6221 float_type, 6222 "as_float"); 6223 gcc_jit_field *fields[] = @{as_int, as_float@}; 6224 gcc_jit_type *union_type = 6225 gcc_jit_context_new_union_type (ctxt, NULL, 6226 "int_or_float", 2, fields); 6227 6228 /* Build the test function. */ 6229 gcc_jit_param *param_i = 6230 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 6231 gcc_jit_function *test_fn = 6232 gcc_jit_context_new_function (ctxt, NULL, 6233 GCC_JIT_FUNCTION_EXPORTED, 6234 float_type, 6235 "test_union", 6236 1, ¶m_i, 6237 0); 6238 6239 gcc_jit_lvalue *u = 6240 gcc_jit_function_new_local (test_fn, NULL, 6241 union_type, "u"); 6242 6243 gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); 6244 6245 /* u.as_int = i; */ 6246 gcc_jit_block_add_assignment ( 6247 block, 6248 NULL, 6249 /* "u.as_int = ..." */ 6250 gcc_jit_lvalue_access_field (u, 6251 NULL, 6252 as_int), 6253 gcc_jit_param_as_rvalue (param_i)); 6254 6255 /* return u.as_float; */ 6256 gcc_jit_block_end_with_return ( 6257 block, NULL, 6258 gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (u), 6259 NULL, 6260 as_float)); 6261@} 6262 6263 6264@end example 6265 6266@noindent 6267@end deffn 6268 6269@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 6270@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 6271@c 6272@c This is free software: you can redistribute it and/or modify it 6273@c under the terms of the GNU General Public License as published by 6274@c the Free Software Foundation, either version 3 of the License, or 6275@c (at your option) any later version. 6276@c 6277@c This program is distributed in the hope that it will be useful, but 6278@c WITHOUT ANY WARRANTY; without even the implied warranty of 6279@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 6280@c General Public License for more details. 6281@c 6282@c You should have received a copy of the GNU General Public License 6283@c along with this program. If not, see 6284@c <http://www.gnu.org/licenses/>. 6285 6286@node Expressions,Creating and using functions,Types,Topic Reference 6287@anchor{topics/expressions expressions}@anchor{8a}@anchor{topics/expressions doc}@anchor{8b} 6288@section Expressions 6289 6290 6291@menu 6292* Rvalues:: 6293* Lvalues:: 6294* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 6295 6296Rvalues 6297 6298* Simple expressions:: 6299* Unary Operations:: 6300* Binary Operations:: 6301* Comparisons:: 6302* Function calls:: 6303* Type-coercion:: 6304 6305Lvalues 6306 6307* Global variables:: 6308 6309@end menu 6310 6311 6312@node Rvalues,Lvalues,,Expressions 6313@anchor{topics/expressions rvalues}@anchor{8c} 6314@subsection Rvalues 6315 6316 6317@geindex gcc_jit_rvalue (C type) 6318@anchor{topics/expressions gcc_jit_rvalue}@anchor{13} 6319@deffn {C Type} gcc_jit_rvalue 6320@end deffn 6321 6322A @pxref{13,,gcc_jit_rvalue *} is an expression that can be computed. 6323 6324It can be simple, e.g.: 6325 6326@quotation 6327 6328 6329@itemize * 6330 6331@item 6332an integer value e.g. @cite{0} or @cite{42} 6333 6334@item 6335a string literal e.g. @cite{"Hello world"} 6336 6337@item 6338a variable e.g. @cite{i}. These are also lvalues (see below). 6339@end itemize 6340@end quotation 6341 6342or compound e.g.: 6343 6344@quotation 6345 6346 6347@itemize * 6348 6349@item 6350a unary expression e.g. @cite{!cond} 6351 6352@item 6353a binary expression e.g. @cite{(a + b)} 6354 6355@item 6356a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} 6357 6358@item 6359etc. 6360@end itemize 6361@end quotation 6362 6363Every rvalue has an associated type, and the API will check to ensure 6364that types match up correctly (otherwise the context will emit an error). 6365 6366@geindex gcc_jit_rvalue_get_type (C function) 6367@anchor{topics/expressions gcc_jit_rvalue_get_type}@anchor{8d} 6368@deffn {C Function} gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue@w{ }*rvalue) 6369 6370Get the type of this rvalue. 6371@end deffn 6372 6373@geindex gcc_jit_rvalue_as_object (C function) 6374@anchor{topics/expressions gcc_jit_rvalue_as_object}@anchor{14} 6375@deffn {C Function} gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue@w{ }*rvalue) 6376 6377Upcast the given rvalue to be an object. 6378@end deffn 6379 6380@menu 6381* Simple expressions:: 6382* Unary Operations:: 6383* Binary Operations:: 6384* Comparisons:: 6385* Function calls:: 6386* Type-coercion:: 6387 6388@end menu 6389 6390@node Simple expressions,Unary Operations,,Rvalues 6391@anchor{topics/expressions simple-expressions}@anchor{8e} 6392@subsubsection Simple expressions 6393 6394 6395@geindex gcc_jit_context_new_rvalue_from_int (C function) 6396@anchor{topics/expressions gcc_jit_context_new_rvalue_from_int}@anchor{30} 6397@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_int (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type, int@w{ }value) 6398 6399Given a numeric type (integer or floating point), build an rvalue for 6400the given constant @code{int} value. 6401@end deffn 6402 6403@geindex gcc_jit_context_new_rvalue_from_long (C function) 6404@anchor{topics/expressions gcc_jit_context_new_rvalue_from_long}@anchor{8f} 6405@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_long (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type, long@w{ }value) 6406 6407Given a numeric type (integer or floating point), build an rvalue for 6408the given constant @code{long} value. 6409@end deffn 6410 6411@geindex gcc_jit_context_zero (C function) 6412@anchor{topics/expressions gcc_jit_context_zero}@anchor{2b} 6413@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) 6414 6415Given a numeric type (integer or floating point), get the rvalue for 6416zero. Essentially this is just a shortcut for: 6417 6418@example 6419gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0) 6420@end example 6421 6422@noindent 6423@end deffn 6424 6425@geindex gcc_jit_context_one (C function) 6426@anchor{topics/expressions gcc_jit_context_one}@anchor{2f} 6427@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_one (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) 6428 6429Given a numeric type (integer or floating point), get the rvalue for 6430one. Essentially this is just a shortcut for: 6431 6432@example 6433gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1) 6434@end example 6435 6436@noindent 6437@end deffn 6438 6439@geindex gcc_jit_context_new_rvalue_from_double (C function) 6440@anchor{topics/expressions gcc_jit_context_new_rvalue_from_double}@anchor{31} 6441@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_double (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type, double@w{ }value) 6442 6443Given a numeric type (integer or floating point), build an rvalue for 6444the given constant @code{double} value. 6445@end deffn 6446 6447@geindex gcc_jit_context_new_rvalue_from_ptr (C function) 6448@anchor{topics/expressions gcc_jit_context_new_rvalue_from_ptr}@anchor{90} 6449@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type, void@w{ }*value) 6450 6451Given a pointer type, build an rvalue for the given address. 6452@end deffn 6453 6454@geindex gcc_jit_context_null (C function) 6455@anchor{topics/expressions gcc_jit_context_null}@anchor{91} 6456@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type) 6457 6458Given a pointer type, build an rvalue for @code{NULL}. Essentially this 6459is just a shortcut for: 6460 6461@example 6462gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL) 6463@end example 6464 6465@noindent 6466@end deffn 6467 6468@geindex gcc_jit_context_new_string_literal (C function) 6469@anchor{topics/expressions gcc_jit_context_new_string_literal}@anchor{92} 6470@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_string_literal (gcc_jit_context@w{ }*ctxt, const char@w{ }*value) 6471 6472Generate an rvalue for the given NIL-terminated string, of type 6473@code{GCC_JIT_TYPE_CONST_CHAR_PTR}. 6474 6475The parameter @code{value} must be non-NULL. The call takes a copy of the 6476underlying string, so it is valid to pass in a pointer to an on-stack 6477buffer. 6478@end deffn 6479 6480@node Unary Operations,Binary Operations,Simple expressions,Rvalues 6481@anchor{topics/expressions unary-operations}@anchor{93} 6482@subsubsection Unary Operations 6483 6484 6485@geindex gcc_jit_context_new_unary_op (C function) 6486@anchor{topics/expressions gcc_jit_context_new_unary_op}@anchor{94} 6487@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_unary_op (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_unary_op@w{ }op, gcc_jit_type@w{ }*result_type, gcc_jit_rvalue@w{ }*rvalue) 6488 6489Build a unary operation out of an input rvalue. 6490@end deffn 6491 6492@geindex gcc_jit_unary_op (C type) 6493@anchor{topics/expressions gcc_jit_unary_op}@anchor{95} 6494@deffn {C Type} enum gcc_jit_unary_op 6495@end deffn 6496 6497The available unary operations are: 6498 6499 6500@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6501@headitem 6502 6503Unary Operation 6504 6505@tab 6506 6507C equivalent 6508 6509@item 6510 6511@pxref{96,,GCC_JIT_UNARY_OP_MINUS} 6512 6513@tab 6514 6515@cite{-(EXPR)} 6516 6517@item 6518 6519@pxref{97,,GCC_JIT_UNARY_OP_BITWISE_NEGATE} 6520 6521@tab 6522 6523@cite{~(EXPR)} 6524 6525@item 6526 6527@pxref{98,,GCC_JIT_UNARY_OP_LOGICAL_NEGATE} 6528 6529@tab 6530 6531@cite{!(EXPR)} 6532 6533@item 6534 6535@pxref{99,,GCC_JIT_UNARY_OP_ABS} 6536 6537@tab 6538 6539@cite{abs (EXPR)} 6540 6541@end multitable 6542 6543 6544@geindex GCC_JIT_UNARY_OP_MINUS (C macro) 6545@anchor{topics/expressions GCC_JIT_UNARY_OP_MINUS}@anchor{96} 6546@deffn {C Macro} GCC_JIT_UNARY_OP_MINUS 6547 6548Negate an arithmetic value; analogous to: 6549 6550@example 6551-(EXPR) 6552@end example 6553 6554@noindent 6555 6556in C. 6557@end deffn 6558 6559@geindex GCC_JIT_UNARY_OP_BITWISE_NEGATE (C macro) 6560@anchor{topics/expressions GCC_JIT_UNARY_OP_BITWISE_NEGATE}@anchor{97} 6561@deffn {C Macro} GCC_JIT_UNARY_OP_BITWISE_NEGATE 6562 6563Bitwise negation of an integer value (one's complement); analogous 6564to: 6565 6566@example 6567~(EXPR) 6568@end example 6569 6570@noindent 6571 6572in C. 6573@end deffn 6574 6575@geindex GCC_JIT_UNARY_OP_LOGICAL_NEGATE (C macro) 6576@anchor{topics/expressions GCC_JIT_UNARY_OP_LOGICAL_NEGATE}@anchor{98} 6577@deffn {C Macro} GCC_JIT_UNARY_OP_LOGICAL_NEGATE 6578 6579Logical negation of an arithmetic or pointer value; analogous to: 6580 6581@example 6582!(EXPR) 6583@end example 6584 6585@noindent 6586 6587in C. 6588@end deffn 6589 6590@geindex GCC_JIT_UNARY_OP_ABS (C macro) 6591@anchor{topics/expressions GCC_JIT_UNARY_OP_ABS}@anchor{99} 6592@deffn {C Macro} GCC_JIT_UNARY_OP_ABS 6593 6594Absolute value of an arithmetic expression; analogous to: 6595 6596@example 6597abs (EXPR) 6598@end example 6599 6600@noindent 6601 6602in C. 6603@end deffn 6604 6605@node Binary Operations,Comparisons,Unary Operations,Rvalues 6606@anchor{topics/expressions binary-operations}@anchor{9a} 6607@subsubsection Binary Operations 6608 6609 6610@geindex gcc_jit_context_new_binary_op (C function) 6611@anchor{topics/expressions gcc_jit_context_new_binary_op}@anchor{12} 6612@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_new_binary_op (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_binary_op@w{ }op, gcc_jit_type@w{ }*result_type, gcc_jit_rvalue@w{ }*a, gcc_jit_rvalue@w{ }*b) 6613 6614Build a binary operation out of two constituent rvalues. 6615@end deffn 6616 6617@geindex gcc_jit_binary_op (C type) 6618@anchor{topics/expressions gcc_jit_binary_op}@anchor{9b} 6619@deffn {C Type} enum gcc_jit_binary_op 6620@end deffn 6621 6622The available binary operations are: 6623 6624 6625@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6626@headitem 6627 6628Binary Operation 6629 6630@tab 6631 6632C equivalent 6633 6634@item 6635 6636@pxref{9c,,GCC_JIT_BINARY_OP_PLUS} 6637 6638@tab 6639 6640@cite{x + y} 6641 6642@item 6643 6644@pxref{9d,,GCC_JIT_BINARY_OP_MINUS} 6645 6646@tab 6647 6648@cite{x - y} 6649 6650@item 6651 6652@pxref{9e,,GCC_JIT_BINARY_OP_MULT} 6653 6654@tab 6655 6656@cite{x * y} 6657 6658@item 6659 6660@pxref{9f,,GCC_JIT_BINARY_OP_DIVIDE} 6661 6662@tab 6663 6664@cite{x / y} 6665 6666@item 6667 6668@pxref{a0,,GCC_JIT_BINARY_OP_MODULO} 6669 6670@tab 6671 6672@cite{x % y} 6673 6674@item 6675 6676@pxref{a1,,GCC_JIT_BINARY_OP_BITWISE_AND} 6677 6678@tab 6679 6680@cite{x & y} 6681 6682@item 6683 6684@pxref{a2,,GCC_JIT_BINARY_OP_BITWISE_XOR} 6685 6686@tab 6687 6688@cite{x ^ y} 6689 6690@item 6691 6692@pxref{a3,,GCC_JIT_BINARY_OP_BITWISE_OR} 6693 6694@tab 6695 6696@cite{x | y} 6697 6698@item 6699 6700@pxref{a4,,GCC_JIT_BINARY_OP_LOGICAL_AND} 6701 6702@tab 6703 6704@cite{x && y} 6705 6706@item 6707 6708@pxref{a5,,GCC_JIT_BINARY_OP_LOGICAL_OR} 6709 6710@tab 6711 6712@cite{x || y} 6713 6714@item 6715 6716@pxref{a6,,GCC_JIT_BINARY_OP_LSHIFT} 6717 6718@tab 6719 6720@cite{x << y} 6721 6722@item 6723 6724@pxref{a7,,GCC_JIT_BINARY_OP_RSHIFT} 6725 6726@tab 6727 6728@cite{x >> y} 6729 6730@end multitable 6731 6732 6733@geindex GCC_JIT_BINARY_OP_PLUS (C macro) 6734@anchor{topics/expressions GCC_JIT_BINARY_OP_PLUS}@anchor{9c} 6735@deffn {C Macro} GCC_JIT_BINARY_OP_PLUS 6736 6737Addition of arithmetic values; analogous to: 6738 6739@example 6740(EXPR_A) + (EXPR_B) 6741@end example 6742 6743@noindent 6744 6745in C. 6746 6747For pointer addition, use @pxref{a8,,gcc_jit_context_new_array_access()}. 6748@end deffn 6749 6750@geindex GCC_JIT_BINARY_OP_MINUS (C macro) 6751@anchor{topics/expressions GCC_JIT_BINARY_OP_MINUS}@anchor{9d} 6752@deffn {C Macro} GCC_JIT_BINARY_OP_MINUS 6753 6754Subtraction of arithmetic values; analogous to: 6755 6756@example 6757(EXPR_A) - (EXPR_B) 6758@end example 6759 6760@noindent 6761 6762in C. 6763@end deffn 6764 6765@geindex GCC_JIT_BINARY_OP_MULT (C macro) 6766@anchor{topics/expressions GCC_JIT_BINARY_OP_MULT}@anchor{9e} 6767@deffn {C Macro} GCC_JIT_BINARY_OP_MULT 6768 6769Multiplication of a pair of arithmetic values; analogous to: 6770 6771@example 6772(EXPR_A) * (EXPR_B) 6773@end example 6774 6775@noindent 6776 6777in C. 6778@end deffn 6779 6780@geindex GCC_JIT_BINARY_OP_DIVIDE (C macro) 6781@anchor{topics/expressions GCC_JIT_BINARY_OP_DIVIDE}@anchor{9f} 6782@deffn {C Macro} GCC_JIT_BINARY_OP_DIVIDE 6783 6784Quotient of division of arithmetic values; analogous to: 6785 6786@example 6787(EXPR_A) / (EXPR_B) 6788@end example 6789 6790@noindent 6791 6792in C. 6793 6794The result type affects the kind of division: if the result type is 6795integer-based, then the result is truncated towards zero, whereas 6796a floating-point result type indicates floating-point division. 6797@end deffn 6798 6799@geindex GCC_JIT_BINARY_OP_MODULO (C macro) 6800@anchor{topics/expressions GCC_JIT_BINARY_OP_MODULO}@anchor{a0} 6801@deffn {C Macro} GCC_JIT_BINARY_OP_MODULO 6802 6803Remainder of division of arithmetic values; analogous to: 6804 6805@example 6806(EXPR_A) % (EXPR_B) 6807@end example 6808 6809@noindent 6810 6811in C. 6812@end deffn 6813 6814@geindex GCC_JIT_BINARY_OP_BITWISE_AND (C macro) 6815@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_AND}@anchor{a1} 6816@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_AND 6817 6818Bitwise AND; analogous to: 6819 6820@example 6821(EXPR_A) & (EXPR_B) 6822@end example 6823 6824@noindent 6825 6826in C. 6827@end deffn 6828 6829@geindex GCC_JIT_BINARY_OP_BITWISE_XOR (C macro) 6830@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_XOR}@anchor{a2} 6831@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_XOR 6832 6833Bitwise exclusive OR; analogous to: 6834 6835@example 6836(EXPR_A) ^ (EXPR_B) 6837@end example 6838 6839@noindent 6840 6841in C. 6842@end deffn 6843 6844@geindex GCC_JIT_BINARY_OP_BITWISE_OR (C macro) 6845@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_OR}@anchor{a3} 6846@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_OR 6847 6848Bitwise inclusive OR; analogous to: 6849 6850@example 6851(EXPR_A) | (EXPR_B) 6852@end example 6853 6854@noindent 6855 6856in C. 6857@end deffn 6858 6859@geindex GCC_JIT_BINARY_OP_LOGICAL_AND (C macro) 6860@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_AND}@anchor{a4} 6861@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_AND 6862 6863Logical AND; analogous to: 6864 6865@example 6866(EXPR_A) && (EXPR_B) 6867@end example 6868 6869@noindent 6870 6871in C. 6872@end deffn 6873 6874@geindex GCC_JIT_BINARY_OP_LOGICAL_OR (C macro) 6875@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_OR}@anchor{a5} 6876@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_OR 6877 6878Logical OR; analogous to: 6879 6880@example 6881(EXPR_A) || (EXPR_B) 6882@end example 6883 6884@noindent 6885 6886in C. 6887@end deffn 6888 6889@geindex GCC_JIT_BINARY_OP_LSHIFT (C macro) 6890@anchor{topics/expressions GCC_JIT_BINARY_OP_LSHIFT}@anchor{a6} 6891@deffn {C Macro} GCC_JIT_BINARY_OP_LSHIFT 6892 6893Left shift; analogous to: 6894 6895@example 6896(EXPR_A) << (EXPR_B) 6897@end example 6898 6899@noindent 6900 6901in C. 6902@end deffn 6903 6904@geindex GCC_JIT_BINARY_OP_RSHIFT (C macro) 6905@anchor{topics/expressions GCC_JIT_BINARY_OP_RSHIFT}@anchor{a7} 6906@deffn {C Macro} GCC_JIT_BINARY_OP_RSHIFT 6907 6908Right shift; analogous to: 6909 6910@example 6911(EXPR_A) >> (EXPR_B) 6912@end example 6913 6914@noindent 6915 6916in C. 6917@end deffn 6918 6919@node Comparisons,Function calls,Binary Operations,Rvalues 6920@anchor{topics/expressions comparisons}@anchor{a9} 6921@subsubsection Comparisons 6922 6923 6924@geindex gcc_jit_context_new_comparison (C function) 6925@anchor{topics/expressions gcc_jit_context_new_comparison}@anchor{2c} 6926@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_comparison (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_comparison@w{ }op, gcc_jit_rvalue@w{ }*a, gcc_jit_rvalue@w{ }*b) 6927 6928Build a boolean rvalue out of the comparison of two other rvalues. 6929@end deffn 6930 6931@geindex gcc_jit_comparison (C type) 6932@anchor{topics/expressions gcc_jit_comparison}@anchor{aa} 6933@deffn {C Type} enum gcc_jit_comparison 6934@end deffn 6935 6936 6937@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6938@headitem 6939 6940Comparison 6941 6942@tab 6943 6944C equivalent 6945 6946@item 6947 6948@code{GCC_JIT_COMPARISON_EQ} 6949 6950@tab 6951 6952@cite{x == y} 6953 6954@item 6955 6956@code{GCC_JIT_COMPARISON_NE} 6957 6958@tab 6959 6960@cite{x != y} 6961 6962@item 6963 6964@code{GCC_JIT_COMPARISON_LT} 6965 6966@tab 6967 6968@cite{x < y} 6969 6970@item 6971 6972@code{GCC_JIT_COMPARISON_LE} 6973 6974@tab 6975 6976@cite{x <= y} 6977 6978@item 6979 6980@code{GCC_JIT_COMPARISON_GT} 6981 6982@tab 6983 6984@cite{x > y} 6985 6986@item 6987 6988@code{GCC_JIT_COMPARISON_GE} 6989 6990@tab 6991 6992@cite{x >= y} 6993 6994@end multitable 6995 6996 6997@node Function calls,Type-coercion,Comparisons,Rvalues 6998@anchor{topics/expressions function-calls}@anchor{ab} 6999@subsubsection Function calls 7000 7001 7002@geindex gcc_jit_context_new_call (C function) 7003@anchor{topics/expressions gcc_jit_context_new_call}@anchor{ac} 7004@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_call (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_function@w{ }*func, int@w{ }numargs, gcc_jit_rvalue@w{ }**args) 7005 7006Given a function and the given table of argument rvalues, construct a 7007call to the function, with the result as an rvalue. 7008 7009@cartouche 7010@quotation Note 7011@pxref{ac,,gcc_jit_context_new_call()} merely builds a 7012@pxref{13,,gcc_jit_rvalue} i.e. an expression that can be evaluated, 7013perhaps as part of a more complicated expression. 7014The call @emph{won't} happen unless you add a statement to a function 7015that evaluates the expression. 7016 7017For example, if you want to call a function and discard the result 7018(or to call a function with @code{void} return type), use 7019@pxref{ad,,gcc_jit_block_add_eval()}: 7020 7021@example 7022/* Add "(void)printf (arg0, arg1);". */ 7023gcc_jit_block_add_eval ( 7024 block, NULL, 7025 gcc_jit_context_new_call ( 7026 ctxt, 7027 NULL, 7028 printf_func, 7029 2, args)); 7030@end example 7031 7032@noindent 7033@end quotation 7034@end cartouche 7035@end deffn 7036 7037@geindex gcc_jit_context_new_call_through_ptr (C function) 7038@anchor{topics/expressions gcc_jit_context_new_call_through_ptr}@anchor{ae} 7039@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_call_through_ptr (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*fn_ptr, int@w{ }numargs, gcc_jit_rvalue@w{ }**args) 7040 7041Given an rvalue of function pointer type, and the given table of 7042argument rvalues, construct a call to the function pointer, with the 7043result as an rvalue. 7044 7045@cartouche 7046@quotation Note 7047The same caveat as for @pxref{ac,,gcc_jit_context_new_call()} applies. 7048@end quotation 7049@end cartouche 7050@end deffn 7051 7052@node Type-coercion,,Function calls,Rvalues 7053@anchor{topics/expressions type-coercion}@anchor{af} 7054@subsubsection Type-coercion 7055 7056 7057@geindex gcc_jit_context_new_cast (C function) 7058@anchor{topics/expressions gcc_jit_context_new_cast}@anchor{b0} 7059@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_cast (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue, gcc_jit_type@w{ }*type) 7060 7061Given an rvalue of T, construct another rvalue of another type. 7062 7063Currently only a limited set of conversions are possible: 7064 7065@quotation 7066 7067 7068@itemize * 7069 7070@item 7071int <-> float 7072 7073@item 7074int <-> bool 7075 7076@item 7077P* <-> Q*, for pointer types P and Q 7078@end itemize 7079@end quotation 7080@end deffn 7081 7082@node Lvalues,Working with pointers structs and unions,Rvalues,Expressions 7083@anchor{topics/expressions lvalues}@anchor{b1} 7084@subsection Lvalues 7085 7086 7087@geindex gcc_jit_lvalue (C type) 7088@anchor{topics/expressions gcc_jit_lvalue}@anchor{24} 7089@deffn {C Type} gcc_jit_lvalue 7090@end deffn 7091 7092An lvalue is something that can of the @emph{left}-hand side of an assignment: 7093a storage area (such as a variable). It is also usable as an rvalue, 7094where the rvalue is computed by reading from the storage area. 7095 7096@geindex gcc_jit_lvalue_as_object (C function) 7097@anchor{topics/expressions gcc_jit_lvalue_as_object}@anchor{b2} 7098@deffn {C Function} gcc_jit_object * gcc_jit_lvalue_as_object (gcc_jit_lvalue@w{ }*lvalue) 7099 7100Upcast an lvalue to be an object. 7101@end deffn 7102 7103@geindex gcc_jit_lvalue_as_rvalue (C function) 7104@anchor{topics/expressions gcc_jit_lvalue_as_rvalue}@anchor{b3} 7105@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue@w{ }*lvalue) 7106 7107Upcast an lvalue to be an rvalue. 7108@end deffn 7109 7110@geindex gcc_jit_lvalue_get_address (C function) 7111@anchor{topics/expressions gcc_jit_lvalue_get_address}@anchor{b4} 7112@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_get_address (gcc_jit_lvalue@w{ }*lvalue, gcc_jit_location@w{ }*loc) 7113 7114Take the address of an lvalue; analogous to: 7115 7116@example 7117&(EXPR) 7118@end example 7119 7120@noindent 7121 7122in C. 7123@end deffn 7124 7125@menu 7126* Global variables:: 7127 7128@end menu 7129 7130@node Global variables,,,Lvalues 7131@anchor{topics/expressions global-variables}@anchor{b5} 7132@subsubsection Global variables 7133 7134 7135@geindex gcc_jit_context_new_global (C function) 7136@anchor{topics/expressions gcc_jit_context_new_global}@anchor{b6} 7137@deffn {C Function} gcc_jit_lvalue * gcc_jit_context_new_global (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_global_kind@w{ }kind, gcc_jit_type@w{ }*type, const char@w{ }*name) 7138 7139Add a new global variable of the given type and name to the context. 7140 7141The parameter @code{name} must be non-NULL. The call takes a copy of the 7142underlying string, so it is valid to pass in a pointer to an on-stack 7143buffer. 7144 7145The "kind" parameter determines the visibility of the "global" outside 7146of the @pxref{16,,gcc_jit_result}: 7147 7148@geindex gcc_jit_global_kind (C type) 7149@anchor{topics/expressions gcc_jit_global_kind}@anchor{b7} 7150@deffn {C Type} enum gcc_jit_global_kind 7151@end deffn 7152 7153@geindex GCC_JIT_GLOBAL_EXPORTED (C macro) 7154@anchor{topics/expressions GCC_JIT_GLOBAL_EXPORTED}@anchor{b8} 7155@deffn {C Macro} GCC_JIT_GLOBAL_EXPORTED 7156 7157Global is defined by the client code and is visible 7158by name outside of this JIT context via 7159@pxref{b9,,gcc_jit_result_get_global()} (and this value is required for 7160the global to be accessible via that entrypoint). 7161@end deffn 7162 7163@geindex GCC_JIT_GLOBAL_INTERNAL (C macro) 7164@anchor{topics/expressions GCC_JIT_GLOBAL_INTERNAL}@anchor{ba} 7165@deffn {C Macro} GCC_JIT_GLOBAL_INTERNAL 7166 7167Global is defined by the client code, but is invisible 7168outside of it. Analogous to a "static" global within a .c file. 7169Specifically, the variable will only be visible within this 7170context and within child contexts. 7171@end deffn 7172 7173@geindex GCC_JIT_GLOBAL_IMPORTED (C macro) 7174@anchor{topics/expressions GCC_JIT_GLOBAL_IMPORTED}@anchor{bb} 7175@deffn {C Macro} GCC_JIT_GLOBAL_IMPORTED 7176 7177Global is not defined by the client code; we're merely 7178referring to it. Analogous to using an "extern" global from a 7179header file. 7180@end deffn 7181@end deffn 7182 7183@node Working with pointers structs and unions,,Lvalues,Expressions 7184@anchor{topics/expressions working-with-pointers-structs-and-unions}@anchor{bc} 7185@subsection Working with pointers, structs and unions 7186 7187 7188@geindex gcc_jit_rvalue_dereference (C function) 7189@anchor{topics/expressions gcc_jit_rvalue_dereference}@anchor{bd} 7190@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference (gcc_jit_rvalue@w{ }*rvalue, gcc_jit_location@w{ }*loc) 7191 7192Given an rvalue of pointer type @code{T *}, dereferencing the pointer, 7193getting an lvalue of type @code{T}. Analogous to: 7194 7195@example 7196*(EXPR) 7197@end example 7198 7199@noindent 7200 7201in C. 7202@end deffn 7203 7204Field access is provided separately for both lvalues and rvalues. 7205 7206@geindex gcc_jit_lvalue_access_field (C function) 7207@anchor{topics/expressions gcc_jit_lvalue_access_field}@anchor{be} 7208@deffn {C Function} gcc_jit_lvalue * gcc_jit_lvalue_access_field (gcc_jit_lvalue@w{ }*struct_, gcc_jit_location@w{ }*loc, gcc_jit_field@w{ }*field) 7209 7210Given an lvalue of struct or union type, access the given field, 7211getting an lvalue of the field's type. Analogous to: 7212 7213@example 7214(EXPR).field = ...; 7215@end example 7216 7217@noindent 7218 7219in C. 7220@end deffn 7221 7222@geindex gcc_jit_rvalue_access_field (C function) 7223@anchor{topics/expressions gcc_jit_rvalue_access_field}@anchor{bf} 7224@deffn {C Function} gcc_jit_rvalue * gcc_jit_rvalue_access_field (gcc_jit_rvalue@w{ }*struct_, gcc_jit_location@w{ }*loc, gcc_jit_field@w{ }*field) 7225 7226Given an rvalue of struct or union type, access the given field 7227as an rvalue. Analogous to: 7228 7229@example 7230(EXPR).field 7231@end example 7232 7233@noindent 7234 7235in C. 7236@end deffn 7237 7238@geindex gcc_jit_rvalue_dereference_field (C function) 7239@anchor{topics/expressions gcc_jit_rvalue_dereference_field}@anchor{c0} 7240@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference_field (gcc_jit_rvalue@w{ }*ptr, gcc_jit_location@w{ }*loc, gcc_jit_field@w{ }*field) 7241 7242Given an rvalue of pointer type @code{T *} where T is of struct or union 7243type, access the given field as an lvalue. Analogous to: 7244 7245@example 7246(EXPR)->field 7247@end example 7248 7249@noindent 7250 7251in C, itself equivalent to @code{(*EXPR).FIELD}. 7252@end deffn 7253 7254@geindex gcc_jit_context_new_array_access (C function) 7255@anchor{topics/expressions gcc_jit_context_new_array_access}@anchor{a8} 7256@deffn {C Function} gcc_jit_lvalue * gcc_jit_context_new_array_access (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*ptr, gcc_jit_rvalue@w{ }*index) 7257 7258Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at 7259the given index, using standard C array indexing rules i.e. each 7260increment of @code{index} corresponds to @code{sizeof(T)} bytes. 7261Analogous to: 7262 7263@example 7264PTR[INDEX] 7265@end example 7266 7267@noindent 7268 7269in C (or, indeed, to @code{PTR + INDEX}). 7270@end deffn 7271 7272@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 7273@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7274@c 7275@c This is free software: you can redistribute it and/or modify it 7276@c under the terms of the GNU General Public License as published by 7277@c the Free Software Foundation, either version 3 of the License, or 7278@c (at your option) any later version. 7279@c 7280@c This program is distributed in the hope that it will be useful, but 7281@c WITHOUT ANY WARRANTY; without even the implied warranty of 7282@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7283@c General Public License for more details. 7284@c 7285@c You should have received a copy of the GNU General Public License 7286@c along with this program. If not, see 7287@c <http://www.gnu.org/licenses/>. 7288 7289@node Creating and using functions,Source Locations,Expressions,Topic Reference 7290@anchor{topics/functions doc}@anchor{c1}@anchor{topics/functions creating-and-using-functions}@anchor{c2} 7291@section Creating and using functions 7292 7293 7294@menu 7295* Params:: 7296* Functions:: 7297* Blocks:: 7298* Statements:: 7299 7300@end menu 7301 7302@node Params,Functions,,Creating and using functions 7303@anchor{topics/functions params}@anchor{c3} 7304@subsection Params 7305 7306 7307@geindex gcc_jit_param (C type) 7308@anchor{topics/functions gcc_jit_param}@anchor{25} 7309@deffn {C Type} gcc_jit_param 7310 7311A @cite{gcc_jit_param} represents a parameter to a function. 7312@end deffn 7313 7314@geindex gcc_jit_context_new_param (C function) 7315@anchor{topics/functions gcc_jit_context_new_param}@anchor{10} 7316@deffn {C Function} gcc_jit_param * gcc_jit_context_new_param (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, const char@w{ }*name) 7317 7318In preparation for creating a function, create a new parameter of the 7319given type and name. 7320 7321The parameter @code{name} must be non-NULL. The call takes a copy of the 7322underlying string, so it is valid to pass in a pointer to an on-stack 7323buffer. 7324@end deffn 7325 7326Parameters are lvalues, and thus are also rvalues (and objects), so the 7327following upcasts are available: 7328 7329@geindex gcc_jit_param_as_lvalue (C function) 7330@anchor{topics/functions gcc_jit_param_as_lvalue}@anchor{c4} 7331@deffn {C Function} gcc_jit_lvalue * gcc_jit_param_as_lvalue (gcc_jit_param@w{ }*param) 7332 7333Upcasting from param to lvalue. 7334@end deffn 7335 7336@geindex gcc_jit_param_as_rvalue (C function) 7337@anchor{topics/functions gcc_jit_param_as_rvalue}@anchor{c5} 7338@deffn {C Function} gcc_jit_rvalue * gcc_jit_param_as_rvalue (gcc_jit_param@w{ }*param) 7339 7340Upcasting from param to rvalue. 7341@end deffn 7342 7343@geindex gcc_jit_param_as_object (C function) 7344@anchor{topics/functions gcc_jit_param_as_object}@anchor{c6} 7345@deffn {C Function} gcc_jit_object * gcc_jit_param_as_object (gcc_jit_param@w{ }*param) 7346 7347Upcasting from param to object. 7348@end deffn 7349 7350@node Functions,Blocks,Params,Creating and using functions 7351@anchor{topics/functions functions}@anchor{c7} 7352@subsection Functions 7353 7354 7355@geindex gcc_jit_function (C type) 7356@anchor{topics/functions gcc_jit_function}@anchor{29} 7357@deffn {C Type} gcc_jit_function 7358 7359A @cite{gcc_jit_function} represents a function - either one that we're 7360creating ourselves, or one that we're referencing. 7361@end deffn 7362 7363@geindex gcc_jit_context_new_function (C function) 7364@anchor{topics/functions gcc_jit_context_new_function}@anchor{11} 7365@deffn {C Function} gcc_jit_function * gcc_jit_context_new_function (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_function_kind@w{ }kind, gcc_jit_type@w{ }*return_type, const char@w{ }*name, int@w{ }num_params, gcc_jit_param@w{ }**params, int@w{ }is_variadic) 7366 7367Create a gcc_jit_function with the given name and parameters. 7368 7369@geindex gcc_jit_function_kind (C type) 7370@anchor{topics/functions gcc_jit_function_kind}@anchor{c8} 7371@deffn {C Type} enum gcc_jit_function_kind 7372@end deffn 7373 7374This enum controls the kind of function created, and has the following 7375values: 7376 7377@quotation 7378 7379@geindex GCC_JIT_FUNCTION_EXPORTED (C macro) 7380@anchor{topics/functions GCC_JIT_FUNCTION_EXPORTED}@anchor{c9} 7381@deffn {C Macro} GCC_JIT_FUNCTION_EXPORTED 7382 7383Function is defined by the client code and visible 7384by name outside of the JIT. 7385 7386This value is required if you want to extract machine code 7387for this function from a @pxref{16,,gcc_jit_result} via 7388@pxref{17,,gcc_jit_result_get_code()}. 7389@end deffn 7390 7391@geindex GCC_JIT_FUNCTION_INTERNAL (C macro) 7392@anchor{topics/functions GCC_JIT_FUNCTION_INTERNAL}@anchor{ca} 7393@deffn {C Macro} GCC_JIT_FUNCTION_INTERNAL 7394 7395Function is defined by the client code, but is invisible 7396outside of the JIT. Analogous to a "static" function. 7397@end deffn 7398 7399@geindex GCC_JIT_FUNCTION_IMPORTED (C macro) 7400@anchor{topics/functions GCC_JIT_FUNCTION_IMPORTED}@anchor{cb} 7401@deffn {C Macro} GCC_JIT_FUNCTION_IMPORTED 7402 7403Function is not defined by the client code; we're merely 7404referring to it. Analogous to using an "extern" function from a 7405header file. 7406@end deffn 7407 7408@geindex GCC_JIT_FUNCTION_ALWAYS_INLINE (C macro) 7409@anchor{topics/functions GCC_JIT_FUNCTION_ALWAYS_INLINE}@anchor{cc} 7410@deffn {C Macro} GCC_JIT_FUNCTION_ALWAYS_INLINE 7411 7412Function is only ever inlined into other functions, and is 7413invisible outside of the JIT. 7414 7415Analogous to prefixing with @code{inline} and adding 7416@code{__attribute__((always_inline))} 7417 7418Inlining will only occur when the optimization level is 7419above 0; when optimization is off, this is essentially the 7420same as GCC_JIT_FUNCTION_INTERNAL. 7421@end deffn 7422@end quotation 7423 7424The parameter @code{name} must be non-NULL. The call takes a copy of the 7425underlying string, so it is valid to pass in a pointer to an on-stack 7426buffer. 7427@end deffn 7428 7429@geindex gcc_jit_context_get_builtin_function (C function) 7430@anchor{topics/functions gcc_jit_context_get_builtin_function}@anchor{cd} 7431@deffn {C Function} gcc_jit_function *gcc_jit_context_get_builtin_function (gcc_jit_context@w{ }*ctxt, const char@w{ }*name) 7432@end deffn 7433 7434@geindex gcc_jit_function_as_object (C function) 7435@anchor{topics/functions gcc_jit_function_as_object}@anchor{ce} 7436@deffn {C Function} gcc_jit_object * gcc_jit_function_as_object (gcc_jit_function@w{ }*func) 7437 7438Upcasting from function to object. 7439@end deffn 7440 7441@geindex gcc_jit_function_get_param (C function) 7442@anchor{topics/functions gcc_jit_function_get_param}@anchor{cf} 7443@deffn {C Function} gcc_jit_param * gcc_jit_function_get_param (gcc_jit_function@w{ }*func, int@w{ }index) 7444 7445Get the param of the given index (0-based). 7446@end deffn 7447 7448@geindex gcc_jit_function_dump_to_dot (C function) 7449@anchor{topics/functions gcc_jit_function_dump_to_dot}@anchor{33} 7450@deffn {C Function} void gcc_jit_function_dump_to_dot (gcc_jit_function@w{ }*func, const char@w{ }*path) 7451 7452Emit the function in graphviz format to the given path. 7453@end deffn 7454 7455@geindex gcc_jit_function_new_local (C function) 7456@anchor{topics/functions gcc_jit_function_new_local}@anchor{26} 7457@deffn {C Function} gcc_jit_lvalue * gcc_jit_function_new_local (gcc_jit_function@w{ }*func, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, const char@w{ }*name) 7458 7459Create a new local variable within the function, of the given type and 7460name. 7461 7462The parameter @code{name} must be non-NULL. The call takes a copy of the 7463underlying string, so it is valid to pass in a pointer to an on-stack 7464buffer. 7465@end deffn 7466 7467@node Blocks,Statements,Functions,Creating and using functions 7468@anchor{topics/functions blocks}@anchor{d0} 7469@subsection Blocks 7470 7471 7472@geindex gcc_jit_block (C type) 7473@anchor{topics/functions gcc_jit_block}@anchor{28} 7474@deffn {C Type} gcc_jit_block 7475 7476A @cite{gcc_jit_block} represents a basic block within a function i.e. a 7477sequence of statements with a single entry point and a single exit 7478point. 7479 7480The first basic block that you create within a function will 7481be the entrypoint. 7482 7483Each basic block that you create within a function must be 7484terminated, either with a conditional, a jump, a return, or a 7485switch. 7486 7487It's legal to have multiple basic blocks that return within 7488one function. 7489@end deffn 7490 7491@geindex gcc_jit_function_new_block (C function) 7492@anchor{topics/functions gcc_jit_function_new_block}@anchor{d1} 7493@deffn {C Function} gcc_jit_block * gcc_jit_function_new_block (gcc_jit_function@w{ }*func, const char@w{ }*name) 7494 7495Create a basic block of the given name. The name may be NULL, but 7496providing meaningful names is often helpful when debugging: it may 7497show up in dumps of the internal representation, and in error 7498messages. It is copied, so the input buffer does not need to outlive 7499the call; you can pass in a pointer to an on-stack buffer, e.g.: 7500 7501@example 7502for (pc = 0; pc < fn->fn_num_ops; pc++) 7503 @{ 7504 char buf[16]; 7505 sprintf (buf, "instr%i", pc); 7506 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); 7507 @} 7508@end example 7509 7510@noindent 7511@end deffn 7512 7513@geindex gcc_jit_block_as_object (C function) 7514@anchor{topics/functions gcc_jit_block_as_object}@anchor{d2} 7515@deffn {C Function} gcc_jit_object * gcc_jit_block_as_object (gcc_jit_block@w{ }*block) 7516 7517Upcast from block to object. 7518@end deffn 7519 7520@geindex gcc_jit_block_get_function (C function) 7521@anchor{topics/functions gcc_jit_block_get_function}@anchor{d3} 7522@deffn {C Function} gcc_jit_function * gcc_jit_block_get_function (gcc_jit_block@w{ }*block) 7523 7524Which function is this block within? 7525@end deffn 7526 7527@node Statements,,Blocks,Creating and using functions 7528@anchor{topics/functions statements}@anchor{d4} 7529@subsection Statements 7530 7531 7532@geindex gcc_jit_block_add_eval (C function) 7533@anchor{topics/functions gcc_jit_block_add_eval}@anchor{ad} 7534@deffn {C Function} void gcc_jit_block_add_eval (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue) 7535 7536Add evaluation of an rvalue, discarding the result 7537(e.g. a function call that "returns" void). 7538 7539This is equivalent to this C code: 7540 7541@example 7542(void)expression; 7543@end example 7544 7545@noindent 7546@end deffn 7547 7548@geindex gcc_jit_block_add_assignment (C function) 7549@anchor{topics/functions gcc_jit_block_add_assignment}@anchor{2a} 7550@deffn {C Function} void gcc_jit_block_add_assignment (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_lvalue@w{ }*lvalue, gcc_jit_rvalue@w{ }*rvalue) 7551 7552Add evaluation of an rvalue, assigning the result to the given 7553lvalue. 7554 7555This is roughly equivalent to this C code: 7556 7557@example 7558lvalue = rvalue; 7559@end example 7560 7561@noindent 7562@end deffn 7563 7564@geindex gcc_jit_block_add_assignment_op (C function) 7565@anchor{topics/functions gcc_jit_block_add_assignment_op}@anchor{2e} 7566@deffn {C Function} void gcc_jit_block_add_assignment_op (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_lvalue@w{ }*lvalue, enum gcc_jit_binary_op@w{ }op, gcc_jit_rvalue@w{ }*rvalue) 7567 7568Add evaluation of an rvalue, using the result to modify an 7569lvalue. 7570 7571This is analogous to "+=" and friends: 7572 7573@example 7574lvalue += rvalue; 7575lvalue *= rvalue; 7576lvalue /= rvalue; 7577@end example 7578 7579@noindent 7580 7581etc. For example: 7582 7583@example 7584/* "i++" */ 7585gcc_jit_block_add_assignment_op ( 7586 loop_body, NULL, 7587 i, 7588 GCC_JIT_BINARY_OP_PLUS, 7589 gcc_jit_context_one (ctxt, int_type)); 7590@end example 7591 7592@noindent 7593@end deffn 7594 7595@geindex gcc_jit_block_add_comment (C function) 7596@anchor{topics/functions gcc_jit_block_add_comment}@anchor{3d} 7597@deffn {C Function} void gcc_jit_block_add_comment (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*text) 7598 7599Add a no-op textual comment to the internal representation of the 7600code. It will be optimized away, but will be visible in the dumps 7601seen via @pxref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} 7602and @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, 7603and thus may be of use when debugging how your project's internal 7604representation gets converted to the libgccjit IR. 7605 7606The parameter @code{text} must be non-NULL. It is copied, so the input 7607buffer does not need to outlive the call. For example: 7608 7609@example 7610char buf[100]; 7611snprintf (buf, sizeof (buf), 7612 "op%i: %s", 7613 pc, opcode_names[op->op_opcode]); 7614gcc_jit_block_add_comment (block, loc, buf); 7615@end example 7616 7617@noindent 7618@end deffn 7619 7620@geindex gcc_jit_block_end_with_conditional (C function) 7621@anchor{topics/functions gcc_jit_block_end_with_conditional}@anchor{2d} 7622@deffn {C Function} void gcc_jit_block_end_with_conditional (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*boolval, gcc_jit_block@w{ }*on_true, gcc_jit_block@w{ }*on_false) 7623 7624Terminate a block by adding evaluation of an rvalue, branching on the 7625result to the appropriate successor block. 7626 7627This is roughly equivalent to this C code: 7628 7629@example 7630if (boolval) 7631 goto on_true; 7632else 7633 goto on_false; 7634@end example 7635 7636@noindent 7637 7638block, boolval, on_true, and on_false must be non-NULL. 7639@end deffn 7640 7641@geindex gcc_jit_block_end_with_jump (C function) 7642@anchor{topics/functions gcc_jit_block_end_with_jump}@anchor{d5} 7643@deffn {C Function} void gcc_jit_block_end_with_jump (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_block@w{ }*target) 7644 7645Terminate a block by adding a jump to the given target block. 7646 7647This is roughly equivalent to this C code: 7648 7649@example 7650goto target; 7651@end example 7652 7653@noindent 7654@end deffn 7655 7656@geindex gcc_jit_block_end_with_return (C function) 7657@anchor{topics/functions gcc_jit_block_end_with_return}@anchor{d6} 7658@deffn {C Function} void gcc_jit_block_end_with_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue) 7659 7660Terminate a block by adding evaluation of an rvalue, returning the value. 7661 7662This is roughly equivalent to this C code: 7663 7664@example 7665return expression; 7666@end example 7667 7668@noindent 7669@end deffn 7670 7671@geindex gcc_jit_block_end_with_void_return (C function) 7672@anchor{topics/functions gcc_jit_block_end_with_void_return}@anchor{d7} 7673@deffn {C Function} void gcc_jit_block_end_with_void_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc) 7674 7675Terminate a block by adding a valueless return, for use within a function 7676with "void" return type. 7677 7678This is equivalent to this C code: 7679 7680@example 7681return; 7682@end example 7683 7684@noindent 7685@end deffn 7686 7687@geindex gcc_jit_block_end_with_switch (C function) 7688@anchor{topics/functions gcc_jit_block_end_with_switch}@anchor{d8} 7689@deffn {C Function} void gcc_jit_block_end_with_switch (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*expr, gcc_jit_block@w{ }*default_block, int@w{ }num_cases, gcc_jit_case@w{ }**cases) 7690 7691Terminate a block by adding evalation of an rvalue, then performing 7692a multiway branch. 7693 7694This is roughly equivalent to this C code: 7695 7696@example 7697switch (expr) 7698 @{ 7699 default: 7700 goto default_block; 7701 7702 case C0.min_value ... C0.max_value: 7703 goto C0.dest_block; 7704 7705 case C1.min_value ... C1.max_value: 7706 goto C1.dest_block; 7707 7708 ...etc... 7709 7710 case C[N - 1].min_value ... C[N - 1].max_value: 7711 goto C[N - 1].dest_block; 7712@} 7713@end example 7714 7715@noindent 7716 7717@code{block}, @code{expr}, @code{default_block} and @code{cases} must all be 7718non-NULL. 7719 7720@code{expr} must be of the same integer type as all of the @code{min_value} 7721and @code{max_value} within the cases. 7722 7723@code{num_cases} must be >= 0. 7724 7725The ranges of the cases must not overlap (or have duplicate 7726values). 7727 7728The API entrypoints relating to switch statements and cases: 7729 7730@quotation 7731 7732 7733@itemize * 7734 7735@item 7736@pxref{d8,,gcc_jit_block_end_with_switch()} 7737 7738@item 7739@pxref{d9,,gcc_jit_case_as_object()} 7740 7741@item 7742@pxref{da,,gcc_jit_context_new_case()} 7743@end itemize 7744@end quotation 7745 7746were added in @pxref{db,,LIBGCCJIT_ABI_3}; you can test for their presence 7747using 7748 7749@example 7750#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 7751@end example 7752 7753@noindent 7754 7755@geindex gcc_jit_case (C type) 7756@anchor{topics/functions gcc_jit_case}@anchor{dc} 7757@deffn {C Type} gcc_jit_case 7758@end deffn 7759 7760A @cite{gcc_jit_case} represents a case within a switch statement, and 7761is created within a particular @pxref{8,,gcc_jit_context} using 7762@pxref{da,,gcc_jit_context_new_case()}. 7763 7764Each case expresses a multivalued range of integer values. You 7765can express single-valued cases by passing in the same value for 7766both @cite{min_value} and @cite{max_value}. 7767 7768@geindex gcc_jit_context_new_case (C function) 7769@anchor{topics/functions gcc_jit_context_new_case}@anchor{da} 7770@deffn {C Function} gcc_jit_case * gcc_jit_context_new_case (gcc_jit_context@w{ }*ctxt, gcc_jit_rvalue@w{ }*min_value, gcc_jit_rvalue@w{ }*max_value, gcc_jit_block@w{ }*dest_block) 7771 7772Create a new gcc_jit_case instance for use in a switch statement. 7773@cite{min_value} and @cite{max_value} must be constants of an integer type, 7774which must match that of the expression of the switch statement. 7775 7776@cite{dest_block} must be within the same function as the switch 7777statement. 7778@end deffn 7779 7780@geindex gcc_jit_case_as_object (C function) 7781@anchor{topics/functions gcc_jit_case_as_object}@anchor{d9} 7782@deffn {C Function} gcc_jit_object * gcc_jit_case_as_object (gcc_jit_case@w{ }*case_) 7783 7784Upcast from a case to an object. 7785@end deffn 7786 7787Here's an example of creating a switch statement: 7788 7789@quotation 7790 7791@example 7792 7793void 7794create_code (gcc_jit_context *ctxt, void *user_data) 7795@{ 7796 /* Let's try to inject the equivalent of: 7797 int 7798 test_switch (int x) 7799 @{ 7800 switch (x) 7801 @{ 7802 case 0 ... 5: 7803 return 3; 7804 7805 case 25 ... 27: 7806 return 4; 7807 7808 case -42 ... -17: 7809 return 83; 7810 7811 case 40: 7812 return 8; 7813 7814 default: 7815 return 10; 7816 @} 7817 @} 7818 */ 7819 gcc_jit_type *t_int = 7820 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 7821 gcc_jit_type *return_type = t_int; 7822 gcc_jit_param *x = 7823 gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); 7824 gcc_jit_param *params[1] = @{x@}; 7825 gcc_jit_function *func = 7826 gcc_jit_context_new_function (ctxt, NULL, 7827 GCC_JIT_FUNCTION_EXPORTED, 7828 return_type, 7829 "test_switch", 7830 1, params, 0); 7831 7832 gcc_jit_block *b_initial = 7833 gcc_jit_function_new_block (func, "initial"); 7834 7835 gcc_jit_block *b_default = 7836 gcc_jit_function_new_block (func, "default"); 7837 gcc_jit_block *b_case_0_5 = 7838 gcc_jit_function_new_block (func, "case_0_5"); 7839 gcc_jit_block *b_case_25_27 = 7840 gcc_jit_function_new_block (func, "case_25_27"); 7841 gcc_jit_block *b_case_m42_m17 = 7842 gcc_jit_function_new_block (func, "case_m42_m17"); 7843 gcc_jit_block *b_case_40 = 7844 gcc_jit_function_new_block (func, "case_40"); 7845 7846 gcc_jit_case *cases[4] = @{ 7847 gcc_jit_context_new_case ( 7848 ctxt, 7849 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0), 7850 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5), 7851 b_case_0_5), 7852 gcc_jit_context_new_case ( 7853 ctxt, 7854 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 25), 7855 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 27), 7856 b_case_25_27), 7857 gcc_jit_context_new_case ( 7858 ctxt, 7859 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -42), 7860 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -17), 7861 b_case_m42_m17), 7862 gcc_jit_context_new_case ( 7863 ctxt, 7864 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), 7865 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), 7866 b_case_40) 7867 @}; 7868 gcc_jit_block_end_with_switch ( 7869 b_initial, NULL, 7870 gcc_jit_param_as_rvalue (x), 7871 b_default, 7872 4, cases); 7873 7874 gcc_jit_block_end_with_return ( 7875 b_case_0_5, NULL, 7876 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); 7877 gcc_jit_block_end_with_return ( 7878 b_case_25_27, NULL, 7879 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4)); 7880 gcc_jit_block_end_with_return ( 7881 b_case_m42_m17, NULL, 7882 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 83)); 7883 gcc_jit_block_end_with_return ( 7884 b_case_40, NULL, 7885 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 8)); 7886 gcc_jit_block_end_with_return ( 7887 b_default, NULL, 7888 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); 7889@} 7890 7891 7892@end example 7893 7894@noindent 7895@end quotation 7896@end deffn 7897 7898@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 7899@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7900@c 7901@c This is free software: you can redistribute it and/or modify it 7902@c under the terms of the GNU General Public License as published by 7903@c the Free Software Foundation, either version 3 of the License, or 7904@c (at your option) any later version. 7905@c 7906@c This program is distributed in the hope that it will be useful, but 7907@c WITHOUT ANY WARRANTY; without even the implied warranty of 7908@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7909@c General Public License for more details. 7910@c 7911@c You should have received a copy of the GNU General Public License 7912@c along with this program. If not, see 7913@c <http://www.gnu.org/licenses/>. 7914 7915@node Source Locations,Compiling a context,Creating and using functions,Topic Reference 7916@anchor{topics/locations source-locations}@anchor{dd}@anchor{topics/locations doc}@anchor{de} 7917@section Source Locations 7918 7919 7920@geindex gcc_jit_location (C type) 7921@anchor{topics/locations gcc_jit_location}@anchor{3b} 7922@deffn {C Type} gcc_jit_location 7923 7924A @cite{gcc_jit_location} encapsulates a source code location, so that 7925you can (optionally) associate locations in your language with 7926statements in the JIT-compiled code, allowing the debugger to 7927single-step through your language. 7928 7929@cite{gcc_jit_location} instances are optional: you can always pass NULL to 7930any API entrypoint accepting one. 7931 7932You can construct them using @pxref{41,,gcc_jit_context_new_location()}. 7933 7934You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 7935@pxref{8,,gcc_jit_context} for these locations to actually be usable by 7936the debugger: 7937 7938@example 7939gcc_jit_context_set_bool_option ( 7940 ctxt, 7941 GCC_JIT_BOOL_OPTION_DEBUGINFO, 7942 1); 7943@end example 7944 7945@noindent 7946@end deffn 7947 7948@geindex gcc_jit_context_new_location (C function) 7949@anchor{topics/locations gcc_jit_context_new_location}@anchor{41} 7950@deffn {C Function} gcc_jit_location * gcc_jit_context_new_location (gcc_jit_context@w{ }*ctxt, const char@w{ }*filename, int@w{ }line, int@w{ }column) 7951 7952Create a @cite{gcc_jit_location} instance representing the given source 7953location. 7954 7955The parameter @code{filename} must be non-NULL. The call takes a copy of 7956the underlying string, so it is valid to pass in a pointer to an 7957on-stack buffer. 7958@end deffn 7959 7960@menu 7961* Faking it:: 7962 7963@end menu 7964 7965@node Faking it,,,Source Locations 7966@anchor{topics/locations faking-it}@anchor{df} 7967@subsection Faking it 7968 7969 7970If you don't have source code for your internal representation, but need 7971to debug, you can generate a C-like representation of the functions in 7972your context using @pxref{5a,,gcc_jit_context_dump_to_file()}: 7973 7974@example 7975gcc_jit_context_dump_to_file (ctxt, "/tmp/something.c", 7976 1 /* update_locations */); 7977@end example 7978 7979@noindent 7980 7981This will dump C-like code to the given path. If the @cite{update_locations} 7982argument is true, this will also set up @cite{gcc_jit_location} information 7983throughout the context, pointing at the dump file as if it were a source 7984file, giving you @emph{something} you can step through in the debugger. 7985 7986@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 7987@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7988@c 7989@c This is free software: you can redistribute it and/or modify it 7990@c under the terms of the GNU General Public License as published by 7991@c the Free Software Foundation, either version 3 of the License, or 7992@c (at your option) any later version. 7993@c 7994@c This program is distributed in the hope that it will be useful, but 7995@c WITHOUT ANY WARRANTY; without even the implied warranty of 7996@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7997@c General Public License for more details. 7998@c 7999@c You should have received a copy of the GNU General Public License 8000@c along with this program. If not, see 8001@c <http://www.gnu.org/licenses/>. 8002 8003@node Compiling a context,ABI and API compatibility,Source Locations,Topic Reference 8004@anchor{topics/compilation compiling-a-context}@anchor{e0}@anchor{topics/compilation doc}@anchor{e1} 8005@section Compiling a context 8006 8007 8008Once populated, a @pxref{8,,gcc_jit_context *} can be compiled to 8009machine code, either in-memory via @pxref{15,,gcc_jit_context_compile()} or 8010to disk via @pxref{4a,,gcc_jit_context_compile_to_file()}. 8011 8012You can compile a context multiple times (using either form of 8013compilation), although any errors that occur on the context will 8014prevent any future compilation of that context. 8015 8016@menu 8017* In-memory compilation:: 8018* Ahead-of-time compilation:: 8019 8020@end menu 8021 8022@node In-memory compilation,Ahead-of-time compilation,,Compiling a context 8023@anchor{topics/compilation in-memory-compilation}@anchor{e2} 8024@subsection In-memory compilation 8025 8026 8027@geindex gcc_jit_context_compile (C function) 8028@anchor{topics/compilation gcc_jit_context_compile}@anchor{15} 8029@deffn {C Function} gcc_jit_result * gcc_jit_context_compile (gcc_jit_context@w{ }*ctxt) 8030 8031This calls into GCC and builds the code, returning a 8032@cite{gcc_jit_result *}. 8033 8034If the result is non-NULL, the caller becomes responsible for 8035calling @pxref{39,,gcc_jit_result_release()} on it once they're done 8036with it. 8037@end deffn 8038 8039@geindex gcc_jit_result (C type) 8040@anchor{topics/compilation gcc_jit_result}@anchor{16} 8041@deffn {C Type} gcc_jit_result 8042 8043A @cite{gcc_jit_result} encapsulates the result of compiling a context 8044in-memory, and the lifetimes of any machine code functions or globals 8045that are within the result. 8046@end deffn 8047 8048@geindex gcc_jit_result_get_code (C function) 8049@anchor{topics/compilation gcc_jit_result_get_code}@anchor{17} 8050@deffn {C Function} void * gcc_jit_result_get_code (gcc_jit_result@w{ }*result, const char@w{ }*funcname) 8051 8052Locate a given function within the built machine code. 8053 8054Functions are looked up by name. For this to succeed, a function 8055with a name matching @cite{funcname} must have been created on 8056@cite{result}'s context (or a parent context) via a call to 8057@pxref{11,,gcc_jit_context_new_function()} with @cite{kind} 8058@pxref{c9,,GCC_JIT_FUNCTION_EXPORTED}: 8059 8060@example 8061gcc_jit_context_new_function (ctxt, 8062 any_location, /* or NULL */ 8063 /* Required for func to be visible to 8064 gcc_jit_result_get_code: */ 8065 GCC_JIT_FUNCTION_EXPORTED, 8066 any_return_type, 8067 /* Must string-compare equal: */ 8068 funcname, 8069 /* etc */); 8070@end example 8071 8072@noindent 8073 8074If such a function is not found (or @cite{result} or @cite{funcname} are 8075@code{NULL}), an error message will be emitted on stderr and 8076@code{NULL} will be returned. 8077 8078If the function is found, the result will need to be cast to a 8079function pointer of the correct type before it can be called. 8080 8081Note that the resulting machine code becomes invalid after 8082@pxref{39,,gcc_jit_result_release()} is called on the 8083@pxref{16,,gcc_jit_result *}; attempting to call it after that may lead 8084to a segmentation fault. 8085@end deffn 8086 8087@geindex gcc_jit_result_get_global (C function) 8088@anchor{topics/compilation gcc_jit_result_get_global}@anchor{b9} 8089@deffn {C Function} void * gcc_jit_result_get_global (gcc_jit_result@w{ }*result, const char@w{ }*name) 8090 8091Locate a given global within the built machine code. 8092 8093Globals are looked up by name. For this to succeed, a global 8094with a name matching @cite{name} must have been created on 8095@cite{result}'s context (or a parent context) via a call to 8096@pxref{b6,,gcc_jit_context_new_global()} with @cite{kind} 8097@pxref{b8,,GCC_JIT_GLOBAL_EXPORTED}. 8098 8099If the global is found, the result will need to be cast to a 8100pointer of the correct type before it can be called. 8101 8102This is a @emph{pointer} to the global, so e.g. for an @code{int} this is 8103an @code{int *}. 8104 8105For example, given an @code{int foo;} created this way: 8106 8107@example 8108gcc_jit_lvalue *exported_global = 8109 gcc_jit_context_new_global (ctxt, 8110 any_location, /* or NULL */ 8111 GCC_JIT_GLOBAL_EXPORTED, 8112 int_type, 8113 "foo"); 8114@end example 8115 8116@noindent 8117 8118we can access it like this: 8119 8120@example 8121int *ptr_to_foo = 8122 (int *)gcc_jit_result_get_global (result, "foo"); 8123@end example 8124 8125@noindent 8126 8127If such a global is not found (or @cite{result} or @cite{name} are 8128@code{NULL}), an error message will be emitted on stderr and 8129@code{NULL} will be returned. 8130 8131Note that the resulting address becomes invalid after 8132@pxref{39,,gcc_jit_result_release()} is called on the 8133@pxref{16,,gcc_jit_result *}; attempting to use it after that may lead 8134to a segmentation fault. 8135@end deffn 8136 8137@geindex gcc_jit_result_release (C function) 8138@anchor{topics/compilation gcc_jit_result_release}@anchor{39} 8139@deffn {C Function} void gcc_jit_result_release (gcc_jit_result@w{ }*result) 8140 8141Once we're done with the code, this unloads the built .so file. 8142This cleans up the result; after calling this, it's no longer 8143valid to use the result, or any code or globals that were obtained 8144by calling @pxref{17,,gcc_jit_result_get_code()} or 8145@pxref{b9,,gcc_jit_result_get_global()} on it. 8146@end deffn 8147 8148@node Ahead-of-time compilation,,In-memory compilation,Compiling a context 8149@anchor{topics/compilation ahead-of-time-compilation}@anchor{e3} 8150@subsection Ahead-of-time compilation 8151 8152 8153Although libgccjit is primarily aimed at just-in-time compilation, it 8154can also be used for implementing more traditional ahead-of-time 8155compilers, via the @pxref{4a,,gcc_jit_context_compile_to_file()} 8156API entrypoint. 8157 8158@geindex gcc_jit_context_compile_to_file (C function) 8159@anchor{topics/compilation gcc_jit_context_compile_to_file}@anchor{4a} 8160@deffn {C Function} void gcc_jit_context_compile_to_file (gcc_jit_context@w{ }*ctxt, enum gcc_jit_output_kind@w{ }output_kind, const char@w{ }*output_path) 8161 8162Compile the @pxref{8,,gcc_jit_context *} to a file of the given 8163kind. 8164@end deffn 8165 8166@pxref{4a,,gcc_jit_context_compile_to_file()} ignores the suffix of 8167@code{output_path}, and insteads uses the given 8168@code{enum gcc_jit_output_kind} to decide what to do. 8169 8170@cartouche 8171@quotation Note 8172This is different from the @code{gcc} program, which does make use of the 8173suffix of the output file when determining what to do. 8174@end quotation 8175@end cartouche 8176 8177@geindex gcc_jit_output_kind (C type) 8178@anchor{topics/compilation gcc_jit_output_kind}@anchor{e4} 8179@deffn {C Type} enum gcc_jit_output_kind 8180@end deffn 8181 8182The available kinds of output are: 8183 8184 8185@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxx} 8186@headitem 8187 8188Output kind 8189 8190@tab 8191 8192Typical suffix 8193 8194@item 8195 8196@pxref{e5,,GCC_JIT_OUTPUT_KIND_ASSEMBLER} 8197 8198@tab 8199 8200.s 8201 8202@item 8203 8204@pxref{e6,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE} 8205 8206@tab 8207 8208.o 8209 8210@item 8211 8212@pxref{e7,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY} 8213 8214@tab 8215 8216.so or .dll 8217 8218@item 8219 8220@pxref{e8,,GCC_JIT_OUTPUT_KIND_EXECUTABLE} 8221 8222@tab 8223 8224None, or .exe 8225 8226@end multitable 8227 8228 8229@geindex GCC_JIT_OUTPUT_KIND_ASSEMBLER (C macro) 8230@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{e5} 8231@deffn {C Macro} GCC_JIT_OUTPUT_KIND_ASSEMBLER 8232 8233Compile the context to an assembler file. 8234@end deffn 8235 8236@geindex GCC_JIT_OUTPUT_KIND_OBJECT_FILE (C macro) 8237@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{e6} 8238@deffn {C Macro} GCC_JIT_OUTPUT_KIND_OBJECT_FILE 8239 8240Compile the context to an object file. 8241@end deffn 8242 8243@geindex GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY (C macro) 8244@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{e7} 8245@deffn {C Macro} GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY 8246 8247Compile the context to a dynamic library. 8248 8249There is currently no support for specifying other libraries to link 8250against. 8251@end deffn 8252 8253@geindex GCC_JIT_OUTPUT_KIND_EXECUTABLE (C macro) 8254@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{e8} 8255@deffn {C Macro} GCC_JIT_OUTPUT_KIND_EXECUTABLE 8256 8257Compile the context to an executable. 8258 8259There is currently no support for specifying libraries to link 8260against. 8261@end deffn 8262 8263@c Copyright (C) 2015-2017 Free Software Foundation, Inc. 8264@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8265@c 8266@c This is free software: you can redistribute it and/or modify it 8267@c under the terms of the GNU General Public License as published by 8268@c the Free Software Foundation, either version 3 of the License, or 8269@c (at your option) any later version. 8270@c 8271@c This program is distributed in the hope that it will be useful, but 8272@c WITHOUT ANY WARRANTY; without even the implied warranty of 8273@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8274@c General Public License for more details. 8275@c 8276@c You should have received a copy of the GNU General Public License 8277@c along with this program. If not, see 8278@c <http://www.gnu.org/licenses/>. 8279 8280@node ABI and API compatibility,Performance,Compiling a context,Topic Reference 8281@anchor{topics/compatibility abi-and-api-compatibility}@anchor{e9}@anchor{topics/compatibility doc}@anchor{ea} 8282@section ABI and API compatibility 8283 8284 8285The libgccjit developers strive for ABI and API backward-compatibility: 8286programs built against libgccjit.so stand a good chance of running 8287without recompilation against newer versions of libgccjit.so, and 8288ought to recompile without modification against newer versions of 8289libgccjit.h. 8290 8291@cartouche 8292@quotation Note 8293The libgccjit++.h C++ API is more experimental, and less 8294locked-down at this time. 8295@end quotation 8296@end cartouche 8297 8298API compatibility is achieved by extending the API rather than changing 8299it. For ABI compatiblity, we avoid bumping the SONAME, and instead use 8300symbol versioning to tag each symbol, so that a binary linked against 8301libgccjit.so is tagged according to the symbols that it uses. 8302 8303For example, @pxref{72,,gcc_jit_context_add_command_line_option()} was added in 8304@code{LIBGCCJIT_ABI_1}. If a client program uses it, this can be detected 8305from metadata by using @code{objdump}: 8306 8307@example 8308$ objdump -p testsuite/jit/test-extra-options.c.exe | tail -n 8 8309 8310Version References: 8311 required from libgccjit.so.0: 8312 0x00824161 0x00 04 LIBGCCJIT_ABI_1 8313 0x00824160 0x00 03 LIBGCCJIT_ABI_0 8314 required from libc.so.6: 8315@end example 8316 8317@noindent 8318 8319You can see the symbol tags provided by libgccjit.so using @code{objdump}: 8320 8321@example 8322$ objdump -p libgccjit.so | less 8323[...snip...] 8324Version definitions: 83251 0x01 0x0ff81f20 libgccjit.so.0 83262 0x00 0x00824160 LIBGCCJIT_ABI_0 83273 0x00 0x00824161 LIBGCCJIT_ABI_1 8328 LIBGCCJIT_ABI_0 8329[...snip...] 8330@end example 8331 8332@noindent 8333 8334@menu 8335* ABI symbol tags:: 8336 8337ABI symbol tags 8338 8339* LIBGCCJIT_ABI_0:: 8340* LIBGCCJIT_ABI_1:: 8341* LIBGCCJIT_ABI_2:: 8342* LIBGCCJIT_ABI_3:: 8343* LIBGCCJIT_ABI_4:: 8344* LIBGCCJIT_ABI_5:: 8345 8346@end menu 8347 8348 8349@node ABI symbol tags,,,ABI and API compatibility 8350@anchor{topics/compatibility abi-symbol-tags}@anchor{eb} 8351@subsection ABI symbol tags 8352 8353 8354The initial release of libgccjit (in gcc 5.1) did not use symbol versioning. 8355 8356Newer releases use the following tags. 8357 8358@menu 8359* LIBGCCJIT_ABI_0:: 8360* LIBGCCJIT_ABI_1:: 8361* LIBGCCJIT_ABI_2:: 8362* LIBGCCJIT_ABI_3:: 8363* LIBGCCJIT_ABI_4:: 8364* LIBGCCJIT_ABI_5:: 8365 8366@end menu 8367 8368@node LIBGCCJIT_ABI_0,LIBGCCJIT_ABI_1,,ABI symbol tags 8369@anchor{topics/compatibility libgccjit-abi-0}@anchor{ec}@anchor{topics/compatibility id1}@anchor{ed} 8370@subsubsection @code{LIBGCCJIT_ABI_0} 8371 8372 8373All entrypoints in the initial release of libgccjit are tagged with 8374@code{LIBGCCJIT_ABI_0}, to signify the transition to symbol versioning. 8375 8376Binaries built against older copies of @code{libgccjit.so} should 8377continue to work, with this being handled transparently by the linker 8378(see this post@footnote{https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html}) 8379 8380@node LIBGCCJIT_ABI_1,LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_0,ABI symbol tags 8381@anchor{topics/compatibility libgccjit-abi-1}@anchor{73}@anchor{topics/compatibility id2}@anchor{ee} 8382@subsubsection @code{LIBGCCJIT_ABI_1} 8383 8384 8385@code{LIBGCCJIT_ABI_1} covers the addition of 8386@pxref{72,,gcc_jit_context_add_command_line_option()} 8387 8388@node LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_1,ABI symbol tags 8389@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c}@anchor{topics/compatibility id3}@anchor{ef} 8390@subsubsection @code{LIBGCCJIT_ABI_2} 8391 8392 8393@code{LIBGCCJIT_ABI_2} covers the addition of 8394@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()} 8395 8396@node LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_2,ABI symbol tags 8397@anchor{topics/compatibility libgccjit-abi-3}@anchor{db}@anchor{topics/compatibility id4}@anchor{f0} 8398@subsubsection @code{LIBGCCJIT_ABI_3} 8399 8400 8401@code{LIBGCCJIT_ABI_3} covers the addition of switch statements via API 8402entrypoints: 8403 8404@quotation 8405 8406 8407@itemize * 8408 8409@item 8410@pxref{d8,,gcc_jit_block_end_with_switch()} 8411 8412@item 8413@pxref{d9,,gcc_jit_case_as_object()} 8414 8415@item 8416@pxref{da,,gcc_jit_context_new_case()} 8417@end itemize 8418@end quotation 8419 8420@node LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_3,ABI symbol tags 8421@anchor{topics/compatibility id5}@anchor{f1}@anchor{topics/compatibility libgccjit-abi-4}@anchor{f2} 8422@subsubsection @code{LIBGCCJIT_ABI_4} 8423 8424 8425@code{LIBGCCJIT_ABI_4} covers the addition of timers via API 8426entrypoints: 8427 8428@quotation 8429 8430 8431@itemize * 8432 8433@item 8434@pxref{f3,,gcc_jit_context_get_timer()} 8435 8436@item 8437@pxref{f4,,gcc_jit_context_set_timer()} 8438 8439@item 8440@pxref{f5,,gcc_jit_timer_new()} 8441 8442@item 8443@pxref{f6,,gcc_jit_timer_release()} 8444 8445@item 8446@pxref{f7,,gcc_jit_timer_push()} 8447 8448@item 8449@pxref{f8,,gcc_jit_timer_pop()} 8450 8451@item 8452@pxref{f9,,gcc_jit_timer_print()} 8453@end itemize 8454@end quotation 8455 8456@node LIBGCCJIT_ABI_5,,LIBGCCJIT_ABI_4,ABI symbol tags 8457@anchor{topics/compatibility id6}@anchor{fa}@anchor{topics/compatibility libgccjit-abi-5}@anchor{6e} 8458@subsubsection @code{LIBGCCJIT_ABI_5} 8459 8460 8461@code{LIBGCCJIT_ABI_5} covers the addition of 8462@pxref{6d,,gcc_jit_context_set_bool_use_external_driver()} 8463 8464@c Copyright (C) 2015-2017 Free Software Foundation, Inc. 8465@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8466@c 8467@c This is free software: you can redistribute it and/or modify it 8468@c under the terms of the GNU General Public License as published by 8469@c the Free Software Foundation, either version 3 of the License, or 8470@c (at your option) any later version. 8471@c 8472@c This program is distributed in the hope that it will be useful, but 8473@c WITHOUT ANY WARRANTY; without even the implied warranty of 8474@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8475@c General Public License for more details. 8476@c 8477@c You should have received a copy of the GNU General Public License 8478@c along with this program. If not, see 8479@c <http://www.gnu.org/licenses/>. 8480 8481@node Performance,,ABI and API compatibility,Topic Reference 8482@anchor{topics/performance performance}@anchor{fb}@anchor{topics/performance doc}@anchor{fc} 8483@section Performance 8484 8485 8486@menu 8487* The timing API:: 8488 8489@end menu 8490 8491@node The timing API,,,Performance 8492@anchor{topics/performance the-timing-api}@anchor{fd} 8493@subsection The timing API 8494 8495 8496As of GCC 6, libgccjit exposes a timing API, for printing reports on 8497how long was spent in different parts of code. 8498 8499You can create a @pxref{fe,,gcc_jit_timer} instance, which will 8500measure time spent since its creation. The timer maintains a stack 8501of "timer items": as control flow moves through your code, you can push 8502and pop named items relating to your code onto the stack, and the timer 8503will account the time spent accordingly. 8504 8505You can also asssociate a timer with a @pxref{8,,gcc_jit_context}, in 8506which case the time spent inside compilation will be subdivided. 8507 8508For example, the following code uses a timer, recording client items 8509"create_code", "compile", and "running code": 8510 8511@example 8512/* Create a timer. */ 8513gcc_jit_timer *timer = gcc_jit_timer_new (); 8514if (!timer) 8515 @{ 8516 error ("gcc_jit_timer_new failed"); 8517 return -1; 8518 @} 8519 8520/* Let's repeatedly compile and run some code, accumulating it 8521 all into the timer. */ 8522for (int i = 0; i < num_iterations; i++) 8523 @{ 8524 /* Create a context and associate it with the timer. */ 8525 gcc_jit_context *ctxt = gcc_jit_context_acquire (); 8526 if (!ctxt) 8527 @{ 8528 error ("gcc_jit_context_acquire failed"); 8529 return -1; 8530 @} 8531 gcc_jit_context_set_timer (ctxt, timer); 8532 8533 /* Populate the context, timing it as client item "create_code". */ 8534 gcc_jit_timer_push (timer, "create_code"); 8535 create_code (ctxt); 8536 gcc_jit_timer_pop (timer, "create_code"); 8537 8538 /* Compile the context, timing it as client item "compile". */ 8539 gcc_jit_timer_push (timer, "compile"); 8540 result = gcc_jit_context_compile (ctxt); 8541 gcc_jit_timer_pop (timer, "compile"); 8542 8543 /* Run the generated code, timing it as client item "running code". */ 8544 gcc_jit_timer_push (timer, "running code"); 8545 run_the_code (ctxt, result); 8546 gcc_jit_timer_pop (timer, "running code"); 8547 8548 /* Clean up. */ 8549 gcc_jit_context_release (ctxt); 8550 gcc_jit_result_release (result); 8551@} 8552 8553/* Print the accumulated timings. */ 8554gcc_jit_timer_print (timer, stderr); 8555gcc_jit_timer_release (timer); 8556@end example 8557 8558@noindent 8559 8560giving output like this, showing the internal GCC items at the top, then 8561client items, then the total: 8562 8563@example 8564Execution times (seconds) 8565GCC items: 8566 phase setup : 0.29 (14%) usr 0.00 ( 0%) sys 0.32 ( 5%) wall 10661 kB (50%) ggc 8567 phase parsing : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 653 kB ( 3%) ggc 8568 phase finalize : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8569 dump files : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc 8570 callgraph construction : 0.02 ( 1%) usr 0.01 ( 6%) sys 0.01 ( 0%) wall 242 kB ( 1%) ggc 8571 callgraph optimization : 0.03 ( 2%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 142 kB ( 1%) ggc 8572 trivially dead code : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8573 df scan insns : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 9 kB ( 0%) ggc 8574 df live regs : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc 8575 inline parameters : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 82 kB ( 0%) ggc 8576 tree CFG cleanup : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8577 tree PHI insertion : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 64 kB ( 0%) ggc 8578 tree SSA other : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 18 kB ( 0%) ggc 8579 expand : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 398 kB ( 2%) ggc 8580 jump : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8581 loop init : 0.01 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 67 kB ( 0%) ggc 8582 integrated RA : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 2468 kB (12%) ggc 8583 thread pro- & epilogue : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 162 kB ( 1%) ggc 8584 final : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 216 kB ( 1%) ggc 8585 rest of compilation : 1.37 (69%) usr 0.00 ( 0%) sys 1.13 (18%) wall 1391 kB ( 6%) ggc 8586 assemble JIT code : 0.01 ( 1%) usr 0.00 ( 0%) sys 4.04 (66%) wall 0 kB ( 0%) ggc 8587 load JIT result : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8588 JIT client code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8589Client items: 8590 create_code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8591 compile : 0.36 (18%) usr 0.15 (83%) sys 0.86 (14%) wall 14939 kB (70%) ggc 8592 running code : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8593 TOTAL : 2.00 0.18 6.12 21444 kB 8594@end example 8595 8596@noindent 8597 8598The exact format is intended to be human-readable, and is subject to change. 8599 8600@geindex LIBGCCJIT_HAVE_TIMING_API (C macro) 8601@anchor{topics/performance LIBGCCJIT_HAVE_TIMING_API}@anchor{ff} 8602@deffn {C Macro} LIBGCCJIT_HAVE_TIMING_API 8603 8604The timer API was added to libgccjit in GCC 6. 8605This macro is only defined in versions of libgccjit.h which have the 8606timer API, and so can be used to guard code that may need to compile 8607against earlier releases: 8608 8609@example 8610#ifdef LIBGCCJIT_HAVE_TIMING_API 8611gcc_jit_timer *t = gcc_jit_timer_new (); 8612gcc_jit_context_set_timer (ctxt, t); 8613#endif 8614@end example 8615 8616@noindent 8617@end deffn 8618 8619@geindex gcc_jit_timer (C type) 8620@anchor{topics/performance gcc_jit_timer}@anchor{fe} 8621@deffn {C Type} gcc_jit_timer 8622@end deffn 8623 8624@geindex gcc_jit_timer_new (C function) 8625@anchor{topics/performance gcc_jit_timer_new}@anchor{f5} 8626@deffn {C Function} gcc_jit_timer * gcc_jit_timer_new (void) 8627 8628Create a @pxref{fe,,gcc_jit_timer} instance, and start timing: 8629 8630@example 8631gcc_jit_timer *t = gcc_jit_timer_new (); 8632@end example 8633 8634@noindent 8635 8636This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test 8637for its presence using 8638 8639@example 8640#ifdef LIBGCCJIT_HAVE_TIMING_API 8641@end example 8642 8643@noindent 8644@end deffn 8645 8646@geindex gcc_jit_timer_release (C function) 8647@anchor{topics/performance gcc_jit_timer_release}@anchor{f6} 8648@deffn {C Function} void gcc_jit_timer_release (gcc_jit_timer@w{ }*timer) 8649 8650Release a @pxref{fe,,gcc_jit_timer} instance: 8651 8652@example 8653gcc_jit_timer_release (t); 8654@end example 8655 8656@noindent 8657 8658This should be called exactly once on a timer. 8659 8660This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test 8661for its presence using 8662 8663@example 8664#ifdef LIBGCCJIT_HAVE_TIMING_API 8665@end example 8666 8667@noindent 8668@end deffn 8669 8670@geindex gcc_jit_context_set_timer (C function) 8671@anchor{topics/performance gcc_jit_context_set_timer}@anchor{f4} 8672@deffn {C Function} void gcc_jit_context_set_timer (gcc_jit_context@w{ }*ctxt, gcc_jit_timer@w{ }*timer) 8673 8674Associate a @pxref{fe,,gcc_jit_timer} instance with a context: 8675 8676@example 8677gcc_jit_context_set_timer (ctxt, t); 8678@end example 8679 8680@noindent 8681 8682A timer instance can be shared between multiple 8683@pxref{8,,gcc_jit_context} instances. 8684 8685Timers have no locking, so if you have a multithreaded program, you 8686must provide your own locks if more than one thread could be working 8687with the same timer via timer-associated contexts. 8688 8689This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test 8690for its presence using 8691 8692@example 8693#ifdef LIBGCCJIT_HAVE_TIMING_API 8694@end example 8695 8696@noindent 8697@end deffn 8698 8699@geindex gcc_jit_context_get_timer (C function) 8700@anchor{topics/performance gcc_jit_context_get_timer}@anchor{f3} 8701@deffn {C Function} gcc_jit_timer *gcc_jit_context_get_timer (gcc_jit_context@w{ }*ctxt) 8702 8703Get the timer associated with a context (if any). 8704 8705This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test 8706for its presence using 8707 8708@example 8709#ifdef LIBGCCJIT_HAVE_TIMING_API 8710@end example 8711 8712@noindent 8713@end deffn 8714 8715@geindex gcc_jit_timer_push (C function) 8716@anchor{topics/performance gcc_jit_timer_push}@anchor{f7} 8717@deffn {C Function} void gcc_jit_timer_push (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name) 8718 8719Push the given item onto the timer's stack: 8720 8721@example 8722gcc_jit_timer_push (t, "running code"); 8723run_the_code (ctxt, result); 8724gcc_jit_timer_pop (t, "running code"); 8725@end example 8726 8727@noindent 8728 8729This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test 8730for its presence using 8731 8732@example 8733#ifdef LIBGCCJIT_HAVE_TIMING_API 8734@end example 8735 8736@noindent 8737@end deffn 8738 8739@geindex gcc_jit_timer_pop (C function) 8740@anchor{topics/performance gcc_jit_timer_pop}@anchor{f8} 8741@deffn {C Function} void gcc_jit_timer_pop (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name) 8742 8743Pop the top item from the timer's stack. 8744 8745If "item_name" is provided, it must match that of the top item. 8746Alternatively, @code{NULL} can be passed in, to suppress checking. 8747 8748This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test 8749for its presence using 8750 8751@example 8752#ifdef LIBGCCJIT_HAVE_TIMING_API 8753@end example 8754 8755@noindent 8756@end deffn 8757 8758@geindex gcc_jit_timer_print (C function) 8759@anchor{topics/performance gcc_jit_timer_print}@anchor{f9} 8760@deffn {C Function} void gcc_jit_timer_print (gcc_jit_timer@w{ }*timer, FILE@w{ }*f_out) 8761 8762Print timing information to the given stream about activity since 8763the timer was started. 8764 8765This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test 8766for its presence using 8767 8768@example 8769#ifdef LIBGCCJIT_HAVE_TIMING_API 8770@end example 8771 8772@noindent 8773@end deffn 8774 8775@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 8776@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8777@c 8778@c This is free software: you can redistribute it and/or modify it 8779@c under the terms of the GNU General Public License as published by 8780@c the Free Software Foundation, either version 3 of the License, or 8781@c (at your option) any later version. 8782@c 8783@c This program is distributed in the hope that it will be useful, but 8784@c WITHOUT ANY WARRANTY; without even the implied warranty of 8785@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8786@c General Public License for more details. 8787@c 8788@c You should have received a copy of the GNU General Public License 8789@c along with this program. If not, see 8790@c <http://www.gnu.org/licenses/>. 8791 8792@node C++ bindings for libgccjit,Internals,Topic Reference,Top 8793@anchor{cp/index c-bindings-for-libgccjit}@anchor{100}@anchor{cp/index doc}@anchor{101} 8794@chapter C++ bindings for libgccjit 8795 8796 8797This document describes the C++ bindings to 8798libgccjit@footnote{http://gcc.gnu.org/wiki/JIT}, an API for embedding GCC 8799inside programs and libraries. 8800 8801The C++ bindings consist of a single header file @code{libgccjit++.h}. 8802 8803This is a collection of "thin" wrapper classes around the C API. 8804Everything is an inline function, implemented in terms of the C API, 8805so there is nothing extra to link against. 8806 8807Note that libgccjit is currently of "Alpha" quality; 8808the APIs are not yet set in stone, and they shouldn't be used in 8809production yet. 8810 8811Contents: 8812 8813@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 8814@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8815@c 8816@c This is free software: you can redistribute it and/or modify it 8817@c under the terms of the GNU General Public License as published by 8818@c the Free Software Foundation, either version 3 of the License, or 8819@c (at your option) any later version. 8820@c 8821@c This program is distributed in the hope that it will be useful, but 8822@c WITHOUT ANY WARRANTY; without even the implied warranty of 8823@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8824@c General Public License for more details. 8825@c 8826@c You should have received a copy of the GNU General Public License 8827@c along with this program. If not, see 8828@c <http://www.gnu.org/licenses/>. 8829 8830@menu 8831* Tutorial: Tutorial<2>. 8832* Topic Reference: Topic Reference<2>. 8833 8834Tutorial 8835 8836* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 8837* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 8838* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 8839* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 8840 8841Tutorial part 2: Creating a trivial machine code function 8842 8843* Options: Options<3>. 8844* Full example: Full example<3>. 8845 8846Tutorial part 3: Loops and variables 8847 8848* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 8849* Control flow: Control flow<2>. 8850* Visualizing the control flow graph: Visualizing the control flow graph<2>. 8851* Full example: Full example<4>. 8852 8853Tutorial part 4: Adding JIT-compilation to a toy interpreter 8854 8855* Our toy interpreter: Our toy interpreter<2>. 8856* Compiling to machine code: Compiling to machine code<2>. 8857* Setting things up: Setting things up<2>. 8858* Populating the function: Populating the function<2>. 8859* Verifying the control flow graph: Verifying the control flow graph<2>. 8860* Compiling the context: Compiling the context<2>. 8861* Single-stepping through the generated code: Single-stepping through the generated code<2>. 8862* Examining the generated code: Examining the generated code<2>. 8863* Putting it all together: Putting it all together<2>. 8864* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 8865 8866Behind the curtain: How does our code get optimized? 8867 8868* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 8869* Elimination of tail recursion: Elimination of tail recursion<2>. 8870 8871Topic Reference 8872 8873* Compilation contexts: Compilation contexts<2>. 8874* Objects: Objects<2>. 8875* Types: Types<2>. 8876* Expressions: Expressions<2>. 8877* Creating and using functions: Creating and using functions<2>. 8878* Source Locations: Source Locations<2>. 8879* Compiling a context: Compiling a context<2>. 8880 8881Compilation contexts 8882 8883* Lifetime-management: Lifetime-management<2>. 8884* Thread-safety: Thread-safety<2>. 8885* Error-handling: Error-handling<3>. 8886* Debugging: Debugging<2>. 8887* Options: Options<4>. 8888 8889Options 8890 8891* String Options: String Options<2>. 8892* Boolean options: Boolean options<2>. 8893* Integer options: Integer options<2>. 8894* Additional command-line options: Additional command-line options<2>. 8895 8896Types 8897 8898* Standard types: Standard types<2>. 8899* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 8900* Structures and unions: Structures and unions<2>. 8901 8902Expressions 8903 8904* Rvalues: Rvalues<2>. 8905* Lvalues: Lvalues<2>. 8906* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 8907 8908Rvalues 8909 8910* Simple expressions: Simple expressions<2>. 8911* Unary Operations: Unary Operations<2>. 8912* Binary Operations: Binary Operations<2>. 8913* Comparisons: Comparisons<2>. 8914* Function calls: Function calls<2>. 8915* Type-coercion: Type-coercion<2>. 8916 8917Lvalues 8918 8919* Global variables: Global variables<2>. 8920 8921Creating and using functions 8922 8923* Params: Params<2>. 8924* Functions: Functions<2>. 8925* Blocks: Blocks<2>. 8926* Statements: Statements<2>. 8927 8928Source Locations 8929 8930* Faking it: Faking it<2>. 8931 8932Compiling a context 8933 8934* In-memory compilation: In-memory compilation<2>. 8935* Ahead-of-time compilation: Ahead-of-time compilation<2>. 8936 8937@end menu 8938 8939 8940@node Tutorial<2>,Topic Reference<2>,,C++ bindings for libgccjit 8941@anchor{cp/intro/index doc}@anchor{102}@anchor{cp/intro/index tutorial}@anchor{103} 8942@section Tutorial 8943 8944 8945@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 8946@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8947@c 8948@c This is free software: you can redistribute it and/or modify it 8949@c under the terms of the GNU General Public License as published by 8950@c the Free Software Foundation, either version 3 of the License, or 8951@c (at your option) any later version. 8952@c 8953@c This program is distributed in the hope that it will be useful, but 8954@c WITHOUT ANY WARRANTY; without even the implied warranty of 8955@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8956@c General Public License for more details. 8957@c 8958@c You should have received a copy of the GNU General Public License 8959@c along with this program. If not, see 8960@c <http://www.gnu.org/licenses/>. 8961 8962@menu 8963* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 8964* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 8965* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 8966* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 8967 8968@end menu 8969 8970@node Tutorial part 1 "Hello world"<2>,Tutorial part 2 Creating a trivial machine code function<2>,,Tutorial<2> 8971@anchor{cp/intro/tutorial01 doc}@anchor{104}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{105} 8972@subsection Tutorial part 1: "Hello world" 8973 8974 8975Before we look at the details of the API, let's look at building and 8976running programs that use the library. 8977 8978Here's a toy "hello world" program that uses the library's C++ API to 8979synthesize a call to @cite{printf} and uses it to write a message to stdout. 8980 8981Don't worry about the content of the program for now; we'll cover 8982the details in later parts of this tutorial. 8983 8984@quotation 8985 8986@example 8987/* Smoketest example for libgccjit.so C++ API 8988 Copyright (C) 2014-2017 Free Software Foundation, Inc. 8989 8990This file is part of GCC. 8991 8992GCC is free software; you can redistribute it and/or modify it 8993under the terms of the GNU General Public License as published by 8994the Free Software Foundation; either version 3, or (at your option) 8995any later version. 8996 8997GCC is distributed in the hope that it will be useful, but 8998WITHOUT ANY WARRANTY; without even the implied warranty of 8999MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9000General Public License for more details. 9001 9002You should have received a copy of the GNU General Public License 9003along with GCC; see the file COPYING3. If not see 9004<http://www.gnu.org/licenses/>. */ 9005 9006#include <libgccjit++.h> 9007 9008#include <stdlib.h> 9009#include <stdio.h> 9010 9011static void 9012create_code (gccjit::context ctxt) 9013@{ 9014 /* Let's try to inject the equivalent of this C code: 9015 void 9016 greet (const char *name) 9017 @{ 9018 printf ("hello %s\n", name); 9019 @} 9020 */ 9021 gccjit::type void_type = ctxt.get_type (GCC_JIT_TYPE_VOID); 9022 gccjit::type const_char_ptr_type = 9023 ctxt.get_type (GCC_JIT_TYPE_CONST_CHAR_PTR); 9024 gccjit::param param_name = 9025 ctxt.new_param (const_char_ptr_type, "name"); 9026 std::vector<gccjit::param> func_params; 9027 func_params.push_back (param_name); 9028 gccjit::function func = 9029 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9030 void_type, 9031 "greet", 9032 func_params, 0); 9033 9034 gccjit::param param_format = 9035 ctxt.new_param (const_char_ptr_type, "format"); 9036 std::vector<gccjit::param> printf_params; 9037 printf_params.push_back (param_format); 9038 gccjit::function printf_func = 9039 ctxt.new_function (GCC_JIT_FUNCTION_IMPORTED, 9040 ctxt.get_type (GCC_JIT_TYPE_INT), 9041 "printf", 9042 printf_params, 1); 9043 9044 gccjit::block block = func.new_block (); 9045 block.add_eval (ctxt.new_call (printf_func, 9046 ctxt.new_rvalue ("hello %s\n"), 9047 param_name)); 9048 block.end_with_return (); 9049@} 9050 9051int 9052main (int argc, char **argv) 9053@{ 9054 gccjit::context ctxt; 9055 gcc_jit_result *result; 9056 9057 /* Get a "context" object for working with the library. */ 9058 ctxt = gccjit::context::acquire (); 9059 9060 /* Set some options on the context. 9061 Turn this on to see the code being generated, in assembler form. */ 9062 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 0); 9063 9064 /* Populate the context. */ 9065 create_code (ctxt); 9066 9067 /* Compile the code. */ 9068 result = ctxt.compile (); 9069 if (!result) 9070 @{ 9071 fprintf (stderr, "NULL result"); 9072 exit (1); 9073 @} 9074 9075 ctxt.release (); 9076 9077 /* Extract the generated code from "result". */ 9078 typedef void (*fn_type) (const char *); 9079 fn_type greet = 9080 (fn_type)gcc_jit_result_get_code (result, "greet"); 9081 if (!greet) 9082 @{ 9083 fprintf (stderr, "NULL greet"); 9084 exit (1); 9085 @} 9086 9087 /* Now call the generated function: */ 9088 greet ("world"); 9089 fflush (stdout); 9090 9091 gcc_jit_result_release (result); 9092 return 0; 9093@} 9094 9095@end example 9096 9097@noindent 9098@end quotation 9099 9100Copy the above to @cite{tut01-hello-world.cc}. 9101 9102Assuming you have the jit library installed, build the test program 9103using: 9104 9105@example 9106$ gcc \ 9107 tut01-hello-world.cc \ 9108 -o tut01-hello-world \ 9109 -lgccjit 9110@end example 9111 9112@noindent 9113 9114You should then be able to run the built program: 9115 9116@example 9117$ ./tut01-hello-world 9118hello world 9119@end example 9120 9121@noindent 9122 9123@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 9124@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9125@c 9126@c This is free software: you can redistribute it and/or modify it 9127@c under the terms of the GNU General Public License as published by 9128@c the Free Software Foundation, either version 3 of the License, or 9129@c (at your option) any later version. 9130@c 9131@c This program is distributed in the hope that it will be useful, but 9132@c WITHOUT ANY WARRANTY; without even the implied warranty of 9133@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9134@c General Public License for more details. 9135@c 9136@c You should have received a copy of the GNU General Public License 9137@c along with this program. If not, see 9138@c <http://www.gnu.org/licenses/>. 9139 9140@node Tutorial part 2 Creating a trivial machine code function<2>,Tutorial part 3 Loops and variables<2>,Tutorial part 1 "Hello world"<2>,Tutorial<2> 9141@anchor{cp/intro/tutorial02 doc}@anchor{106}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{107} 9142@subsection Tutorial part 2: Creating a trivial machine code function 9143 9144 9145Consider this C function: 9146 9147@example 9148int square (int i) 9149@{ 9150 return i * i; 9151@} 9152@end example 9153 9154@noindent 9155 9156How can we construct this at run-time using libgccjit's C++ API? 9157 9158First we need to include the relevant header: 9159 9160@example 9161#include <libgccjit++.h> 9162@end example 9163 9164@noindent 9165 9166All state associated with compilation is associated with a 9167@code{gccjit::context}, which is a thin C++ wrapper around the C API's 9168@pxref{8,,gcc_jit_context *}. 9169 9170Create one using @pxref{108,,gccjit;;context;;acquire()}: 9171 9172@example 9173gccjit::context ctxt; 9174ctxt = gccjit::context::acquire (); 9175@end example 9176 9177@noindent 9178 9179The JIT library has a system of types. It is statically-typed: every 9180expression is of a specific type, fixed at compile-time. In our example, 9181all of the expressions are of the C @cite{int} type, so let's obtain this from 9182the context, as a @code{gccjit::type}, using 9183@pxref{109,,gccjit;;context;;get_type()}: 9184 9185@example 9186gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 9187@end example 9188 9189@noindent 9190 9191@code{gccjit::type} is an example of a "contextual" object: every 9192entity in the API is associated with a @code{gccjit::context}. 9193 9194Memory management is easy: all such "contextual" objects are automatically 9195cleaned up for you when the context is released, using 9196@pxref{10a,,gccjit;;context;;release()}: 9197 9198@example 9199ctxt.release (); 9200@end example 9201 9202@noindent 9203 9204so you don't need to manually track and cleanup all objects, just the 9205contexts. 9206 9207All of the C++ classes in the API are thin wrappers around pointers to 9208types in the C API. 9209 9210The C++ class hierarchy within the @code{gccjit} namespace looks like this: 9211 9212@example 9213+- object 9214 +- location 9215 +- type 9216 +- struct 9217 +- field 9218 +- function 9219 +- block 9220 +- rvalue 9221 +- lvalue 9222 +- param 9223@end example 9224 9225@noindent 9226 9227One thing you can do with a @code{gccjit::object} is 9228to ask it for a human-readable description as a @code{std::string}, using 9229@pxref{10b,,gccjit;;object;;get_debug_string()}: 9230 9231@example 9232printf ("obj: %s\n", obj.get_debug_string ().c_str ()); 9233@end example 9234 9235@noindent 9236 9237giving this text on stdout: 9238 9239@example 9240obj: int 9241@end example 9242 9243@noindent 9244 9245This is invaluable when debugging. 9246 9247Let's create the function. To do so, we first need to construct 9248its single parameter, specifying its type and giving it a name, 9249using @pxref{10c,,gccjit;;context;;new_param()}: 9250 9251@example 9252gccjit::param param_i = ctxt.new_param (int_type, "i"); 9253@end example 9254 9255@noindent 9256 9257and we can then make a vector of all of the params of the function, 9258in this case just one: 9259 9260@example 9261std::vector<gccjit::param> params; 9262params.push_back (param_i); 9263@end example 9264 9265@noindent 9266 9267Now we can create the function, using 9268@code{gccjit::context::new_function()}: 9269 9270@example 9271gccjit::function func = 9272 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9273 int_type, 9274 "square", 9275 params, 9276 0); 9277@end example 9278 9279@noindent 9280 9281To define the code within the function, we must create basic blocks 9282containing statements. 9283 9284Every basic block contains a list of statements, eventually terminated 9285by a statement that either returns, or jumps to another basic block. 9286 9287Our function has no control-flow, so we just need one basic block: 9288 9289@example 9290gccjit::block block = func.new_block (); 9291@end example 9292 9293@noindent 9294 9295Our basic block is relatively simple: it immediately terminates by 9296returning the value of an expression. 9297 9298We can build the expression using @pxref{10d,,gccjit;;context;;new_binary_op()}: 9299 9300@example 9301gccjit::rvalue expr = 9302 ctxt.new_binary_op ( 9303 GCC_JIT_BINARY_OP_MULT, int_type, 9304 param_i, param_i); 9305@end example 9306 9307@noindent 9308 9309A @code{gccjit::rvalue} is another example of a 9310@code{gccjit::object} subclass. As before, we can print it with 9311@pxref{10b,,gccjit;;object;;get_debug_string()}. 9312 9313@example 9314printf ("expr: %s\n", expr.get_debug_string ().c_str ()); 9315@end example 9316 9317@noindent 9318 9319giving this output: 9320 9321@example 9322expr: i * i 9323@end example 9324 9325@noindent 9326 9327Note that @code{gccjit::rvalue} provides numerous overloaded operators 9328which can be used to dramatically reduce the amount of typing needed. 9329We can build the above binary operation more directly with this one-liner: 9330 9331@example 9332gccjit::rvalue expr = param_i * param_i; 9333@end example 9334 9335@noindent 9336 9337Creating the expression in itself doesn't do anything; we have to add 9338this expression to a statement within the block. In this case, we use it 9339to build a return statement, which terminates the basic block: 9340 9341@example 9342block.end_with_return (expr); 9343@end example 9344 9345@noindent 9346 9347OK, we've populated the context. We can now compile it using 9348@pxref{10e,,gccjit;;context;;compile()}: 9349 9350@example 9351gcc_jit_result *result; 9352result = ctxt.compile (); 9353@end example 9354 9355@noindent 9356 9357and get a @pxref{16,,gcc_jit_result *}. 9358 9359We can now use @pxref{17,,gcc_jit_result_get_code()} to look up a specific 9360machine code routine within the result, in this case, the function we 9361created above. 9362 9363@example 9364void *fn_ptr = gcc_jit_result_get_code (result, "square"); 9365if (!fn_ptr) 9366 @{ 9367 fprintf (stderr, "NULL fn_ptr"); 9368 goto error; 9369 @} 9370@end example 9371 9372@noindent 9373 9374We can now cast the pointer to an appropriate function pointer type, and 9375then call it: 9376 9377@example 9378typedef int (*fn_type) (int); 9379fn_type square = (fn_type)fn_ptr; 9380printf ("result: %d", square (5)); 9381@end example 9382 9383@noindent 9384 9385@example 9386result: 25 9387@end example 9388 9389@noindent 9390 9391@menu 9392* Options: Options<3>. 9393* Full example: Full example<3>. 9394 9395@end menu 9396 9397@node Options<3>,Full example<3>,,Tutorial part 2 Creating a trivial machine code function<2> 9398@anchor{cp/intro/tutorial02 options}@anchor{10f} 9399@subsubsection Options 9400 9401 9402To get more information on what's going on, you can set debugging flags 9403on the context using @pxref{110,,gccjit;;context;;set_bool_option()}. 9404 9405@c (I'm deliberately not mentioning 9406@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think 9407@c it's probably more of use to implementors than to users) 9408 9409Setting @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a 9410C-like representation to stderr when you compile (GCC's "GIMPLE" 9411representation): 9412 9413@example 9414ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); 9415result = ctxt.compile (); 9416@end example 9417 9418@noindent 9419 9420@example 9421square (signed int i) 9422@{ 9423 signed int D.260; 9424 9425 entry: 9426 D.260 = i * i; 9427 return D.260; 9428@} 9429@end example 9430 9431@noindent 9432 9433We can see the generated machine code in assembler form (on stderr) by 9434setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context 9435before compiling: 9436 9437@example 9438ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); 9439result = ctxt.compile (); 9440@end example 9441 9442@noindent 9443 9444@example 9445 .file "fake.c" 9446 .text 9447 .globl square 9448 .type square, @@function 9449square: 9450.LFB6: 9451 .cfi_startproc 9452 pushq %rbp 9453 .cfi_def_cfa_offset 16 9454 .cfi_offset 6, -16 9455 movq %rsp, %rbp 9456 .cfi_def_cfa_register 6 9457 movl %edi, -4(%rbp) 9458.L14: 9459 movl -4(%rbp), %eax 9460 imull -4(%rbp), %eax 9461 popq %rbp 9462 .cfi_def_cfa 7, 8 9463 ret 9464 .cfi_endproc 9465.LFE6: 9466 .size square, .-square 9467 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 9468 .section .note.GNU-stack,"",@@progbits 9469@end example 9470 9471@noindent 9472 9473By default, no optimizations are performed, the equivalent of GCC's 9474@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling 9475@pxref{111,,gccjit;;context;;set_int_option()} with 9476@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 9477 9478@example 9479ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); 9480@end example 9481 9482@noindent 9483 9484@example 9485 .file "fake.c" 9486 .text 9487 .p2align 4,,15 9488 .globl square 9489 .type square, @@function 9490square: 9491.LFB7: 9492 .cfi_startproc 9493.L16: 9494 movl %edi, %eax 9495 imull %edi, %eax 9496 ret 9497 .cfi_endproc 9498.LFE7: 9499 .size square, .-square 9500 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 9501 .section .note.GNU-stack,"",@@progbits 9502@end example 9503 9504@noindent 9505 9506Naturally this has only a small effect on such a trivial function. 9507 9508@node Full example<3>,,Options<3>,Tutorial part 2 Creating a trivial machine code function<2> 9509@anchor{cp/intro/tutorial02 full-example}@anchor{112} 9510@subsubsection Full example 9511 9512 9513Here's what the above looks like as a complete program: 9514 9515@quotation 9516 9517@example 9518/* Usage example for libgccjit.so's C++ API 9519 Copyright (C) 2014-2017 Free Software Foundation, Inc. 9520 9521This file is part of GCC. 9522 9523GCC is free software; you can redistribute it and/or modify it 9524under the terms of the GNU General Public License as published by 9525the Free Software Foundation; either version 3, or (at your option) 9526any later version. 9527 9528GCC is distributed in the hope that it will be useful, but 9529WITHOUT ANY WARRANTY; without even the implied warranty of 9530MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9531General Public License for more details. 9532 9533You should have received a copy of the GNU General Public License 9534along with GCC; see the file COPYING3. If not see 9535<http://www.gnu.org/licenses/>. */ 9536 9537#include <libgccjit++.h> 9538 9539#include <stdlib.h> 9540#include <stdio.h> 9541 9542void 9543create_code (gccjit::context ctxt) 9544@{ 9545 /* Let's try to inject the equivalent of this C code: 9546 9547 int square (int i) 9548 @{ 9549 return i * i; 9550 @} 9551 */ 9552 gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 9553 gccjit::param param_i = ctxt.new_param (int_type, "i"); 9554 std::vector<gccjit::param> params; 9555 params.push_back (param_i); 9556 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9557 int_type, 9558 "square", 9559 params, 0); 9560 9561 gccjit::block block = func.new_block (); 9562 9563 gccjit::rvalue expr = 9564 ctxt.new_binary_op (GCC_JIT_BINARY_OP_MULT, int_type, 9565 param_i, param_i); 9566 9567 block.end_with_return (expr); 9568@} 9569 9570int 9571main (int argc, char **argv) 9572@{ 9573 /* Get a "context" object for working with the library. */ 9574 gccjit::context ctxt = gccjit::context::acquire (); 9575 9576 /* Set some options on the context. 9577 Turn this on to see the code being generated, in assembler form. */ 9578 ctxt.set_bool_option ( 9579 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 9580 0); 9581 9582 /* Populate the context. */ 9583 create_code (ctxt); 9584 9585 /* Compile the code. */ 9586 gcc_jit_result *result = ctxt.compile (); 9587 9588 /* We're done with the context; we can release it: */ 9589 ctxt.release (); 9590 9591 if (!result) 9592 @{ 9593 fprintf (stderr, "NULL result"); 9594 return 1; 9595 @} 9596 9597 /* Extract the generated code from "result". */ 9598 void *fn_ptr = gcc_jit_result_get_code (result, "square"); 9599 if (!fn_ptr) 9600 @{ 9601 fprintf (stderr, "NULL fn_ptr"); 9602 gcc_jit_result_release (result); 9603 return 1; 9604 @} 9605 9606 typedef int (*fn_type) (int); 9607 fn_type square = (fn_type)fn_ptr; 9608 printf ("result: %d\n", square (5)); 9609 9610 gcc_jit_result_release (result); 9611 return 0; 9612@} 9613 9614@end example 9615 9616@noindent 9617@end quotation 9618 9619Building and running it: 9620 9621@example 9622$ gcc \ 9623 tut02-square.cc \ 9624 -o tut02-square \ 9625 -lgccjit 9626 9627# Run the built program: 9628$ ./tut02-square 9629result: 25 9630@end example 9631 9632@noindent 9633 9634@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 9635@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9636@c 9637@c This is free software: you can redistribute it and/or modify it 9638@c under the terms of the GNU General Public License as published by 9639@c the Free Software Foundation, either version 3 of the License, or 9640@c (at your option) any later version. 9641@c 9642@c This program is distributed in the hope that it will be useful, but 9643@c WITHOUT ANY WARRANTY; without even the implied warranty of 9644@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9645@c General Public License for more details. 9646@c 9647@c You should have received a copy of the GNU General Public License 9648@c along with this program. If not, see 9649@c <http://www.gnu.org/licenses/>. 9650 9651@node Tutorial part 3 Loops and variables<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,Tutorial part 2 Creating a trivial machine code function<2>,Tutorial<2> 9652@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{113}@anchor{cp/intro/tutorial03 doc}@anchor{114} 9653@subsection Tutorial part 3: Loops and variables 9654 9655 9656Consider this C function: 9657 9658@quotation 9659 9660@example 9661int loop_test (int n) 9662@{ 9663 int sum = 0; 9664 for (int i = 0; i < n; i++) 9665 sum += i * i; 9666 return sum; 9667@} 9668@end example 9669 9670@noindent 9671@end quotation 9672 9673This example demonstrates some more features of libgccjit, with local 9674variables and a loop. 9675 9676To break this down into libgccjit terms, it's usually easier to reword 9677the @cite{for} loop as a @cite{while} loop, giving: 9678 9679@quotation 9680 9681@example 9682int loop_test (int n) 9683@{ 9684 int sum = 0; 9685 int i = 0; 9686 while (i < n) 9687 @{ 9688 sum += i * i; 9689 i++; 9690 @} 9691 return sum; 9692@} 9693@end example 9694 9695@noindent 9696@end quotation 9697 9698Here's what the final control flow graph will look like: 9699 9700@quotation 9701 9702 9703@float Figure 9704 9705@image{sum-of-squares,,,image of a control flow graph,png} 9706 9707@end float 9708 9709@end quotation 9710 9711As before, we include the libgccjit++ header and make a 9712@code{gccjit::context}. 9713 9714@example 9715#include <libgccjit++.h> 9716 9717void test (void) 9718@{ 9719 gccjit::context ctxt; 9720 ctxt = gccjit::context::acquire (); 9721@end example 9722 9723@noindent 9724 9725The function works with the C @cite{int} type. 9726 9727In the previous tutorial we acquired this via 9728 9729@example 9730gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_INT); 9731@end example 9732 9733@noindent 9734 9735though we could equally well make it work on, say, @cite{double}: 9736 9737@example 9738gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_DOUBLE); 9739@end example 9740 9741@noindent 9742 9743For integer types we can use @code{gccjit::context::get_int_type} 9744to directly bind a specific type: 9745 9746@example 9747gccjit::type the_type = ctxt.get_int_type <int> (); 9748@end example 9749 9750@noindent 9751 9752Let's build the function: 9753 9754@example 9755gcc_jit_param n = ctxt.new_param (the_type, "n"); 9756std::vector<gccjit::param> params; 9757params.push_back (n); 9758gccjit::function func = 9759 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9760 return_type, 9761 "loop_test", 9762 params, 0); 9763@end example 9764 9765@noindent 9766 9767@menu 9768* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 9769* Control flow: Control flow<2>. 9770* Visualizing the control flow graph: Visualizing the control flow graph<2>. 9771* Full example: Full example<4>. 9772 9773@end menu 9774 9775@node Expressions lvalues and rvalues<2>,Control flow<2>,,Tutorial part 3 Loops and variables<2> 9776@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{115} 9777@subsubsection Expressions: lvalues and rvalues 9778 9779 9780The base class of expression is the @code{gccjit::rvalue}, 9781representing an expression that can be on the @emph{right}-hand side of 9782an assignment: a value that can be computed somehow, and assigned 9783@emph{to} a storage area (such as a variable). It has a specific 9784@code{gccjit::type}. 9785 9786Anothe important class is @code{gccjit::lvalue}. 9787A @code{gccjit::lvalue}. is something that can of the @emph{left}-hand 9788side of an assignment: a storage area (such as a variable). 9789 9790In other words, every assignment can be thought of as: 9791 9792@example 9793LVALUE = RVALUE; 9794@end example 9795 9796@noindent 9797 9798Note that @code{gccjit::lvalue} is a subclass of 9799@code{gccjit::rvalue}, where in an assignment of the form: 9800 9801@example 9802LVALUE_A = LVALUE_B; 9803@end example 9804 9805@noindent 9806 9807the @cite{LVALUE_B} implies reading the current value of that storage 9808area, assigning it into the @cite{LVALUE_A}. 9809 9810So far the only expressions we've seen are from the previous tutorial: 9811 9812 9813@enumerate 9814 9815@item 9816the multiplication @cite{i * i}: 9817@end enumerate 9818 9819@quotation 9820 9821@example 9822gccjit::rvalue expr = 9823 ctxt.new_binary_op ( 9824 GCC_JIT_BINARY_OP_MULT, int_type, 9825 param_i, param_i); 9826 9827/* Alternatively, using operator-overloading: */ 9828gccjit::rvalue expr = param_i * param_i; 9829@end example 9830 9831@noindent 9832 9833which is a @code{gccjit::rvalue}, and 9834@end quotation 9835 9836 9837@enumerate 2 9838 9839@item 9840the various function parameters: @cite{param_i} and @cite{param_n}, instances of 9841@code{gccjit::param}, which is a subclass of @code{gccjit::lvalue} 9842(and, in turn, of @code{gccjit::rvalue}): 9843we can both read from and write to function parameters within the 9844body of a function. 9845@end enumerate 9846 9847Our new example has a new kind of expression: we have two local 9848variables. We create them by calling 9849@pxref{116,,gccjit;;function;;new_local()}, supplying a type and a name: 9850 9851@example 9852/* Build locals: */ 9853gccjit::lvalue i = func.new_local (the_type, "i"); 9854gccjit::lvalue sum = func.new_local (the_type, "sum"); 9855@end example 9856 9857@noindent 9858 9859These are instances of @code{gccjit::lvalue} - they can be read from 9860and written to. 9861 9862Note that there is no precanned way to create @emph{and} initialize a variable 9863like in C: 9864 9865@example 9866int i = 0; 9867@end example 9868 9869@noindent 9870 9871Instead, having added the local to the function, we have to separately add 9872an assignment of @cite{0} to @cite{local_i} at the beginning of the function. 9873 9874@node Control flow<2>,Visualizing the control flow graph<2>,Expressions lvalues and rvalues<2>,Tutorial part 3 Loops and variables<2> 9875@anchor{cp/intro/tutorial03 control-flow}@anchor{117} 9876@subsubsection Control flow 9877 9878 9879This function has a loop, so we need to build some basic blocks to 9880handle the control flow. In this case, we need 4 blocks: 9881 9882 9883@enumerate 9884 9885@item 9886before the loop (initializing the locals) 9887 9888@item 9889the conditional at the top of the loop (comparing @cite{i < n}) 9890 9891@item 9892the body of the loop 9893 9894@item 9895after the loop terminates (@cite{return sum}) 9896@end enumerate 9897 9898so we create these as @code{gccjit::block} instances within the 9899@code{gccjit::function}: 9900 9901@example 9902gccjit::block b_initial = func.new_block ("initial"); 9903gccjit::block b_loop_cond = func.new_block ("loop_cond"); 9904gccjit::block b_loop_body = func.new_block ("loop_body"); 9905gccjit::block b_after_loop = func.new_block ("after_loop"); 9906@end example 9907 9908@noindent 9909 9910We now populate each block with statements. 9911 9912The entry block @cite{b_initial} consists of initializations followed by a jump 9913to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using 9914@pxref{118,,gccjit;;block;;add_assignment()} to add 9915an assignment statement, and using @pxref{119,,gccjit;;context;;zero()} to get 9916the constant value @cite{0} for the relevant type for the right-hand side of 9917the assignment: 9918 9919@example 9920/* sum = 0; */ 9921b_initial.add_assignment (sum, ctxt.zero (the_type)); 9922 9923/* i = 0; */ 9924b_initial.add_assignment (i, ctxt.zero (the_type)); 9925@end example 9926 9927@noindent 9928 9929We can then terminate the entry block by jumping to the conditional: 9930 9931@example 9932b_initial.end_with_jump (b_loop_cond); 9933@end example 9934 9935@noindent 9936 9937The conditional block is equivalent to the line @cite{while (i < n)} from our 9938C example. It contains a single statement: a conditional, which jumps to 9939one of two destination blocks depending on a boolean 9940@code{gccjit::rvalue}, in this case the comparison of @cite{i} and @cite{n}. 9941 9942We could build the comparison using @pxref{11a,,gccjit;;context;;new_comparison()}: 9943 9944@example 9945gccjit::rvalue guard = 9946 ctxt.new_comparison (GCC_JIT_COMPARISON_GE, 9947 i, n); 9948@end example 9949 9950@noindent 9951 9952and can then use this to add @cite{b_loop_cond}'s sole statement, via 9953@pxref{11b,,gccjit;;block;;end_with_conditional()}: 9954 9955@example 9956b_loop_cond.end_with_conditional (guard, 9957 b_after_loop, // on_true 9958 b_loop_body); // on_false 9959@end example 9960 9961@noindent 9962 9963However @code{gccjit::rvalue} has overloaded operators for this, so we 9964express the conditional as 9965 9966@example 9967gccjit::rvalue guard = (i >= n); 9968@end example 9969 9970@noindent 9971 9972and hence we can write the block more concisely as: 9973 9974@example 9975b_loop_cond.end_with_conditional ( 9976 i >= n, 9977 b_after_loop, // on_true 9978 b_loop_body); // on_false 9979@end example 9980 9981@noindent 9982 9983Next, we populate the body of the loop. 9984 9985The C statement @cite{sum += i * i;} is an assignment operation, where an 9986lvalue is modified "in-place". We use 9987@pxref{11c,,gccjit;;block;;add_assignment_op()} to handle these operations: 9988 9989@example 9990/* sum += i * i */ 9991b_loop_body.add_assignment_op (sum, 9992 GCC_JIT_BINARY_OP_PLUS, 9993 i * i); 9994@end example 9995 9996@noindent 9997 9998The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in 9999a similar way. We use @pxref{2f,,gcc_jit_context_one()} to get the constant 10000value @cite{1} (for the relevant type) for the right-hand side 10001of the assignment. 10002 10003@example 10004/* i++ */ 10005b_loop_body.add_assignment_op (i, 10006 GCC_JIT_BINARY_OP_PLUS, 10007 ctxt.one (the_type)); 10008@end example 10009 10010@noindent 10011 10012@cartouche 10013@quotation Note 10014For numeric constants other than 0 or 1, we could use 10015@pxref{11d,,gccjit;;context;;new_rvalue()}, which has overloads 10016for both @code{int} and @code{double}. 10017@end quotation 10018@end cartouche 10019 10020The loop body completes by jumping back to the conditional: 10021 10022@example 10023b_loop_body.end_with_jump (b_loop_cond); 10024@end example 10025 10026@noindent 10027 10028Finally, we populate the @cite{b_after_loop} block, reached when the loop 10029conditional is false. We want to generate the equivalent of: 10030 10031@example 10032return sum; 10033@end example 10034 10035@noindent 10036 10037so the block is just one statement: 10038 10039@example 10040/* return sum */ 10041b_after_loop.end_with_return (sum); 10042@end example 10043 10044@noindent 10045 10046@cartouche 10047@quotation Note 10048You can intermingle block creation with statement creation, 10049but given that the terminator statements generally include references 10050to other blocks, I find it's clearer to create all the blocks, 10051@emph{then} all the statements. 10052@end quotation 10053@end cartouche 10054 10055We've finished populating the function. As before, we can now compile it 10056to machine code: 10057 10058@example 10059gcc_jit_result *result; 10060result = ctxt.compile (); 10061 10062ctxt.release (); 10063 10064if (!result) 10065 @{ 10066 fprintf (stderr, "NULL result"); 10067 return 1; 10068 @} 10069 10070typedef int (*loop_test_fn_type) (int); 10071loop_test_fn_type loop_test = 10072 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 10073if (!loop_test) 10074 @{ 10075 fprintf (stderr, "NULL loop_test"); 10076 gcc_jit_result_release (result); 10077 return 1; 10078 @} 10079printf ("result: %d", loop_test (10)); 10080@end example 10081 10082@noindent 10083 10084@example 10085result: 285 10086@end example 10087 10088@noindent 10089 10090@node Visualizing the control flow graph<2>,Full example<4>,Control flow<2>,Tutorial part 3 Loops and variables<2> 10091@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{11e} 10092@subsubsection Visualizing the control flow graph 10093 10094 10095You can see the control flow graph of a function using 10096@pxref{11f,,gccjit;;function;;dump_to_dot()}: 10097 10098@example 10099func.dump_to_dot ("/tmp/sum-of-squares.dot"); 10100@end example 10101 10102@noindent 10103 10104giving a .dot file in GraphViz format. 10105 10106You can convert this to an image using @cite{dot}: 10107 10108@example 10109$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png 10110@end example 10111 10112@noindent 10113 10114or use a viewer (my preferred one is xdot.py; see 10115@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can 10116install it with @cite{yum install python-xdot}): 10117 10118@quotation 10119 10120 10121@float Figure 10122 10123@image{sum-of-squares,,,image of a control flow graph,png} 10124 10125@end float 10126 10127@end quotation 10128 10129@node Full example<4>,,Visualizing the control flow graph<2>,Tutorial part 3 Loops and variables<2> 10130@anchor{cp/intro/tutorial03 full-example}@anchor{120} 10131@subsubsection Full example 10132 10133 10134@quotation 10135 10136@example 10137/* Usage example for libgccjit.so's C++ API 10138 Copyright (C) 2014-2017 Free Software Foundation, Inc. 10139 10140This file is part of GCC. 10141 10142GCC is free software; you can redistribute it and/or modify it 10143under the terms of the GNU General Public License as published by 10144the Free Software Foundation; either version 3, or (at your option) 10145any later version. 10146 10147GCC is distributed in the hope that it will be useful, but 10148WITHOUT ANY WARRANTY; without even the implied warranty of 10149MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10150General Public License for more details. 10151 10152You should have received a copy of the GNU General Public License 10153along with GCC; see the file COPYING3. If not see 10154<http://www.gnu.org/licenses/>. */ 10155 10156#include <libgccjit++.h> 10157 10158#include <stdlib.h> 10159#include <stdio.h> 10160 10161void 10162create_code (gccjit::context ctxt) 10163@{ 10164 /* 10165 Simple sum-of-squares, to test conditionals and looping 10166 10167 int loop_test (int n) 10168 @{ 10169 int i; 10170 int sum = 0; 10171 for (i = 0; i < n ; i ++) 10172 @{ 10173 sum += i * i; 10174 @} 10175 return sum; 10176 */ 10177 gccjit::type the_type = ctxt.get_int_type <int> (); 10178 gccjit::type return_type = the_type; 10179 10180 gccjit::param n = ctxt.new_param (the_type, "n"); 10181 std::vector<gccjit::param> params; 10182 params.push_back (n); 10183 gccjit::function func = 10184 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10185 return_type, 10186 "loop_test", 10187 params, 0); 10188 10189 /* Build locals: */ 10190 gccjit::lvalue i = func.new_local (the_type, "i"); 10191 gccjit::lvalue sum = func.new_local (the_type, "sum"); 10192 10193 gccjit::block b_initial = func.new_block ("initial"); 10194 gccjit::block b_loop_cond = func.new_block ("loop_cond"); 10195 gccjit::block b_loop_body = func.new_block ("loop_body"); 10196 gccjit::block b_after_loop = func.new_block ("after_loop"); 10197 10198 /* sum = 0; */ 10199 b_initial.add_assignment (sum, ctxt.zero (the_type)); 10200 10201 /* i = 0; */ 10202 b_initial.add_assignment (i, ctxt.zero (the_type)); 10203 10204 b_initial.end_with_jump (b_loop_cond); 10205 10206 /* if (i >= n) */ 10207 b_loop_cond.end_with_conditional ( 10208 i >= n, 10209 b_after_loop, 10210 b_loop_body); 10211 10212 /* sum += i * i */ 10213 b_loop_body.add_assignment_op (sum, 10214 GCC_JIT_BINARY_OP_PLUS, 10215 i * i); 10216 10217 /* i++ */ 10218 b_loop_body.add_assignment_op (i, 10219 GCC_JIT_BINARY_OP_PLUS, 10220 ctxt.one (the_type)); 10221 10222 b_loop_body.end_with_jump (b_loop_cond); 10223 10224 /* return sum */ 10225 b_after_loop.end_with_return (sum); 10226@} 10227 10228int 10229main (int argc, char **argv) 10230@{ 10231 gccjit::context ctxt; 10232 gcc_jit_result *result = NULL; 10233 10234 /* Get a "context" object for working with the library. */ 10235 ctxt = gccjit::context::acquire (); 10236 10237 /* Set some options on the context. 10238 Turn this on to see the code being generated, in assembler form. */ 10239 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 10240 0); 10241 10242 /* Populate the context. */ 10243 create_code (ctxt); 10244 10245 /* Compile the code. */ 10246 result = ctxt.compile (); 10247 10248 ctxt.release (); 10249 10250 if (!result) 10251 @{ 10252 fprintf (stderr, "NULL result"); 10253 return 1; 10254 @} 10255 10256 /* Extract the generated code from "result". */ 10257 typedef int (*loop_test_fn_type) (int); 10258 loop_test_fn_type loop_test = 10259 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 10260 if (!loop_test) 10261 @{ 10262 fprintf (stderr, "NULL loop_test"); 10263 gcc_jit_result_release (result); 10264 return 1; 10265 @} 10266 10267 /* Run the generated code. */ 10268 int val = loop_test (10); 10269 printf("loop_test returned: %d\n", val); 10270 10271 gcc_jit_result_release (result); 10272 return 0; 10273@} 10274 10275@end example 10276 10277@noindent 10278@end quotation 10279 10280Building and running it: 10281 10282@example 10283$ gcc \ 10284 tut03-sum-of-squares.cc \ 10285 -o tut03-sum-of-squares \ 10286 -lgccjit 10287 10288# Run the built program: 10289$ ./tut03-sum-of-squares 10290loop_test returned: 285 10291@end example 10292 10293@noindent 10294 10295@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 10296@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 10297@c 10298@c This is free software: you can redistribute it and/or modify it 10299@c under the terms of the GNU General Public License as published by 10300@c the Free Software Foundation, either version 3 of the License, or 10301@c (at your option) any later version. 10302@c 10303@c This program is distributed in the hope that it will be useful, but 10304@c WITHOUT ANY WARRANTY; without even the implied warranty of 10305@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10306@c General Public License for more details. 10307@c 10308@c You should have received a copy of the GNU General Public License 10309@c along with this program. If not, see 10310@c <http://www.gnu.org/licenses/>. 10311 10312@node Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,,Tutorial part 3 Loops and variables<2>,Tutorial<2> 10313@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{121}@anchor{cp/intro/tutorial04 doc}@anchor{122} 10314@subsection Tutorial part 4: Adding JIT-compilation to a toy interpreter 10315 10316 10317In this example we construct a "toy" interpreter, and add JIT-compilation 10318to it. 10319 10320@menu 10321* Our toy interpreter: Our toy interpreter<2>. 10322* Compiling to machine code: Compiling to machine code<2>. 10323* Setting things up: Setting things up<2>. 10324* Populating the function: Populating the function<2>. 10325* Verifying the control flow graph: Verifying the control flow graph<2>. 10326* Compiling the context: Compiling the context<2>. 10327* Single-stepping through the generated code: Single-stepping through the generated code<2>. 10328* Examining the generated code: Examining the generated code<2>. 10329* Putting it all together: Putting it all together<2>. 10330* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 10331 10332@end menu 10333 10334@node Our toy interpreter<2>,Compiling to machine code<2>,,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 10335@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{123} 10336@subsubsection Our toy interpreter 10337 10338 10339It's a stack-based interpreter, and is intended as a (very simple) example 10340of the kind of bytecode interpreter seen in dynamic languages such as 10341Python, Ruby etc. 10342 10343For the sake of simplicity, our toy virtual machine is very limited: 10344 10345@quotation 10346 10347 10348@itemize * 10349 10350@item 10351The only data type is @cite{int} 10352 10353@item 10354It can only work on one function at a time (so that the only 10355function call that can be made is to recurse). 10356 10357@item 10358Functions can only take one parameter. 10359 10360@item 10361Functions have a stack of @cite{int} values. 10362 10363@item 10364We'll implement function call within the interpreter by calling a 10365function in our implementation, rather than implementing our own 10366frame stack. 10367 10368@item 10369The parser is only good enough to get the examples to work. 10370@end itemize 10371@end quotation 10372 10373Naturally, a real interpreter would be much more complicated that this. 10374 10375The following operations are supported: 10376 10377 10378@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx} 10379@headitem 10380 10381Operation 10382 10383@tab 10384 10385Meaning 10386 10387@tab 10388 10389Old Stack 10390 10391@tab 10392 10393New Stack 10394 10395@item 10396 10397DUP 10398 10399@tab 10400 10401Duplicate top of stack. 10402 10403@tab 10404 10405@code{[..., x]} 10406 10407@tab 10408 10409@code{[..., x, x]} 10410 10411@item 10412 10413ROT 10414 10415@tab 10416 10417Swap top two elements 10418of stack. 10419 10420@tab 10421 10422@code{[..., x, y]} 10423 10424@tab 10425 10426@code{[..., y, x]} 10427 10428@item 10429 10430BINARY_ADD 10431 10432@tab 10433 10434Add the top two elements 10435on the stack. 10436 10437@tab 10438 10439@code{[..., x, y]} 10440 10441@tab 10442 10443@code{[..., (x+y)]} 10444 10445@item 10446 10447BINARY_SUBTRACT 10448 10449@tab 10450 10451Likewise, but subtract. 10452 10453@tab 10454 10455@code{[..., x, y]} 10456 10457@tab 10458 10459@code{[..., (x-y)]} 10460 10461@item 10462 10463BINARY_MULT 10464 10465@tab 10466 10467Likewise, but multiply. 10468 10469@tab 10470 10471@code{[..., x, y]} 10472 10473@tab 10474 10475@code{[..., (x*y)]} 10476 10477@item 10478 10479BINARY_COMPARE_LT 10480 10481@tab 10482 10483Compare the top two 10484elements on the stack 10485and push a nonzero/zero 10486if (x<y). 10487 10488@tab 10489 10490@code{[..., x, y]} 10491 10492@tab 10493 10494@code{[..., (x<y)]} 10495 10496@item 10497 10498RECURSE 10499 10500@tab 10501 10502Recurse, passing the top 10503of the stack, and 10504popping the result. 10505 10506@tab 10507 10508@code{[..., x]} 10509 10510@tab 10511 10512@code{[..., fn(x)]} 10513 10514@item 10515 10516RETURN 10517 10518@tab 10519 10520Return the top of the 10521stack. 10522 10523@tab 10524 10525@code{[x]} 10526 10527@tab 10528 10529@code{[]} 10530 10531@item 10532 10533PUSH_CONST @cite{arg} 10534 10535@tab 10536 10537Push an int const. 10538 10539@tab 10540 10541@code{[...]} 10542 10543@tab 10544 10545@code{[..., arg]} 10546 10547@item 10548 10549JUMP_ABS_IF_TRUE @cite{arg} 10550 10551@tab 10552 10553Pop; if top of stack was 10554nonzero, jump to 10555@code{arg}. 10556 10557@tab 10558 10559@code{[..., x]} 10560 10561@tab 10562 10563@code{[...]} 10564 10565@end multitable 10566 10567 10568Programs can be interpreted, disassembled, and compiled to machine code. 10569 10570The interpreter reads @code{.toy} scripts. Here's what a simple recursive 10571factorial program looks like, the script @code{factorial.toy}. 10572The parser ignores lines beginning with a @cite{#}. 10573 10574@quotation 10575 10576@example 10577# Simple recursive factorial implementation, roughly equivalent to: 10578# 10579# int factorial (int arg) 10580# @{ 10581# if (arg < 2) 10582# return arg 10583# return arg * factorial (arg - 1) 10584# @} 10585 10586# Initial state: 10587# stack: [arg] 10588 10589# 0: 10590DUP 10591# stack: [arg, arg] 10592 10593# 1: 10594PUSH_CONST 2 10595# stack: [arg, arg, 2] 10596 10597# 2: 10598BINARY_COMPARE_LT 10599# stack: [arg, (arg < 2)] 10600 10601# 3: 10602JUMP_ABS_IF_TRUE 9 10603# stack: [arg] 10604 10605# 4: 10606DUP 10607# stack: [arg, arg] 10608 10609# 5: 10610PUSH_CONST 1 10611# stack: [arg, arg, 1] 10612 10613# 6: 10614BINARY_SUBTRACT 10615# stack: [arg, (arg - 1) 10616 10617# 7: 10618RECURSE 10619# stack: [arg, factorial(arg - 1)] 10620 10621# 8: 10622BINARY_MULT 10623# stack: [arg * factorial(arg - 1)] 10624 10625# 9: 10626RETURN 10627 10628@end example 10629 10630@noindent 10631@end quotation 10632 10633The interpreter is a simple infinite loop with a big @code{switch} statement 10634based on what the next opcode is: 10635 10636@quotation 10637 10638@example 10639 10640int 10641toyvm_function::interpret (int arg, FILE *trace) 10642@{ 10643 toyvm_frame frame; 10644#define PUSH(ARG) (frame.push (ARG)) 10645#define POP(ARG) (frame.pop ()) 10646 10647 frame.frm_function = this; 10648 frame.frm_pc = 0; 10649 frame.frm_cur_depth = 0; 10650 10651 PUSH (arg); 10652 10653 while (1) 10654 @{ 10655 toyvm_op *op; 10656 int x, y; 10657 assert (frame.frm_pc < fn_num_ops); 10658 op = &fn_ops[frame.frm_pc++]; 10659 10660 if (trace) 10661 @{ 10662 frame.dump_stack (trace); 10663 disassemble_op (op, frame.frm_pc, trace); 10664 @} 10665 10666 switch (op->op_opcode) 10667 @{ 10668 /* Ops taking no operand. */ 10669 case DUP: 10670 x = POP (); 10671 PUSH (x); 10672 PUSH (x); 10673 break; 10674 10675 case ROT: 10676 y = POP (); 10677 x = POP (); 10678 PUSH (y); 10679 PUSH (x); 10680 break; 10681 10682 case BINARY_ADD: 10683 y = POP (); 10684 x = POP (); 10685 PUSH (x + y); 10686 break; 10687 10688 case BINARY_SUBTRACT: 10689 y = POP (); 10690 x = POP (); 10691 PUSH (x - y); 10692 break; 10693 10694 case BINARY_MULT: 10695 y = POP (); 10696 x = POP (); 10697 PUSH (x * y); 10698 break; 10699 10700 case BINARY_COMPARE_LT: 10701 y = POP (); 10702 x = POP (); 10703 PUSH (x < y); 10704 break; 10705 10706 case RECURSE: 10707 x = POP (); 10708 x = interpret (x, trace); 10709 PUSH (x); 10710 break; 10711 10712 case RETURN: 10713 return POP (); 10714 10715 /* Ops taking an operand. */ 10716 case PUSH_CONST: 10717 PUSH (op->op_operand); 10718 break; 10719 10720 case JUMP_ABS_IF_TRUE: 10721 x = POP (); 10722 if (x) 10723 frame.frm_pc = op->op_operand; 10724 break; 10725 10726 default: 10727 assert (0); /* unknown opcode */ 10728 10729 @} /* end of switch on opcode */ 10730 @} /* end of while loop */ 10731 10732#undef PUSH 10733#undef POP 10734@} 10735 10736 10737@end example 10738 10739@noindent 10740@end quotation 10741 10742@node Compiling to machine code<2>,Setting things up<2>,Our toy interpreter<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 10743@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{124} 10744@subsubsection Compiling to machine code 10745 10746 10747We want to generate machine code that can be cast to this type and 10748then directly executed in-process: 10749 10750@quotation 10751 10752@example 10753typedef int (*toyvm_compiled_func) (int); 10754 10755 10756@end example 10757 10758@noindent 10759@end quotation 10760 10761Our compiler isn't very sophisticated; it takes the implementation of 10762each opcode above, and maps it directly to the operations supported by 10763the libgccjit API. 10764 10765How should we handle the stack? In theory we could calculate what the 10766stack depth will be at each opcode, and optimize away the stack 10767manipulation "by hand". We'll see below that libgccjit is able to do 10768this for us, so we'll implement stack manipulation 10769in a direct way, by creating a @code{stack} array and @code{stack_depth} 10770variables, local within the generated function, equivalent to this C code: 10771 10772@example 10773int stack_depth; 10774int stack[MAX_STACK_DEPTH]; 10775@end example 10776 10777@noindent 10778 10779We'll also have local variables @code{x} and @code{y} for use when implementing 10780the opcodes, equivalent to this: 10781 10782@example 10783int x; 10784int y; 10785@end example 10786 10787@noindent 10788 10789This means our compiler has the following state: 10790 10791@quotation 10792 10793@example 10794 10795 toyvm_function &toyvmfn; 10796 10797 gccjit::context ctxt; 10798 10799 gccjit::type int_type; 10800 gccjit::type bool_type; 10801 gccjit::type stack_type; /* int[MAX_STACK_DEPTH] */ 10802 10803 gccjit::rvalue const_one; 10804 10805 gccjit::function fn; 10806 gccjit::param param_arg; 10807 gccjit::lvalue stack; 10808 gccjit::lvalue stack_depth; 10809 gccjit::lvalue x; 10810 gccjit::lvalue y; 10811 10812 gccjit::location op_locs[MAX_OPS]; 10813 gccjit::block initial_block; 10814 gccjit::block op_blocks[MAX_OPS]; 10815 10816 10817@end example 10818 10819@noindent 10820@end quotation 10821 10822@node Setting things up<2>,Populating the function<2>,Compiling to machine code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 10823@anchor{cp/intro/tutorial04 setting-things-up}@anchor{125} 10824@subsubsection Setting things up 10825 10826 10827First we create our types: 10828 10829@quotation 10830 10831@example 10832 10833void 10834compilation_state::create_types () 10835@{ 10836 /* Create types. */ 10837 int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 10838 bool_type = ctxt.get_type (GCC_JIT_TYPE_BOOL); 10839 stack_type = ctxt.new_array_type (int_type, MAX_STACK_DEPTH); 10840 10841 10842@end example 10843 10844@noindent 10845@end quotation 10846 10847along with extracting a useful @cite{int} constant: 10848 10849@quotation 10850 10851@example 10852 const_one = ctxt.one (int_type); 10853 10854@} 10855 10856 10857@end example 10858 10859@noindent 10860@end quotation 10861 10862We'll implement push and pop in terms of the @code{stack} array and 10863@code{stack_depth}. Here are helper functions for adding statements to 10864a block, implementing pushing and popping values: 10865 10866@quotation 10867 10868@example 10869 10870void 10871compilation_state::add_push (gccjit::block block, 10872 gccjit::rvalue rvalue, 10873 gccjit::location loc) 10874@{ 10875 /* stack[stack_depth] = RVALUE */ 10876 block.add_assignment ( 10877 /* stack[stack_depth] */ 10878 ctxt.new_array_access ( 10879 stack, 10880 stack_depth, 10881 loc), 10882 rvalue, 10883 loc); 10884 10885 /* "stack_depth++;". */ 10886 block.add_assignment_op ( 10887 stack_depth, 10888 GCC_JIT_BINARY_OP_PLUS, 10889 const_one, 10890 loc); 10891@} 10892 10893void 10894compilation_state::add_pop (gccjit::block block, 10895 gccjit::lvalue lvalue, 10896 gccjit::location loc) 10897@{ 10898 /* "--stack_depth;". */ 10899 block.add_assignment_op ( 10900 stack_depth, 10901 GCC_JIT_BINARY_OP_MINUS, 10902 const_one, 10903 loc); 10904 10905 /* "LVALUE = stack[stack_depth];". */ 10906 block.add_assignment ( 10907 lvalue, 10908 /* stack[stack_depth] */ 10909 ctxt.new_array_access (stack, 10910 stack_depth, 10911 loc), 10912 loc); 10913@} 10914 10915 10916@end example 10917 10918@noindent 10919@end quotation 10920 10921We will support single-stepping through the generated code in the 10922debugger, so we need to create @code{gccjit::location} instances, one 10923per operation in the source code. These will reference the lines of 10924e.g. @code{factorial.toy}. 10925 10926@quotation 10927 10928@example 10929 10930void 10931compilation_state::create_locations () 10932@{ 10933 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 10934 @{ 10935 toyvm_op *op = &toyvmfn.fn_ops[pc]; 10936 10937 op_locs[pc] = ctxt.new_location (toyvmfn.fn_filename, 10938 op->op_linenum, 10939 0); /* column */ 10940 @} 10941@} 10942 10943 10944@end example 10945 10946@noindent 10947@end quotation 10948 10949Let's create the function itself. As usual, we create its parameter 10950first, then use the parameter to create the function: 10951 10952@quotation 10953 10954@example 10955 10956void 10957compilation_state::create_function (const char *funcname) 10958@{ 10959 std::vector <gccjit::param> params; 10960 param_arg = ctxt.new_param (int_type, "arg", op_locs[0]); 10961 params.push_back (param_arg); 10962 fn = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10963 int_type, 10964 funcname, 10965 params, 0, 10966 op_locs[0]); 10967 10968 10969@end example 10970 10971@noindent 10972@end quotation 10973 10974We create the locals within the function. 10975 10976@quotation 10977 10978@example 10979 stack = fn.new_local (stack_type, "stack"); 10980 stack_depth = fn.new_local (int_type, "stack_depth"); 10981 x = fn.new_local (int_type, "x"); 10982 y = fn.new_local (int_type, "y"); 10983 10984 10985@end example 10986 10987@noindent 10988@end quotation 10989 10990@node Populating the function<2>,Verifying the control flow graph<2>,Setting things up<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 10991@anchor{cp/intro/tutorial04 populating-the-function}@anchor{126} 10992@subsubsection Populating the function 10993 10994 10995There's some one-time initialization, and the API treats the first block 10996you create as the entrypoint of the function, so we need to create that 10997block first: 10998 10999@quotation 11000 11001@example 11002 initial_block = fn.new_block ("initial"); 11003 11004 11005@end example 11006 11007@noindent 11008@end quotation 11009 11010We can now create blocks for each of the operations. Most of these will 11011be consolidated into larger blocks when the optimizer runs. 11012 11013@quotation 11014 11015@example 11016 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 11017 @{ 11018 char buf[16]; 11019 sprintf (buf, "instr%i", pc); 11020 op_blocks[pc] = fn.new_block (buf); 11021 @} 11022 11023 11024@end example 11025 11026@noindent 11027@end quotation 11028 11029Now that we have a block it can jump to when it's done, we can populate 11030the initial block: 11031 11032@quotation 11033 11034@example 11035 11036 /* "stack_depth = 0;". */ 11037 initial_block.add_assignment (stack_depth, 11038 ctxt.zero (int_type), 11039 op_locs[0]); 11040 11041 /* "PUSH (arg);". */ 11042 add_push (initial_block, 11043 param_arg, 11044 op_locs[0]); 11045 11046 /* ...and jump to insn 0. */ 11047 initial_block.end_with_jump (op_blocks[0], 11048 op_locs[0]); 11049 11050 11051@end example 11052 11053@noindent 11054@end quotation 11055 11056We can now populate the blocks for the individual operations. We loop 11057through them, adding instructions to their blocks: 11058 11059@quotation 11060 11061@example 11062 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 11063 @{ 11064 gccjit::location loc = op_locs[pc]; 11065 11066 gccjit::block block = op_blocks[pc]; 11067 gccjit::block next_block = (pc < toyvmfn.fn_num_ops 11068 ? op_blocks[pc + 1] 11069 : NULL); 11070 11071 toyvm_op *op; 11072 op = &toyvmfn.fn_ops[pc]; 11073 11074 11075@end example 11076 11077@noindent 11078@end quotation 11079 11080We're going to have another big @code{switch} statement for implementing 11081the opcodes, this time for compiling them, rather than interpreting 11082them. It's helpful to have macros for implementing push and pop, so that 11083we can make the @code{switch} statement that's coming up look as much as 11084possible like the one above within the interpreter: 11085 11086@example 11087 11088#define X_EQUALS_POP()\ 11089 add_pop (block, x, loc) 11090#define Y_EQUALS_POP()\ 11091 add_pop (block, y, loc) 11092#define PUSH_RVALUE(RVALUE)\ 11093 add_push (block, (RVALUE), loc) 11094#define PUSH_X()\ 11095 PUSH_RVALUE (x) 11096#define PUSH_Y() \ 11097 PUSH_RVALUE (y) 11098 11099 11100@end example 11101 11102@noindent 11103 11104@cartouche 11105@quotation Note 11106A particularly clever implementation would have an @emph{identical} 11107@code{switch} statement shared by the interpreter and the compiler, with 11108some preprocessor "magic". We're not doing that here, for the sake 11109of simplicity. 11110@end quotation 11111@end cartouche 11112 11113When I first implemented this compiler, I accidentally missed an edit 11114when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the 11115stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y} 11116uninitialized. 11117 11118To track this kind of thing down, we can use 11119@pxref{127,,gccjit;;block;;add_comment()} to add descriptive comments 11120to the internal representation. This is invaluable when looking through 11121the generated IR for, say @code{factorial}: 11122 11123@quotation 11124 11125@example 11126 11127 block.add_comment (opcode_names[op->op_opcode], loc); 11128 11129 11130@end example 11131 11132@noindent 11133@end quotation 11134 11135We can now write the big @code{switch} statement that implements the 11136individual opcodes, populating the relevant block with statements: 11137 11138@quotation 11139 11140@example 11141 11142 switch (op->op_opcode) 11143 @{ 11144 case DUP: 11145 X_EQUALS_POP (); 11146 PUSH_X (); 11147 PUSH_X (); 11148 break; 11149 11150 case ROT: 11151 Y_EQUALS_POP (); 11152 X_EQUALS_POP (); 11153 PUSH_Y (); 11154 PUSH_X (); 11155 break; 11156 11157 case BINARY_ADD: 11158 Y_EQUALS_POP (); 11159 X_EQUALS_POP (); 11160 PUSH_RVALUE ( 11161 ctxt.new_binary_op ( 11162 GCC_JIT_BINARY_OP_PLUS, 11163 int_type, 11164 x, y, 11165 loc)); 11166 break; 11167 11168 case BINARY_SUBTRACT: 11169 Y_EQUALS_POP (); 11170 X_EQUALS_POP (); 11171 PUSH_RVALUE ( 11172 ctxt.new_binary_op ( 11173 GCC_JIT_BINARY_OP_MINUS, 11174 int_type, 11175 x, y, 11176 loc)); 11177 break; 11178 11179 case BINARY_MULT: 11180 Y_EQUALS_POP (); 11181 X_EQUALS_POP (); 11182 PUSH_RVALUE ( 11183 ctxt.new_binary_op ( 11184 GCC_JIT_BINARY_OP_MULT, 11185 int_type, 11186 x, y, 11187 loc)); 11188 break; 11189 11190 case BINARY_COMPARE_LT: 11191 Y_EQUALS_POP (); 11192 X_EQUALS_POP (); 11193 PUSH_RVALUE ( 11194 /* cast of bool to int */ 11195 ctxt.new_cast ( 11196 /* (x < y) as a bool */ 11197 ctxt.new_comparison ( 11198 GCC_JIT_COMPARISON_LT, 11199 x, y, 11200 loc), 11201 int_type, 11202 loc)); 11203 break; 11204 11205 case RECURSE: 11206 @{ 11207 X_EQUALS_POP (); 11208 PUSH_RVALUE ( 11209 ctxt.new_call ( 11210 fn, 11211 x, 11212 loc)); 11213 break; 11214 @} 11215 11216 case RETURN: 11217 X_EQUALS_POP (); 11218 block.end_with_return (x, loc); 11219 break; 11220 11221 /* Ops taking an operand. */ 11222 case PUSH_CONST: 11223 PUSH_RVALUE ( 11224 ctxt.new_rvalue (int_type, op->op_operand)); 11225 break; 11226 11227 case JUMP_ABS_IF_TRUE: 11228 X_EQUALS_POP (); 11229 block.end_with_conditional ( 11230 /* "(bool)x". */ 11231 ctxt.new_cast (x, bool_type, loc), 11232 op_blocks[op->op_operand], /* on_true */ 11233 next_block, /* on_false */ 11234 loc); 11235 break; 11236 11237 default: 11238 assert(0); 11239 @} /* end of switch on opcode */ 11240 11241 11242@end example 11243 11244@noindent 11245@end quotation 11246 11247Every block must be terminated, via a call to one of the 11248@code{gccjit::block::end_with_} entrypoints. This has been done for two 11249of the opcodes, but we need to do it for the other ones, by jumping 11250to the next block. 11251 11252@quotation 11253 11254@example 11255 if (op->op_opcode != JUMP_ABS_IF_TRUE 11256 && op->op_opcode != RETURN) 11257 block.end_with_jump (next_block, loc); 11258 11259 11260@end example 11261 11262@noindent 11263@end quotation 11264 11265This is analogous to simply incrementing the program counter. 11266 11267@node Verifying the control flow graph<2>,Compiling the context<2>,Populating the function<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 11268@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{128} 11269@subsubsection Verifying the control flow graph 11270 11271 11272Having finished looping over the blocks, the context is complete. 11273 11274As before, we can verify that the control flow and statements are sane by 11275using @pxref{11f,,gccjit;;function;;dump_to_dot()}: 11276 11277@example 11278fn.dump_to_dot ("/tmp/factorial.dot"); 11279@end example 11280 11281@noindent 11282 11283and viewing the result. Note how the label names, comments, and 11284variable names show up in the dump, to make it easier to spot 11285errors in our compiler. 11286 11287@quotation 11288 11289 11290@float Figure 11291 11292@image{factorial,,,image of a control flow graph,png} 11293 11294@end float 11295 11296@end quotation 11297 11298@node Compiling the context<2>,Single-stepping through the generated code<2>,Verifying the control flow graph<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 11299@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{129} 11300@subsubsection Compiling the context 11301 11302 11303Having finished looping over the blocks and populating them with 11304statements, the context is complete. 11305 11306We can now compile it, extract machine code from the result, and 11307run it: 11308 11309@quotation 11310 11311@example 11312 11313class compilation_result 11314@{ 11315public: 11316 compilation_result (gcc_jit_result *result) : 11317 m_result (result) 11318 @{ 11319 @} 11320 ~compilation_result () 11321 @{ 11322 gcc_jit_result_release (m_result); 11323 @} 11324 11325 void *get_code (const char *funcname) 11326 @{ 11327 return gcc_jit_result_get_code (m_result, funcname); 11328 @} 11329 11330private: 11331 gcc_jit_result *m_result; 11332@}; 11333 11334 11335@end example 11336 11337@noindent 11338 11339@example 11340 compilation_result compiler_result = fn->compile (); 11341 11342 const char *funcname = fn->get_function_name (); 11343 toyvm_compiled_func code 11344 = (toyvm_compiled_func)compiler_result.get_code (funcname); 11345 11346 printf ("compiler result: %d\n", 11347 code (atoi (argv[2]))); 11348 11349 11350@end example 11351 11352@noindent 11353@end quotation 11354 11355@node Single-stepping through the generated code<2>,Examining the generated code<2>,Compiling the context<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 11356@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{12a} 11357@subsubsection Single-stepping through the generated code 11358 11359 11360It's possible to debug the generated code. To do this we need to both: 11361 11362@quotation 11363 11364 11365@itemize * 11366 11367@item 11368Set up source code locations for our statements, so that we can 11369meaningfully step through the code. We did this above by 11370calling @pxref{12b,,gccjit;;context;;new_location()} and using the 11371results. 11372 11373@item 11374Enable the generation of debugging information, by setting 11375@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 11376@code{gccjit::context} via 11377@pxref{110,,gccjit;;context;;set_bool_option()}: 11378 11379@example 11380ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1); 11381@end example 11382 11383@noindent 11384@end itemize 11385@end quotation 11386 11387Having done this, we can put a breakpoint on the generated function: 11388 11389@example 11390$ gdb --args ./toyvm factorial.toy 10 11391(gdb) break factorial 11392Function "factorial" not defined. 11393Make breakpoint pending on future shared library load? (y or [n]) y 11394Breakpoint 1 (factorial) pending. 11395(gdb) run 11396Breakpoint 1, factorial (arg=10) at factorial.toy:14 1139714 DUP 11398@end example 11399 11400@noindent 11401 11402We've set up location information, which references @code{factorial.toy}. 11403This allows us to use e.g. @code{list} to see where we are in the script: 11404 11405@example 11406(gdb) list 114079 1140810 # Initial state: 1140911 # stack: [arg] 1141012 1141113 # 0: 1141214 DUP 1141315 # stack: [arg, arg] 1141416 1141517 # 1: 1141618 PUSH_CONST 2 11417@end example 11418 11419@noindent 11420 11421and to step through the function, examining the data: 11422 11423@example 11424(gdb) n 1142518 PUSH_CONST 2 11426(gdb) n 1142722 BINARY_COMPARE_LT 11428(gdb) print stack 11429$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@} 11430(gdb) print stack_depth 11431$6 = 3 11432@end example 11433 11434@noindent 11435 11436You'll see that the parts of the @code{stack} array that haven't been 11437touched yet are uninitialized. 11438 11439@cartouche 11440@quotation Note 11441Turning on optimizations may lead to unpredictable results when 11442stepping through the generated code: the execution may appear to 11443"jump around" the source code. This is analogous to turning up the 11444optimization level in a regular compiler. 11445@end quotation 11446@end cartouche 11447 11448@node Examining the generated code<2>,Putting it all together<2>,Single-stepping through the generated code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 11449@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{12c} 11450@subsubsection Examining the generated code 11451 11452 11453How good is the optimized code? 11454 11455We can turn up optimizations, by calling 11456@pxref{111,,gccjit;;context;;set_int_option()} with 11457@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 11458 11459@example 11460ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); 11461@end example 11462 11463@noindent 11464 11465One of GCC's internal representations is called "gimple". A dump of the 11466initial gimple representation of the code can be seen by setting: 11467 11468@example 11469ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); 11470@end example 11471 11472@noindent 11473 11474With optimization on and source locations displayed, this gives: 11475 11476@c We'll use "c" for gimple dumps 11477 11478@example 11479factorial (signed int arg) 11480@{ 11481 <unnamed type> D.80; 11482 signed int D.81; 11483 signed int D.82; 11484 signed int D.83; 11485 signed int D.84; 11486 signed int D.85; 11487 signed int y; 11488 signed int x; 11489 signed int stack_depth; 11490 signed int stack[8]; 11491 11492 try 11493 @{ 11494 initial: 11495 stack_depth = 0; 11496 stack[stack_depth] = arg; 11497 stack_depth = stack_depth + 1; 11498 goto instr0; 11499 instr0: 11500 /* DUP */: 11501 stack_depth = stack_depth + -1; 11502 x = stack[stack_depth]; 11503 stack[stack_depth] = x; 11504 stack_depth = stack_depth + 1; 11505 stack[stack_depth] = x; 11506 stack_depth = stack_depth + 1; 11507 goto instr1; 11508 instr1: 11509 /* PUSH_CONST */: 11510 stack[stack_depth] = 2; 11511 stack_depth = stack_depth + 1; 11512 goto instr2; 11513 11514 /* etc */ 11515@end example 11516 11517@noindent 11518 11519You can see the generated machine code in assembly form via: 11520 11521@example 11522ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); 11523result = ctxt.compile (); 11524@end example 11525 11526@noindent 11527 11528which shows that (on this x86_64 box) the compiler has unrolled the loop 11529and is using MMX instructions to perform several multiplications 11530simultaneously: 11531 11532@example 11533 .file "fake.c" 11534 .text 11535.Ltext0: 11536 .p2align 4,,15 11537 .globl factorial 11538 .type factorial, @@function 11539factorial: 11540.LFB0: 11541 .file 1 "factorial.toy" 11542 .loc 1 14 0 11543 .cfi_startproc 11544.LVL0: 11545.L2: 11546 .loc 1 26 0 11547 cmpl $1, %edi 11548 jle .L13 11549 leal -1(%rdi), %edx 11550 movl %edx, %ecx 11551 shrl $2, %ecx 11552 leal 0(,%rcx,4), %esi 11553 testl %esi, %esi 11554 je .L14 11555 cmpl $9, %edx 11556 jbe .L14 11557 leal -2(%rdi), %eax 11558 movl %eax, -16(%rsp) 11559 leal -3(%rdi), %eax 11560 movd -16(%rsp), %xmm0 11561 movl %edi, -16(%rsp) 11562 movl %eax, -12(%rsp) 11563 movd -16(%rsp), %xmm1 11564 xorl %eax, %eax 11565 movl %edx, -16(%rsp) 11566 movd -12(%rsp), %xmm4 11567 movd -16(%rsp), %xmm6 11568 punpckldq %xmm4, %xmm0 11569 movdqa .LC1(%rip), %xmm4 11570 punpckldq %xmm6, %xmm1 11571 punpcklqdq %xmm0, %xmm1 11572 movdqa .LC0(%rip), %xmm0 11573 jmp .L5 11574 # etc - edited for brevity 11575@end example 11576 11577@noindent 11578 11579This is clearly overkill for a function that will likely overflow the 11580@code{int} type before the vectorization is worthwhile - but then again, this 11581is a toy example. 11582 11583Turning down the optimization level to 2: 11584 11585@example 11586ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2); 11587@end example 11588 11589@noindent 11590 11591yields this code, which is simple enough to quote in its entirety: 11592 11593@example 11594 .file "fake.c" 11595 .text 11596 .p2align 4,,15 11597 .globl factorial 11598 .type factorial, @@function 11599factorial: 11600.LFB0: 11601 .cfi_startproc 11602.L2: 11603 cmpl $1, %edi 11604 jle .L8 11605 movl $1, %edx 11606 jmp .L4 11607 .p2align 4,,10 11608 .p2align 3 11609.L6: 11610 movl %eax, %edi 11611.L4: 11612.L5: 11613 leal -1(%rdi), %eax 11614 imull %edi, %edx 11615 cmpl $1, %eax 11616 jne .L6 11617.L3: 11618.L7: 11619 imull %edx, %eax 11620 ret 11621.L8: 11622 movl %edi, %eax 11623 movl $1, %edx 11624 jmp .L7 11625 .cfi_endproc 11626.LFE0: 11627 .size factorial, .-factorial 11628 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})" 11629 .section .note.GNU-stack,"",@@progbits 11630@end example 11631 11632@noindent 11633 11634Note that the stack pushing and popping have been eliminated, as has the 11635recursive call (in favor of an iteration). 11636 11637@node Putting it all together<2>,Behind the curtain How does our code get optimized?<2>,Examining the generated code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 11638@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{12d} 11639@subsubsection Putting it all together 11640 11641 11642The complete example can be seen in the source tree at 11643@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.cc} 11644 11645along with a Makefile and a couple of sample .toy scripts: 11646 11647@example 11648$ ls -al 11649drwxrwxr-x. 2 david david 4096 Sep 19 17:46 . 11650drwxrwxr-x. 3 david david 4096 Sep 19 15:26 .. 11651-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy 11652-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy 11653-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile 11654-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.cc 11655 11656$ make toyvm 11657g++ -Wall -g -o toyvm toyvm.cc -lgccjit 11658 11659$ ./toyvm factorial.toy 10 11660interpreter result: 3628800 11661compiler result: 3628800 11662 11663$ ./toyvm fibonacci.toy 10 11664interpreter result: 55 11665compiler result: 55 11666@end example 11667 11668@noindent 11669 11670@node Behind the curtain How does our code get optimized?<2>,,Putting it all together<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 11671@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{12e} 11672@subsubsection Behind the curtain: How does our code get optimized? 11673 11674 11675Our example is done, but you may be wondering about exactly how the 11676compiler turned what we gave it into the machine code seen above. 11677 11678We can examine what the compiler is doing in detail by setting: 11679 11680@example 11681state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 1); 11682state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 1); 11683@end example 11684 11685@noindent 11686 11687This will dump detailed information about the compiler's state to a 11688directory under @code{/tmp}, and keep it from being cleaned up. 11689 11690The precise names and their formats of these files is subject to change. 11691Higher optimization levels lead to more files. 11692Here's what I saw (edited for brevity; there were almost 200 files): 11693 11694@example 11695intermediate files written to /tmp/libgccjit-KPQbGw 11696$ ls /tmp/libgccjit-KPQbGw/ 11697fake.c.000i.cgraph 11698fake.c.000i.type-inheritance 11699fake.c.004t.gimple 11700fake.c.007t.omplower 11701fake.c.008t.lower 11702fake.c.011t.eh 11703fake.c.012t.cfg 11704fake.c.014i.visibility 11705fake.c.015i.early_local_cleanups 11706fake.c.016t.ssa 11707# etc 11708@end example 11709 11710@noindent 11711 11712The gimple code is converted into Static Single Assignment form, 11713with annotations for use when generating the debuginfo: 11714 11715@example 11716$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa 11717@end example 11718 11719@noindent 11720 11721@example 11722;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11723 11724factorial (signed int arg) 11725@{ 11726 signed int stack[8]; 11727 signed int stack_depth; 11728 signed int x; 11729 signed int y; 11730 <unnamed type> _20; 11731 signed int _21; 11732 signed int _38; 11733 signed int _44; 11734 signed int _51; 11735 signed int _56; 11736 11737initial: 11738 stack_depth_3 = 0; 11739 # DEBUG stack_depth => stack_depth_3 11740 stack[stack_depth_3] = arg_5(D); 11741 stack_depth_7 = stack_depth_3 + 1; 11742 # DEBUG stack_depth => stack_depth_7 11743 # DEBUG instr0 => NULL 11744 # DEBUG /* DUP */ => NULL 11745 stack_depth_8 = stack_depth_7 + -1; 11746 # DEBUG stack_depth => stack_depth_8 11747 x_9 = stack[stack_depth_8]; 11748 # DEBUG x => x_9 11749 stack[stack_depth_8] = x_9; 11750 stack_depth_11 = stack_depth_8 + 1; 11751 # DEBUG stack_depth => stack_depth_11 11752 stack[stack_depth_11] = x_9; 11753 stack_depth_13 = stack_depth_11 + 1; 11754 # DEBUG stack_depth => stack_depth_13 11755 # DEBUG instr1 => NULL 11756 # DEBUG /* PUSH_CONST */ => NULL 11757 stack[stack_depth_13] = 2; 11758 11759 /* etc; edited for brevity */ 11760@end example 11761 11762@noindent 11763 11764We can perhaps better see the code by turning off 11765@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG} 11766statements, giving: 11767 11768@example 11769$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa 11770@end example 11771 11772@noindent 11773 11774@example 11775;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11776 11777factorial (signed int arg) 11778@{ 11779 signed int stack[8]; 11780 signed int stack_depth; 11781 signed int x; 11782 signed int y; 11783 <unnamed type> _20; 11784 signed int _21; 11785 signed int _38; 11786 signed int _44; 11787 signed int _51; 11788 signed int _56; 11789 11790initial: 11791 stack_depth_3 = 0; 11792 stack[stack_depth_3] = arg_5(D); 11793 stack_depth_7 = stack_depth_3 + 1; 11794 stack_depth_8 = stack_depth_7 + -1; 11795 x_9 = stack[stack_depth_8]; 11796 stack[stack_depth_8] = x_9; 11797 stack_depth_11 = stack_depth_8 + 1; 11798 stack[stack_depth_11] = x_9; 11799 stack_depth_13 = stack_depth_11 + 1; 11800 stack[stack_depth_13] = 2; 11801 stack_depth_15 = stack_depth_13 + 1; 11802 stack_depth_16 = stack_depth_15 + -1; 11803 y_17 = stack[stack_depth_16]; 11804 stack_depth_18 = stack_depth_16 + -1; 11805 x_19 = stack[stack_depth_18]; 11806 _20 = x_19 < y_17; 11807 _21 = (signed int) _20; 11808 stack[stack_depth_18] = _21; 11809 stack_depth_23 = stack_depth_18 + 1; 11810 stack_depth_24 = stack_depth_23 + -1; 11811 x_25 = stack[stack_depth_24]; 11812 if (x_25 != 0) 11813 goto <bb 4> (instr9); 11814 else 11815 goto <bb 3> (instr4); 11816 11817instr4: 11818/* DUP */: 11819 stack_depth_26 = stack_depth_24 + -1; 11820 x_27 = stack[stack_depth_26]; 11821 stack[stack_depth_26] = x_27; 11822 stack_depth_29 = stack_depth_26 + 1; 11823 stack[stack_depth_29] = x_27; 11824 stack_depth_31 = stack_depth_29 + 1; 11825 stack[stack_depth_31] = 1; 11826 stack_depth_33 = stack_depth_31 + 1; 11827 stack_depth_34 = stack_depth_33 + -1; 11828 y_35 = stack[stack_depth_34]; 11829 stack_depth_36 = stack_depth_34 + -1; 11830 x_37 = stack[stack_depth_36]; 11831 _38 = x_37 - y_35; 11832 stack[stack_depth_36] = _38; 11833 stack_depth_40 = stack_depth_36 + 1; 11834 stack_depth_41 = stack_depth_40 + -1; 11835 x_42 = stack[stack_depth_41]; 11836 _44 = factorial (x_42); 11837 stack[stack_depth_41] = _44; 11838 stack_depth_46 = stack_depth_41 + 1; 11839 stack_depth_47 = stack_depth_46 + -1; 11840 y_48 = stack[stack_depth_47]; 11841 stack_depth_49 = stack_depth_47 + -1; 11842 x_50 = stack[stack_depth_49]; 11843 _51 = x_50 * y_48; 11844 stack[stack_depth_49] = _51; 11845 stack_depth_53 = stack_depth_49 + 1; 11846 11847 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)> 11848instr9: 11849/* RETURN */: 11850 stack_depth_54 = stack_depth_1 + -1; 11851 x_55 = stack[stack_depth_54]; 11852 _56 = x_55; 11853 stack =@{v@} @{CLOBBER@}; 11854 return _56; 11855 11856@} 11857@end example 11858 11859@noindent 11860 11861Note in the above how all the @code{gccjit::block} instances we 11862created have been consolidated into just 3 blocks in GCC's internal 11863representation: @code{initial}, @code{instr4} and @code{instr9}. 11864 11865@menu 11866* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 11867* Elimination of tail recursion: Elimination of tail recursion<2>. 11868 11869@end menu 11870 11871@node Optimizing away stack manipulation<2>,Elimination of tail recursion<2>,,Behind the curtain How does our code get optimized?<2> 11872@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{12f} 11873@subsubsection Optimizing away stack manipulation 11874 11875 11876Recall our simple implementation of stack operations. Let's examine 11877how the stack operations are optimized away. 11878 11879After a pass of constant-propagation, the depth of the stack at each 11880opcode can be determined at compile-time: 11881 11882@example 11883$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1 11884@end example 11885 11886@noindent 11887 11888@example 11889;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11890 11891factorial (signed int arg) 11892@{ 11893 signed int stack[8]; 11894 signed int stack_depth; 11895 signed int x; 11896 signed int y; 11897 <unnamed type> _20; 11898 signed int _21; 11899 signed int _38; 11900 signed int _44; 11901 signed int _51; 11902 11903initial: 11904 stack[0] = arg_5(D); 11905 x_9 = stack[0]; 11906 stack[0] = x_9; 11907 stack[1] = x_9; 11908 stack[2] = 2; 11909 y_17 = stack[2]; 11910 x_19 = stack[1]; 11911 _20 = x_19 < y_17; 11912 _21 = (signed int) _20; 11913 stack[1] = _21; 11914 x_25 = stack[1]; 11915 if (x_25 != 0) 11916 goto <bb 4> (instr9); 11917 else 11918 goto <bb 3> (instr4); 11919 11920instr4: 11921/* DUP */: 11922 x_27 = stack[0]; 11923 stack[0] = x_27; 11924 stack[1] = x_27; 11925 stack[2] = 1; 11926 y_35 = stack[2]; 11927 x_37 = stack[1]; 11928 _38 = x_37 - y_35; 11929 stack[1] = _38; 11930 x_42 = stack[1]; 11931 _44 = factorial (x_42); 11932 stack[1] = _44; 11933 y_48 = stack[1]; 11934 x_50 = stack[0]; 11935 _51 = x_50 * y_48; 11936 stack[0] = _51; 11937 11938instr9: 11939/* RETURN */: 11940 x_55 = stack[0]; 11941 x_56 = x_55; 11942 stack =@{v@} @{CLOBBER@}; 11943 return x_56; 11944 11945@} 11946@end example 11947 11948@noindent 11949 11950Note how, in the above, all those @code{stack_depth} values are now just 11951constants: we're accessing specific stack locations at each opcode. 11952 11953The "esra" pass ("Early Scalar Replacement of Aggregates") breaks 11954out our "stack" array into individual elements: 11955 11956@example 11957$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra 11958@end example 11959 11960@noindent 11961 11962@example 11963;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11964 11965Created a replacement for stack offset: 0, size: 32: stack$0 11966Created a replacement for stack offset: 32, size: 32: stack$1 11967Created a replacement for stack offset: 64, size: 32: stack$2 11968 11969Symbols to be put in SSA form 11970@{ D.89 D.90 D.91 @} 11971Incremental SSA update started at block: 0 11972Number of blocks in CFG: 5 11973Number of blocks to update: 4 ( 80%) 11974 11975 11976factorial (signed int arg) 11977@{ 11978 signed int stack$2; 11979 signed int stack$1; 11980 signed int stack$0; 11981 signed int stack[8]; 11982 signed int stack_depth; 11983 signed int x; 11984 signed int y; 11985 <unnamed type> _20; 11986 signed int _21; 11987 signed int _38; 11988 signed int _44; 11989 signed int _51; 11990 11991initial: 11992 stack$0_45 = arg_5(D); 11993 x_9 = stack$0_45; 11994 stack$0_39 = x_9; 11995 stack$1_32 = x_9; 11996 stack$2_30 = 2; 11997 y_17 = stack$2_30; 11998 x_19 = stack$1_32; 11999 _20 = x_19 < y_17; 12000 _21 = (signed int) _20; 12001 stack$1_28 = _21; 12002 x_25 = stack$1_28; 12003 if (x_25 != 0) 12004 goto <bb 4> (instr9); 12005 else 12006 goto <bb 3> (instr4); 12007 12008instr4: 12009/* DUP */: 12010 x_27 = stack$0_39; 12011 stack$0_22 = x_27; 12012 stack$1_14 = x_27; 12013 stack$2_12 = 1; 12014 y_35 = stack$2_12; 12015 x_37 = stack$1_14; 12016 _38 = x_37 - y_35; 12017 stack$1_10 = _38; 12018 x_42 = stack$1_10; 12019 _44 = factorial (x_42); 12020 stack$1_6 = _44; 12021 y_48 = stack$1_6; 12022 x_50 = stack$0_22; 12023 _51 = x_50 * y_48; 12024 stack$0_1 = _51; 12025 12026 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)> 12027instr9: 12028/* RETURN */: 12029 x_55 = stack$0_52; 12030 x_56 = x_55; 12031 stack =@{v@} @{CLOBBER@}; 12032 return x_56; 12033 12034@} 12035@end example 12036 12037@noindent 12038 12039Hence at this point, all those pushes and pops of the stack are now 12040simply assignments to specific temporary variables. 12041 12042After some copy propagation, the stack manipulation has been completely 12043optimized away: 12044 12045@example 12046$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1 12047@end example 12048 12049@noindent 12050 12051@example 12052;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12053 12054factorial (signed int arg) 12055@{ 12056 signed int stack$2; 12057 signed int stack$1; 12058 signed int stack$0; 12059 signed int stack[8]; 12060 signed int stack_depth; 12061 signed int x; 12062 signed int y; 12063 <unnamed type> _20; 12064 signed int _21; 12065 signed int _38; 12066 signed int _44; 12067 signed int _51; 12068 12069initial: 12070 stack$0_39 = arg_5(D); 12071 _20 = arg_5(D) <= 1; 12072 _21 = (signed int) _20; 12073 if (_21 != 0) 12074 goto <bb 4> (instr9); 12075 else 12076 goto <bb 3> (instr4); 12077 12078instr4: 12079/* DUP */: 12080 _38 = arg_5(D) + -1; 12081 _44 = factorial (_38); 12082 _51 = arg_5(D) * _44; 12083 stack$0_1 = _51; 12084 12085 # stack$0_52 = PHI <arg_5(D)(2), _51(3)> 12086instr9: 12087/* RETURN */: 12088 stack =@{v@} @{CLOBBER@}; 12089 return stack$0_52; 12090 12091@} 12092@end example 12093 12094@noindent 12095 12096Later on, another pass finally eliminated @code{stack_depth} local and the 12097unused parts of the @cite{stack`} array altogether: 12098 12099@example 12100$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa 12101@end example 12102 12103@noindent 12104 12105@example 12106;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12107 12108Released 44 names, 314.29%, removed 44 holes 12109factorial (signed int arg) 12110@{ 12111 signed int stack$0; 12112 signed int mult_acc_1; 12113 <unnamed type> _5; 12114 signed int _6; 12115 signed int _7; 12116 signed int mul_tmp_10; 12117 signed int mult_acc_11; 12118 signed int mult_acc_13; 12119 12120 # arg_9 = PHI <arg_8(D)(0)> 12121 # mult_acc_13 = PHI <1(0)> 12122initial: 12123 12124 <bb 5>: 12125 # arg_4 = PHI <arg_9(2), _7(3)> 12126 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)> 12127 _5 = arg_4 <= 1; 12128 _6 = (signed int) _5; 12129 if (_6 != 0) 12130 goto <bb 4> (instr9); 12131 else 12132 goto <bb 3> (instr4); 12133 12134instr4: 12135/* DUP */: 12136 _7 = arg_4 + -1; 12137 mult_acc_11 = mult_acc_1 * arg_4; 12138 goto <bb 5>; 12139 12140 # stack$0_12 = PHI <arg_4(5)> 12141instr9: 12142/* RETURN */: 12143 mul_tmp_10 = mult_acc_1 * stack$0_12; 12144 return mul_tmp_10; 12145 12146@} 12147@end example 12148 12149@noindent 12150 12151@node Elimination of tail recursion<2>,,Optimizing away stack manipulation<2>,Behind the curtain How does our code get optimized?<2> 12152@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{130} 12153@subsubsection Elimination of tail recursion 12154 12155 12156Another significant optimization is the detection that the call to 12157@code{factorial} is tail recursion, which can be eliminated in favor of 12158an iteration: 12159 12160@example 12161$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1 12162@end example 12163 12164@noindent 12165 12166@example 12167;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12168 12169 12170Symbols to be put in SSA form 12171@{ D.88 @} 12172Incremental SSA update started at block: 0 12173Number of blocks in CFG: 5 12174Number of blocks to update: 4 ( 80%) 12175 12176 12177factorial (signed int arg) 12178@{ 12179 signed int stack$2; 12180 signed int stack$1; 12181 signed int stack$0; 12182 signed int stack[8]; 12183 signed int stack_depth; 12184 signed int x; 12185 signed int y; 12186 signed int mult_acc_1; 12187 <unnamed type> _20; 12188 signed int _21; 12189 signed int _38; 12190 signed int mul_tmp_44; 12191 signed int mult_acc_51; 12192 12193 # arg_5 = PHI <arg_39(D)(0), _38(3)> 12194 # mult_acc_1 = PHI <1(0), mult_acc_51(3)> 12195initial: 12196 _20 = arg_5 <= 1; 12197 _21 = (signed int) _20; 12198 if (_21 != 0) 12199 goto <bb 4> (instr9); 12200 else 12201 goto <bb 3> (instr4); 12202 12203instr4: 12204/* DUP */: 12205 _38 = arg_5 + -1; 12206 mult_acc_51 = mult_acc_1 * arg_5; 12207 goto <bb 2> (initial); 12208 12209 # stack$0_52 = PHI <arg_5(2)> 12210instr9: 12211/* RETURN */: 12212 stack =@{v@} @{CLOBBER@}; 12213 mul_tmp_44 = mult_acc_1 * stack$0_52; 12214 return mul_tmp_44; 12215 12216@} 12217@end example 12218 12219@noindent 12220 12221@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 12222@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12223@c 12224@c This is free software: you can redistribute it and/or modify it 12225@c under the terms of the GNU General Public License as published by 12226@c the Free Software Foundation, either version 3 of the License, or 12227@c (at your option) any later version. 12228@c 12229@c This program is distributed in the hope that it will be useful, but 12230@c WITHOUT ANY WARRANTY; without even the implied warranty of 12231@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12232@c General Public License for more details. 12233@c 12234@c You should have received a copy of the GNU General Public License 12235@c along with this program. If not, see 12236@c <http://www.gnu.org/licenses/>. 12237 12238@node Topic Reference<2>,,Tutorial<2>,C++ bindings for libgccjit 12239@anchor{cp/topics/index doc}@anchor{131}@anchor{cp/topics/index topic-reference}@anchor{132} 12240@section Topic Reference 12241 12242 12243@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 12244@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12245@c 12246@c This is free software: you can redistribute it and/or modify it 12247@c under the terms of the GNU General Public License as published by 12248@c the Free Software Foundation, either version 3 of the License, or 12249@c (at your option) any later version. 12250@c 12251@c This program is distributed in the hope that it will be useful, but 12252@c WITHOUT ANY WARRANTY; without even the implied warranty of 12253@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12254@c General Public License for more details. 12255@c 12256@c You should have received a copy of the GNU General Public License 12257@c along with this program. If not, see 12258@c <http://www.gnu.org/licenses/>. 12259 12260@menu 12261* Compilation contexts: Compilation contexts<2>. 12262* Objects: Objects<2>. 12263* Types: Types<2>. 12264* Expressions: Expressions<2>. 12265* Creating and using functions: Creating and using functions<2>. 12266* Source Locations: Source Locations<2>. 12267* Compiling a context: Compiling a context<2>. 12268 12269Compilation contexts 12270 12271* Lifetime-management: Lifetime-management<2>. 12272* Thread-safety: Thread-safety<2>. 12273* Error-handling: Error-handling<3>. 12274* Debugging: Debugging<2>. 12275* Options: Options<4>. 12276 12277Options 12278 12279* String Options: String Options<2>. 12280* Boolean options: Boolean options<2>. 12281* Integer options: Integer options<2>. 12282* Additional command-line options: Additional command-line options<2>. 12283 12284Types 12285 12286* Standard types: Standard types<2>. 12287* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 12288* Structures and unions: Structures and unions<2>. 12289 12290Expressions 12291 12292* Rvalues: Rvalues<2>. 12293* Lvalues: Lvalues<2>. 12294* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 12295 12296Rvalues 12297 12298* Simple expressions: Simple expressions<2>. 12299* Unary Operations: Unary Operations<2>. 12300* Binary Operations: Binary Operations<2>. 12301* Comparisons: Comparisons<2>. 12302* Function calls: Function calls<2>. 12303* Type-coercion: Type-coercion<2>. 12304 12305Lvalues 12306 12307* Global variables: Global variables<2>. 12308 12309Creating and using functions 12310 12311* Params: Params<2>. 12312* Functions: Functions<2>. 12313* Blocks: Blocks<2>. 12314* Statements: Statements<2>. 12315 12316Source Locations 12317 12318* Faking it: Faking it<2>. 12319 12320Compiling a context 12321 12322* In-memory compilation: In-memory compilation<2>. 12323* Ahead-of-time compilation: Ahead-of-time compilation<2>. 12324 12325@end menu 12326 12327 12328@node Compilation contexts<2>,Objects<2>,,Topic Reference<2> 12329@anchor{cp/topics/contexts compilation-contexts}@anchor{133}@anchor{cp/topics/contexts doc}@anchor{134} 12330@subsection Compilation contexts 12331 12332 12333@geindex gccjit;;context (C++ class) 12334@anchor{cp/topics/contexts gccjit context}@anchor{135} 12335@deffn {C++ Class} gccjit::context 12336@end deffn 12337 12338The top-level of the C++ API is the @pxref{135,,gccjit;;context} type. 12339 12340A @pxref{135,,gccjit;;context} instance encapsulates the state of a 12341compilation. 12342 12343You can set up options on it, and add types, functions and code. 12344Invoking @pxref{10e,,gccjit;;context;;compile()} on it gives you a 12345@pxref{16,,gcc_jit_result *}. 12346 12347It is a thin wrapper around the C API's @pxref{8,,gcc_jit_context *}. 12348 12349@menu 12350* Lifetime-management: Lifetime-management<2>. 12351* Thread-safety: Thread-safety<2>. 12352* Error-handling: Error-handling<3>. 12353* Debugging: Debugging<2>. 12354* Options: Options<4>. 12355 12356@end menu 12357 12358@node Lifetime-management<2>,Thread-safety<2>,,Compilation contexts<2> 12359@anchor{cp/topics/contexts lifetime-management}@anchor{136} 12360@subsubsection Lifetime-management 12361 12362 12363Contexts are the unit of lifetime-management within the API: objects 12364have their lifetime bounded by the context they are created within, and 12365cleanup of such objects is done for you when the context is released. 12366 12367@geindex gccjit;;context;;acquire (C++ function) 12368@anchor{cp/topics/contexts gccjit context acquire}@anchor{108} 12369@deffn {C++ Function} gccjit::context gccjit::context::acquire () 12370 12371This function acquires a new @pxref{135,,gccjit;;context} instance, 12372which is independent of any others that may be present within this 12373process. 12374@end deffn 12375 12376@geindex gccjit;;context;;release (C++ function) 12377@anchor{cp/topics/contexts gccjit context release}@anchor{10a} 12378@deffn {C++ Function} void gccjit::context::release () 12379 12380This function releases all resources associated with the given context. 12381Both the context itself and all of its @code{gccjit::object *} 12382instances are cleaned up. It should be called exactly once on a given 12383context. 12384 12385It is invalid to use the context or any of its "contextual" objects 12386after calling this. 12387 12388@example 12389ctxt.release (); 12390@end example 12391 12392@noindent 12393@end deffn 12394 12395@geindex gccjit;;context;;new_child_context (C++ function) 12396@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{137} 12397@deffn {C++ Function} gccjit::context gccjit::context::new_child_context () 12398 12399Given an existing JIT context, create a child context. 12400 12401The child inherits a copy of all option-settings from the parent. 12402 12403The child can reference objects created within the parent, but not 12404vice-versa. 12405 12406The lifetime of the child context must be bounded by that of the 12407parent: you should release a child context before releasing the parent 12408context. 12409 12410If you use a function from a parent context within a child context, 12411you have to compile the parent context before you can compile the 12412child context, and the gccjit::result of the parent context must 12413outlive the gccjit::result of the child context. 12414 12415This allows caching of shared initializations. For example, you could 12416create types and declarations of global functions in a parent context 12417once within a process, and then create child contexts whenever a 12418function or loop becomes hot. Each such child context can be used for 12419JIT-compiling just one function or loop, but can reference types 12420and helper functions created within the parent context. 12421 12422Contexts can be arbitrarily nested, provided the above rules are 12423followed, but it's probably not worth going above 2 or 3 levels, and 12424there will likely be a performance hit for such nesting. 12425@end deffn 12426 12427@node Thread-safety<2>,Error-handling<3>,Lifetime-management<2>,Compilation contexts<2> 12428@anchor{cp/topics/contexts thread-safety}@anchor{138} 12429@subsubsection Thread-safety 12430 12431 12432Instances of @pxref{135,,gccjit;;context} created via 12433@pxref{108,,gccjit;;context;;acquire()} are independent from each other: 12434only one thread may use a given context at once, but multiple threads 12435could each have their own contexts without needing locks. 12436 12437Contexts created via @pxref{137,,gccjit;;context;;new_child_context()} are 12438related to their parent context. They can be partitioned by their 12439ultimate ancestor into independent "family trees". Only one thread 12440within a process may use a given "family tree" of such contexts at once, 12441and if you're using multiple threads you should provide your own locking 12442around entire such context partitions. 12443 12444@node Error-handling<3>,Debugging<2>,Thread-safety<2>,Compilation contexts<2> 12445@anchor{cp/topics/contexts error-handling}@anchor{139} 12446@subsubsection Error-handling 12447 12448 12449@c FIXME: How does error-handling work for C++ API? 12450 12451You can only compile and get code from a context if no errors occur. 12452 12453In general, if an error occurs when using an API entrypoint, it returns 12454NULL. You don't have to check everywhere for NULL results, since the 12455API gracefully handles a NULL being passed in for any argument. 12456 12457Errors are printed on stderr and can be queried using 12458@pxref{13a,,gccjit;;context;;get_first_error()}. 12459 12460@geindex gccjit;;context;;get_first_error (C++ function) 12461@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{13a} 12462@deffn {C++ Function} const char* gccjit::context::get_first_error (gccjit::context* ctxt) 12463 12464Returns the first error message that occurred on the context. 12465 12466The returned string is valid for the rest of the lifetime of the 12467context. 12468 12469If no errors occurred, this will be NULL. 12470@end deffn 12471 12472@node Debugging<2>,Options<4>,Error-handling<3>,Compilation contexts<2> 12473@anchor{cp/topics/contexts debugging}@anchor{13b} 12474@subsubsection Debugging 12475 12476 12477@geindex gccjit;;context;;dump_to_file (C++ function) 12478@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{13c} 12479@deffn {C++ Function} void gccjit::context::dump_to_file (const std::string& path, int update_locations) 12480 12481To help with debugging: dump a C-like representation to the given path, 12482describing what's been set up on the context. 12483 12484If "update_locations" is true, then also set up @pxref{13d,,gccjit;;location} 12485information throughout the context, pointing at the dump file as if it 12486were a source file. This may be of use in conjunction with 12487@code{GCCJIT::BOOL_OPTION_DEBUGINFO} to allow stepping through the 12488code in a debugger. 12489@end deffn 12490 12491@geindex gccjit;;context;;dump_reproducer_to_file (C++ function) 12492@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{13e} 12493@deffn {C++ Function} void gccjit::context::dump_reproducer_to_file (gcc_jit_context* ctxt, const char* path) 12494 12495This is a thin wrapper around the C API 12496@pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}, and hence works the 12497same way. 12498 12499Note that the generated source is C code, not C++; this might be of use 12500for seeing what the C++ bindings are doing at the C level. 12501@end deffn 12502 12503@node Options<4>,,Debugging<2>,Compilation contexts<2> 12504@anchor{cp/topics/contexts options}@anchor{13f} 12505@subsubsection Options 12506 12507 12508@menu 12509* String Options: String Options<2>. 12510* Boolean options: Boolean options<2>. 12511* Integer options: Integer options<2>. 12512* Additional command-line options: Additional command-line options<2>. 12513 12514@end menu 12515 12516@node String Options<2>,Boolean options<2>,,Options<4> 12517@anchor{cp/topics/contexts string-options}@anchor{140} 12518@subsubsection String Options 12519 12520 12521@geindex gccjit;;context;;set_str_option (C++ function) 12522@anchor{cp/topics/contexts gccjit context set_str_option__enum cCP}@anchor{141} 12523@deffn {C++ Function} void gccjit::context::set_str_option (enum gcc_jit_str_option, const char* value) 12524 12525Set a string option of the context. 12526 12527This is a thin wrapper around the C API 12528@pxref{61,,gcc_jit_context_set_str_option()}; the options have the same 12529meaning. 12530@end deffn 12531 12532@node Boolean options<2>,Integer options<2>,String Options<2>,Options<4> 12533@anchor{cp/topics/contexts boolean-options}@anchor{142} 12534@subsubsection Boolean options 12535 12536 12537@geindex gccjit;;context;;set_bool_option (C++ function) 12538@anchor{cp/topics/contexts gccjit context set_bool_option__enum i}@anchor{110} 12539@deffn {C++ Function} void gccjit::context::set_bool_option (enum gcc_jit_bool_option, int value) 12540 12541Set a boolean option of the context. 12542 12543This is a thin wrapper around the C API 12544@pxref{1b,,gcc_jit_context_set_bool_option()}; the options have the same 12545meaning. 12546@end deffn 12547 12548@geindex gccjit;;context;;set_bool_allow_unreachable_blocks (C++ function) 12549@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{143} 12550@deffn {C++ Function} void gccjit::context::set_bool_allow_unreachable_blocks (int bool_value) 12551 12552By default, libgccjit will issue an error about unreachable blocks 12553within a function. 12554 12555This entrypoint can be used to disable that error; it is a thin wrapper 12556around the C API 12557@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}. 12558 12559This entrypoint was added in @pxref{6c,,LIBGCCJIT_ABI_2}; you can test for 12560its presence using 12561 12562@example 12563#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 12564@end example 12565 12566@noindent 12567@end deffn 12568 12569@geindex gccjit;;context;;set_bool_use_external_driver (C++ function) 12570@anchor{cp/topics/contexts gccjit context set_bool_use_external_driver__i}@anchor{144} 12571@deffn {C++ Function} void gccjit::context::set_bool_use_external_driver (int bool_value) 12572 12573libgccjit internally generates assembler, and uses "driver" code 12574for converting it to other formats (e.g. shared libraries). 12575 12576By default, libgccjit will use an embedded copy of the driver 12577code. 12578 12579This option can be used to instead invoke an external driver executable 12580as a subprocess; it is a thin wrapper around the C API 12581@pxref{6d,,gcc_jit_context_set_bool_use_external_driver()}. 12582 12583This entrypoint was added in @pxref{6e,,LIBGCCJIT_ABI_5}; you can test for 12584its presence using 12585 12586@example 12587#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver 12588@end example 12589 12590@noindent 12591@end deffn 12592 12593@node Integer options<2>,Additional command-line options<2>,Boolean options<2>,Options<4> 12594@anchor{cp/topics/contexts integer-options}@anchor{145} 12595@subsubsection Integer options 12596 12597 12598@geindex gccjit;;context;;set_int_option (C++ function) 12599@anchor{cp/topics/contexts gccjit context set_int_option__enum i}@anchor{111} 12600@deffn {C++ Function} void gccjit::context::set_int_option (enum gcc_jit_int_option, int value) 12601 12602Set an integer option of the context. 12603 12604This is a thin wrapper around the C API 12605@pxref{1e,,gcc_jit_context_set_int_option()}; the options have the same 12606meaning. 12607@end deffn 12608 12609@node Additional command-line options<2>,,Integer options<2>,Options<4> 12610@anchor{cp/topics/contexts additional-command-line-options}@anchor{146} 12611@subsubsection Additional command-line options 12612 12613 12614@geindex gccjit;;context;;add_command_line_option (C++ function) 12615@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{147} 12616@deffn {C++ Function} void gccjit::context::add_command_line_option (const char* optname) 12617 12618Add an arbitrary gcc command-line option to the context for use 12619when compiling. 12620 12621This is a thin wrapper around the C API 12622@pxref{72,,gcc_jit_context_add_command_line_option()}. 12623 12624This entrypoint was added in @pxref{73,,LIBGCCJIT_ABI_1}; you can test for 12625its presence using 12626 12627@example 12628#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 12629@end example 12630 12631@noindent 12632@end deffn 12633 12634@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 12635@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12636@c 12637@c This is free software: you can redistribute it and/or modify it 12638@c under the terms of the GNU General Public License as published by 12639@c the Free Software Foundation, either version 3 of the License, or 12640@c (at your option) any later version. 12641@c 12642@c This program is distributed in the hope that it will be useful, but 12643@c WITHOUT ANY WARRANTY; without even the implied warranty of 12644@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12645@c General Public License for more details. 12646@c 12647@c You should have received a copy of the GNU General Public License 12648@c along with this program. If not, see 12649@c <http://www.gnu.org/licenses/>. 12650 12651@node Objects<2>,Types<2>,Compilation contexts<2>,Topic Reference<2> 12652@anchor{cp/topics/objects objects}@anchor{148}@anchor{cp/topics/objects doc}@anchor{149} 12653@subsection Objects 12654 12655 12656@geindex gccjit;;object (C++ class) 12657@anchor{cp/topics/objects gccjit object}@anchor{14a} 12658@deffn {C++ Class} gccjit::object 12659@end deffn 12660 12661Almost every entity in the API (with the exception of 12662@pxref{135,,gccjit;;context} and @pxref{16,,gcc_jit_result *}) is a 12663"contextual" object, a @pxref{14a,,gccjit;;object}. 12664 12665A JIT object: 12666 12667@quotation 12668 12669 12670@itemize * 12671 12672@item 12673is associated with a @pxref{135,,gccjit;;context}. 12674 12675@item 12676is automatically cleaned up for you when its context is released so 12677you don't need to manually track and cleanup all objects, just the 12678contexts. 12679@end itemize 12680@end quotation 12681 12682The C++ class hierarchy within the @code{gccjit} namespace looks like this: 12683 12684@example 12685+- object 12686 +- location 12687 +- type 12688 +- struct 12689 +- field 12690 +- function 12691 +- block 12692 +- rvalue 12693 +- lvalue 12694 +- param 12695 +- case_ 12696@end example 12697 12698@noindent 12699 12700The @pxref{14a,,gccjit;;object} base class has the following operations: 12701 12702@geindex gccjit;;object;;get_context (C++ function) 12703@anchor{cp/topics/objects gccjit object get_contextC}@anchor{14b} 12704@deffn {C++ Function} gccjit::context gccjit::object::get_context () const 12705 12706Which context is the obj within? 12707@end deffn 12708 12709@geindex gccjit;;object;;get_debug_string (C++ function) 12710@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{10b} 12711@deffn {C++ Function} std::string gccjit::object::get_debug_string () const 12712 12713Generate a human-readable description for the given object. 12714 12715For example, 12716 12717@example 12718printf ("obj: %s\n", obj.get_debug_string ().c_str ()); 12719@end example 12720 12721@noindent 12722 12723might give this text on stdout: 12724 12725@example 12726obj: 4.0 * (float)i 12727@end example 12728 12729@noindent 12730@end deffn 12731 12732@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 12733@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12734@c 12735@c This is free software: you can redistribute it and/or modify it 12736@c under the terms of the GNU General Public License as published by 12737@c the Free Software Foundation, either version 3 of the License, or 12738@c (at your option) any later version. 12739@c 12740@c This program is distributed in the hope that it will be useful, but 12741@c WITHOUT ANY WARRANTY; without even the implied warranty of 12742@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12743@c General Public License for more details. 12744@c 12745@c You should have received a copy of the GNU General Public License 12746@c along with this program. If not, see 12747@c <http://www.gnu.org/licenses/>. 12748 12749@node Types<2>,Expressions<2>,Objects<2>,Topic Reference<2> 12750@anchor{cp/topics/types doc}@anchor{14c}@anchor{cp/topics/types types}@anchor{14d} 12751@subsection Types 12752 12753 12754@geindex gccjit;;type (C++ class) 12755@anchor{cp/topics/types gccjit type}@anchor{14e} 12756@deffn {C++ Class} gccjit::type 12757 12758gccjit::type represents a type within the library. It is a subclass 12759of @pxref{14a,,gccjit;;object}. 12760@end deffn 12761 12762Types can be created in several ways: 12763 12764 12765@itemize * 12766 12767@item 12768fundamental types can be accessed using 12769@pxref{109,,gccjit;;context;;get_type()}: 12770 12771@example 12772gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 12773@end example 12774 12775@noindent 12776 12777or using the @code{gccjit::context::get_int_type} template: 12778 12779@example 12780gccjit::type t = ctxt.get_int_type <unsigned short> (); 12781@end example 12782 12783@noindent 12784 12785See @pxref{b,,gcc_jit_context_get_type()} for the available types. 12786 12787@item 12788derived types can be accessed by using functions such as 12789@pxref{14f,,gccjit;;type;;get_pointer()} and @pxref{150,,gccjit;;type;;get_const()}: 12790 12791@example 12792gccjit::type const_int_star = int_type.get_const ().get_pointer (); 12793gccjit::type int_const_star = int_type.get_pointer ().get_const (); 12794@end example 12795 12796@noindent 12797 12798@item 12799by creating structures (see below). 12800@end itemize 12801 12802@menu 12803* Standard types: Standard types<2>. 12804* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 12805* Structures and unions: Structures and unions<2>. 12806 12807@end menu 12808 12809@node Standard types<2>,Pointers const and volatile<2>,,Types<2> 12810@anchor{cp/topics/types standard-types}@anchor{151} 12811@subsubsection Standard types 12812 12813 12814@geindex gccjit;;context;;get_type (C++ function) 12815@anchor{cp/topics/types gccjit context get_type__enum}@anchor{109} 12816@deffn {C++ Function} gccjit::type gccjit::context::get_type (enum gcc_jit_types) 12817 12818Access a specific type. This is a thin wrapper around 12819@pxref{b,,gcc_jit_context_get_type()}; the parameter has the same meaning. 12820@end deffn 12821 12822@geindex gccjit;;context;;get_int_type (C++ function) 12823@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{152} 12824@deffn {C++ Function} gccjit::type gccjit::context::get_int_type (size_t num_bytes, int is_signed) 12825 12826Access the integer type of the given size. 12827@end deffn 12828 12829@geindex gccjit;;context;;get_int_type<T> (C++ function) 12830@anchor{cp/topics/types gccjit context get_int_type T}@anchor{153} 12831@deffn {C++ Function} gccjit::type gccjit::context::get_int_type<T> () 12832 12833Access the given integer type. For example, you could map the 12834@code{unsigned short} type into a gccjit::type via: 12835 12836@example 12837gccjit::type t = ctxt.get_int_type <unsigned short> (); 12838@end example 12839 12840@noindent 12841@end deffn 12842 12843@node Pointers const and volatile<2>,Structures and unions<2>,Standard types<2>,Types<2> 12844@anchor{cp/topics/types pointers-const-and-volatile}@anchor{154} 12845@subsubsection Pointers, @cite{const}, and @cite{volatile} 12846 12847 12848@geindex gccjit;;type;;get_pointer (C++ function) 12849@anchor{cp/topics/types gccjit type get_pointer}@anchor{14f} 12850@deffn {C++ Function} gccjit::type gccjit::type::get_pointer () 12851 12852Given type "T", get type "T*". 12853@end deffn 12854 12855@c FIXME: get_const doesn't seem to exist 12856 12857@geindex gccjit;;type;;get_const (C++ function) 12858@anchor{cp/topics/types gccjit type get_const}@anchor{150} 12859@deffn {C++ Function} gccjit::type gccjit::type::get_const () 12860 12861Given type "T", get type "const T". 12862@end deffn 12863 12864@geindex gccjit;;type;;get_volatile (C++ function) 12865@anchor{cp/topics/types gccjit type get_volatile}@anchor{155} 12866@deffn {C++ Function} gccjit::type gccjit::type::get_volatile () 12867 12868Given type "T", get type "volatile T". 12869@end deffn 12870 12871@geindex gccjit;;context;;new_array_type (C++ function) 12872@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{156} 12873@deffn {C++ Function} gccjit::type gccjit::context::new_array_type (gccjit::type element_type, int num_elements, gccjit::location loc) 12874 12875Given type "T", get type "T[N]" (for a constant N). 12876Param "loc" is optional. 12877@end deffn 12878 12879@node Structures and unions<2>,,Pointers const and volatile<2>,Types<2> 12880@anchor{cp/topics/types structures-and-unions}@anchor{157} 12881@subsubsection Structures and unions 12882 12883 12884@geindex gccjit;;struct_ (C++ class) 12885@anchor{cp/topics/types gccjit struct_}@anchor{158} 12886@deffn {C++ Class} gccjit::struct_ 12887@end deffn 12888 12889A compound type analagous to a C @cite{struct}. 12890 12891@pxref{158,,gccjit;;struct_} is a subclass of @pxref{14e,,gccjit;;type} (and thus 12892of @pxref{14a,,gccjit;;object} in turn). 12893 12894@geindex gccjit;;field (C++ class) 12895@anchor{cp/topics/types gccjit field}@anchor{159} 12896@deffn {C++ Class} gccjit::field 12897@end deffn 12898 12899A field within a @pxref{158,,gccjit;;struct_}. 12900 12901@pxref{159,,gccjit;;field} is a subclass of @pxref{14a,,gccjit;;object}. 12902 12903You can model C @cite{struct} types by creating @pxref{158,,gccjit;;struct_} and 12904@pxref{159,,gccjit;;field} instances, in either order: 12905 12906 12907@itemize * 12908 12909@item 12910by creating the fields, then the structure. For example, to model: 12911 12912@example 12913struct coord @{double x; double y; @}; 12914@end example 12915 12916@noindent 12917 12918you could call: 12919 12920@example 12921gccjit::field field_x = ctxt.new_field (double_type, "x"); 12922gccjit::field field_y = ctxt.new_field (double_type, "y"); 12923std::vector fields; 12924fields.push_back (field_x); 12925fields.push_back (field_y); 12926gccjit::struct_ coord = ctxt.new_struct_type ("coord", fields); 12927@end example 12928 12929@noindent 12930 12931@item 12932by creating the structure, then populating it with fields, typically 12933to allow modelling self-referential structs such as: 12934 12935@example 12936struct node @{ int m_hash; struct node *m_next; @}; 12937@end example 12938 12939@noindent 12940 12941like this: 12942 12943@example 12944gccjit::struct_ node = ctxt.new_opaque_struct_type ("node"); 12945gccjit::type node_ptr = node.get_pointer (); 12946gccjit::field field_hash = ctxt.new_field (int_type, "m_hash"); 12947gccjit::field field_next = ctxt.new_field (node_ptr, "m_next"); 12948std::vector fields; 12949fields.push_back (field_hash); 12950fields.push_back (field_next); 12951node.set_fields (fields); 12952@end example 12953 12954@noindent 12955@end itemize 12956 12957@c FIXME: the above API doesn't seem to exist yet 12958 12959@geindex gccjit;;context;;new_field (C++ function) 12960@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{15a} 12961@deffn {C++ Function} gccjit::field gccjit::context::new_field (gccjit::type type, const char* name, gccjit::location loc) 12962 12963Construct a new field, with the given type and name. 12964@end deffn 12965 12966@geindex gccjit;;context;;new_struct_type (C++ function) 12967@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{15b} 12968@deffn {C++ Function} gccjit::struct_ gccjit::context::new_struct_type (const std::string& name, std::vector<field>& fields, gccjit::location loc) 12969 12970@quotation 12971 12972Construct a new struct type, with the given name and fields. 12973@end quotation 12974@end deffn 12975 12976@geindex gccjit;;context;;new_opaque_struct (C++ function) 12977@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{15c} 12978@deffn {C++ Function} gccjit::struct_ gccjit::context::new_opaque_struct (const std::string& name, gccjit::location loc) 12979 12980Construct a new struct type, with the given name, but without 12981specifying the fields. The fields can be omitted (in which case the 12982size of the struct is not known), or later specified using 12983@pxref{87,,gcc_jit_struct_set_fields()}. 12984@end deffn 12985 12986@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 12987@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12988@c 12989@c This is free software: you can redistribute it and/or modify it 12990@c under the terms of the GNU General Public License as published by 12991@c the Free Software Foundation, either version 3 of the License, or 12992@c (at your option) any later version. 12993@c 12994@c This program is distributed in the hope that it will be useful, but 12995@c WITHOUT ANY WARRANTY; without even the implied warranty of 12996@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12997@c General Public License for more details. 12998@c 12999@c You should have received a copy of the GNU General Public License 13000@c along with this program. If not, see 13001@c <http://www.gnu.org/licenses/>. 13002 13003@node Expressions<2>,Creating and using functions<2>,Types<2>,Topic Reference<2> 13004@anchor{cp/topics/expressions expressions}@anchor{15d}@anchor{cp/topics/expressions doc}@anchor{15e} 13005@subsection Expressions 13006 13007 13008@menu 13009* Rvalues: Rvalues<2>. 13010* Lvalues: Lvalues<2>. 13011* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 13012 13013Rvalues 13014 13015* Simple expressions: Simple expressions<2>. 13016* Unary Operations: Unary Operations<2>. 13017* Binary Operations: Binary Operations<2>. 13018* Comparisons: Comparisons<2>. 13019* Function calls: Function calls<2>. 13020* Type-coercion: Type-coercion<2>. 13021 13022Lvalues 13023 13024* Global variables: Global variables<2>. 13025 13026@end menu 13027 13028 13029@node Rvalues<2>,Lvalues<2>,,Expressions<2> 13030@anchor{cp/topics/expressions rvalues}@anchor{15f} 13031@subsubsection Rvalues 13032 13033 13034@geindex gccjit;;rvalue (C++ class) 13035@anchor{cp/topics/expressions gccjit rvalue}@anchor{160} 13036@deffn {C++ Class} gccjit::rvalue 13037@end deffn 13038 13039A @pxref{160,,gccjit;;rvalue} is an expression that can be computed. It is a 13040subclass of @pxref{14a,,gccjit;;object}, and is a thin wrapper around 13041@pxref{13,,gcc_jit_rvalue *} from the C API. 13042 13043It can be simple, e.g.: 13044 13045@quotation 13046 13047 13048@itemize * 13049 13050@item 13051an integer value e.g. @cite{0} or @cite{42} 13052 13053@item 13054a string literal e.g. @cite{"Hello world"} 13055 13056@item 13057a variable e.g. @cite{i}. These are also lvalues (see below). 13058@end itemize 13059@end quotation 13060 13061or compound e.g.: 13062 13063@quotation 13064 13065 13066@itemize * 13067 13068@item 13069a unary expression e.g. @cite{!cond} 13070 13071@item 13072a binary expression e.g. @cite{(a + b)} 13073 13074@item 13075a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} 13076 13077@item 13078etc. 13079@end itemize 13080@end quotation 13081 13082Every rvalue has an associated type, and the API will check to ensure 13083that types match up correctly (otherwise the context will emit an error). 13084 13085@geindex gccjit;;rvalue;;get_type (C++ function) 13086@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{161} 13087@deffn {C++ Function} gccjit::type gccjit::rvalue::get_type () 13088 13089Get the type of this rvalue. 13090@end deffn 13091 13092@menu 13093* Simple expressions: Simple expressions<2>. 13094* Unary Operations: Unary Operations<2>. 13095* Binary Operations: Binary Operations<2>. 13096* Comparisons: Comparisons<2>. 13097* Function calls: Function calls<2>. 13098* Type-coercion: Type-coercion<2>. 13099 13100@end menu 13101 13102@node Simple expressions<2>,Unary Operations<2>,,Rvalues<2> 13103@anchor{cp/topics/expressions simple-expressions}@anchor{162} 13104@subsubsection Simple expressions 13105 13106 13107@geindex gccjit;;context;;new_rvalue (C++ function) 13108@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{11d} 13109@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, int value) const 13110 13111Given a numeric type (integer or floating point), build an rvalue for 13112the given constant @code{int} value. 13113@end deffn 13114 13115@geindex gccjit;;context;;new_rvalue (C++ function) 13116@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{163} 13117@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, long value) const 13118 13119Given a numeric type (integer or floating point), build an rvalue for 13120the given constant @code{long} value. 13121@end deffn 13122 13123@geindex gccjit;;context;;zero (C++ function) 13124@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{119} 13125@deffn {C++ Function} gccjit::rvalue gccjit::context::zero (gccjit::type numeric_type) const 13126 13127Given a numeric type (integer or floating point), get the rvalue for 13128zero. Essentially this is just a shortcut for: 13129 13130@example 13131ctxt.new_rvalue (numeric_type, 0) 13132@end example 13133 13134@noindent 13135@end deffn 13136 13137@geindex gccjit;;context;;one (C++ function) 13138@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{164} 13139@deffn {C++ Function} gccjit::rvalue gccjit::context::one (gccjit::type numeric_type) const 13140 13141Given a numeric type (integer or floating point), get the rvalue for 13142one. Essentially this is just a shortcut for: 13143 13144@example 13145ctxt.new_rvalue (numeric_type, 1) 13146@end example 13147 13148@noindent 13149@end deffn 13150 13151@geindex gccjit;;context;;new_rvalue (C++ function) 13152@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{165} 13153@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, double value) const 13154 13155Given a numeric type (integer or floating point), build an rvalue for 13156the given constant @code{double} value. 13157@end deffn 13158 13159@geindex gccjit;;context;;new_rvalue (C++ function) 13160@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{166} 13161@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type pointer_type, void* value) const 13162 13163Given a pointer type, build an rvalue for the given address. 13164@end deffn 13165 13166@geindex gccjit;;context;;new_rvalue (C++ function) 13167@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{167} 13168@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (const std::string& value) const 13169 13170Generate an rvalue of type @code{GCC_JIT_TYPE_CONST_CHAR_PTR} for 13171the given string. This is akin to a string literal. 13172@end deffn 13173 13174@node Unary Operations<2>,Binary Operations<2>,Simple expressions<2>,Rvalues<2> 13175@anchor{cp/topics/expressions unary-operations}@anchor{168} 13176@subsubsection Unary Operations 13177 13178 13179@geindex gccjit;;context;;new_unary_op (C++ function) 13180@anchor{cp/topics/expressions gccjit context new_unary_op__enum gccjit type gccjit rvalue gccjit location}@anchor{169} 13181@deffn {C++ Function} gccjit::rvalue gccjit::context::new_unary_op (enum gcc_jit_unary_op, gccjit::type result_type, gccjit::rvalue rvalue, gccjit::location loc) 13182 13183Build a unary operation out of an input rvalue. 13184 13185Parameter @code{loc} is optional. 13186 13187This is a thin wrapper around the C API's 13188@pxref{94,,gcc_jit_context_new_unary_op()} and the available unary 13189operations are documented there. 13190@end deffn 13191 13192There are shorter ways to spell the various specific kinds of unary 13193operation: 13194 13195@geindex gccjit;;context;;new_minus (C++ function) 13196@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{16a} 13197@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 13198 13199Negate an arithmetic value; for example: 13200 13201@example 13202gccjit::rvalue negpi = ctxt.new_minus (t_double, pi); 13203@end example 13204 13205@noindent 13206 13207builds the equivalent of this C expression: 13208 13209@example 13210-pi 13211@end example 13212 13213@noindent 13214@end deffn 13215 13216@geindex new_bitwise_negate (C++ function) 13217@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{16b} 13218@deffn {C++ Function} gccjit::rvalue new_bitwise_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 13219 13220Bitwise negation of an integer value (one's complement); for example: 13221 13222@example 13223gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a); 13224@end example 13225 13226@noindent 13227 13228builds the equivalent of this C expression: 13229 13230@example 13231~a 13232@end example 13233 13234@noindent 13235@end deffn 13236 13237@geindex new_logical_negate (C++ function) 13238@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{16c} 13239@deffn {C++ Function} gccjit::rvalue new_logical_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 13240 13241Logical negation of an arithmetic or pointer value; for example: 13242 13243@example 13244gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond); 13245@end example 13246 13247@noindent 13248 13249builds the equivalent of this C expression: 13250 13251@example 13252!cond 13253@end example 13254 13255@noindent 13256@end deffn 13257 13258The most concise way to spell them is with overloaded operators: 13259 13260@geindex operator- (C++ function) 13261@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{16d} 13262@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a) 13263 13264@example 13265gccjit::rvalue negpi = -pi; 13266@end example 13267 13268@noindent 13269@end deffn 13270 13271@geindex operator~ (C++ function) 13272@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{16e} 13273@deffn {C++ Function} gccjit::rvalue operator~ (gccjit::rvalue a) 13274 13275@example 13276gccjit::rvalue mask = ~a; 13277@end example 13278 13279@noindent 13280@end deffn 13281 13282@geindex operator! (C++ function) 13283@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{16f} 13284@deffn {C++ Function} gccjit::rvalue operator! (gccjit::rvalue a) 13285 13286@example 13287gccjit::rvalue guard = !cond; 13288@end example 13289 13290@noindent 13291@end deffn 13292 13293@node Binary Operations<2>,Comparisons<2>,Unary Operations<2>,Rvalues<2> 13294@anchor{cp/topics/expressions binary-operations}@anchor{170} 13295@subsubsection Binary Operations 13296 13297 13298@geindex gccjit;;context;;new_binary_op (C++ function) 13299@anchor{cp/topics/expressions gccjit context new_binary_op__enum gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{10d} 13300@deffn {C++ Function} gccjit::rvalue gccjit::context::new_binary_op (enum gcc_jit_binary_op, gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13301 13302Build a binary operation out of two constituent rvalues. 13303 13304Parameter @code{loc} is optional. 13305 13306This is a thin wrapper around the C API's 13307@pxref{12,,gcc_jit_context_new_binary_op()} and the available binary 13308operations are documented there. 13309@end deffn 13310 13311There are shorter ways to spell the various specific kinds of binary 13312operation: 13313 13314@geindex gccjit;;context;;new_plus (C++ function) 13315@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{171} 13316@deffn {C++ Function} gccjit::rvalue gccjit::context::new_plus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13317@end deffn 13318 13319@geindex gccjit;;context;;new_minus (C++ function) 13320@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{172} 13321@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13322@end deffn 13323 13324@geindex gccjit;;context;;new_mult (C++ function) 13325@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{173} 13326@deffn {C++ Function} gccjit::rvalue gccjit::context::new_mult (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13327@end deffn 13328 13329@geindex gccjit;;context;;new_divide (C++ function) 13330@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{174} 13331@deffn {C++ Function} gccjit::rvalue gccjit::context::new_divide (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13332@end deffn 13333 13334@geindex gccjit;;context;;new_modulo (C++ function) 13335@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{175} 13336@deffn {C++ Function} gccjit::rvalue gccjit::context::new_modulo (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13337@end deffn 13338 13339@geindex gccjit;;context;;new_bitwise_and (C++ function) 13340@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{176} 13341@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13342@end deffn 13343 13344@geindex gccjit;;context;;new_bitwise_xor (C++ function) 13345@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{177} 13346@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_xor (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13347@end deffn 13348 13349@geindex gccjit;;context;;new_bitwise_or (C++ function) 13350@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{178} 13351@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13352@end deffn 13353 13354@geindex gccjit;;context;;new_logical_and (C++ function) 13355@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{179} 13356@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13357@end deffn 13358 13359@geindex gccjit;;context;;new_logical_or (C++ function) 13360@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{17a} 13361@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13362@end deffn 13363 13364The most concise way to spell them is with overloaded operators: 13365 13366@geindex operator+ (C++ function) 13367@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{17b} 13368@deffn {C++ Function} gccjit::rvalue operator+ (gccjit::rvalue a, gccjit::rvalue b) 13369 13370@example 13371gccjit::rvalue sum = a + b; 13372@end example 13373 13374@noindent 13375@end deffn 13376 13377@geindex operator- (C++ function) 13378@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{17c} 13379@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a, gccjit::rvalue b) 13380 13381@example 13382gccjit::rvalue diff = a - b; 13383@end example 13384 13385@noindent 13386@end deffn 13387 13388@geindex operator* (C++ function) 13389@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{17d} 13390@deffn {C++ Function} gccjit::rvalue operator* (gccjit::rvalue a, gccjit::rvalue b) 13391 13392@example 13393gccjit::rvalue prod = a * b; 13394@end example 13395 13396@noindent 13397@end deffn 13398 13399@geindex operator/ (C++ function) 13400@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{17e} 13401@deffn {C++ Function} gccjit::rvalue operator/ (gccjit::rvalue a, gccjit::rvalue b) 13402 13403@example 13404gccjit::rvalue result = a / b; 13405@end example 13406 13407@noindent 13408@end deffn 13409 13410@geindex operator% (C++ function) 13411@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{17f} 13412@deffn {C++ Function} gccjit::rvalue operator% (gccjit::rvalue a, gccjit::rvalue b) 13413 13414@example 13415gccjit::rvalue mod = a % b; 13416@end example 13417 13418@noindent 13419@end deffn 13420 13421@geindex operator& (C++ function) 13422@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{180} 13423@deffn {C++ Function} gccjit::rvalue operator& (gccjit::rvalue a, gccjit::rvalue b) 13424 13425@example 13426gccjit::rvalue x = a & b; 13427@end example 13428 13429@noindent 13430@end deffn 13431 13432@geindex operator^ (C++ function) 13433@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{181} 13434@deffn {C++ Function} gccjit::rvalue operator^ (gccjit::rvalue a, gccjit::rvalue b) 13435 13436@example 13437gccjit::rvalue x = a ^ b; 13438@end example 13439 13440@noindent 13441@end deffn 13442 13443@geindex operator| (C++ function) 13444@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{182} 13445@deffn {C++ Function} gccjit::rvalue operator| (gccjit::rvalue a, gccjit::rvalue b) 13446 13447@example 13448gccjit::rvalue x = a | b; 13449@end example 13450 13451@noindent 13452@end deffn 13453 13454@geindex operator&& (C++ function) 13455@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{183} 13456@deffn {C++ Function} gccjit::rvalue operator&& (gccjit::rvalue a, gccjit::rvalue b) 13457 13458@example 13459gccjit::rvalue cond = a && b; 13460@end example 13461 13462@noindent 13463@end deffn 13464 13465@geindex operator|| (C++ function) 13466@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{184} 13467@deffn {C++ Function} gccjit::rvalue operator|| (gccjit::rvalue a, gccjit::rvalue b) 13468 13469@example 13470gccjit::rvalue cond = a || b; 13471@end example 13472 13473@noindent 13474@end deffn 13475 13476These can of course be combined, giving a terse way to build compound 13477expressions: 13478 13479@quotation 13480 13481@example 13482gccjit::rvalue discriminant = (b * b) - (four * a * c); 13483@end example 13484 13485@noindent 13486@end quotation 13487 13488@node Comparisons<2>,Function calls<2>,Binary Operations<2>,Rvalues<2> 13489@anchor{cp/topics/expressions comparisons}@anchor{185} 13490@subsubsection Comparisons 13491 13492 13493@geindex gccjit;;context;;new_comparison (C++ function) 13494@anchor{cp/topics/expressions gccjit context new_comparison__enum gccjit rvalue gccjit rvalue gccjit location}@anchor{11a} 13495@deffn {C++ Function} gccjit::rvalue gccjit::context::new_comparison (enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13496 13497Build a boolean rvalue out of the comparison of two other rvalues. 13498 13499Parameter @code{loc} is optional. 13500 13501This is a thin wrapper around the C API's 13502@pxref{2c,,gcc_jit_context_new_comparison()} and the available kinds 13503of comparison are documented there. 13504@end deffn 13505 13506There are shorter ways to spell the various specific kinds of binary 13507operation: 13508 13509@geindex gccjit;;context;;new_eq (C++ function) 13510@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{186} 13511@deffn {C++ Function} gccjit::rvalue gccjit::context::new_eq (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13512@end deffn 13513 13514@geindex gccjit;;context;;new_ne (C++ function) 13515@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{187} 13516@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ne (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13517@end deffn 13518 13519@geindex gccjit;;context;;new_lt (C++ function) 13520@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{188} 13521@deffn {C++ Function} gccjit::rvalue gccjit::context::new_lt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13522@end deffn 13523 13524@geindex gccjit;;context;;new_le (C++ function) 13525@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{189} 13526@deffn {C++ Function} gccjit::rvalue gccjit::context::new_le (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13527@end deffn 13528 13529@geindex gccjit;;context;;new_gt (C++ function) 13530@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{18a} 13531@deffn {C++ Function} gccjit::rvalue gccjit::context::new_gt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13532@end deffn 13533 13534@geindex gccjit;;context;;new_ge (C++ function) 13535@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{18b} 13536@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ge (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13537@end deffn 13538 13539The most concise way to spell them is with overloaded operators: 13540 13541@geindex operator== (C++ function) 13542@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{18c} 13543@deffn {C++ Function} gccjit::rvalue operator== (gccjit::rvalue a, gccjit::rvalue b) 13544 13545@example 13546gccjit::rvalue cond = (a == ctxt.zero (t_int)); 13547@end example 13548 13549@noindent 13550@end deffn 13551 13552@geindex operator!= (C++ function) 13553@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{18d} 13554@deffn {C++ Function} gccjit::rvalue operator!= (gccjit::rvalue a, gccjit::rvalue b) 13555 13556@example 13557gccjit::rvalue cond = (i != j); 13558@end example 13559 13560@noindent 13561@end deffn 13562 13563@geindex operator< (C++ function) 13564@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{18e} 13565@deffn {C++ Function} gccjit::rvalue operator< (gccjit::rvalue a, gccjit::rvalue b) 13566 13567@example 13568gccjit::rvalue cond = i < n; 13569@end example 13570 13571@noindent 13572@end deffn 13573 13574@geindex operator<= (C++ function) 13575@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{18f} 13576@deffn {C++ Function} gccjit::rvalue operator<= (gccjit::rvalue a, gccjit::rvalue b) 13577 13578@example 13579gccjit::rvalue cond = i <= n; 13580@end example 13581 13582@noindent 13583@end deffn 13584 13585@geindex operator> (C++ function) 13586@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{190} 13587@deffn {C++ Function} gccjit::rvalue operator> (gccjit::rvalue a, gccjit::rvalue b) 13588 13589@example 13590gccjit::rvalue cond = (ch > limit); 13591@end example 13592 13593@noindent 13594@end deffn 13595 13596@geindex operator>= (C++ function) 13597@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{191} 13598@deffn {C++ Function} gccjit::rvalue operator>= (gccjit::rvalue a, gccjit::rvalue b) 13599 13600@example 13601gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100)); 13602@end example 13603 13604@noindent 13605@end deffn 13606 13607@c TODO: beyond this point 13608 13609@node Function calls<2>,Type-coercion<2>,Comparisons<2>,Rvalues<2> 13610@anchor{cp/topics/expressions function-calls}@anchor{192} 13611@subsubsection Function calls 13612 13613 13614@geindex gcc_jit_context_new_call (C++ function) 13615@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{193} 13616@deffn {C++ Function} gcc_jit_rvalue* gcc_jit_context_new_call (gcc_jit_context* ctxt, gcc_jit_location* loc, gcc_jit_function* func, int numargs, gcc_jit_rvalue** args) 13617 13618Given a function and the given table of argument rvalues, construct a 13619call to the function, with the result as an rvalue. 13620 13621@cartouche 13622@quotation Note 13623@code{gccjit::context::new_call()} merely builds a 13624@pxref{160,,gccjit;;rvalue} i.e. an expression that can be evaluated, 13625perhaps as part of a more complicated expression. 13626The call @emph{won't} happen unless you add a statement to a function 13627that evaluates the expression. 13628 13629For example, if you want to call a function and discard the result 13630(or to call a function with @code{void} return type), use 13631@pxref{194,,gccjit;;block;;add_eval()}: 13632 13633@example 13634/* Add "(void)printf (arg0, arg1);". */ 13635block.add_eval (ctxt.new_call (printf_func, arg0, arg1)); 13636@end example 13637 13638@noindent 13639@end quotation 13640@end cartouche 13641@end deffn 13642 13643@node Type-coercion<2>,,Function calls<2>,Rvalues<2> 13644@anchor{cp/topics/expressions type-coercion}@anchor{195} 13645@subsubsection Type-coercion 13646 13647 13648@geindex gccjit;;context;;new_cast (C++ function) 13649@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{196} 13650@deffn {C++ Function} gccjit::rvalue gccjit::context::new_cast (gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc) 13651 13652Given an rvalue of T, construct another rvalue of another type. 13653 13654Currently only a limited set of conversions are possible: 13655 13656@quotation 13657 13658 13659@itemize * 13660 13661@item 13662int <-> float 13663 13664@item 13665int <-> bool 13666 13667@item 13668P* <-> Q*, for pointer types P and Q 13669@end itemize 13670@end quotation 13671@end deffn 13672 13673@node Lvalues<2>,Working with pointers structs and unions<2>,Rvalues<2>,Expressions<2> 13674@anchor{cp/topics/expressions lvalues}@anchor{197} 13675@subsubsection Lvalues 13676 13677 13678@geindex gccjit;;lvalue (C++ class) 13679@anchor{cp/topics/expressions gccjit lvalue}@anchor{198} 13680@deffn {C++ Class} gccjit::lvalue 13681@end deffn 13682 13683An lvalue is something that can of the @emph{left}-hand side of an assignment: 13684a storage area (such as a variable). It is a subclass of 13685@pxref{160,,gccjit;;rvalue}, where the rvalue is computed by reading from the 13686storage area. 13687 13688It iss a thin wrapper around @pxref{24,,gcc_jit_lvalue *} from the C API. 13689 13690@geindex gccjit;;lvalue;;get_address (C++ function) 13691@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{199} 13692@deffn {C++ Function} gccjit::rvalue gccjit::lvalue::get_address (gccjit::location loc) 13693 13694Take the address of an lvalue; analogous to: 13695 13696@example 13697&(EXPR) 13698@end example 13699 13700@noindent 13701 13702in C. 13703 13704Parameter "loc" is optional. 13705@end deffn 13706 13707@menu 13708* Global variables: Global variables<2>. 13709 13710@end menu 13711 13712@node Global variables<2>,,,Lvalues<2> 13713@anchor{cp/topics/expressions global-variables}@anchor{19a} 13714@subsubsection Global variables 13715 13716 13717@geindex gccjit;;context;;new_global (C++ function) 13718@anchor{cp/topics/expressions gccjit context new_global__enum gccjit type cCP gccjit location}@anchor{19b} 13719@deffn {C++ Function} gccjit::lvalue gccjit::context::new_global (enum gcc_jit_global_kind, gccjit::type type, const char* name, gccjit::location loc) 13720 13721Add a new global variable of the given type and name to the context. 13722 13723This is a thin wrapper around @pxref{b6,,gcc_jit_context_new_global()} from 13724the C API; the "kind" parameter has the same meaning as there. 13725@end deffn 13726 13727@node Working with pointers structs and unions<2>,,Lvalues<2>,Expressions<2> 13728@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{19c} 13729@subsubsection Working with pointers, structs and unions 13730 13731 13732@geindex gccjit;;rvalue;;dereference (C++ function) 13733@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{19d} 13734@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference (gccjit::location loc) 13735 13736Given an rvalue of pointer type @code{T *}, dereferencing the pointer, 13737getting an lvalue of type @code{T}. Analogous to: 13738 13739@example 13740*(EXPR) 13741@end example 13742 13743@noindent 13744 13745in C. 13746 13747Parameter "loc" is optional. 13748@end deffn 13749 13750If you don't need to specify the location, this can also be expressed using 13751an overloaded operator: 13752 13753@geindex gccjit;;rvalue;;operator* (C++ function) 13754@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{19e} 13755@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::operator* () 13756 13757@example 13758gccjit::lvalue content = *ptr; 13759@end example 13760 13761@noindent 13762@end deffn 13763 13764Field access is provided separately for both lvalues and rvalues: 13765 13766@geindex gccjit;;lvalue;;access_field (C++ function) 13767@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{19f} 13768@deffn {C++ Function} gccjit::lvalue gccjit::lvalue::access_field (gccjit::field field, gccjit::location loc) 13769 13770Given an lvalue of struct or union type, access the given field, 13771getting an lvalue of the field's type. Analogous to: 13772 13773@example 13774(EXPR).field = ...; 13775@end example 13776 13777@noindent 13778 13779in C. 13780@end deffn 13781 13782@geindex gccjit;;rvalue;;access_field (C++ function) 13783@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{1a0} 13784@deffn {C++ Function} gccjit::rvalue gccjit::rvalue::access_field (gccjit::field field, gccjit::location loc) 13785 13786Given an rvalue of struct or union type, access the given field 13787as an rvalue. Analogous to: 13788 13789@example 13790(EXPR).field 13791@end example 13792 13793@noindent 13794 13795in C. 13796@end deffn 13797 13798@geindex gccjit;;rvalue;;dereference_field (C++ function) 13799@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{1a1} 13800@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference_field (gccjit::field field, gccjit::location loc) 13801 13802Given an rvalue of pointer type @code{T *} where T is of struct or union 13803type, access the given field as an lvalue. Analogous to: 13804 13805@example 13806(EXPR)->field 13807@end example 13808 13809@noindent 13810 13811in C, itself equivalent to @code{(*EXPR).FIELD}. 13812@end deffn 13813 13814@geindex gccjit;;context;;new_array_access (C++ function) 13815@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{1a2} 13816@deffn {C++ Function} gccjit::lvalue gccjit::context::new_array_access (gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc) 13817 13818Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at 13819the given index, using standard C array indexing rules i.e. each 13820increment of @code{index} corresponds to @code{sizeof(T)} bytes. 13821Analogous to: 13822 13823@example 13824PTR[INDEX] 13825@end example 13826 13827@noindent 13828 13829in C (or, indeed, to @code{PTR + INDEX}). 13830 13831Parameter "loc" is optional. 13832@end deffn 13833 13834For array accesses where you don't need to specify a @pxref{13d,,gccjit;;location}, 13835two overloaded operators are available: 13836 13837@quotation 13838 13839gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index) 13840 13841@example 13842gccjit::lvalue element = array[idx]; 13843@end example 13844 13845@noindent 13846 13847gccjit::lvalue gccjit::rvalue::operator[] (int index) 13848 13849@example 13850gccjit::lvalue element = array[0]; 13851@end example 13852 13853@noindent 13854@end quotation 13855 13856@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 13857@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13858@c 13859@c This is free software: you can redistribute it and/or modify it 13860@c under the terms of the GNU General Public License as published by 13861@c the Free Software Foundation, either version 3 of the License, or 13862@c (at your option) any later version. 13863@c 13864@c This program is distributed in the hope that it will be useful, but 13865@c WITHOUT ANY WARRANTY; without even the implied warranty of 13866@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13867@c General Public License for more details. 13868@c 13869@c You should have received a copy of the GNU General Public License 13870@c along with this program. If not, see 13871@c <http://www.gnu.org/licenses/>. 13872 13873@node Creating and using functions<2>,Source Locations<2>,Expressions<2>,Topic Reference<2> 13874@anchor{cp/topics/functions doc}@anchor{1a3}@anchor{cp/topics/functions creating-and-using-functions}@anchor{1a4} 13875@subsection Creating and using functions 13876 13877 13878@menu 13879* Params: Params<2>. 13880* Functions: Functions<2>. 13881* Blocks: Blocks<2>. 13882* Statements: Statements<2>. 13883 13884@end menu 13885 13886@node Params<2>,Functions<2>,,Creating and using functions<2> 13887@anchor{cp/topics/functions params}@anchor{1a5} 13888@subsubsection Params 13889 13890 13891@geindex gccjit;;param (C++ class) 13892@anchor{cp/topics/functions gccjit param}@anchor{1a6} 13893@deffn {C++ Class} gccjit::param 13894 13895A @cite{gccjit::param} represents a parameter to a function. 13896@end deffn 13897 13898@geindex gccjit;;context;;new_param (C++ function) 13899@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{10c} 13900@deffn {C++ Function} gccjit::param gccjit::context::new_param (gccjit::type type, const char* name, gccjit::location loc) 13901 13902In preparation for creating a function, create a new parameter of the 13903given type and name. 13904@end deffn 13905 13906@pxref{1a6,,gccjit;;param} is a subclass of @pxref{198,,gccjit;;lvalue} (and thus 13907of @pxref{160,,gccjit;;rvalue} and @pxref{14a,,gccjit;;object}). It is a thin 13908wrapper around the C API's @pxref{25,,gcc_jit_param *}. 13909 13910@node Functions<2>,Blocks<2>,Params<2>,Creating and using functions<2> 13911@anchor{cp/topics/functions functions}@anchor{1a7} 13912@subsubsection Functions 13913 13914 13915@geindex gccjit;;function (C++ class) 13916@anchor{cp/topics/functions gccjit function}@anchor{1a8} 13917@deffn {C++ Class} gccjit::function 13918 13919A @cite{gccjit::function} represents a function - either one that we're 13920creating ourselves, or one that we're referencing. 13921@end deffn 13922 13923@geindex gccjit;;context;;new_function (C++ function) 13924@anchor{cp/topics/functions gccjit context new_function__enum gccjit type cCP std vector param R i gccjit location}@anchor{1a9} 13925@deffn {C++ Function} gccjit::function gccjit::context::new_function (enum gcc_jit_function_kind, gccjit::type return_type, const char* name, std::vector<param>& params, int is_variadic, gccjit::location loc) 13926 13927Create a gcc_jit_function with the given name and parameters. 13928 13929Parameters "is_variadic" and "loc" are optional. 13930 13931This is a wrapper around the C API's @pxref{11,,gcc_jit_context_new_function()}. 13932@end deffn 13933 13934@geindex gccjit;;context;;get_builtin_function (C++ function) 13935@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{1aa} 13936@deffn {C++ Function} gccjit::function gccjit::context::get_builtin_function (const char* name) 13937 13938This is a wrapper around the C API's 13939@pxref{cd,,gcc_jit_context_get_builtin_function()}. 13940@end deffn 13941 13942@geindex gccjit;;function;;get_param (C++ function) 13943@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{1ab} 13944@deffn {C++ Function} gccjit::param gccjit::function::get_param (int index) const 13945 13946Get the param of the given index (0-based). 13947@end deffn 13948 13949@geindex gccjit;;function;;dump_to_dot (C++ function) 13950@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{11f} 13951@deffn {C++ Function} void gccjit::function::dump_to_dot (const char* path) 13952 13953Emit the function in graphviz format to the given path. 13954@end deffn 13955 13956@geindex gccjit;;function;;new_local (C++ function) 13957@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{116} 13958@deffn {C++ Function} gccjit::lvalue gccjit::function::new_local (gccjit::type type, const char* name, gccjit::location loc) 13959 13960Create a new local variable within the function, of the given type and 13961name. 13962@end deffn 13963 13964@node Blocks<2>,Statements<2>,Functions<2>,Creating and using functions<2> 13965@anchor{cp/topics/functions blocks}@anchor{1ac} 13966@subsubsection Blocks 13967 13968 13969@geindex gccjit;;block (C++ class) 13970@anchor{cp/topics/functions gccjit block}@anchor{1ad} 13971@deffn {C++ Class} gccjit::block 13972 13973A @cite{gccjit::block} represents a basic block within a function i.e. a 13974sequence of statements with a single entry point and a single exit 13975point. 13976 13977@pxref{1ad,,gccjit;;block} is a subclass of @pxref{14a,,gccjit;;object}. 13978 13979The first basic block that you create within a function will 13980be the entrypoint. 13981 13982Each basic block that you create within a function must be 13983terminated, either with a conditional, a jump, a return, or 13984a switch. 13985 13986It's legal to have multiple basic blocks that return within 13987one function. 13988@end deffn 13989 13990@geindex gccjit;;function;;new_block (C++ function) 13991@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{1ae} 13992@deffn {C++ Function} gccjit::block gccjit::function::new_block (const char* name) 13993 13994Create a basic block of the given name. The name may be NULL, but 13995providing meaningful names is often helpful when debugging: it may 13996show up in dumps of the internal representation, and in error 13997messages. 13998@end deffn 13999 14000@node Statements<2>,,Blocks<2>,Creating and using functions<2> 14001@anchor{cp/topics/functions statements}@anchor{1af} 14002@subsubsection Statements 14003 14004 14005@geindex gccjit;;block;;add_eval (C++ function) 14006@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{194} 14007@deffn {C++ Function} void gccjit::block::add_eval (gccjit::rvalue rvalue, gccjit::location loc) 14008 14009Add evaluation of an rvalue, discarding the result 14010(e.g. a function call that "returns" void). 14011 14012This is equivalent to this C code: 14013 14014@example 14015(void)expression; 14016@end example 14017 14018@noindent 14019@end deffn 14020 14021@geindex gccjit;;block;;add_assignment (C++ function) 14022@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{118} 14023@deffn {C++ Function} void gccjit::block::add_assignment (gccjit::lvalue lvalue, gccjit::rvalue rvalue, gccjit::location loc) 14024 14025Add evaluation of an rvalue, assigning the result to the given 14026lvalue. 14027 14028This is roughly equivalent to this C code: 14029 14030@example 14031lvalue = rvalue; 14032@end example 14033 14034@noindent 14035@end deffn 14036 14037@geindex gccjit;;block;;add_assignment_op (C++ function) 14038@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue enum gccjit rvalue gccjit location}@anchor{11c} 14039@deffn {C++ Function} void gccjit::block::add_assignment_op (gccjit::lvalue lvalue, enum gcc_jit_binary_op, gccjit::rvalue rvalue, gccjit::location loc) 14040 14041Add evaluation of an rvalue, using the result to modify an 14042lvalue. 14043 14044This is analogous to "+=" and friends: 14045 14046@example 14047lvalue += rvalue; 14048lvalue *= rvalue; 14049lvalue /= rvalue; 14050@end example 14051 14052@noindent 14053 14054etc. For example: 14055 14056@example 14057/* "i++" */ 14058loop_body.add_assignment_op ( 14059 i, 14060 GCC_JIT_BINARY_OP_PLUS, 14061 ctxt.one (int_type)); 14062@end example 14063 14064@noindent 14065@end deffn 14066 14067@geindex gccjit;;block;;add_comment (C++ function) 14068@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{127} 14069@deffn {C++ Function} void gccjit::block::add_comment (const char* text, gccjit::location loc) 14070 14071Add a no-op textual comment to the internal representation of the 14072code. It will be optimized away, but will be visible in the dumps 14073seen via @pxref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} 14074and @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, 14075and thus may be of use when debugging how your project's internal 14076representation gets converted to the libgccjit IR. 14077 14078Parameter "loc" is optional. 14079@end deffn 14080 14081@geindex gccjit;;block;;end_with_conditional (C++ function) 14082@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{11b} 14083@deffn {C++ Function} void gccjit::block::end_with_conditional (gccjit::rvalue boolval, gccjit::block on_true, gccjit::block on_false, gccjit::location loc) 14084 14085Terminate a block by adding evaluation of an rvalue, branching on the 14086result to the appropriate successor block. 14087 14088This is roughly equivalent to this C code: 14089 14090@example 14091if (boolval) 14092 goto on_true; 14093else 14094 goto on_false; 14095@end example 14096 14097@noindent 14098 14099block, boolval, on_true, and on_false must be non-NULL. 14100@end deffn 14101 14102@geindex gccjit;;block;;end_with_jump (C++ function) 14103@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{1b0} 14104@deffn {C++ Function} void gccjit::block::end_with_jump (gccjit::block target, gccjit::location loc) 14105 14106Terminate a block by adding a jump to the given target block. 14107 14108This is roughly equivalent to this C code: 14109 14110@example 14111goto target; 14112@end example 14113 14114@noindent 14115@end deffn 14116 14117@geindex gccjit;;block;;end_with_return (C++ function) 14118@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{1b1} 14119@deffn {C++ Function} void gccjit::block::end_with_return (gccjit::rvalue rvalue, gccjit::location loc) 14120 14121Terminate a block. 14122 14123Both params are optional. 14124 14125An rvalue must be provided for a function returning non-void, and 14126must not be provided by a function "returning" @cite{void}. 14127 14128If an rvalue is provided, the block is terminated by evaluating the 14129rvalue and returning the value. 14130 14131This is roughly equivalent to this C code: 14132 14133@example 14134return expression; 14135@end example 14136 14137@noindent 14138 14139If an rvalue is not provided, the block is terminated by adding a 14140valueless return, for use within a function with "void" return type. 14141 14142This is equivalent to this C code: 14143 14144@example 14145return; 14146@end example 14147 14148@noindent 14149@end deffn 14150 14151@geindex gccjit;;block;;end_with_switch (C++ function) 14152@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{1b2} 14153@deffn {C++ Function} void gccjit::block::end_with_switch (gccjit::rvalue expr, gccjit::block default_block, std::vector<gccjit::case_> cases, gccjit::location loc) 14154 14155Terminate a block by adding evalation of an rvalue, then performing 14156a multiway branch. 14157 14158This is roughly equivalent to this C code: 14159 14160@example 14161switch (expr) 14162 @{ 14163 default: 14164 goto default_block; 14165 14166 case C0.min_value ... C0.max_value: 14167 goto C0.dest_block; 14168 14169 case C1.min_value ... C1.max_value: 14170 goto C1.dest_block; 14171 14172 ...etc... 14173 14174 case C[N - 1].min_value ... C[N - 1].max_value: 14175 goto C[N - 1].dest_block; 14176@} 14177@end example 14178 14179@noindent 14180 14181@code{expr} must be of the same integer type as all of the @code{min_value} 14182and @code{max_value} within the cases. 14183 14184The ranges of the cases must not overlap (or have duplicate 14185values). 14186 14187The API entrypoints relating to switch statements and cases: 14188 14189@quotation 14190 14191 14192@itemize * 14193 14194@item 14195@pxref{1b2,,gccjit;;block;;end_with_switch()} 14196 14197@item 14198@pxref{1b3,,gccjit;;context;;new_case()} 14199@end itemize 14200@end quotation 14201 14202were added in @pxref{db,,LIBGCCJIT_ABI_3}; you can test for their presence 14203using 14204 14205@example 14206#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 14207@end example 14208 14209@noindent 14210 14211@geindex gccjit;;block;;end_with_switch;;gccjit;;case_ (C++ class) 14212@anchor{cp/topics/functions gccjit block end_with_switch gccjit case_}@anchor{1b4} 14213@deffn {C++ Class} gccjit::case_ 14214@end deffn 14215 14216A @cite{gccjit::case_} represents a case within a switch statement, and 14217is created within a particular @pxref{135,,gccjit;;context} using 14218@pxref{1b3,,gccjit;;context;;new_case()}. It is a subclass of 14219@pxref{14a,,gccjit;;object}. 14220 14221Each case expresses a multivalued range of integer values. You 14222can express single-valued cases by passing in the same value for 14223both @cite{min_value} and @cite{max_value}. 14224 14225@geindex gccjit;;block;;end_with_switch;;gccjit;;context;;new_case (C++ function) 14226@anchor{cp/topics/functions gccjit block end_with_switch gccjit context new_case__gccjit rvalue gccjit rvalue gccjit block}@anchor{1b3} 14227@deffn {C++ Function} gccjit::case_* gccjit::context::new_case (gccjit::rvalue min_value, gccjit::rvalue max_value, gccjit::block dest_block) 14228 14229Create a new gccjit::case for use in a switch statement. 14230@cite{min_value} and @cite{max_value} must be constants of an integer type, 14231which must match that of the expression of the switch statement. 14232 14233@cite{dest_block} must be within the same function as the switch 14234statement. 14235@end deffn 14236 14237Here's an example of creating a switch statement: 14238 14239@quotation 14240 14241@example 14242 14243void 14244create_code (gcc_jit_context *c_ctxt, void *user_data) 14245@{ 14246 /* Let's try to inject the equivalent of: 14247 int 14248 test_switch (int x) 14249 @{ 14250 switch (x) 14251 @{ 14252 case 0 ... 5: 14253 return 3; 14254 14255 case 25 ... 27: 14256 return 4; 14257 14258 case -42 ... -17: 14259 return 83; 14260 14261 case 40: 14262 return 8; 14263 14264 default: 14265 return 10; 14266 @} 14267 @} 14268 */ 14269 gccjit::context ctxt (c_ctxt); 14270 gccjit::type t_int = ctxt.get_type (GCC_JIT_TYPE_INT); 14271 gccjit::type return_type = t_int; 14272 gccjit::param x = ctxt.new_param (t_int, "x"); 14273 std::vector <gccjit::param> params; 14274 params.push_back (x); 14275 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 14276 return_type, 14277 "test_switch", 14278 params, 0); 14279 14280 gccjit::block b_initial = func.new_block ("initial"); 14281 14282 gccjit::block b_default = func.new_block ("default"); 14283 gccjit::block b_case_0_5 = func.new_block ("case_0_5"); 14284 gccjit::block b_case_25_27 = func.new_block ("case_25_27"); 14285 gccjit::block b_case_m42_m17 = func.new_block ("case_m42_m17"); 14286 gccjit::block b_case_40 = func.new_block ("case_40"); 14287 14288 std::vector <gccjit::case_> cases; 14289 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 0), 14290 ctxt.new_rvalue (t_int, 5), 14291 b_case_0_5)); 14292 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 25), 14293 ctxt.new_rvalue (t_int, 27), 14294 b_case_25_27)); 14295 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, -42), 14296 ctxt.new_rvalue (t_int, -17), 14297 b_case_m42_m17)); 14298 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 40), 14299 ctxt.new_rvalue (t_int, 40), 14300 b_case_40)); 14301 b_initial.end_with_switch (x, 14302 b_default, 14303 cases); 14304 14305 b_case_0_5.end_with_return (ctxt.new_rvalue (t_int, 3)); 14306 b_case_25_27.end_with_return (ctxt.new_rvalue (t_int, 4)); 14307 b_case_m42_m17.end_with_return (ctxt.new_rvalue (t_int, 83)); 14308 b_case_40.end_with_return (ctxt.new_rvalue (t_int, 8)); 14309 b_default.end_with_return (ctxt.new_rvalue (t_int, 10)); 14310@} 14311 14312 14313@end example 14314 14315@noindent 14316@end quotation 14317@end deffn 14318 14319@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 14320@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14321@c 14322@c This is free software: you can redistribute it and/or modify it 14323@c under the terms of the GNU General Public License as published by 14324@c the Free Software Foundation, either version 3 of the License, or 14325@c (at your option) any later version. 14326@c 14327@c This program is distributed in the hope that it will be useful, but 14328@c WITHOUT ANY WARRANTY; without even the implied warranty of 14329@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14330@c General Public License for more details. 14331@c 14332@c You should have received a copy of the GNU General Public License 14333@c along with this program. If not, see 14334@c <http://www.gnu.org/licenses/>. 14335 14336@node Source Locations<2>,Compiling a context<2>,Creating and using functions<2>,Topic Reference<2> 14337@anchor{cp/topics/locations source-locations}@anchor{1b5}@anchor{cp/topics/locations doc}@anchor{1b6} 14338@subsection Source Locations 14339 14340 14341@geindex gccjit;;location (C++ class) 14342@anchor{cp/topics/locations gccjit location}@anchor{13d} 14343@deffn {C++ Class} gccjit::location 14344 14345A @cite{gccjit::location} encapsulates a source code location, so that 14346you can (optionally) associate locations in your language with 14347statements in the JIT-compiled code, allowing the debugger to 14348single-step through your language. 14349 14350@cite{gccjit::location} instances are optional: you can always omit them 14351from any C++ API entrypoint accepting one. 14352 14353You can construct them using @pxref{12b,,gccjit;;context;;new_location()}. 14354 14355You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 14356@pxref{135,,gccjit;;context} for these locations to actually be usable by 14357the debugger: 14358 14359@example 14360ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1); 14361@end example 14362 14363@noindent 14364@end deffn 14365 14366@geindex gccjit;;context;;new_location (C++ function) 14367@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{12b} 14368@deffn {C++ Function} gccjit::location gccjit::context::new_location (const char* filename, int line, int column) 14369 14370Create a @cite{gccjit::location} instance representing the given source 14371location. 14372@end deffn 14373 14374@menu 14375* Faking it: Faking it<2>. 14376 14377@end menu 14378 14379@node Faking it<2>,,,Source Locations<2> 14380@anchor{cp/topics/locations faking-it}@anchor{1b7} 14381@subsubsection Faking it 14382 14383 14384If you don't have source code for your internal representation, but need 14385to debug, you can generate a C-like representation of the functions in 14386your context using @pxref{13c,,gccjit;;context;;dump_to_file()}: 14387 14388@example 14389ctxt.dump_to_file ("/tmp/something.c", 14390 1 /* update_locations */); 14391@end example 14392 14393@noindent 14394 14395This will dump C-like code to the given path. If the @cite{update_locations} 14396argument is true, this will also set up @cite{gccjit::location} information 14397throughout the context, pointing at the dump file as if it were a source 14398file, giving you @emph{something} you can step through in the debugger. 14399 14400@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 14401@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14402@c 14403@c This is free software: you can redistribute it and/or modify it 14404@c under the terms of the GNU General Public License as published by 14405@c the Free Software Foundation, either version 3 of the License, or 14406@c (at your option) any later version. 14407@c 14408@c This program is distributed in the hope that it will be useful, but 14409@c WITHOUT ANY WARRANTY; without even the implied warranty of 14410@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14411@c General Public License for more details. 14412@c 14413@c You should have received a copy of the GNU General Public License 14414@c along with this program. If not, see 14415@c <http://www.gnu.org/licenses/>. 14416 14417@node Compiling a context<2>,,Source Locations<2>,Topic Reference<2> 14418@anchor{cp/topics/compilation compiling-a-context}@anchor{1b8}@anchor{cp/topics/compilation doc}@anchor{1b9} 14419@subsection Compiling a context 14420 14421 14422Once populated, a @pxref{135,,gccjit;;context} can be compiled to 14423machine code, either in-memory via @pxref{10e,,gccjit;;context;;compile()} or 14424to disk via @pxref{1ba,,gccjit;;context;;compile_to_file()}. 14425 14426You can compile a context multiple times (using either form of 14427compilation), although any errors that occur on the context will 14428prevent any future compilation of that context. 14429 14430@menu 14431* In-memory compilation: In-memory compilation<2>. 14432* Ahead-of-time compilation: Ahead-of-time compilation<2>. 14433 14434@end menu 14435 14436@node In-memory compilation<2>,Ahead-of-time compilation<2>,,Compiling a context<2> 14437@anchor{cp/topics/compilation in-memory-compilation}@anchor{1bb} 14438@subsubsection In-memory compilation 14439 14440 14441@geindex gccjit;;context;;compile (C++ function) 14442@anchor{cp/topics/compilation gccjit context compile}@anchor{10e} 14443@deffn {C++ Function} gcc_jit_result* gccjit::context::compile () 14444 14445This calls into GCC and builds the code, returning a 14446@cite{gcc_jit_result *}. 14447 14448This is a thin wrapper around the 14449@pxref{15,,gcc_jit_context_compile()} API entrypoint. 14450@end deffn 14451 14452@node Ahead-of-time compilation<2>,,In-memory compilation<2>,Compiling a context<2> 14453@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{1bc} 14454@subsubsection Ahead-of-time compilation 14455 14456 14457Although libgccjit is primarily aimed at just-in-time compilation, it 14458can also be used for implementing more traditional ahead-of-time 14459compilers, via the @pxref{1ba,,gccjit;;context;;compile_to_file()} method. 14460 14461@geindex gccjit;;context;;compile_to_file (C++ function) 14462@anchor{cp/topics/compilation gccjit context compile_to_file__enum cCP}@anchor{1ba} 14463@deffn {C++ Function} void gccjit::context::compile_to_file (enum gcc_jit_output_kind, const char* output_path) 14464 14465Compile the @pxref{135,,gccjit;;context} to a file of the given 14466kind. 14467 14468This is a thin wrapper around the 14469@pxref{4a,,gcc_jit_context_compile_to_file()} API entrypoint. 14470@end deffn 14471 14472@c Copyright (C) 2014-2017 Free Software Foundation, Inc. 14473@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14474@c 14475@c This is free software: you can redistribute it and/or modify it 14476@c under the terms of the GNU General Public License as published by 14477@c the Free Software Foundation, either version 3 of the License, or 14478@c (at your option) any later version. 14479@c 14480@c This program is distributed in the hope that it will be useful, but 14481@c WITHOUT ANY WARRANTY; without even the implied warranty of 14482@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14483@c General Public License for more details. 14484@c 14485@c You should have received a copy of the GNU General Public License 14486@c along with this program. If not, see 14487@c <http://www.gnu.org/licenses/>. 14488 14489@node Internals,Indices and tables,C++ bindings for libgccjit,Top 14490@anchor{internals/index internals}@anchor{1bd}@anchor{internals/index doc}@anchor{1be} 14491@chapter Internals 14492 14493 14494@menu 14495* Working on the JIT library:: 14496* Running the test suite:: 14497* Environment variables:: 14498* Packaging notes:: 14499* Overview of code structure:: 14500* Design notes:: 14501* Submitting patches:: 14502 14503@end menu 14504 14505@node Working on the JIT library,Running the test suite,,Internals 14506@anchor{internals/index working-on-the-jit-library}@anchor{1bf} 14507@section Working on the JIT library 14508 14509 14510Having checked out the source code (to "src"), you can configure and build 14511the JIT library like this: 14512 14513@example 14514mkdir build 14515mkdir install 14516PREFIX=$(pwd)/install 14517cd build 14518../src/configure \ 14519 --enable-host-shared \ 14520 --enable-languages=jit,c++ \ 14521 --disable-bootstrap \ 14522 --enable-checking=release \ 14523 --prefix=$PREFIX 14524nice make -j4 # altering the "4" to however many cores you have 14525@end example 14526 14527@noindent 14528 14529This should build a libgccjit.so within jit/build/gcc: 14530 14531@example 14532[build] $ file gcc/libgccjit.so* 14533gcc/libgccjit.so: symbolic link to `libgccjit.so.0' 14534gcc/libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' 14535gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped 14536@end example 14537 14538@noindent 14539 14540Here's what those configuration options mean: 14541 14542@geindex command line option; --enable-host-shared 14543@anchor{internals/index cmdoption--enable-host-shared}@anchor{1c0} 14544@deffn {Option} --enable-host-shared 14545 14546Configuring with this option means that the compiler is built as 14547position-independent code, which incurs a slight performance hit, 14548but it necessary for a shared library. 14549@end deffn 14550 14551@geindex command line option; --enable-languages=jit@comma{}c++ 14552@anchor{internals/index cmdoption--enable-languages}@anchor{1c1} 14553@deffn {Option} --enable-languages=jit,c++ 14554 14555This specifies which frontends to build. The JIT library looks like 14556a frontend to the rest of the code. 14557 14558The C++ portion of the JIT test suite requires the C++ frontend to be 14559enabled at configure-time, or you may see errors like this when 14560running the test suite: 14561 14562@example 14563xgcc: error: /home/david/jit/src/gcc/testsuite/jit.dg/test-quadratic.cc: C++ compiler not installed on this system 14564c++: error trying to exec 'cc1plus': execvp: No such file or directory 14565@end example 14566 14567@noindent 14568@end deffn 14569 14570@geindex command line option; --disable-bootstrap 14571@anchor{internals/index cmdoption--disable-bootstrap}@anchor{1c2} 14572@deffn {Option} --disable-bootstrap 14573 14574For hacking on the "jit" subdirectory, performing a full 14575bootstrap can be overkill, since it's unused by a bootstrap. However, 14576when submitting patches, you should remove this option, to ensure that 14577the compiler can still bootstrap itself. 14578@end deffn 14579 14580@geindex command line option; --enable-checking=release 14581@anchor{internals/index cmdoption--enable-checking}@anchor{1c3} 14582@deffn {Option} --enable-checking=release 14583 14584The compile can perform extensive self-checking as it runs, useful when 14585debugging, but slowing things down. 14586 14587For maximum speed, configure with @code{--enable-checking=release} to 14588disable this self-checking. 14589@end deffn 14590 14591@node Running the test suite,Environment variables,Working on the JIT library,Internals 14592@anchor{internals/index running-the-test-suite}@anchor{1c4} 14593@section Running the test suite 14594 14595 14596@example 14597[build] $ cd gcc 14598[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v" 14599@end example 14600 14601@noindent 14602 14603A summary of the tests can then be seen in: 14604 14605@example 14606jit/build/gcc/testsuite/jit/jit.sum 14607@end example 14608 14609@noindent 14610 14611and detailed logs in: 14612 14613@example 14614jit/build/gcc/testsuite/jit/jit.log 14615@end example 14616 14617@noindent 14618 14619The test executables can be seen as: 14620 14621@example 14622jit/build/gcc/testsuite/jit/*.exe 14623@end example 14624 14625@noindent 14626 14627which can be run independently. 14628 14629You can compile and run individual tests by passing "jit.exp=TESTNAME" to RUNTESTFLAGS e.g.: 14630 14631@example 14632[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v jit.exp=test-factorial.c" 14633@end example 14634 14635@noindent 14636 14637and once a test has been compiled, you can debug it directly: 14638 14639@example 14640[gcc] $ PATH=.:$PATH \ 14641 LD_LIBRARY_PATH=. \ 14642 LIBRARY_PATH=. \ 14643 gdb --args \ 14644 testsuite/jit/test-factorial.c.exe 14645@end example 14646 14647@noindent 14648 14649@menu 14650* Running under valgrind:: 14651 14652@end menu 14653 14654@node Running under valgrind,,,Running the test suite 14655@anchor{internals/index running-under-valgrind}@anchor{1c5} 14656@subsection Running under valgrind 14657 14658 14659The jit testsuite detects if RUN_UNDER_VALGRIND is present in the 14660environment (with any value). If it is present, it runs the test client 14661code under valgrind@footnote{http://valgrind.org}, 14662specifcally, the default 14663memcheck@footnote{http://valgrind.org/docs/manual/mc-manual.html} 14664tool with 14665--leak-check=full@footnote{http://valgrind.org/docs/manual/mc-manual.html#opt.leak-check}. 14666 14667It automatically parses the output from valgrind, injecting XFAIL results if 14668any issues are found, or PASS results if the output is clean. The output 14669is saved to @code{TESTNAME.exe.valgrind.txt}. 14670 14671For example, the following invocation verbosely runs the testcase 14672@code{test-sum-of-squares.c} under valgrind, showing an issue: 14673 14674@example 14675$ RUN_UNDER_VALGRIND= \ 14676 make check-jit \ 14677 RUNTESTFLAGS="-v -v -v jit.exp=test-sum-of-squares.c" 14678 14679(...verbose log contains detailed valgrind errors, if any...) 14680 14681 === jit Summary === 14682 14683# of expected passes 28 14684# of expected failures 2 14685 14686$ less testsuite/jit/jit.sum 14687(...other results...) 14688XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: definitely lost: 8 bytes in 1 blocks 14689XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: unsuppressed errors: 1 14690(...other results...) 14691 14692$ less testsuite/jit/test-sum-of-squares.c.exe.valgrind.txt 14693(...shows full valgrind report for this test case...) 14694@end example 14695 14696@noindent 14697 14698When running under valgrind, it's best to have configured gcc with 14699@code{--enable-valgrind-annotations}, which automatically suppresses 14700various known false positives. 14701 14702@node Environment variables,Packaging notes,Running the test suite,Internals 14703@anchor{internals/index environment-variables}@anchor{1c6} 14704@section Environment variables 14705 14706 14707When running client code against a locally-built libgccjit, three 14708environment variables need to be set up: 14709 14710@geindex environment variable; LD_LIBRARY_PATH 14711@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{1c7} 14712@deffn {Environment Variable} LD_LIBRARY_PATH 14713 14714@quotation 14715 14716@cite{libgccjit.so} is dynamically linked into client code, so if running 14717against a locally-built library, @code{LD_LIBRARY_PATH} needs to be set 14718up appropriately. The library can be found within the "gcc" 14719subdirectory of the build tree: 14720@end quotation 14721 14722@example 14723$ file libgccjit.so* 14724libgccjit.so: symbolic link to `libgccjit.so.0' 14725libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' 14726libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, not stripped 14727@end example 14728 14729@noindent 14730@end deffn 14731 14732@geindex environment variable; PATH 14733@anchor{internals/index envvar-PATH}@anchor{1c8} 14734@deffn {Environment Variable} PATH 14735 14736The library uses a driver executable for converting from .s assembler 14737files to .so shared libraries. Specifically, it looks for a name 14738expanded from 14739@code{$@{target_noncanonical@}-gcc-$@{gcc_BASEVER@}$@{exeext@}} 14740such as @code{x86_64-unknown-linux-gnu-gcc-5.0.0}. 14741 14742Hence @code{PATH} needs to include a directory where the library can 14743locate this executable. 14744 14745The executable is normally installed to the installation bindir 14746(e.g. /usr/bin), but a copy is also created within the "gcc" 14747subdirectory of the build tree for running the testsuite, and for ease 14748of development. 14749@end deffn 14750 14751@geindex environment variable; LIBRARY_PATH 14752@anchor{internals/index envvar-LIBRARY_PATH}@anchor{1c9} 14753@deffn {Environment Variable} LIBRARY_PATH 14754 14755The driver executable invokes the linker, and the latter needs to locate 14756support libraries needed by the generated code, or you will see errors 14757like: 14758 14759@example 14760ld: cannot find crtbeginS.o: No such file or directory 14761ld: cannot find -lgcc 14762ld: cannot find -lgcc_s 14763@end example 14764 14765@noindent 14766 14767Hence if running directly from a locally-built copy (without installing), 14768@code{LIBRARY_PATH} needs to contain the "gcc" subdirectory of the build 14769tree. 14770@end deffn 14771 14772For example, to run a binary that uses the library against a non-installed 14773build of the library in LIBGCCJIT_BUILD_DIR you need an invocation of the 14774client code like this, to preprend the dir to each of the environment 14775variables: 14776 14777@example 14778$ LD_LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LD_LIBRARY_PATH) \ 14779 PATH=$(LIBGCCJIT_BUILD_DIR):$(PATH) \ 14780 LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LIBRARY_PATH) \ 14781 ./jit-hello-world 14782hello world 14783@end example 14784 14785@noindent 14786 14787@node Packaging notes,Overview of code structure,Environment variables,Internals 14788@anchor{internals/index packaging-notes}@anchor{1ca} 14789@section Packaging notes 14790 14791 14792The configure-time option @pxref{1c0,,--enable-host-shared} is needed when 14793building the jit in order to get position-independent code. This will 14794slow down the regular compiler by a few percent. Hence when packaging gcc 14795with libgccjit, please configure and build twice: 14796 14797@quotation 14798 14799 14800@itemize * 14801 14802@item 14803once without @pxref{1c0,,--enable-host-shared} for most languages, and 14804 14805@item 14806once with @pxref{1c0,,--enable-host-shared} for the jit 14807@end itemize 14808@end quotation 14809 14810For example: 14811 14812@example 14813# Configure and build with --enable-host-shared 14814# for the jit: 14815mkdir configuration-for-jit 14816pushd configuration-for-jit 14817$(SRCDIR)/configure \ 14818 --enable-host-shared \ 14819 --enable-languages=jit \ 14820 --prefix=$(DESTDIR) 14821make 14822popd 14823 14824# Configure and build *without* --enable-host-shared 14825# for maximum speed: 14826mkdir standard-configuration 14827pushd standard-configuration 14828$(SRCDIR)/configure \ 14829 --enable-languages=all \ 14830 --prefix=$(DESTDIR) 14831make 14832popd 14833 14834# Both of the above are configured to install to $(DESTDIR) 14835# Install the configuration with --enable-host-shared first 14836# *then* the one without, so that the faster build 14837# of "cc1" et al overwrites the slower build. 14838pushd configuration-for-jit 14839make install 14840popd 14841 14842pushd standard-configuration 14843make install 14844popd 14845@end example 14846 14847@noindent 14848 14849@node Overview of code structure,Design notes,Packaging notes,Internals 14850@anchor{internals/index overview-of-code-structure}@anchor{1cb} 14851@section Overview of code structure 14852 14853 14854The library is implemented in C++. The source files have the @code{.c} 14855extension for legacy reasons. 14856 14857 14858@itemize * 14859 14860@item 14861@code{libgccjit.c} implements the API entrypoints. It performs error 14862checking, then calls into classes of the gcc::jit::recording namespace 14863within @code{jit-recording.c} and @code{jit-recording.h}. 14864 14865@item 14866The gcc::jit::recording classes (within @code{jit-recording.c} and 14867@code{jit-recording.h}) record the API calls that are made: 14868 14869@quotation 14870 14871@example 14872 14873 /* Indentation indicates inheritance: */ 14874 class context; 14875 class memento; 14876 class string; 14877 class location; 14878 class type; 14879 class function_type; 14880 class compound_type; 14881 class struct_; 14882 class union_; 14883 class field; 14884 class fields; 14885 class function; 14886 class block; 14887 class rvalue; 14888 class lvalue; 14889 class local; 14890 class global; 14891 class param; 14892 class statement; 14893 class case_; 14894 14895 14896@end example 14897 14898@noindent 14899@end quotation 14900 14901@item 14902When the context is compiled, the gcc::jit::playback classes (within 14903@code{jit-playback.c} and @code{jit-playback.h}) replay the API calls 14904within langhook:parse_file: 14905 14906@quotation 14907 14908@example 14909 14910 /* Indentation indicates inheritance: */ 14911 class context; 14912 class wrapper; 14913 class type; 14914 class compound_type; 14915 class field; 14916 class function; 14917 class block; 14918 class rvalue; 14919 class lvalue; 14920 class param; 14921 class source_file; 14922 class source_line; 14923 class location; 14924 class case_; 14925 14926 14927@end example 14928 14929@noindent 14930 14931@example 14932Client Code . Generated . libgccjit.so 14933 . code . 14934 . . JIT API . JIT "Frontend". (libbackend.a) 14935.................................................................................... 14936 ��� . . . . 14937 ������������������������������������������������������������������������������> . . 14938 . . ��� . . 14939 . . V . . 14940 . . ������> libgccjit.c . 14941 . . ��� (error-checking). 14942 . . ��� . 14943 . . ������> jit-recording.c 14944 . . (record API calls) 14945 . . <��������������������� . 14946 . . ��� . . 14947 <��������������������������������������������������������������������������������� . . 14948 ��� . . . . 14949 ��� . . . . 14950 V . . gcc_jit_context_compile . 14951 ������������������������������������������������������������������������������> . . 14952 . . ��� start of recording::context::compile () 14953 . . ��� . . 14954 . . ��� start of playback::context::compile () 14955 . . ��� (create tempdir) . 14956 . . ��� . . 14957 . . ��� ACQUIRE MUTEX . 14958 . . ��� . . 14959 . . V���������������������������������������������������������������������> toplev::main (for now) 14960 . . . . ��� 14961 . . . . (various code) 14962 . . . . ��� 14963 . . . . V 14964 . . . <��������������������������������������������������� langhook:parse_file 14965 . . . ��� . 14966 . . . ��� (jit_langhook_parse_file) 14967 . . . ��� . 14968..........................................���..................VVVVVVVVVVVVV... 14969 . . . ��� . No GC in here 14970 . . . ��� jit-playback.c 14971 . . . ��� (playback of API calls) 14972 . . . ���������������������������������������������> creation of functions, 14973 . . . . types, expression trees 14974 . . . <������������������������������������������������ etc 14975 . . . ���(handle_locations: add locations to 14976 . . . ��� linemap and associate them with trees) 14977 . . . ��� . 14978 . . . ��� . No GC in here 14979..........................................���..................AAAAAAAAAAAAA... 14980 . . . ��� for each function 14981 . . . ������> postprocess 14982 . . . ��� . 14983 . . . ������������������������������������> cgraph_finalize_function 14984 . . . <������������������������������������ 14985 . . . <������ . 14986 . . . ��� . 14987 . . . ������������������������������������������������������> (end of 14988 . . . . ��� langhook_parse_file) 14989 . . . . ��� 14990 . . . . (various code) 14991 . . . . ��� 14992 . . . . ��� 14993 . . . <��������������������������������������������������� langhook:write_globals 14994 . . . ��� . 14995 . . . ��� (jit_langhook_write_globals) 14996 . . . ��� . 14997 . . . ��� . 14998 . . . ������������������������������������������������������> finalize_compilation_unit 14999 . . . . ��� 15000 . . . . (the middle���end and backend) 15001 . . . . ��� 15002 . . <��������������������������������������������������������������������������������������� end of toplev::main 15003 . . ��� . . 15004 . . V���������������������������������������������������������������������> toplev::finalize 15005 . . . . ��� (purge internal state) 15006 . . <������������������������������������������������������������������������ end of toplev::finalize 15007 . . ��� . . 15008 . . V���> playback::context::postprocess: 15009 . . ��� . . 15010 . . ��� (assuming an in-memory compile): 15011 . . ��� . . 15012 . . --> Convert assembler to DSO, via embedded 15013 . . copy of driver: 15014 . . driver::main () 15015 . . invocation of "as" 15016 . . invocation of "ld" 15017 . . driver::finalize () 15018 . . <---- 15019 . . ��� . . 15020 . . ��� . Load DSO (dlopen "fake.so") 15021 . . ��� . . 15022 . . ��� . Bundle it up in a jit::result 15023 . . <������ . . 15024 . . ��� . . 15025 . . ��� RELEASE MUTEX . 15026 . . ��� . . 15027 . . ��� end of playback::context::compile () 15028 . . ��� . . 15029 . . ��� playback::context dtor 15030 . . ������> . . 15031 . . ��� Normally we cleanup the tempdir here: 15032 . . ��� ("fake.so" is unlinked from the 15033 . . ��� filesystem at this point) 15034 . . ��� If the client code requested debuginfo, the 15035 . . ��� cleanup happens later (in gcc_jit_result_release) 15036 . . ��� to make it easier on the debugger (see PR jit/64206) 15037 . . <������ . . 15038 . . ��� . . 15039 . . ��� end of recording::context::compile () 15040 <��������������������������������������������������������������������������������� . . 15041 ��� . . . . 15042 V . . gcc_jit_result_get_code . 15043 ������������������������������������������������������������������������������> . . 15044 . . ��� dlsym () within loaded DSO 15045 <��������������������������������������������������������������������������������� . . 15046 Get (void*). . . . 15047 ��� . . . . 15048 ��� Call it . . . . 15049 ���������������������������������������������> . . . 15050 . ��� . . . 15051 . ��� . . . 15052 <��������������������������������������������� . . . 15053 ��� . . . . 15054etc��� . . . . 15055 ��� . . . . 15056 V . . gcc_jit_result_release . 15057 ������������������������������������������������������������������������������> . . 15058 . . ��� dlclose () the loaded DSO 15059 . . ��� (code becomes uncallable) 15060 . . ��� . . 15061 . . ��� If the client code requested debuginfo, then 15062 . . ��� cleanup of the tempdir was delayed. 15063 . . ��� If that was the case, clean it up now. 15064 <��������������������������������������������������������������������������������� . . 15065 ��� . . . . 15066 15067@end example 15068 15069@noindent 15070@end quotation 15071@end itemize 15072 15073Here is a high-level summary from @code{jit-common.h}: 15074 15075@quotation 15076 15077In order to allow jit objects to be usable outside of a compile 15078whilst working with the existing structure of GCC's code the 15079C API is implemented in terms of a gcc::jit::recording::context, 15080which records the calls made to it. 15081 15082When a gcc_jit_context is compiled, the recording context creates a 15083playback context. The playback context invokes the bulk of the GCC 15084code, and within the "frontend" parsing hook, plays back the recorded 15085API calls, creating GCC tree objects. 15086 15087So there are two parallel families of classes: those relating to 15088recording, and those relating to playback: 15089 15090 15091@itemize * 15092 15093@item 15094Visibility: recording objects are exposed back to client code, 15095whereas playback objects are internal to the library. 15096 15097@item 15098Lifetime: recording objects have a lifetime equal to that of the 15099recording context that created them, whereas playback objects only 15100exist within the frontend hook. 15101 15102@item 15103Memory allocation: recording objects are allocated by the recording 15104context, and automatically freed by it when the context is released, 15105whereas playback objects are allocated within the GC heap, and 15106garbage-collected; they can own GC-references. 15107 15108@item 15109Integration with rest of GCC: recording objects are unrelated to the 15110rest of GCC, whereas playback objects are wrappers around "tree" 15111instances. Hence you can't ask a recording rvalue or lvalue what its 15112type is, whereas you can for a playback rvalue of lvalue (since it 15113can work with the underlying GCC tree nodes). 15114 15115@item 15116Instancing: There can be multiple recording contexts "alive" at once 15117(albeit it only one compiling at once), whereas there can only be one 15118playback context alive at one time (since it interacts with the GC). 15119@end itemize 15120 15121Ultimately if GCC could support multiple GC heaps and contexts, and 15122finer-grained initialization, then this recording vs playback 15123distinction could be eliminated. 15124 15125During a playback, we associate objects from the recording with 15126their counterparts during this playback. For simplicity, we store this 15127within the recording objects, as @code{void *m_playback_obj}, casting it to 15128the appropriate playback object subclass. For these casts to make 15129sense, the two class hierarchies need to have the same structure. 15130 15131Note that the playback objects that @code{m_playback_obj} points to are 15132GC-allocated, but the recording objects don't own references: 15133these associations only exist within a part of the code where 15134the GC doesn't collect, and are set back to NULL before the GC can 15135run. 15136@end quotation 15137@anchor{internals/index example-of-log-file}@anchor{5c} 15138Another way to understand the structure of the code is to enable logging, 15139via @pxref{5b,,gcc_jit_context_set_logfile()}. Here is an example of a log 15140generated via this call: 15141 15142@example 15143JIT: libgccjit (GCC) version 6.0.0 20150803 (experimental) (x86_64-pc-linux-gnu) 15144JIT: compiled by GNU C version 4.8.3 20140911 (Red Hat 4.8.3-7), GMP version 5.1.2, MPFR version 3.1.2, MPC version 1.0.1 15145JIT: entering: gcc_jit_context_set_str_option 15146JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe" 15147JIT: exiting: gcc_jit_context_set_str_option 15148JIT: entering: gcc_jit_context_set_int_option 15149JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3 15150JIT: exiting: gcc_jit_context_set_int_option 15151JIT: entering: gcc_jit_context_set_bool_option 15152JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true 15153JIT: exiting: gcc_jit_context_set_bool_option 15154JIT: entering: gcc_jit_context_set_bool_option 15155JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false 15156JIT: exiting: gcc_jit_context_set_bool_option 15157JIT: entering: gcc_jit_context_set_bool_option 15158JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false 15159JIT: exiting: gcc_jit_context_set_bool_option 15160JIT: entering: gcc_jit_context_set_bool_option 15161JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true 15162JIT: exiting: gcc_jit_context_set_bool_option 15163JIT: entering: gcc_jit_context_set_bool_option 15164JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false 15165JIT: exiting: gcc_jit_context_set_bool_option 15166JIT: entering: gcc_jit_context_get_type 15167JIT: exiting: gcc_jit_context_get_type 15168JIT: entering: gcc_jit_context_get_type 15169JIT: exiting: gcc_jit_context_get_type 15170JIT: entering: gcc_jit_context_new_param 15171JIT: exiting: gcc_jit_context_new_param 15172JIT: entering: gcc_jit_context_new_function 15173JIT: exiting: gcc_jit_context_new_function 15174JIT: entering: gcc_jit_context_new_param 15175JIT: exiting: gcc_jit_context_new_param 15176JIT: entering: gcc_jit_context_get_type 15177JIT: exiting: gcc_jit_context_get_type 15178JIT: entering: gcc_jit_context_new_function 15179JIT: exiting: gcc_jit_context_new_function 15180JIT: entering: gcc_jit_context_new_string_literal 15181JIT: exiting: gcc_jit_context_new_string_literal 15182JIT: entering: gcc_jit_function_new_block 15183JIT: exiting: gcc_jit_function_new_block 15184JIT: entering: gcc_jit_block_add_comment 15185JIT: exiting: gcc_jit_block_add_comment 15186JIT: entering: gcc_jit_context_new_call 15187JIT: exiting: gcc_jit_context_new_call 15188JIT: entering: gcc_jit_block_add_eval 15189JIT: exiting: gcc_jit_block_add_eval 15190JIT: entering: gcc_jit_block_end_with_void_return 15191JIT: exiting: gcc_jit_block_end_with_void_return 15192JIT: entering: gcc_jit_context_dump_reproducer_to_file 15193JIT: entering: void gcc::jit::recording::context::dump_reproducer_to_file(const char*) 15194JIT: exiting: void gcc::jit::recording::context::dump_reproducer_to_file(const char*) 15195JIT: exiting: gcc_jit_context_dump_reproducer_to_file 15196JIT: entering: gcc_jit_context_compile 15197JIT: in-memory compile of ctxt: 0x1283e20 15198JIT: entering: gcc::jit::result* gcc::jit::recording::context::compile() 15199JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe" 15200JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3 15201JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true 15202JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false 15203JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false 15204JIT: GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE: false 15205JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false 15206JIT: GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING: false 15207JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true 15208JIT: GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES: false 15209JIT: gcc_jit_context_set_bool_allow_unreachable_blocks: false 15210JIT: gcc_jit_context_set_bool_use_external_driver: false 15211JIT: entering: void gcc::jit::recording::context::validate() 15212JIT: exiting: void gcc::jit::recording::context::validate() 15213JIT: entering: gcc::jit::playback::context::context(gcc::jit::recording::context*) 15214JIT: exiting: gcc::jit::playback::context::context(gcc::jit::recording::context*) 15215JIT: entering: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*) 15216JIT: exiting: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*) 15217JIT: entering: void gcc::jit::playback::context::compile() 15218JIT: entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int) 15219JIT: exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int) 15220JIT: entering: bool gcc::jit::tempdir::create() 15221JIT: m_path_template: /tmp/libgccjit-XXXXXX 15222JIT: m_path_tempdir: /tmp/libgccjit-CKq1M9 15223JIT: exiting: bool gcc::jit::tempdir::create() 15224JIT: entering: void gcc::jit::playback::context::acquire_mutex() 15225JIT: exiting: void gcc::jit::playback::context::acquire_mutex() 15226JIT: entering: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*) 15227JIT: reusing cached configure-time options 15228JIT: configure_time_options[0]: -mtune=generic 15229JIT: configure_time_options[1]: -march=x86-64 15230JIT: exiting: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*) 15231JIT: entering: toplev::main 15232JIT: argv[0]: ./test-hello-world.c.exe 15233JIT: argv[1]: /tmp/libgccjit-CKq1M9/fake.c 15234JIT: argv[2]: -fPIC 15235JIT: argv[3]: -O3 15236JIT: argv[4]: -g 15237JIT: argv[5]: -quiet 15238JIT: argv[6]: --param 15239JIT: argv[7]: ggc-min-expand=0 15240JIT: argv[8]: --param 15241JIT: argv[9]: ggc-min-heapsize=0 15242JIT: argv[10]: -mtune=generic 15243JIT: argv[11]: -march=x86-64 15244JIT: entering: bool jit_langhook_init() 15245JIT: exiting: bool jit_langhook_init() 15246JIT: entering: void gcc::jit::playback::context::replay() 15247JIT: entering: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*) 15248JIT: exiting: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*) 15249JIT: entering: void gcc::jit::recording::context::disassociate_from_playback() 15250JIT: exiting: void gcc::jit::recording::context::disassociate_from_playback() 15251JIT: entering: void gcc::jit::playback::context::handle_locations() 15252JIT: exiting: void gcc::jit::playback::context::handle_locations() 15253JIT: entering: void gcc::jit::playback::function::build_stmt_list() 15254JIT: exiting: void gcc::jit::playback::function::build_stmt_list() 15255JIT: entering: void gcc::jit::playback::function::build_stmt_list() 15256JIT: exiting: void gcc::jit::playback::function::build_stmt_list() 15257JIT: entering: void gcc::jit::playback::function::postprocess() 15258JIT: exiting: void gcc::jit::playback::function::postprocess() 15259JIT: entering: void gcc::jit::playback::function::postprocess() 15260JIT: exiting: void gcc::jit::playback::function::postprocess() 15261JIT: exiting: void gcc::jit::playback::context::replay() 15262JIT: exiting: toplev::main 15263JIT: entering: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*) 15264JIT: exiting: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*) 15265JIT: entering: toplev::finalize 15266JIT: exiting: toplev::finalize 15267JIT: entering: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*) 15268JIT: entering: void gcc::jit::playback::context::convert_to_dso(const char*) 15269JIT: entering: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool) 15270JIT: entering: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*) 15271JIT: exiting: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*) 15272JIT: argv[0]: x86_64-unknown-linux-gnu-gcc-6.0.0 15273JIT: argv[1]: -m64 15274JIT: argv[2]: -shared 15275JIT: argv[3]: /tmp/libgccjit-CKq1M9/fake.s 15276JIT: argv[4]: -o 15277JIT: argv[5]: /tmp/libgccjit-CKq1M9/fake.so 15278JIT: argv[6]: -fno-use-linker-plugin 15279JIT: entering: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*) 15280JIT: exiting: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*) 15281JIT: exiting: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool) 15282JIT: exiting: void gcc::jit::playback::context::convert_to_dso(const char*) 15283JIT: entering: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso() 15284JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir to jit::result 15285JIT: entering: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*) 15286JIT: exiting: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*) 15287JIT: exiting: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso() 15288JIT: exiting: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*) 15289JIT: entering: void gcc::jit::playback::context::release_mutex() 15290JIT: exiting: void gcc::jit::playback::context::release_mutex() 15291JIT: exiting: void gcc::jit::playback::context::compile() 15292JIT: entering: gcc::jit::playback::context::~context() 15293JIT: exiting: gcc::jit::playback::context::~context() 15294JIT: exiting: gcc::jit::result* gcc::jit::recording::context::compile() 15295JIT: gcc_jit_context_compile: returning (gcc_jit_result *)0x12f75d0 15296JIT: exiting: gcc_jit_context_compile 15297JIT: entering: gcc_jit_result_get_code 15298JIT: locating fnname: hello_world 15299JIT: entering: void* gcc::jit::result::get_code(const char*) 15300JIT: exiting: void* gcc::jit::result::get_code(const char*) 15301JIT: gcc_jit_result_get_code: returning (void *)0x7ff6b8cd87f0 15302JIT: exiting: gcc_jit_result_get_code 15303JIT: entering: gcc_jit_context_release 15304JIT: deleting ctxt: 0x1283e20 15305JIT: entering: gcc::jit::recording::context::~context() 15306JIT: exiting: gcc::jit::recording::context::~context() 15307JIT: exiting: gcc_jit_context_release 15308JIT: entering: gcc_jit_result_release 15309JIT: deleting result: 0x12f75d0 15310JIT: entering: virtual gcc::jit::result::~result() 15311JIT: entering: gcc::jit::tempdir::~tempdir() 15312JIT: unlinking .s file: /tmp/libgccjit-CKq1M9/fake.s 15313JIT: unlinking .so file: /tmp/libgccjit-CKq1M9/fake.so 15314JIT: removing tempdir: /tmp/libgccjit-CKq1M9 15315JIT: exiting: gcc::jit::tempdir::~tempdir() 15316JIT: exiting: virtual gcc::jit::result::~result() 15317JIT: exiting: gcc_jit_result_release 15318JIT: gcc::jit::logger::~logger() 15319 15320@end example 15321 15322@noindent 15323 15324@node Design notes,Submitting patches,Overview of code structure,Internals 15325@anchor{internals/index design-notes}@anchor{1cc} 15326@section Design notes 15327 15328 15329It should not be possible for client code to cause an internal compiler 15330error. If this @emph{does} happen, the root cause should be isolated (perhaps 15331using @pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}) and the cause 15332should be rejected via additional checking. The checking ideally should 15333be within the libgccjit API entrypoints in libgccjit.c, since this is as 15334close as possible to the error; failing that, a good place is within 15335@code{recording::context::validate ()} in jit-recording.c. 15336 15337@node Submitting patches,,Design notes,Internals 15338@anchor{internals/index submitting-patches}@anchor{1cd} 15339@section Submitting patches 15340 15341 15342Please read the contribution guidelines for gcc at 15343@indicateurl{https://gcc.gnu.org/contribute.html}. 15344 15345Patches for the jit should be sent to both the 15346@email{gcc-patches@@gcc.gnu.org} and @email{jit@@gcc.gnu.org} mailing lists, 15347with "jit" and "PATCH" in the Subject line. 15348 15349You don't need to do a full bootstrap for code that just touches the 15350@code{jit} and @code{testsuite/jit.dg} subdirectories. However, please run 15351@code{make check-jit} before submitting the patch, and mention the results 15352in your email (along with the host triple that the tests were run on). 15353 15354A good patch should contain the information listed in the 15355gcc contribution guide linked to above; for a @code{jit} patch, the patch 15356shold contain: 15357 15358@quotation 15359 15360 15361@itemize * 15362 15363@item 15364the code itself (for example, a new API entrypoint will typically 15365touch @code{libgccjit.h} and @code{.c}, along with support code in 15366@code{jit-recording.[ch]} and @code{jit-playback.[ch]} as appropriate) 15367 15368@item 15369test coverage 15370 15371@item 15372documentation for the C API 15373 15374@item 15375documentation for the C++ API 15376@end itemize 15377@end quotation 15378 15379A patch that adds new API entrypoints should also contain: 15380 15381@quotation 15382 15383 15384@itemize * 15385 15386@item 15387a feature macro in @code{libgccjit.h} so that client code that doesn't 15388use a "configure" mechanism can still easily detect the presence of 15389the entrypoint. See e.g. @code{LIBGCCJIT_HAVE_SWITCH_STATEMENTS} (for 15390a category of entrypoints) and 15391@code{LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks} 15392(for an individual entrypoint). 15393 15394@item 15395a new ABI tag containing the new symbols (in @code{libgccjit.map}), so 15396that we can detect client code that uses them 15397 15398@item 15399Support for @pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}. Most 15400jit testcases attempt to dump their contexts to a .c file; @code{jit.exp} 15401then sanity-checks the generated c by compiling them (though 15402not running them). A new API entrypoint 15403needs to "know" how to write itself back out to C (by implementing 15404@code{gcc::jit::recording::memento::write_reproducer} for the appropriate 15405@code{memento} subclass). 15406 15407@item 15408C++ bindings for the new entrypoints (see @code{libgccjit++.h}); ideally 15409with test coverage, though the C++ API test coverage is admittedly 15410spotty at the moment 15411 15412@item 15413documentation for the new C entrypoints 15414 15415@item 15416documentation for the new C++ entrypoints 15417 15418@item 15419documentation for the new ABI tag (see @code{topics/compatibility.rst}). 15420@end itemize 15421@end quotation 15422 15423Depending on the patch you can either extend an existing test case, or 15424add a new test case. If you add an entirely new testcase: @code{jit.exp} 15425expects jit testcases to begin with @code{test-}, or @code{test-error-} (for a 15426testcase that generates an error on a @pxref{8,,gcc_jit_context}). 15427 15428Every new testcase that doesn't generate errors should also touch 15429@code{gcc/testsuite/jit.dg/all-non-failing-tests.h}: 15430 15431@quotation 15432 15433 15434@itemize * 15435 15436@item 15437Testcases that don't generate errors should ideally be added to the 15438@code{testcases} array in that file; this means that, in addition 15439to being run standalone, they also get run within 15440@code{test-combination.c} (which runs all successful tests inside one 15441big @pxref{8,,gcc_jit_context}), and @code{test-threads.c} (which runs all 15442successful tests in one process, each one running in a different 15443thread on a different @pxref{8,,gcc_jit_context}). 15444 15445@cartouche 15446@quotation Note 15447Given that exported functions within a @pxref{8,,gcc_jit_context} 15448must have unique names, and most testcases are run within 15449@code{test-combination.c}, this means that every jit-compiled test 15450function typically needs a name that's unique across the entire 15451test suite. 15452@end quotation 15453@end cartouche 15454 15455@item 15456Testcases that aren't to be added to the @code{testcases} array should 15457instead add a comment to the file clarifying why they're not in that 15458array. See the file for examples. 15459@end itemize 15460@end quotation 15461 15462Typically a patch that touches the .rst documentation will also need the 15463texinfo to be regenerated. You can do this with 15464Sphinx 1.0@footnote{http://sphinx-doc.org/} or later by 15465running @code{make texinfo} within @code{SRCDIR/gcc/jit/docs}. Don't do this 15466within the patch sent to the mailing list; it can often be relatively 15467large and inconsequential (e.g. anchor renumbering), rather like generated 15468"configure" changes from configure.ac. You can regenerate it when 15469committing to svn. 15470 15471@node Indices and tables,Index,Internals,Top 15472@anchor{index indices-and-tables}@anchor{1ce} 15473@unnumbered Indices and tables 15474 15475 15476 15477@itemize * 15478 15479@item 15480@emph{genindex} 15481 15482@item 15483@emph{modindex} 15484 15485@item 15486@emph{search} 15487@end itemize 15488 15489@c Some notes: 15490@c 15491@c The Sphinx C domain appears to lack explicit support for enum values, 15492@c so I've been using :c:macro: for them. 15493@c 15494@c See http://sphinx-doc.org/domains.html#the-c-domain 15495 15496@node Index,,Indices and tables,Top 15497@unnumbered Index 15498 15499 15500@printindex ge 15501 15502@c %**end of body 15503@bye 15504