libgccjit.texi revision 1.4
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 8.0.0 (experimental 20171031), October 31, 2017 23 24David Malcolm 25 26Copyright @copyright{} 2014-2018 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-2018 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-2018 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* Function pointers: Function pointers<2>. 170* Source Locations:: 171* Compiling a context:: 172* ABI and API compatibility:: 173* Performance:: 174 175Compilation contexts 176 177* Lifetime-management:: 178* Thread-safety:: 179* Error-handling: Error-handling<2>. 180* Debugging:: 181* Options: Options<2>. 182 183Options 184 185* String Options:: 186* Boolean options:: 187* Integer options:: 188* Additional command-line options:: 189 190Types 191 192* Standard types:: 193* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 194* Vector types:: 195* Structures and unions:: 196* Function pointer types:: 197 198Expressions 199 200* Rvalues:: 201* Lvalues:: 202* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 203 204Rvalues 205 206* Simple expressions:: 207* Vector expressions:: 208* Unary Operations:: 209* Binary Operations:: 210* Comparisons:: 211* Function calls:: 212* Function pointers:: 213* Type-coercion:: 214 215Lvalues 216 217* Global variables:: 218 219Creating and using functions 220 221* Params:: 222* Functions:: 223* Blocks:: 224* Statements:: 225 226Source Locations 227 228* Faking it:: 229 230Compiling a context 231 232* In-memory compilation:: 233* Ahead-of-time compilation:: 234 235ABI and API compatibility 236 237* ABI symbol tags:: 238 239ABI symbol tags 240 241* LIBGCCJIT_ABI_0:: 242* LIBGCCJIT_ABI_1:: 243* LIBGCCJIT_ABI_2:: 244* LIBGCCJIT_ABI_3:: 245* LIBGCCJIT_ABI_4:: 246* LIBGCCJIT_ABI_5:: 247* LIBGCCJIT_ABI_6:: 248* LIBGCCJIT_ABI_7:: 249* LIBGCCJIT_ABI_8:: 250* LIBGCCJIT_ABI_9:: 251* LIBGCCJIT_ABI_10:: 252 253Performance 254 255* The timing API:: 256 257C++ bindings for libgccjit 258 259* Tutorial: Tutorial<2>. 260* Topic Reference: Topic Reference<2>. 261 262Tutorial 263 264* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 265* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 266* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 267* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 268 269Tutorial part 2: Creating a trivial machine code function 270 271* Options: Options<3>. 272* Full example: Full example<3>. 273 274Tutorial part 3: Loops and variables 275 276* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 277* Control flow: Control flow<2>. 278* Visualizing the control flow graph: Visualizing the control flow graph<2>. 279* Full example: Full example<4>. 280 281Tutorial part 4: Adding JIT-compilation to a toy interpreter 282 283* Our toy interpreter: Our toy interpreter<2>. 284* Compiling to machine code: Compiling to machine code<2>. 285* Setting things up: Setting things up<2>. 286* Populating the function: Populating the function<2>. 287* Verifying the control flow graph: Verifying the control flow graph<2>. 288* Compiling the context: Compiling the context<2>. 289* Single-stepping through the generated code: Single-stepping through the generated code<2>. 290* Examining the generated code: Examining the generated code<2>. 291* Putting it all together: Putting it all together<2>. 292* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 293 294Behind the curtain: How does our code get optimized? 295 296* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 297* Elimination of tail recursion: Elimination of tail recursion<2>. 298 299Topic Reference 300 301* Compilation contexts: Compilation contexts<2>. 302* Objects: Objects<2>. 303* Types: Types<2>. 304* Expressions: Expressions<2>. 305* Creating and using functions: Creating and using functions<2>. 306* Source Locations: Source Locations<2>. 307* Compiling a context: Compiling a context<2>. 308 309Compilation contexts 310 311* Lifetime-management: Lifetime-management<2>. 312* Thread-safety: Thread-safety<2>. 313* Error-handling: Error-handling<3>. 314* Debugging: Debugging<2>. 315* Options: Options<4>. 316 317Options 318 319* String Options: String Options<2>. 320* Boolean options: Boolean options<2>. 321* Integer options: Integer options<2>. 322* Additional command-line options: Additional command-line options<2>. 323 324Types 325 326* Standard types: Standard types<2>. 327* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 328* Vector types: Vector types<2>. 329* Structures and unions: Structures and unions<2>. 330 331Expressions 332 333* Rvalues: Rvalues<2>. 334* Lvalues: Lvalues<2>. 335* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 336 337Rvalues 338 339* Simple expressions: Simple expressions<2>. 340* Vector expressions: Vector expressions<2>. 341* Unary Operations: Unary Operations<2>. 342* Binary Operations: Binary Operations<2>. 343* Comparisons: Comparisons<2>. 344* Function calls: Function calls<2>. 345* Function pointers: Function pointers<3>. 346* Type-coercion: Type-coercion<2>. 347 348Lvalues 349 350* Global variables: Global variables<2>. 351 352Creating and using functions 353 354* Params: Params<2>. 355* Functions: Functions<2>. 356* Blocks: Blocks<2>. 357* Statements: Statements<2>. 358 359Source Locations 360 361* Faking it: Faking it<2>. 362 363Compiling a context 364 365* In-memory compilation: In-memory compilation<2>. 366* Ahead-of-time compilation: Ahead-of-time compilation<2>. 367 368Internals 369 370* Working on the JIT library:: 371* Running the test suite:: 372* Environment variables:: 373* Packaging notes:: 374* Overview of code structure:: 375* Design notes:: 376* Submitting patches:: 377 378Running the test suite 379 380* Running under valgrind:: 381 382@end detailmenu 383@end menu 384 385 386@node Tutorial,Topic Reference,Top,Top 387@anchor{intro/index libgccjit}@anchor{1}@anchor{intro/index doc}@anchor{2}@anchor{intro/index tutorial}@anchor{3} 388@chapter Tutorial 389 390 391@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 392@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 393@c 394@c This is free software: you can redistribute it and/or modify it 395@c under the terms of the GNU General Public License as published by 396@c the Free Software Foundation, either version 3 of the License, or 397@c (at your option) any later version. 398@c 399@c This program is distributed in the hope that it will be useful, but 400@c WITHOUT ANY WARRANTY; without even the implied warranty of 401@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 402@c General Public License for more details. 403@c 404@c You should have received a copy of the GNU General Public License 405@c along with this program. If not, see 406@c <http://www.gnu.org/licenses/>. 407 408@menu 409* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world". 410* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function. 411* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables. 412* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter. 413* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler. 414 415@end menu 416 417@node Tutorial part 1 "Hello world",Tutorial part 2 Creating a trivial machine code function,,Tutorial 418@anchor{intro/tutorial01 doc}@anchor{4}@anchor{intro/tutorial01 tutorial-part-1-hello-world}@anchor{5} 419@section Tutorial part 1: "Hello world" 420 421 422Before we look at the details of the API, let's look at building and 423running programs that use the library. 424 425Here's a toy "hello world" program that uses the library to synthesize 426a call to @cite{printf} and uses it to write a message to stdout. 427 428Don't worry about the content of the program for now; we'll cover 429the details in later parts of this tutorial. 430 431@quotation 432 433@example 434/* Smoketest example for libgccjit.so 435 Copyright (C) 2014-2018 Free Software Foundation, Inc. 436 437This file is part of GCC. 438 439GCC is free software; you can redistribute it and/or modify it 440under the terms of the GNU General Public License as published by 441the Free Software Foundation; either version 3, or (at your option) 442any later version. 443 444GCC is distributed in the hope that it will be useful, but 445WITHOUT ANY WARRANTY; without even the implied warranty of 446MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 447General Public License for more details. 448 449You should have received a copy of the GNU General Public License 450along with GCC; see the file COPYING3. If not see 451<http://www.gnu.org/licenses/>. */ 452 453#include <libgccjit.h> 454 455#include <stdlib.h> 456#include <stdio.h> 457 458static void 459create_code (gcc_jit_context *ctxt) 460@{ 461 /* Let's try to inject the equivalent of: 462 void 463 greet (const char *name) 464 @{ 465 printf ("hello %s\n", name); 466 @} 467 */ 468 gcc_jit_type *void_type = 469 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); 470 gcc_jit_type *const_char_ptr_type = 471 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); 472 gcc_jit_param *param_name = 473 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); 474 gcc_jit_function *func = 475 gcc_jit_context_new_function (ctxt, NULL, 476 GCC_JIT_FUNCTION_EXPORTED, 477 void_type, 478 "greet", 479 1, ¶m_name, 480 0); 481 482 gcc_jit_param *param_format = 483 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); 484 gcc_jit_function *printf_func = 485 gcc_jit_context_new_function (ctxt, NULL, 486 GCC_JIT_FUNCTION_IMPORTED, 487 gcc_jit_context_get_type ( 488 ctxt, GCC_JIT_TYPE_INT), 489 "printf", 490 1, ¶m_format, 491 1); 492 gcc_jit_rvalue *args[2]; 493 args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); 494 args[1] = gcc_jit_param_as_rvalue (param_name); 495 496 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 497 498 gcc_jit_block_add_eval ( 499 block, NULL, 500 gcc_jit_context_new_call (ctxt, 501 NULL, 502 printf_func, 503 2, args)); 504 gcc_jit_block_end_with_void_return (block, NULL); 505@} 506 507int 508main (int argc, char **argv) 509@{ 510 gcc_jit_context *ctxt; 511 gcc_jit_result *result; 512 513 /* Get a "context" object for working with the library. */ 514 ctxt = gcc_jit_context_acquire (); 515 if (!ctxt) 516 @{ 517 fprintf (stderr, "NULL ctxt"); 518 exit (1); 519 @} 520 521 /* Set some options on the context. 522 Let's see the code being generated, in assembler form. */ 523 gcc_jit_context_set_bool_option ( 524 ctxt, 525 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 526 0); 527 528 /* Populate the context. */ 529 create_code (ctxt); 530 531 /* Compile the code. */ 532 result = gcc_jit_context_compile (ctxt); 533 if (!result) 534 @{ 535 fprintf (stderr, "NULL result"); 536 exit (1); 537 @} 538 539 /* Extract the generated code from "result". */ 540 typedef void (*fn_type) (const char *); 541 fn_type greet = 542 (fn_type)gcc_jit_result_get_code (result, "greet"); 543 if (!greet) 544 @{ 545 fprintf (stderr, "NULL greet"); 546 exit (1); 547 @} 548 549 /* Now call the generated function: */ 550 greet ("world"); 551 fflush (stdout); 552 553 gcc_jit_context_release (ctxt); 554 gcc_jit_result_release (result); 555 return 0; 556@} 557 558@end example 559 560@noindent 561@end quotation 562 563Copy the above to @cite{tut01-hello-world.c}. 564 565Assuming you have the jit library installed, build the test program 566using: 567 568@example 569$ gcc \ 570 tut01-hello-world.c \ 571 -o tut01-hello-world \ 572 -lgccjit 573@end example 574 575@noindent 576 577You should then be able to run the built program: 578 579@example 580$ ./tut01-hello-world 581hello world 582@end example 583 584@noindent 585 586@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 587@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 588@c 589@c This is free software: you can redistribute it and/or modify it 590@c under the terms of the GNU General Public License as published by 591@c the Free Software Foundation, either version 3 of the License, or 592@c (at your option) any later version. 593@c 594@c This program is distributed in the hope that it will be useful, but 595@c WITHOUT ANY WARRANTY; without even the implied warranty of 596@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 597@c General Public License for more details. 598@c 599@c You should have received a copy of the GNU General Public License 600@c along with this program. If not, see 601@c <http://www.gnu.org/licenses/>. 602 603@node Tutorial part 2 Creating a trivial machine code function,Tutorial part 3 Loops and variables,Tutorial part 1 "Hello world",Tutorial 604@anchor{intro/tutorial02 doc}@anchor{6}@anchor{intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{7} 605@section Tutorial part 2: Creating a trivial machine code function 606 607 608Consider this C function: 609 610@example 611int square (int i) 612@{ 613 return i * i; 614@} 615@end example 616 617@noindent 618 619How can we construct this at run-time using libgccjit? 620 621First we need to include the relevant header: 622 623@example 624#include <libgccjit.h> 625@end example 626 627@noindent 628 629All state associated with compilation is associated with a 630@pxref{8,,gcc_jit_context *}. 631 632Create one using @pxref{9,,gcc_jit_context_acquire()}: 633 634@example 635gcc_jit_context *ctxt; 636ctxt = gcc_jit_context_acquire (); 637@end example 638 639@noindent 640 641The JIT library has a system of types. It is statically-typed: every 642expression is of a specific type, fixed at compile-time. In our example, 643all of the expressions are of the C @cite{int} type, so let's obtain this from 644the context, as a @pxref{a,,gcc_jit_type *}, using 645@pxref{b,,gcc_jit_context_get_type()}: 646 647@example 648gcc_jit_type *int_type = 649 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 650@end example 651 652@noindent 653 654@pxref{a,,gcc_jit_type *} is an example of a "contextual" object: every 655entity in the API is associated with a @pxref{8,,gcc_jit_context *}. 656 657Memory management is easy: all such "contextual" objects are automatically 658cleaned up for you when the context is released, using 659@pxref{c,,gcc_jit_context_release()}: 660 661@example 662gcc_jit_context_release (ctxt); 663@end example 664 665@noindent 666 667so you don't need to manually track and cleanup all objects, just the 668contexts. 669 670Although the API is C-based, there is a form of class hierarchy, which 671looks like this: 672 673@example 674+- gcc_jit_object 675 +- gcc_jit_location 676 +- gcc_jit_type 677 +- gcc_jit_struct 678 +- gcc_jit_field 679 +- gcc_jit_function 680 +- gcc_jit_block 681 +- gcc_jit_rvalue 682 +- gcc_jit_lvalue 683 +- gcc_jit_param 684@end example 685 686@noindent 687 688There are casting methods for upcasting from subclasses to parent classes. 689For example, @pxref{d,,gcc_jit_type_as_object()}: 690 691@example 692gcc_jit_object *obj = gcc_jit_type_as_object (int_type); 693@end example 694 695@noindent 696 697One thing you can do with a @pxref{e,,gcc_jit_object *} is 698to ask it for a human-readable description, using 699@pxref{f,,gcc_jit_object_get_debug_string()}: 700 701@example 702printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); 703@end example 704 705@noindent 706 707giving this text on stdout: 708 709@example 710obj: int 711@end example 712 713@noindent 714 715This is invaluable when debugging. 716 717Let's create the function. To do so, we first need to construct 718its single parameter, specifying its type and giving it a name, 719using @pxref{10,,gcc_jit_context_new_param()}: 720 721@example 722gcc_jit_param *param_i = 723 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 724@end example 725 726@noindent 727 728Now we can create the function, using 729@pxref{11,,gcc_jit_context_new_function()}: 730 731@example 732gcc_jit_function *func = 733 gcc_jit_context_new_function (ctxt, NULL, 734 GCC_JIT_FUNCTION_EXPORTED, 735 int_type, 736 "square", 737 1, ¶m_i, 738 0); 739@end example 740 741@noindent 742 743To define the code within the function, we must create basic blocks 744containing statements. 745 746Every basic block contains a list of statements, eventually terminated 747by a statement that either returns, or jumps to another basic block. 748 749Our function has no control-flow, so we just need one basic block: 750 751@example 752gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 753@end example 754 755@noindent 756 757Our basic block is relatively simple: it immediately terminates by 758returning the value of an expression. 759 760We can build the expression using @pxref{12,,gcc_jit_context_new_binary_op()}: 761 762@example 763gcc_jit_rvalue *expr = 764 gcc_jit_context_new_binary_op ( 765 ctxt, NULL, 766 GCC_JIT_BINARY_OP_MULT, int_type, 767 gcc_jit_param_as_rvalue (param_i), 768 gcc_jit_param_as_rvalue (param_i)); 769@end example 770 771@noindent 772 773A @pxref{13,,gcc_jit_rvalue *} is another example of a 774@pxref{e,,gcc_jit_object *} subclass. We can upcast it using 775@pxref{14,,gcc_jit_rvalue_as_object()} and as before print it with 776@pxref{f,,gcc_jit_object_get_debug_string()}. 777 778@example 779printf ("expr: %s\n", 780 gcc_jit_object_get_debug_string ( 781 gcc_jit_rvalue_as_object (expr))); 782@end example 783 784@noindent 785 786giving this output: 787 788@example 789expr: i * i 790@end example 791 792@noindent 793 794Creating the expression in itself doesn't do anything; we have to add 795this expression to a statement within the block. In this case, we use it 796to build a return statement, which terminates the basic block: 797 798@example 799gcc_jit_block_end_with_return (block, NULL, expr); 800@end example 801 802@noindent 803 804OK, we've populated the context. We can now compile it using 805@pxref{15,,gcc_jit_context_compile()}: 806 807@example 808gcc_jit_result *result; 809result = gcc_jit_context_compile (ctxt); 810@end example 811 812@noindent 813 814and get a @pxref{16,,gcc_jit_result *}. 815 816At this point we're done with the context; we can release it: 817 818@example 819gcc_jit_context_release (ctxt); 820@end example 821 822@noindent 823 824We can now use @pxref{17,,gcc_jit_result_get_code()} to look up a specific 825machine code routine within the result, in this case, the function we 826created above. 827 828@example 829void *fn_ptr = gcc_jit_result_get_code (result, "square"); 830if (!fn_ptr) 831 @{ 832 fprintf (stderr, "NULL fn_ptr"); 833 goto error; 834 @} 835@end example 836 837@noindent 838 839We can now cast the pointer to an appropriate function pointer type, and 840then call it: 841 842@example 843typedef int (*fn_type) (int); 844fn_type square = (fn_type)fn_ptr; 845printf ("result: %d", square (5)); 846@end example 847 848@noindent 849 850@example 851result: 25 852@end example 853 854@noindent 855 856Once we're done with the code, we can release the result: 857 858@example 859gcc_jit_result_release (result); 860@end example 861 862@noindent 863 864We can't call @code{square} anymore once we've released @code{result}. 865 866@menu 867* Error-handling:: 868* Options:: 869* Full example:: 870 871@end menu 872 873@node Error-handling,Options,,Tutorial part 2 Creating a trivial machine code function 874@anchor{intro/tutorial02 error-handling}@anchor{18} 875@subsection Error-handling 876 877 878Various kinds of errors are possible when using the API, such as 879mismatched types in an assignment. You can only compile and get code 880from a context if no errors occur. 881 882Errors are printed on stderr; they typically contain the name of the API 883entrypoint where the error occurred, and pertinent information on the 884problem: 885 886@example 887./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *) 888@end example 889 890@noindent 891 892The API is designed to cope with errors without crashing, so you can get 893away with having a single error-handling check in your code: 894 895@example 896void *fn_ptr = gcc_jit_result_get_code (result, "square"); 897if (!fn_ptr) 898 @{ 899 fprintf (stderr, "NULL fn_ptr"); 900 goto error; 901 @} 902@end example 903 904@noindent 905 906For more information, see the @pxref{19,,error-handling guide} 907within the Topic eference. 908 909@node Options,Full example,Error-handling,Tutorial part 2 Creating a trivial machine code function 910@anchor{intro/tutorial02 options}@anchor{1a} 911@subsection Options 912 913 914To get more information on what's going on, you can set debugging flags 915on the context using @pxref{1b,,gcc_jit_context_set_bool_option()}. 916 917@c (I'm deliberately not mentioning 918@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think 919@c it's probably more of use to implementors than to users) 920 921Setting @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a 922C-like representation to stderr when you compile (GCC's "GIMPLE" 923representation): 924 925@example 926gcc_jit_context_set_bool_option ( 927 ctxt, 928 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 929 1); 930result = gcc_jit_context_compile (ctxt); 931@end example 932 933@noindent 934 935@example 936square (signed int i) 937@{ 938 signed int D.260; 939 940 entry: 941 D.260 = i * i; 942 return D.260; 943@} 944@end example 945 946@noindent 947 948We can see the generated machine code in assembler form (on stderr) by 949setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context 950before compiling: 951 952@example 953gcc_jit_context_set_bool_option ( 954 ctxt, 955 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 956 1); 957result = gcc_jit_context_compile (ctxt); 958@end example 959 960@noindent 961 962@example 963 .file "fake.c" 964 .text 965 .globl square 966 .type square, @@function 967square: 968.LFB6: 969 .cfi_startproc 970 pushq %rbp 971 .cfi_def_cfa_offset 16 972 .cfi_offset 6, -16 973 movq %rsp, %rbp 974 .cfi_def_cfa_register 6 975 movl %edi, -4(%rbp) 976.L14: 977 movl -4(%rbp), %eax 978 imull -4(%rbp), %eax 979 popq %rbp 980 .cfi_def_cfa 7, 8 981 ret 982 .cfi_endproc 983.LFE6: 984 .size square, .-square 985 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 986 .section .note.GNU-stack,"",@@progbits 987@end example 988 989@noindent 990 991By default, no optimizations are performed, the equivalent of GCC's 992@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling 993@pxref{1e,,gcc_jit_context_set_int_option()} with 994@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 995 996@example 997gcc_jit_context_set_int_option ( 998 ctxt, 999 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 1000 3); 1001@end example 1002 1003@noindent 1004 1005@example 1006 .file "fake.c" 1007 .text 1008 .p2align 4,,15 1009 .globl square 1010 .type square, @@function 1011square: 1012.LFB7: 1013 .cfi_startproc 1014.L16: 1015 movl %edi, %eax 1016 imull %edi, %eax 1017 ret 1018 .cfi_endproc 1019.LFE7: 1020 .size square, .-square 1021 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 1022 .section .note.GNU-stack,"",@@progbits 1023@end example 1024 1025@noindent 1026 1027Naturally this has only a small effect on such a trivial function. 1028 1029@node Full example,,Options,Tutorial part 2 Creating a trivial machine code function 1030@anchor{intro/tutorial02 full-example}@anchor{20} 1031@subsection Full example 1032 1033 1034Here's what the above looks like as a complete program: 1035 1036@quotation 1037 1038@example 1039/* Usage example for libgccjit.so 1040 Copyright (C) 2014-2018 Free Software Foundation, Inc. 1041 1042This file is part of GCC. 1043 1044GCC is free software; you can redistribute it and/or modify it 1045under the terms of the GNU General Public License as published by 1046the Free Software Foundation; either version 3, or (at your option) 1047any later version. 1048 1049GCC is distributed in the hope that it will be useful, but 1050WITHOUT ANY WARRANTY; without even the implied warranty of 1051MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1052General Public License for more details. 1053 1054You should have received a copy of the GNU General Public License 1055along with GCC; see the file COPYING3. If not see 1056<http://www.gnu.org/licenses/>. */ 1057 1058#include <libgccjit.h> 1059 1060#include <stdlib.h> 1061#include <stdio.h> 1062 1063void 1064create_code (gcc_jit_context *ctxt) 1065@{ 1066 /* Let's try to inject the equivalent of: 1067 1068 int square (int i) 1069 @{ 1070 return i * i; 1071 @} 1072 */ 1073 gcc_jit_type *int_type = 1074 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1075 gcc_jit_param *param_i = 1076 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 1077 gcc_jit_function *func = 1078 gcc_jit_context_new_function (ctxt, NULL, 1079 GCC_JIT_FUNCTION_EXPORTED, 1080 int_type, 1081 "square", 1082 1, ¶m_i, 1083 0); 1084 1085 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 1086 1087 gcc_jit_rvalue *expr = 1088 gcc_jit_context_new_binary_op ( 1089 ctxt, NULL, 1090 GCC_JIT_BINARY_OP_MULT, int_type, 1091 gcc_jit_param_as_rvalue (param_i), 1092 gcc_jit_param_as_rvalue (param_i)); 1093 1094 gcc_jit_block_end_with_return (block, NULL, expr); 1095@} 1096 1097int 1098main (int argc, char **argv) 1099@{ 1100 gcc_jit_context *ctxt = NULL; 1101 gcc_jit_result *result = NULL; 1102 1103 /* Get a "context" object for working with the library. */ 1104 ctxt = gcc_jit_context_acquire (); 1105 if (!ctxt) 1106 @{ 1107 fprintf (stderr, "NULL ctxt"); 1108 goto error; 1109 @} 1110 1111 /* Set some options on the context. 1112 Let's see the code being generated, in assembler form. */ 1113 gcc_jit_context_set_bool_option ( 1114 ctxt, 1115 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1116 0); 1117 1118 /* Populate the context. */ 1119 create_code (ctxt); 1120 1121 /* Compile the code. */ 1122 result = gcc_jit_context_compile (ctxt); 1123 if (!result) 1124 @{ 1125 fprintf (stderr, "NULL result"); 1126 goto error; 1127 @} 1128 1129 /* We're done with the context; we can release it: */ 1130 gcc_jit_context_release (ctxt); 1131 ctxt = NULL; 1132 1133 /* Extract the generated code from "result". */ 1134 void *fn_ptr = gcc_jit_result_get_code (result, "square"); 1135 if (!fn_ptr) 1136 @{ 1137 fprintf (stderr, "NULL fn_ptr"); 1138 goto error; 1139 @} 1140 1141 typedef int (*fn_type) (int); 1142 fn_type square = (fn_type)fn_ptr; 1143 printf ("result: %d\n", square (5)); 1144 1145 error: 1146 if (ctxt) 1147 gcc_jit_context_release (ctxt); 1148 if (result) 1149 gcc_jit_result_release (result); 1150 return 0; 1151@} 1152 1153@end example 1154 1155@noindent 1156@end quotation 1157 1158Building and running it: 1159 1160@example 1161$ gcc \ 1162 tut02-square.c \ 1163 -o tut02-square \ 1164 -lgccjit 1165 1166# Run the built program: 1167$ ./tut02-square 1168result: 25 1169@end example 1170 1171@noindent 1172 1173@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 1174@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 1175@c 1176@c This is free software: you can redistribute it and/or modify it 1177@c under the terms of the GNU General Public License as published by 1178@c the Free Software Foundation, either version 3 of the License, or 1179@c (at your option) any later version. 1180@c 1181@c This program is distributed in the hope that it will be useful, but 1182@c WITHOUT ANY WARRANTY; without even the implied warranty of 1183@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1184@c General Public License for more details. 1185@c 1186@c You should have received a copy of the GNU General Public License 1187@c along with this program. If not, see 1188@c <http://www.gnu.org/licenses/>. 1189 1190@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 1191@anchor{intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{21}@anchor{intro/tutorial03 doc}@anchor{22} 1192@section Tutorial part 3: Loops and variables 1193 1194 1195Consider this C function: 1196 1197@quotation 1198 1199@example 1200int loop_test (int n) 1201@{ 1202 int sum = 0; 1203 for (int i = 0; i < n; i++) 1204 sum += i * i; 1205 return sum; 1206@} 1207@end example 1208 1209@noindent 1210@end quotation 1211 1212This example demonstrates some more features of libgccjit, with local 1213variables and a loop. 1214 1215To break this down into libgccjit terms, it's usually easier to reword 1216the @cite{for} loop as a @cite{while} loop, giving: 1217 1218@quotation 1219 1220@example 1221int loop_test (int n) 1222@{ 1223 int sum = 0; 1224 int i = 0; 1225 while (i < n) 1226 @{ 1227 sum += i * i; 1228 i++; 1229 @} 1230 return sum; 1231@} 1232@end example 1233 1234@noindent 1235@end quotation 1236 1237Here's what the final control flow graph will look like: 1238 1239@quotation 1240 1241 1242@float Figure 1243 1244@image{sum-of-squares1,,,image of a control flow graph,png} 1245 1246@end float 1247 1248@end quotation 1249 1250As before, we include the libgccjit header and make a 1251@pxref{8,,gcc_jit_context *}. 1252 1253@example 1254#include <libgccjit.h> 1255 1256void test (void) 1257@{ 1258 gcc_jit_context *ctxt; 1259 ctxt = gcc_jit_context_acquire (); 1260@end example 1261 1262@noindent 1263 1264The function works with the C @cite{int} type: 1265 1266@example 1267gcc_jit_type *the_type = 1268 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1269gcc_jit_type *return_type = the_type; 1270@end example 1271 1272@noindent 1273 1274though we could equally well make it work on, say, @cite{double}: 1275 1276@example 1277gcc_jit_type *the_type = 1278 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE); 1279@end example 1280 1281@noindent 1282 1283Let's build the function: 1284 1285@example 1286gcc_jit_param *n = 1287 gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); 1288gcc_jit_param *params[1] = @{n@}; 1289gcc_jit_function *func = 1290 gcc_jit_context_new_function (ctxt, NULL, 1291 GCC_JIT_FUNCTION_EXPORTED, 1292 return_type, 1293 "loop_test", 1294 1, params, 0); 1295@end example 1296 1297@noindent 1298 1299@menu 1300* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. 1301* Control flow:: 1302* Visualizing the control flow graph:: 1303* Full example: Full example<2>. 1304 1305@end menu 1306 1307@node Expressions lvalues and rvalues,Control flow,,Tutorial part 3 Loops and variables 1308@anchor{intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{23} 1309@subsection Expressions: lvalues and rvalues 1310 1311 1312The base class of expression is the @pxref{13,,gcc_jit_rvalue *}, 1313representing an expression that can be on the @emph{right}-hand side of 1314an assignment: a value that can be computed somehow, and assigned 1315@emph{to} a storage area (such as a variable). It has a specific 1316@pxref{a,,gcc_jit_type *}. 1317 1318Anothe important class is @pxref{24,,gcc_jit_lvalue *}. 1319A @pxref{24,,gcc_jit_lvalue *}. is something that can of the @emph{left}-hand 1320side of an assignment: a storage area (such as a variable). 1321 1322In other words, every assignment can be thought of as: 1323 1324@example 1325LVALUE = RVALUE; 1326@end example 1327 1328@noindent 1329 1330Note that @pxref{24,,gcc_jit_lvalue *} is a subclass of 1331@pxref{13,,gcc_jit_rvalue *}, where in an assignment of the form: 1332 1333@example 1334LVALUE_A = LVALUE_B; 1335@end example 1336 1337@noindent 1338 1339the @cite{LVALUE_B} implies reading the current value of that storage 1340area, assigning it into the @cite{LVALUE_A}. 1341 1342So far the only expressions we've seen are @cite{i * i}: 1343 1344@example 1345gcc_jit_rvalue *expr = 1346 gcc_jit_context_new_binary_op ( 1347 ctxt, NULL, 1348 GCC_JIT_BINARY_OP_MULT, int_type, 1349 gcc_jit_param_as_rvalue (param_i), 1350 gcc_jit_param_as_rvalue (param_i)); 1351@end example 1352 1353@noindent 1354 1355which is a @pxref{13,,gcc_jit_rvalue *}, and the various function 1356parameters: @cite{param_i} and @cite{param_n}, instances of 1357@pxref{25,,gcc_jit_param *}, which is a subclass of 1358@pxref{24,,gcc_jit_lvalue *} (and, in turn, of @pxref{13,,gcc_jit_rvalue *}): 1359we can both read from and write to function parameters within the 1360body of a function. 1361 1362Our new example has a couple of local variables. We create them by 1363calling @pxref{26,,gcc_jit_function_new_local()}, supplying a type and a 1364name: 1365 1366@example 1367/* Build locals: */ 1368gcc_jit_lvalue *i = 1369 gcc_jit_function_new_local (func, NULL, the_type, "i"); 1370gcc_jit_lvalue *sum = 1371 gcc_jit_function_new_local (func, NULL, the_type, "sum"); 1372@end example 1373 1374@noindent 1375 1376These are instances of @pxref{24,,gcc_jit_lvalue *} - they can be read from 1377and written to. 1378 1379Note that there is no precanned way to create @emph{and} initialize a variable 1380like in C: 1381 1382@example 1383int i = 0; 1384@end example 1385 1386@noindent 1387 1388Instead, having added the local to the function, we have to separately add 1389an assignment of @cite{0} to @cite{local_i} at the beginning of the function. 1390 1391@node Control flow,Visualizing the control flow graph,Expressions lvalues and rvalues,Tutorial part 3 Loops and variables 1392@anchor{intro/tutorial03 control-flow}@anchor{27} 1393@subsection Control flow 1394 1395 1396This function has a loop, so we need to build some basic blocks to 1397handle the control flow. In this case, we need 4 blocks: 1398 1399 1400@enumerate 1401 1402@item 1403before the loop (initializing the locals) 1404 1405@item 1406the conditional at the top of the loop (comparing @cite{i < n}) 1407 1408@item 1409the body of the loop 1410 1411@item 1412after the loop terminates (@cite{return sum}) 1413@end enumerate 1414 1415so we create these as @pxref{28,,gcc_jit_block *} instances within the 1416@pxref{29,,gcc_jit_function *}: 1417 1418@example 1419gcc_jit_block *b_initial = 1420 gcc_jit_function_new_block (func, "initial"); 1421gcc_jit_block *b_loop_cond = 1422 gcc_jit_function_new_block (func, "loop_cond"); 1423gcc_jit_block *b_loop_body = 1424 gcc_jit_function_new_block (func, "loop_body"); 1425gcc_jit_block *b_after_loop = 1426 gcc_jit_function_new_block (func, "after_loop"); 1427@end example 1428 1429@noindent 1430 1431We now populate each block with statements. 1432 1433The entry block @cite{b_initial} consists of initializations followed by a jump 1434to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using 1435@pxref{2a,,gcc_jit_block_add_assignment()} to add 1436an assignment statement, and using @pxref{2b,,gcc_jit_context_zero()} to get 1437the constant value @cite{0} for the relevant type for the right-hand side of 1438the assignment: 1439 1440@example 1441/* sum = 0; */ 1442gcc_jit_block_add_assignment ( 1443 b_initial, NULL, 1444 sum, 1445 gcc_jit_context_zero (ctxt, the_type)); 1446 1447/* i = 0; */ 1448gcc_jit_block_add_assignment ( 1449 b_initial, NULL, 1450 i, 1451 gcc_jit_context_zero (ctxt, the_type)); 1452@end example 1453 1454@noindent 1455 1456We can then terminate the entry block by jumping to the conditional: 1457 1458@example 1459gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); 1460@end example 1461 1462@noindent 1463 1464The conditional block is equivalent to the line @cite{while (i < n)} from our 1465C example. It contains a single statement: a conditional, which jumps to 1466one of two destination blocks depending on a boolean 1467@pxref{13,,gcc_jit_rvalue *}, in this case the comparison of @cite{i} and @cite{n}. 1468We build the comparison using @pxref{2c,,gcc_jit_context_new_comparison()}: 1469 1470@example 1471/* (i >= n) */ 1472 gcc_jit_rvalue *guard = 1473 gcc_jit_context_new_comparison ( 1474 ctxt, NULL, 1475 GCC_JIT_COMPARISON_GE, 1476 gcc_jit_lvalue_as_rvalue (i), 1477 gcc_jit_param_as_rvalue (n)); 1478@end example 1479 1480@noindent 1481 1482and can then use this to add @cite{b_loop_cond}'s sole statement, via 1483@pxref{2d,,gcc_jit_block_end_with_conditional()}: 1484 1485@example 1486/* Equivalent to: 1487 if (guard) 1488 goto after_loop; 1489 else 1490 goto loop_body; */ 1491gcc_jit_block_end_with_conditional ( 1492 b_loop_cond, NULL, 1493 guard, 1494 b_after_loop, /* on_true */ 1495 b_loop_body); /* on_false */ 1496@end example 1497 1498@noindent 1499 1500Next, we populate the body of the loop. 1501 1502The C statement @cite{sum += i * i;} is an assignment operation, where an 1503lvalue is modified "in-place". We use 1504@pxref{2e,,gcc_jit_block_add_assignment_op()} to handle these operations: 1505 1506@example 1507/* sum += i * i */ 1508gcc_jit_block_add_assignment_op ( 1509 b_loop_body, NULL, 1510 sum, 1511 GCC_JIT_BINARY_OP_PLUS, 1512 gcc_jit_context_new_binary_op ( 1513 ctxt, NULL, 1514 GCC_JIT_BINARY_OP_MULT, the_type, 1515 gcc_jit_lvalue_as_rvalue (i), 1516 gcc_jit_lvalue_as_rvalue (i))); 1517@end example 1518 1519@noindent 1520 1521The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in 1522a similar way. We use @pxref{2f,,gcc_jit_context_one()} to get the constant 1523value @cite{1} (for the relevant type) for the right-hand side 1524of the assignment. 1525 1526@example 1527/* i++ */ 1528gcc_jit_block_add_assignment_op ( 1529 b_loop_body, NULL, 1530 i, 1531 GCC_JIT_BINARY_OP_PLUS, 1532 gcc_jit_context_one (ctxt, the_type)); 1533@end example 1534 1535@noindent 1536 1537@cartouche 1538@quotation Note 1539For numeric constants other than 0 or 1, we could use 1540@pxref{30,,gcc_jit_context_new_rvalue_from_int()} and 1541@pxref{31,,gcc_jit_context_new_rvalue_from_double()}. 1542@end quotation 1543@end cartouche 1544 1545The loop body completes by jumping back to the conditional: 1546 1547@example 1548gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); 1549@end example 1550 1551@noindent 1552 1553Finally, we populate the @cite{b_after_loop} block, reached when the loop 1554conditional is false. We want to generate the equivalent of: 1555 1556@example 1557return sum; 1558@end example 1559 1560@noindent 1561 1562so the block is just one statement: 1563 1564@example 1565/* return sum */ 1566gcc_jit_block_end_with_return ( 1567 b_after_loop, 1568 NULL, 1569 gcc_jit_lvalue_as_rvalue (sum)); 1570@end example 1571 1572@noindent 1573 1574@cartouche 1575@quotation Note 1576You can intermingle block creation with statement creation, 1577but given that the terminator statements generally include references 1578to other blocks, I find it's clearer to create all the blocks, 1579@emph{then} all the statements. 1580@end quotation 1581@end cartouche 1582 1583We've finished populating the function. As before, we can now compile it 1584to machine code: 1585 1586@example 1587gcc_jit_result *result; 1588result = gcc_jit_context_compile (ctxt); 1589 1590typedef int (*loop_test_fn_type) (int); 1591loop_test_fn_type loop_test = 1592 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 1593if (!loop_test) 1594 goto error; 1595printf ("result: %d", loop_test (10)); 1596@end example 1597 1598@noindent 1599 1600@example 1601result: 285 1602@end example 1603 1604@noindent 1605 1606@node Visualizing the control flow graph,Full example<2>,Control flow,Tutorial part 3 Loops and variables 1607@anchor{intro/tutorial03 visualizing-the-control-flow-graph}@anchor{32} 1608@subsection Visualizing the control flow graph 1609 1610 1611You can see the control flow graph of a function using 1612@pxref{33,,gcc_jit_function_dump_to_dot()}: 1613 1614@example 1615gcc_jit_function_dump_to_dot (func, "/tmp/sum-of-squares.dot"); 1616@end example 1617 1618@noindent 1619 1620giving a .dot file in GraphViz format. 1621 1622You can convert this to an image using @cite{dot}: 1623 1624@example 1625$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png 1626@end example 1627 1628@noindent 1629 1630or use a viewer (my preferred one is xdot.py; see 1631@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can 1632install it with @cite{yum install python-xdot}): 1633 1634@quotation 1635 1636 1637@float Figure 1638 1639@image{sum-of-squares1,,,image of a control flow graph,png} 1640 1641@end float 1642 1643@end quotation 1644 1645@node Full example<2>,,Visualizing the control flow graph,Tutorial part 3 Loops and variables 1646@anchor{intro/tutorial03 full-example}@anchor{34} 1647@subsection Full example 1648 1649 1650@quotation 1651 1652@example 1653/* Usage example for libgccjit.so 1654 Copyright (C) 2014-2018 Free Software Foundation, Inc. 1655 1656This file is part of GCC. 1657 1658GCC is free software; you can redistribute it and/or modify it 1659under the terms of the GNU General Public License as published by 1660the Free Software Foundation; either version 3, or (at your option) 1661any later version. 1662 1663GCC is distributed in the hope that it will be useful, but 1664WITHOUT ANY WARRANTY; without even the implied warranty of 1665MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1666General Public License for more details. 1667 1668You should have received a copy of the GNU General Public License 1669along with GCC; see the file COPYING3. If not see 1670<http://www.gnu.org/licenses/>. */ 1671 1672#include <libgccjit.h> 1673 1674#include <stdlib.h> 1675#include <stdio.h> 1676 1677void 1678create_code (gcc_jit_context *ctxt) 1679@{ 1680 /* 1681 Simple sum-of-squares, to test conditionals and looping 1682 1683 int loop_test (int n) 1684 @{ 1685 int i; 1686 int sum = 0; 1687 for (i = 0; i < n ; i ++) 1688 @{ 1689 sum += i * i; 1690 @} 1691 return sum; 1692 */ 1693 gcc_jit_type *the_type = 1694 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1695 gcc_jit_type *return_type = the_type; 1696 1697 gcc_jit_param *n = 1698 gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); 1699 gcc_jit_param *params[1] = @{n@}; 1700 gcc_jit_function *func = 1701 gcc_jit_context_new_function (ctxt, NULL, 1702 GCC_JIT_FUNCTION_EXPORTED, 1703 return_type, 1704 "loop_test", 1705 1, params, 0); 1706 1707 /* Build locals: */ 1708 gcc_jit_lvalue *i = 1709 gcc_jit_function_new_local (func, NULL, the_type, "i"); 1710 gcc_jit_lvalue *sum = 1711 gcc_jit_function_new_local (func, NULL, the_type, "sum"); 1712 1713 gcc_jit_block *b_initial = 1714 gcc_jit_function_new_block (func, "initial"); 1715 gcc_jit_block *b_loop_cond = 1716 gcc_jit_function_new_block (func, "loop_cond"); 1717 gcc_jit_block *b_loop_body = 1718 gcc_jit_function_new_block (func, "loop_body"); 1719 gcc_jit_block *b_after_loop = 1720 gcc_jit_function_new_block (func, "after_loop"); 1721 1722 /* sum = 0; */ 1723 gcc_jit_block_add_assignment ( 1724 b_initial, NULL, 1725 sum, 1726 gcc_jit_context_zero (ctxt, the_type)); 1727 1728 /* i = 0; */ 1729 gcc_jit_block_add_assignment ( 1730 b_initial, NULL, 1731 i, 1732 gcc_jit_context_zero (ctxt, the_type)); 1733 1734 gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); 1735 1736 /* if (i >= n) */ 1737 gcc_jit_block_end_with_conditional ( 1738 b_loop_cond, NULL, 1739 gcc_jit_context_new_comparison ( 1740 ctxt, NULL, 1741 GCC_JIT_COMPARISON_GE, 1742 gcc_jit_lvalue_as_rvalue (i), 1743 gcc_jit_param_as_rvalue (n)), 1744 b_after_loop, 1745 b_loop_body); 1746 1747 /* sum += i * i */ 1748 gcc_jit_block_add_assignment_op ( 1749 b_loop_body, NULL, 1750 sum, 1751 GCC_JIT_BINARY_OP_PLUS, 1752 gcc_jit_context_new_binary_op ( 1753 ctxt, NULL, 1754 GCC_JIT_BINARY_OP_MULT, the_type, 1755 gcc_jit_lvalue_as_rvalue (i), 1756 gcc_jit_lvalue_as_rvalue (i))); 1757 1758 /* i++ */ 1759 gcc_jit_block_add_assignment_op ( 1760 b_loop_body, NULL, 1761 i, 1762 GCC_JIT_BINARY_OP_PLUS, 1763 gcc_jit_context_one (ctxt, the_type)); 1764 1765 gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); 1766 1767 /* return sum */ 1768 gcc_jit_block_end_with_return ( 1769 b_after_loop, 1770 NULL, 1771 gcc_jit_lvalue_as_rvalue (sum)); 1772@} 1773 1774int 1775main (int argc, char **argv) 1776@{ 1777 gcc_jit_context *ctxt = NULL; 1778 gcc_jit_result *result = NULL; 1779 1780 /* Get a "context" object for working with the library. */ 1781 ctxt = gcc_jit_context_acquire (); 1782 if (!ctxt) 1783 @{ 1784 fprintf (stderr, "NULL ctxt"); 1785 goto error; 1786 @} 1787 1788 /* Set some options on the context. 1789 Let's see the code being generated, in assembler form. */ 1790 gcc_jit_context_set_bool_option ( 1791 ctxt, 1792 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1793 0); 1794 1795 /* Populate the context. */ 1796 create_code (ctxt); 1797 1798 /* Compile the code. */ 1799 result = gcc_jit_context_compile (ctxt); 1800 if (!result) 1801 @{ 1802 fprintf (stderr, "NULL result"); 1803 goto error; 1804 @} 1805 1806 /* Extract the generated code from "result". */ 1807 typedef int (*loop_test_fn_type) (int); 1808 loop_test_fn_type loop_test = 1809 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 1810 if (!loop_test) 1811 @{ 1812 fprintf (stderr, "NULL loop_test"); 1813 goto error; 1814 @} 1815 1816 /* Run the generated code. */ 1817 int val = loop_test (10); 1818 printf("loop_test returned: %d\n", val); 1819 1820 error: 1821 gcc_jit_context_release (ctxt); 1822 gcc_jit_result_release (result); 1823 return 0; 1824@} 1825 1826@end example 1827 1828@noindent 1829@end quotation 1830 1831Building and running it: 1832 1833@example 1834$ gcc \ 1835 tut03-sum-of-squares.c \ 1836 -o tut03-sum-of-squares \ 1837 -lgccjit 1838 1839# Run the built program: 1840$ ./tut03-sum-of-squares 1841loop_test returned: 285 1842@end example 1843 1844@noindent 1845 1846@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 1847@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 1848@c 1849@c This is free software: you can redistribute it and/or modify it 1850@c under the terms of the GNU General Public License as published by 1851@c the Free Software Foundation, either version 3 of the License, or 1852@c (at your option) any later version. 1853@c 1854@c This program is distributed in the hope that it will be useful, but 1855@c WITHOUT ANY WARRANTY; without even the implied warranty of 1856@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1857@c General Public License for more details. 1858@c 1859@c You should have received a copy of the GNU General Public License 1860@c along with this program. If not, see 1861@c <http://www.gnu.org/licenses/>. 1862 1863@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 1864@anchor{intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{35}@anchor{intro/tutorial04 doc}@anchor{36} 1865@section Tutorial part 4: Adding JIT-compilation to a toy interpreter 1866 1867 1868In this example we construct a "toy" interpreter, and add JIT-compilation 1869to it. 1870 1871@menu 1872* Our toy interpreter:: 1873* Compiling to machine code:: 1874* Setting things up:: 1875* Populating the function:: 1876* Verifying the control flow graph:: 1877* Compiling the context:: 1878* Single-stepping through the generated code:: 1879* Examining the generated code:: 1880* Putting it all together:: 1881* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?. 1882 1883@end menu 1884 1885@node Our toy interpreter,Compiling to machine code,,Tutorial part 4 Adding JIT-compilation to a toy interpreter 1886@anchor{intro/tutorial04 our-toy-interpreter}@anchor{37} 1887@subsection Our toy interpreter 1888 1889 1890It's a stack-based interpreter, and is intended as a (very simple) example 1891of the kind of bytecode interpreter seen in dynamic languages such as 1892Python, Ruby etc. 1893 1894For the sake of simplicity, our toy virtual machine is very limited: 1895 1896@quotation 1897 1898 1899@itemize * 1900 1901@item 1902The only data type is @cite{int} 1903 1904@item 1905It can only work on one function at a time (so that the only 1906function call that can be made is to recurse). 1907 1908@item 1909Functions can only take one parameter. 1910 1911@item 1912Functions have a stack of @cite{int} values. 1913 1914@item 1915We'll implement function call within the interpreter by calling a 1916function in our implementation, rather than implementing our own 1917frame stack. 1918 1919@item 1920The parser is only good enough to get the examples to work. 1921@end itemize 1922@end quotation 1923 1924Naturally, a real interpreter would be much more complicated that this. 1925 1926The following operations are supported: 1927 1928 1929@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx} 1930@headitem 1931 1932Operation 1933 1934@tab 1935 1936Meaning 1937 1938@tab 1939 1940Old Stack 1941 1942@tab 1943 1944New Stack 1945 1946@item 1947 1948DUP 1949 1950@tab 1951 1952Duplicate top of stack. 1953 1954@tab 1955 1956@code{[..., x]} 1957 1958@tab 1959 1960@code{[..., x, x]} 1961 1962@item 1963 1964ROT 1965 1966@tab 1967 1968Swap top two elements 1969of stack. 1970 1971@tab 1972 1973@code{[..., x, y]} 1974 1975@tab 1976 1977@code{[..., y, x]} 1978 1979@item 1980 1981BINARY_ADD 1982 1983@tab 1984 1985Add the top two elements 1986on the stack. 1987 1988@tab 1989 1990@code{[..., x, y]} 1991 1992@tab 1993 1994@code{[..., (x+y)]} 1995 1996@item 1997 1998BINARY_SUBTRACT 1999 2000@tab 2001 2002Likewise, but subtract. 2003 2004@tab 2005 2006@code{[..., x, y]} 2007 2008@tab 2009 2010@code{[..., (x-y)]} 2011 2012@item 2013 2014BINARY_MULT 2015 2016@tab 2017 2018Likewise, but multiply. 2019 2020@tab 2021 2022@code{[..., x, y]} 2023 2024@tab 2025 2026@code{[..., (x*y)]} 2027 2028@item 2029 2030BINARY_COMPARE_LT 2031 2032@tab 2033 2034Compare the top two 2035elements on the stack 2036and push a nonzero/zero 2037if (x<y). 2038 2039@tab 2040 2041@code{[..., x, y]} 2042 2043@tab 2044 2045@code{[..., (x<y)]} 2046 2047@item 2048 2049RECURSE 2050 2051@tab 2052 2053Recurse, passing the top 2054of the stack, and 2055popping the result. 2056 2057@tab 2058 2059@code{[..., x]} 2060 2061@tab 2062 2063@code{[..., fn(x)]} 2064 2065@item 2066 2067RETURN 2068 2069@tab 2070 2071Return the top of the 2072stack. 2073 2074@tab 2075 2076@code{[x]} 2077 2078@tab 2079 2080@code{[]} 2081 2082@item 2083 2084PUSH_CONST @cite{arg} 2085 2086@tab 2087 2088Push an int const. 2089 2090@tab 2091 2092@code{[...]} 2093 2094@tab 2095 2096@code{[..., arg]} 2097 2098@item 2099 2100JUMP_ABS_IF_TRUE @cite{arg} 2101 2102@tab 2103 2104Pop; if top of stack was 2105nonzero, jump to 2106@code{arg}. 2107 2108@tab 2109 2110@code{[..., x]} 2111 2112@tab 2113 2114@code{[...]} 2115 2116@end multitable 2117 2118 2119Programs can be interpreted, disassembled, and compiled to machine code. 2120 2121The interpreter reads @code{.toy} scripts. Here's what a simple recursive 2122factorial program looks like, the script @code{factorial.toy}. 2123The parser ignores lines beginning with a @cite{#}. 2124 2125@quotation 2126 2127@example 2128# Simple recursive factorial implementation, roughly equivalent to: 2129# 2130# int factorial (int arg) 2131# @{ 2132# if (arg < 2) 2133# return arg 2134# return arg * factorial (arg - 1) 2135# @} 2136 2137# Initial state: 2138# stack: [arg] 2139 2140# 0: 2141DUP 2142# stack: [arg, arg] 2143 2144# 1: 2145PUSH_CONST 2 2146# stack: [arg, arg, 2] 2147 2148# 2: 2149BINARY_COMPARE_LT 2150# stack: [arg, (arg < 2)] 2151 2152# 3: 2153JUMP_ABS_IF_TRUE 9 2154# stack: [arg] 2155 2156# 4: 2157DUP 2158# stack: [arg, arg] 2159 2160# 5: 2161PUSH_CONST 1 2162# stack: [arg, arg, 1] 2163 2164# 6: 2165BINARY_SUBTRACT 2166# stack: [arg, (arg - 1) 2167 2168# 7: 2169RECURSE 2170# stack: [arg, factorial(arg - 1)] 2171 2172# 8: 2173BINARY_MULT 2174# stack: [arg * factorial(arg - 1)] 2175 2176# 9: 2177RETURN 2178 2179@end example 2180 2181@noindent 2182@end quotation 2183 2184The interpreter is a simple infinite loop with a big @code{switch} statement 2185based on what the next opcode is: 2186 2187@quotation 2188 2189@example 2190 2191static int 2192toyvm_function_interpret (toyvm_function *fn, int arg, FILE *trace) 2193@{ 2194 toyvm_frame frame; 2195#define PUSH(ARG) (toyvm_frame_push (&frame, (ARG))) 2196#define POP(ARG) (toyvm_frame_pop (&frame)) 2197 2198 frame.frm_function = fn; 2199 frame.frm_pc = 0; 2200 frame.frm_cur_depth = 0; 2201 2202 PUSH (arg); 2203 2204 while (1) 2205 @{ 2206 toyvm_op *op; 2207 int x, y; 2208 assert (frame.frm_pc < fn->fn_num_ops); 2209 op = &fn->fn_ops[frame.frm_pc++]; 2210 2211 if (trace) 2212 @{ 2213 toyvm_frame_dump_stack (&frame, trace); 2214 toyvm_function_disassemble_op (fn, op, frame.frm_pc, trace); 2215 @} 2216 2217 switch (op->op_opcode) 2218 @{ 2219 /* Ops taking no operand. */ 2220 case DUP: 2221 x = POP (); 2222 PUSH (x); 2223 PUSH (x); 2224 break; 2225 2226 case ROT: 2227 y = POP (); 2228 x = POP (); 2229 PUSH (y); 2230 PUSH (x); 2231 break; 2232 2233 case BINARY_ADD: 2234 y = POP (); 2235 x = POP (); 2236 PUSH (x + y); 2237 break; 2238 2239 case BINARY_SUBTRACT: 2240 y = POP (); 2241 x = POP (); 2242 PUSH (x - y); 2243 break; 2244 2245 case BINARY_MULT: 2246 y = POP (); 2247 x = POP (); 2248 PUSH (x * y); 2249 break; 2250 2251 case BINARY_COMPARE_LT: 2252 y = POP (); 2253 x = POP (); 2254 PUSH (x < y); 2255 break; 2256 2257 case RECURSE: 2258 x = POP (); 2259 x = toyvm_function_interpret (fn, x, trace); 2260 PUSH (x); 2261 break; 2262 2263 case RETURN: 2264 return POP (); 2265 2266 /* Ops taking an operand. */ 2267 case PUSH_CONST: 2268 PUSH (op->op_operand); 2269 break; 2270 2271 case JUMP_ABS_IF_TRUE: 2272 x = POP (); 2273 if (x) 2274 frame.frm_pc = op->op_operand; 2275 break; 2276 2277 default: 2278 assert (0); /* unknown opcode */ 2279 2280 @} /* end of switch on opcode */ 2281 @} /* end of while loop */ 2282 2283#undef PUSH 2284#undef POP 2285@} 2286 2287 2288@end example 2289 2290@noindent 2291@end quotation 2292 2293@node Compiling to machine code,Setting things up,Our toy interpreter,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2294@anchor{intro/tutorial04 compiling-to-machine-code}@anchor{38} 2295@subsection Compiling to machine code 2296 2297 2298We want to generate machine code that can be cast to this type and 2299then directly executed in-process: 2300 2301@quotation 2302 2303@example 2304typedef int (*toyvm_compiled_code) (int); 2305 2306 2307@end example 2308 2309@noindent 2310@end quotation 2311 2312The lifetime of the code is tied to that of a @pxref{16,,gcc_jit_result *}. 2313We'll handle this by bundling them up in a structure, so that we can 2314clean them up together by calling @pxref{39,,gcc_jit_result_release()}: 2315 2316@quotation 2317 2318@example 2319 2320struct toyvm_compiled_function 2321@{ 2322 gcc_jit_result *cf_jit_result; 2323 toyvm_compiled_code cf_code; 2324@}; 2325 2326 2327@end example 2328 2329@noindent 2330@end quotation 2331 2332Our compiler isn't very sophisticated; it takes the implementation of 2333each opcode above, and maps it directly to the operations supported by 2334the libgccjit API. 2335 2336How should we handle the stack? In theory we could calculate what the 2337stack depth will be at each opcode, and optimize away the stack 2338manipulation "by hand". We'll see below that libgccjit is able to do 2339this for us, so we'll implement stack manipulation 2340in a direct way, by creating a @code{stack} array and @code{stack_depth} 2341variables, local within the generated function, equivalent to this C code: 2342 2343@example 2344int stack_depth; 2345int stack[MAX_STACK_DEPTH]; 2346@end example 2347 2348@noindent 2349 2350We'll also have local variables @code{x} and @code{y} for use when implementing 2351the opcodes, equivalent to this: 2352 2353@example 2354int x; 2355int y; 2356@end example 2357 2358@noindent 2359 2360This means our compiler has the following state: 2361 2362@quotation 2363 2364@example 2365 2366struct compilation_state 2367@{ 2368 gcc_jit_context *ctxt; 2369 2370 gcc_jit_type *int_type; 2371 gcc_jit_type *bool_type; 2372 gcc_jit_type *stack_type; /* int[MAX_STACK_DEPTH] */ 2373 2374 gcc_jit_rvalue *const_one; 2375 2376 gcc_jit_function *fn; 2377 gcc_jit_param *param_arg; 2378 gcc_jit_lvalue *stack; 2379 gcc_jit_lvalue *stack_depth; 2380 gcc_jit_lvalue *x; 2381 gcc_jit_lvalue *y; 2382 2383 gcc_jit_location *op_locs[MAX_OPS]; 2384 gcc_jit_block *initial_block; 2385 gcc_jit_block *op_blocks[MAX_OPS]; 2386 2387@}; 2388 2389 2390@end example 2391 2392@noindent 2393@end quotation 2394 2395@node Setting things up,Populating the function,Compiling to machine code,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2396@anchor{intro/tutorial04 setting-things-up}@anchor{3a} 2397@subsection Setting things up 2398 2399 2400First we create our types: 2401 2402@quotation 2403 2404@example 2405 state.int_type = 2406 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_INT); 2407 state.bool_type = 2408 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_BOOL); 2409 state.stack_type = 2410 gcc_jit_context_new_array_type (state.ctxt, NULL, 2411 state.int_type, MAX_STACK_DEPTH); 2412 2413 2414@end example 2415 2416@noindent 2417@end quotation 2418 2419along with extracting a useful @cite{int} constant: 2420 2421@quotation 2422 2423@example 2424 state.const_one = gcc_jit_context_one (state.ctxt, state.int_type); 2425 2426 2427@end example 2428 2429@noindent 2430@end quotation 2431 2432We'll implement push and pop in terms of the @code{stack} array and 2433@code{stack_depth}. Here are helper functions for adding statements to 2434a block, implementing pushing and popping values: 2435 2436@quotation 2437 2438@example 2439 2440static void 2441add_push (compilation_state *state, 2442 gcc_jit_block *block, 2443 gcc_jit_rvalue *rvalue, 2444 gcc_jit_location *loc) 2445@{ 2446 /* stack[stack_depth] = RVALUE */ 2447 gcc_jit_block_add_assignment ( 2448 block, 2449 loc, 2450 /* stack[stack_depth] */ 2451 gcc_jit_context_new_array_access ( 2452 state->ctxt, 2453 loc, 2454 gcc_jit_lvalue_as_rvalue (state->stack), 2455 gcc_jit_lvalue_as_rvalue (state->stack_depth)), 2456 rvalue); 2457 2458 /* "stack_depth++;". */ 2459 gcc_jit_block_add_assignment_op ( 2460 block, 2461 loc, 2462 state->stack_depth, 2463 GCC_JIT_BINARY_OP_PLUS, 2464 state->const_one); 2465@} 2466 2467static void 2468add_pop (compilation_state *state, 2469 gcc_jit_block *block, 2470 gcc_jit_lvalue *lvalue, 2471 gcc_jit_location *loc) 2472@{ 2473 /* "--stack_depth;". */ 2474 gcc_jit_block_add_assignment_op ( 2475 block, 2476 loc, 2477 state->stack_depth, 2478 GCC_JIT_BINARY_OP_MINUS, 2479 state->const_one); 2480 2481 /* "LVALUE = stack[stack_depth];". */ 2482 gcc_jit_block_add_assignment ( 2483 block, 2484 loc, 2485 lvalue, 2486 /* stack[stack_depth] */ 2487 gcc_jit_lvalue_as_rvalue ( 2488 gcc_jit_context_new_array_access ( 2489 state->ctxt, 2490 loc, 2491 gcc_jit_lvalue_as_rvalue (state->stack), 2492 gcc_jit_lvalue_as_rvalue (state->stack_depth)))); 2493@} 2494 2495 2496@end example 2497 2498@noindent 2499@end quotation 2500 2501We will support single-stepping through the generated code in the 2502debugger, so we need to create @pxref{3b,,gcc_jit_location} instances, one 2503per operation in the source code. These will reference the lines of 2504e.g. @code{factorial.toy}. 2505 2506@quotation 2507 2508@example 2509 for (pc = 0; pc < fn->fn_num_ops; pc++) 2510 @{ 2511 toyvm_op *op = &fn->fn_ops[pc]; 2512 2513 state.op_locs[pc] = gcc_jit_context_new_location (state.ctxt, 2514 fn->fn_filename, 2515 op->op_linenum, 2516 0); /* column */ 2517 @} 2518 2519 2520@end example 2521 2522@noindent 2523@end quotation 2524 2525Let's create the function itself. As usual, we create its parameter 2526first, then use the parameter to create the function: 2527 2528@quotation 2529 2530@example 2531 state.param_arg = 2532 gcc_jit_context_new_param (state.ctxt, state.op_locs[0], 2533 state.int_type, "arg"); 2534 state.fn = 2535 gcc_jit_context_new_function (state.ctxt, 2536 state.op_locs[0], 2537 GCC_JIT_FUNCTION_EXPORTED, 2538 state.int_type, 2539 funcname, 2540 1, &state.param_arg, 0); 2541 2542 2543@end example 2544 2545@noindent 2546@end quotation 2547 2548We create the locals within the function. 2549 2550@quotation 2551 2552@example 2553 state.stack = 2554 gcc_jit_function_new_local (state.fn, NULL, 2555 state.stack_type, "stack"); 2556 state.stack_depth = 2557 gcc_jit_function_new_local (state.fn, NULL, 2558 state.int_type, "stack_depth"); 2559 state.x = 2560 gcc_jit_function_new_local (state.fn, NULL, 2561 state.int_type, "x"); 2562 state.y = 2563 gcc_jit_function_new_local (state.fn, NULL, 2564 state.int_type, "y"); 2565 2566 2567@end example 2568 2569@noindent 2570@end quotation 2571 2572@node Populating the function,Verifying the control flow graph,Setting things up,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2573@anchor{intro/tutorial04 populating-the-function}@anchor{3c} 2574@subsection Populating the function 2575 2576 2577There's some one-time initialization, and the API treats the first block 2578you create as the entrypoint of the function, so we need to create that 2579block first: 2580 2581@quotation 2582 2583@example 2584 state.initial_block = gcc_jit_function_new_block (state.fn, "initial"); 2585 2586 2587@end example 2588 2589@noindent 2590@end quotation 2591 2592We can now create blocks for each of the operations. Most of these will 2593be consolidated into larger blocks when the optimizer runs. 2594 2595@quotation 2596 2597@example 2598 for (pc = 0; pc < fn->fn_num_ops; pc++) 2599 @{ 2600 char buf[16]; 2601 sprintf (buf, "instr%i", pc); 2602 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); 2603 @} 2604 2605 2606@end example 2607 2608@noindent 2609@end quotation 2610 2611Now that we have a block it can jump to when it's done, we can populate 2612the initial block: 2613 2614@quotation 2615 2616@example 2617 2618 /* "stack_depth = 0;". */ 2619 gcc_jit_block_add_assignment ( 2620 state.initial_block, 2621 state.op_locs[0], 2622 state.stack_depth, 2623 gcc_jit_context_zero (state.ctxt, state.int_type)); 2624 2625 /* "PUSH (arg);". */ 2626 add_push (&state, 2627 state.initial_block, 2628 gcc_jit_param_as_rvalue (state.param_arg), 2629 state.op_locs[0]); 2630 2631 /* ...and jump to insn 0. */ 2632 gcc_jit_block_end_with_jump (state.initial_block, 2633 state.op_locs[0], 2634 state.op_blocks[0]); 2635 2636 2637@end example 2638 2639@noindent 2640@end quotation 2641 2642We can now populate the blocks for the individual operations. We loop 2643through them, adding instructions to their blocks: 2644 2645@quotation 2646 2647@example 2648 for (pc = 0; pc < fn->fn_num_ops; pc++) 2649 @{ 2650 gcc_jit_location *loc = state.op_locs[pc]; 2651 2652 gcc_jit_block *block = state.op_blocks[pc]; 2653 gcc_jit_block *next_block = (pc < fn->fn_num_ops 2654 ? state.op_blocks[pc + 1] 2655 : NULL); 2656 2657 toyvm_op *op; 2658 op = &fn->fn_ops[pc]; 2659 2660 2661@end example 2662 2663@noindent 2664@end quotation 2665 2666We're going to have another big @code{switch} statement for implementing 2667the opcodes, this time for compiling them, rather than interpreting 2668them. It's helpful to have macros for implementing push and pop, so that 2669we can make the @code{switch} statement that's coming up look as much as 2670possible like the one above within the interpreter: 2671 2672@example 2673 2674#define X_EQUALS_POP()\ 2675 add_pop (&state, block, state.x, loc) 2676#define Y_EQUALS_POP()\ 2677 add_pop (&state, block, state.y, loc) 2678#define PUSH_RVALUE(RVALUE)\ 2679 add_push (&state, block, (RVALUE), loc) 2680#define PUSH_X()\ 2681 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.x)) 2682#define PUSH_Y() \ 2683 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.y)) 2684 2685 2686@end example 2687 2688@noindent 2689 2690@cartouche 2691@quotation Note 2692A particularly clever implementation would have an @emph{identical} 2693@code{switch} statement shared by the interpreter and the compiler, with 2694some preprocessor "magic". We're not doing that here, for the sake 2695of simplicity. 2696@end quotation 2697@end cartouche 2698 2699When I first implemented this compiler, I accidentally missed an edit 2700when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the 2701stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y} 2702uninitialized. 2703 2704To track this kind of thing down, we can use 2705@pxref{3d,,gcc_jit_block_add_comment()} to add descriptive comments 2706to the internal representation. This is invaluable when looking through 2707the generated IR for, say @code{factorial}: 2708 2709@quotation 2710 2711@example 2712 2713 gcc_jit_block_add_comment (block, loc, opcode_names[op->op_opcode]); 2714 2715 2716@end example 2717 2718@noindent 2719@end quotation 2720 2721We can now write the big @code{switch} statement that implements the 2722individual opcodes, populating the relevant block with statements: 2723 2724@quotation 2725 2726@example 2727 2728 switch (op->op_opcode) 2729 @{ 2730 case DUP: 2731 X_EQUALS_POP (); 2732 PUSH_X (); 2733 PUSH_X (); 2734 break; 2735 2736 case ROT: 2737 Y_EQUALS_POP (); 2738 X_EQUALS_POP (); 2739 PUSH_Y (); 2740 PUSH_X (); 2741 break; 2742 2743 case BINARY_ADD: 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_PLUS, 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_SUBTRACT: 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_MINUS, 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_MULT: 2770 Y_EQUALS_POP (); 2771 X_EQUALS_POP (); 2772 PUSH_RVALUE ( 2773 gcc_jit_context_new_binary_op ( 2774 state.ctxt, 2775 loc, 2776 GCC_JIT_BINARY_OP_MULT, 2777 state.int_type, 2778 gcc_jit_lvalue_as_rvalue (state.x), 2779 gcc_jit_lvalue_as_rvalue (state.y))); 2780 break; 2781 2782 case BINARY_COMPARE_LT: 2783 Y_EQUALS_POP (); 2784 X_EQUALS_POP (); 2785 PUSH_RVALUE ( 2786 /* cast of bool to int */ 2787 gcc_jit_context_new_cast ( 2788 state.ctxt, 2789 loc, 2790 /* (x < y) as a bool */ 2791 gcc_jit_context_new_comparison ( 2792 state.ctxt, 2793 loc, 2794 GCC_JIT_COMPARISON_LT, 2795 gcc_jit_lvalue_as_rvalue (state.x), 2796 gcc_jit_lvalue_as_rvalue (state.y)), 2797 state.int_type)); 2798 break; 2799 2800 case RECURSE: 2801 @{ 2802 X_EQUALS_POP (); 2803 gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (state.x); 2804 PUSH_RVALUE ( 2805 gcc_jit_context_new_call ( 2806 state.ctxt, 2807 loc, 2808 state.fn, 2809 1, &arg)); 2810 break; 2811 @} 2812 2813 case RETURN: 2814 X_EQUALS_POP (); 2815 gcc_jit_block_end_with_return ( 2816 block, 2817 loc, 2818 gcc_jit_lvalue_as_rvalue (state.x)); 2819 break; 2820 2821 /* Ops taking an operand. */ 2822 case PUSH_CONST: 2823 PUSH_RVALUE ( 2824 gcc_jit_context_new_rvalue_from_int ( 2825 state.ctxt, 2826 state.int_type, 2827 op->op_operand)); 2828 break; 2829 2830 case JUMP_ABS_IF_TRUE: 2831 X_EQUALS_POP (); 2832 gcc_jit_block_end_with_conditional ( 2833 block, 2834 loc, 2835 /* "(bool)x". */ 2836 gcc_jit_context_new_cast ( 2837 state.ctxt, 2838 loc, 2839 gcc_jit_lvalue_as_rvalue (state.x), 2840 state.bool_type), 2841 state.op_blocks[op->op_operand], /* on_true */ 2842 next_block); /* on_false */ 2843 break; 2844 2845 default: 2846 assert(0); 2847 @} /* end of switch on opcode */ 2848 2849 2850@end example 2851 2852@noindent 2853@end quotation 2854 2855Every block must be terminated, via a call to one of the 2856@code{gcc_jit_block_end_with_} entrypoints. This has been done for two 2857of the opcodes, but we need to do it for the other ones, by jumping 2858to the next block. 2859 2860@quotation 2861 2862@example 2863 if (op->op_opcode != JUMP_ABS_IF_TRUE 2864 && op->op_opcode != RETURN) 2865 gcc_jit_block_end_with_jump ( 2866 block, 2867 loc, 2868 next_block); 2869 2870 2871@end example 2872 2873@noindent 2874@end quotation 2875 2876This is analogous to simply incrementing the program counter. 2877 2878@node Verifying the control flow graph,Compiling the context,Populating the function,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2879@anchor{intro/tutorial04 verifying-the-control-flow-graph}@anchor{3e} 2880@subsection Verifying the control flow graph 2881 2882 2883Having finished looping over the blocks, the context is complete. 2884 2885As before, we can verify that the control flow and statements are sane by 2886using @pxref{33,,gcc_jit_function_dump_to_dot()}: 2887 2888@example 2889gcc_jit_function_dump_to_dot (state.fn, "/tmp/factorial.dot"); 2890@end example 2891 2892@noindent 2893 2894and viewing the result. Note how the label names, comments, and 2895variable names show up in the dump, to make it easier to spot 2896errors in our compiler. 2897 2898@quotation 2899 2900 2901@float Figure 2902 2903@image{factorial1,,,image of a control flow graph,png} 2904 2905@end float 2906 2907@end quotation 2908 2909@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 2910@anchor{intro/tutorial04 compiling-the-context}@anchor{3f} 2911@subsection Compiling the context 2912 2913 2914Having finished looping over the blocks and populating them with 2915statements, the context is complete. 2916 2917We can now compile it, and extract machine code from the result: 2918 2919@quotation 2920 2921@example 2922 gcc_jit_result *jit_result = gcc_jit_context_compile (state.ctxt); 2923 gcc_jit_context_release (state.ctxt); 2924 2925 toyvm_compiled_function *toyvm_result = 2926 (toyvm_compiled_function *)calloc (1, sizeof (toyvm_compiled_function)); 2927 if (!toyvm_result) 2928 @{ 2929 fprintf (stderr, "out of memory allocating toyvm_compiled_function\n"); 2930 gcc_jit_result_release (jit_result); 2931 return NULL; 2932 @} 2933 2934 toyvm_result->cf_jit_result = jit_result; 2935 toyvm_result->cf_code = 2936 (toyvm_compiled_code)gcc_jit_result_get_code (jit_result, 2937 funcname); 2938 2939 free (funcname); 2940 2941 return toyvm_result; 2942@} 2943 2944char test[1024]; 2945 2946#define CHECK_NON_NULL(PTR) \ 2947 do @{ \ 2948 if ((PTR) != NULL) \ 2949 @{ \ 2950 pass ("%s: %s is non-null", test, #PTR); \ 2951 @} \ 2952 else \ 2953 @{ \ 2954 fail ("%s: %s is NULL", test, #PTR); \ 2955 abort (); \ 2956 @} \ 2957 @} while (0) 2958 2959#define CHECK_VALUE(ACTUAL, EXPECTED) \ 2960 do @{ \ 2961 if ((ACTUAL) == (EXPECTED)) \ 2962 @{ \ 2963 pass ("%s: actual: %s == expected: %s", test, #ACTUAL, #EXPECTED); \ 2964 @} \ 2965 else \ 2966 @{ \ 2967 fail ("%s: actual: %s != expected: %s", test, #ACTUAL, #EXPECTED); \ 2968 fprintf (stderr, "incorrect value\n"); \ 2969 abort (); \ 2970 @} \ 2971 @} while (0) 2972 2973static void 2974test_script (const char *scripts_dir, const char *script_name, int input, 2975 int expected_result) 2976@{ 2977 char *script_path; 2978 toyvm_function *fn; 2979 int interpreted_result; 2980 toyvm_compiled_function *compiled_fn; 2981 toyvm_compiled_code code; 2982 int compiled_result; 2983 2984 snprintf (test, sizeof (test), "toyvm.c: %s", script_name); 2985 2986 script_path = (char *)malloc (strlen (scripts_dir) 2987 + strlen (script_name) + 1); 2988 CHECK_NON_NULL (script_path); 2989 sprintf (script_path, "%s%s", scripts_dir, script_name); 2990 2991 fn = toyvm_function_parse (script_path, script_name); 2992 CHECK_NON_NULL (fn); 2993 2994 interpreted_result = toyvm_function_interpret (fn, input, NULL); 2995 CHECK_VALUE (interpreted_result, expected_result); 2996 2997 compiled_fn = toyvm_function_compile (fn); 2998 CHECK_NON_NULL (compiled_fn); 2999 3000 code = (toyvm_compiled_code)compiled_fn->cf_code; 3001 CHECK_NON_NULL (code); 3002 3003 compiled_result = code (input); 3004 CHECK_VALUE (compiled_result, expected_result); 3005 3006 gcc_jit_result_release (compiled_fn->cf_jit_result); 3007 free (compiled_fn); 3008 free (fn); 3009 free (script_path); 3010@} 3011 3012#define PATH_TO_SCRIPTS ("/jit/docs/examples/tut04-toyvm/") 3013 3014static void 3015test_suite (void) 3016@{ 3017 const char *srcdir; 3018 char *scripts_dir; 3019 3020 snprintf (test, sizeof (test), "toyvm.c"); 3021 3022 /* We need to locate the test scripts. 3023 Rely on "srcdir" being set in the environment. */ 3024 3025 srcdir = getenv ("srcdir"); 3026 CHECK_NON_NULL (srcdir); 3027 3028 scripts_dir = (char *)malloc (strlen (srcdir) + strlen(PATH_TO_SCRIPTS) 3029 + 1); 3030 CHECK_NON_NULL (scripts_dir); 3031 sprintf (scripts_dir, "%s%s", srcdir, PATH_TO_SCRIPTS); 3032 3033 test_script (scripts_dir, "factorial.toy", 10, 3628800); 3034 test_script (scripts_dir, "fibonacci.toy", 10, 55); 3035 3036 free (scripts_dir); 3037@} 3038 3039int 3040main (int argc, char **argv) 3041@{ 3042 const char *filename = NULL; 3043 toyvm_function *fn = NULL; 3044 3045 /* If called with no args, assume we're being run by the test suite. */ 3046 if (argc < 3) 3047 @{ 3048 test_suite (); 3049 return 0; 3050 @} 3051 3052 if (argc != 3) 3053 @{ 3054 fprintf (stdout, 3055 "%s FILENAME INPUT: Parse and run a .toy file\n", 3056 argv[0]); 3057 exit (1); 3058 @} 3059 3060 filename = argv[1]; 3061 fn = toyvm_function_parse (filename, filename); 3062 if (!fn) 3063 exit (1); 3064 3065 if (0) 3066 toyvm_function_disassemble (fn, stdout); 3067 3068 printf ("interpreter result: %d\n", 3069 toyvm_function_interpret (fn, atoi (argv[2]), NULL)); 3070 3071 /* JIT-compilation. */ 3072 toyvm_compiled_function *compiled_fn 3073 = toyvm_function_compile (fn); 3074 3075 toyvm_compiled_code code = compiled_fn->cf_code; 3076 printf ("compiler result: %d\n", 3077 code (atoi (argv[2]))); 3078 3079 gcc_jit_result_release (compiled_fn->cf_jit_result); 3080 free (compiled_fn); 3081 3082 return 0; 3083@} 3084 3085@end example 3086 3087@noindent 3088@end quotation 3089 3090We can now run the result: 3091 3092@quotation 3093 3094@example 3095 toyvm_compiled_function *compiled_fn 3096 = toyvm_function_compile (fn); 3097 3098 toyvm_compiled_code code = compiled_fn->cf_code; 3099 printf ("compiler result: %d\n", 3100 code (atoi (argv[2]))); 3101 3102 gcc_jit_result_release (compiled_fn->cf_jit_result); 3103 free (compiled_fn); 3104 3105 3106@end example 3107 3108@noindent 3109@end quotation 3110 3111@node Single-stepping through the generated code,Examining the generated code,Compiling the context,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3112@anchor{intro/tutorial04 single-stepping-through-the-generated-code}@anchor{40} 3113@subsection Single-stepping through the generated code 3114 3115 3116It's possible to debug the generated code. To do this we need to both: 3117 3118@quotation 3119 3120 3121@itemize * 3122 3123@item 3124Set up source code locations for our statements, so that we can 3125meaningfully step through the code. We did this above by 3126calling @pxref{41,,gcc_jit_context_new_location()} and using the 3127results. 3128 3129@item 3130Enable the generation of debugging information, by setting 3131@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 3132@pxref{8,,gcc_jit_context} via 3133@pxref{1b,,gcc_jit_context_set_bool_option()}: 3134 3135@example 3136gcc_jit_context_set_bool_option ( 3137 ctxt, 3138 GCC_JIT_BOOL_OPTION_DEBUGINFO, 3139 1); 3140@end example 3141 3142@noindent 3143@end itemize 3144@end quotation 3145 3146Having done this, we can put a breakpoint on the generated function: 3147 3148@example 3149$ gdb --args ./toyvm factorial.toy 10 3150(gdb) break factorial 3151Function "factorial" not defined. 3152Make breakpoint pending on future shared library load? (y or [n]) y 3153Breakpoint 1 (factorial) pending. 3154(gdb) run 3155Breakpoint 1, factorial (arg=10) at factorial.toy:14 315614 DUP 3157@end example 3158 3159@noindent 3160 3161We've set up location information, which references @code{factorial.toy}. 3162This allows us to use e.g. @code{list} to see where we are in the script: 3163 3164@example 3165(gdb) list 31669 316710 # Initial state: 316811 # stack: [arg] 316912 317013 # 0: 317114 DUP 317215 # stack: [arg, arg] 317316 317417 # 1: 317518 PUSH_CONST 2 3176@end example 3177 3178@noindent 3179 3180and to step through the function, examining the data: 3181 3182@example 3183(gdb) n 318418 PUSH_CONST 2 3185(gdb) n 318622 BINARY_COMPARE_LT 3187(gdb) print stack 3188$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@} 3189(gdb) print stack_depth 3190$6 = 3 3191@end example 3192 3193@noindent 3194 3195You'll see that the parts of the @code{stack} array that haven't been 3196touched yet are uninitialized. 3197 3198@cartouche 3199@quotation Note 3200Turning on optimizations may lead to unpredictable results when 3201stepping through the generated code: the execution may appear to 3202"jump around" the source code. This is analogous to turning up the 3203optimization level in a regular compiler. 3204@end quotation 3205@end cartouche 3206 3207@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 3208@anchor{intro/tutorial04 examining-the-generated-code}@anchor{43} 3209@subsection Examining the generated code 3210 3211 3212How good is the optimized code? 3213 3214We can turn up optimizations, by calling 3215@pxref{1e,,gcc_jit_context_set_int_option()} with 3216@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 3217 3218@example 3219gcc_jit_context_set_int_option ( 3220 ctxt, 3221 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3222 3); 3223@end example 3224 3225@noindent 3226 3227One of GCC's internal representations is called "gimple". A dump of the 3228initial gimple representation of the code can be seen by setting: 3229 3230@example 3231gcc_jit_context_set_bool_option (ctxt, 3232 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 3233 1); 3234@end example 3235 3236@noindent 3237 3238With optimization on and source locations displayed, this gives: 3239 3240@c We'll use "c" for gimple dumps 3241 3242@example 3243factorial (signed int arg) 3244@{ 3245 <unnamed type> D.80; 3246 signed int D.81; 3247 signed int D.82; 3248 signed int D.83; 3249 signed int D.84; 3250 signed int D.85; 3251 signed int y; 3252 signed int x; 3253 signed int stack_depth; 3254 signed int stack[8]; 3255 3256 try 3257 @{ 3258 initial: 3259 stack_depth = 0; 3260 stack[stack_depth] = arg; 3261 stack_depth = stack_depth + 1; 3262 goto instr0; 3263 instr0: 3264 /* DUP */: 3265 stack_depth = stack_depth + -1; 3266 x = stack[stack_depth]; 3267 stack[stack_depth] = x; 3268 stack_depth = stack_depth + 1; 3269 stack[stack_depth] = x; 3270 stack_depth = stack_depth + 1; 3271 goto instr1; 3272 instr1: 3273 /* PUSH_CONST */: 3274 stack[stack_depth] = 2; 3275 stack_depth = stack_depth + 1; 3276 goto instr2; 3277 3278 /* etc */ 3279@end example 3280 3281@noindent 3282 3283You can see the generated machine code in assembly form via: 3284 3285@example 3286gcc_jit_context_set_bool_option ( 3287 ctxt, 3288 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 3289 1); 3290result = gcc_jit_context_compile (ctxt); 3291@end example 3292 3293@noindent 3294 3295which shows that (on this x86_64 box) the compiler has unrolled the loop 3296and is using MMX instructions to perform several multiplications 3297simultaneously: 3298 3299@example 3300 .file "fake.c" 3301 .text 3302.Ltext0: 3303 .p2align 4,,15 3304 .globl factorial 3305 .type factorial, @@function 3306factorial: 3307.LFB0: 3308 .file 1 "factorial.toy" 3309 .loc 1 14 0 3310 .cfi_startproc 3311.LVL0: 3312.L2: 3313 .loc 1 26 0 3314 cmpl $1, %edi 3315 jle .L13 3316 leal -1(%rdi), %edx 3317 movl %edx, %ecx 3318 shrl $2, %ecx 3319 leal 0(,%rcx,4), %esi 3320 testl %esi, %esi 3321 je .L14 3322 cmpl $9, %edx 3323 jbe .L14 3324 leal -2(%rdi), %eax 3325 movl %eax, -16(%rsp) 3326 leal -3(%rdi), %eax 3327 movd -16(%rsp), %xmm0 3328 movl %edi, -16(%rsp) 3329 movl %eax, -12(%rsp) 3330 movd -16(%rsp), %xmm1 3331 xorl %eax, %eax 3332 movl %edx, -16(%rsp) 3333 movd -12(%rsp), %xmm4 3334 movd -16(%rsp), %xmm6 3335 punpckldq %xmm4, %xmm0 3336 movdqa .LC1(%rip), %xmm4 3337 punpckldq %xmm6, %xmm1 3338 punpcklqdq %xmm0, %xmm1 3339 movdqa .LC0(%rip), %xmm0 3340 jmp .L5 3341 # etc - edited for brevity 3342@end example 3343 3344@noindent 3345 3346This is clearly overkill for a function that will likely overflow the 3347@code{int} type before the vectorization is worthwhile - but then again, this 3348is a toy example. 3349 3350Turning down the optimization level to 2: 3351 3352@example 3353gcc_jit_context_set_int_option ( 3354 ctxt, 3355 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3356 3); 3357@end example 3358 3359@noindent 3360 3361yields this code, which is simple enough to quote in its entirety: 3362 3363@example 3364 .file "fake.c" 3365 .text 3366 .p2align 4,,15 3367 .globl factorial 3368 .type factorial, @@function 3369factorial: 3370.LFB0: 3371 .cfi_startproc 3372.L2: 3373 cmpl $1, %edi 3374 jle .L8 3375 movl $1, %edx 3376 jmp .L4 3377 .p2align 4,,10 3378 .p2align 3 3379.L6: 3380 movl %eax, %edi 3381.L4: 3382.L5: 3383 leal -1(%rdi), %eax 3384 imull %edi, %edx 3385 cmpl $1, %eax 3386 jne .L6 3387.L3: 3388.L7: 3389 imull %edx, %eax 3390 ret 3391.L8: 3392 movl %edi, %eax 3393 movl $1, %edx 3394 jmp .L7 3395 .cfi_endproc 3396.LFE0: 3397 .size factorial, .-factorial 3398 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})" 3399 .section .note.GNU-stack,"",@@progbits 3400@end example 3401 3402@noindent 3403 3404Note that the stack pushing and popping have been eliminated, as has the 3405recursive call (in favor of an iteration). 3406 3407@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 3408@anchor{intro/tutorial04 putting-it-all-together}@anchor{44} 3409@subsection Putting it all together 3410 3411 3412The complete example can be seen in the source tree at 3413@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.c} 3414 3415along with a Makefile and a couple of sample .toy scripts: 3416 3417@example 3418$ ls -al 3419drwxrwxr-x. 2 david david 4096 Sep 19 17:46 . 3420drwxrwxr-x. 3 david david 4096 Sep 19 15:26 .. 3421-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy 3422-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy 3423-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile 3424-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.c 3425 3426$ make toyvm 3427g++ -Wall -g -o toyvm toyvm.c -lgccjit 3428 3429$ ./toyvm factorial.toy 10 3430interpreter result: 3628800 3431compiler result: 3628800 3432 3433$ ./toyvm fibonacci.toy 10 3434interpreter result: 55 3435compiler result: 55 3436@end example 3437 3438@noindent 3439 3440@node Behind the curtain How does our code get optimized?,,Putting it all together,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3441@anchor{intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{45} 3442@subsection Behind the curtain: How does our code get optimized? 3443 3444 3445Our example is done, but you may be wondering about exactly how the 3446compiler turned what we gave it into the machine code seen above. 3447 3448We can examine what the compiler is doing in detail by setting: 3449 3450@example 3451gcc_jit_context_set_bool_option (state.ctxt, 3452 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 3453 1); 3454gcc_jit_context_set_bool_option (state.ctxt, 3455 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 3456 1); 3457@end example 3458 3459@noindent 3460 3461This will dump detailed information about the compiler's state to a 3462directory under @code{/tmp}, and keep it from being cleaned up. 3463 3464The precise names and their formats of these files is subject to change. 3465Higher optimization levels lead to more files. 3466Here's what I saw (edited for brevity; there were almost 200 files): 3467 3468@example 3469intermediate files written to /tmp/libgccjit-KPQbGw 3470$ ls /tmp/libgccjit-KPQbGw/ 3471fake.c.000i.cgraph 3472fake.c.000i.type-inheritance 3473fake.c.004t.gimple 3474fake.c.007t.omplower 3475fake.c.008t.lower 3476fake.c.011t.eh 3477fake.c.012t.cfg 3478fake.c.014i.visibility 3479fake.c.015i.early_local_cleanups 3480fake.c.016t.ssa 3481# etc 3482@end example 3483 3484@noindent 3485 3486The gimple code is converted into Static Single Assignment form, 3487with annotations for use when generating the debuginfo: 3488 3489@example 3490$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa 3491@end example 3492 3493@noindent 3494 3495@example 3496;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3497 3498factorial (signed int arg) 3499@{ 3500 signed int stack[8]; 3501 signed int stack_depth; 3502 signed int x; 3503 signed int y; 3504 <unnamed type> _20; 3505 signed int _21; 3506 signed int _38; 3507 signed int _44; 3508 signed int _51; 3509 signed int _56; 3510 3511initial: 3512 stack_depth_3 = 0; 3513 # DEBUG stack_depth => stack_depth_3 3514 stack[stack_depth_3] = arg_5(D); 3515 stack_depth_7 = stack_depth_3 + 1; 3516 # DEBUG stack_depth => stack_depth_7 3517 # DEBUG instr0 => NULL 3518 # DEBUG /* DUP */ => NULL 3519 stack_depth_8 = stack_depth_7 + -1; 3520 # DEBUG stack_depth => stack_depth_8 3521 x_9 = stack[stack_depth_8]; 3522 # DEBUG x => x_9 3523 stack[stack_depth_8] = x_9; 3524 stack_depth_11 = stack_depth_8 + 1; 3525 # DEBUG stack_depth => stack_depth_11 3526 stack[stack_depth_11] = x_9; 3527 stack_depth_13 = stack_depth_11 + 1; 3528 # DEBUG stack_depth => stack_depth_13 3529 # DEBUG instr1 => NULL 3530 # DEBUG /* PUSH_CONST */ => NULL 3531 stack[stack_depth_13] = 2; 3532 3533 /* etc; edited for brevity */ 3534@end example 3535 3536@noindent 3537 3538We can perhaps better see the code by turning off 3539@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG} 3540statements, giving: 3541 3542@example 3543$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa 3544@end example 3545 3546@noindent 3547 3548@example 3549;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3550 3551factorial (signed int arg) 3552@{ 3553 signed int stack[8]; 3554 signed int stack_depth; 3555 signed int x; 3556 signed int y; 3557 <unnamed type> _20; 3558 signed int _21; 3559 signed int _38; 3560 signed int _44; 3561 signed int _51; 3562 signed int _56; 3563 3564initial: 3565 stack_depth_3 = 0; 3566 stack[stack_depth_3] = arg_5(D); 3567 stack_depth_7 = stack_depth_3 + 1; 3568 stack_depth_8 = stack_depth_7 + -1; 3569 x_9 = stack[stack_depth_8]; 3570 stack[stack_depth_8] = x_9; 3571 stack_depth_11 = stack_depth_8 + 1; 3572 stack[stack_depth_11] = x_9; 3573 stack_depth_13 = stack_depth_11 + 1; 3574 stack[stack_depth_13] = 2; 3575 stack_depth_15 = stack_depth_13 + 1; 3576 stack_depth_16 = stack_depth_15 + -1; 3577 y_17 = stack[stack_depth_16]; 3578 stack_depth_18 = stack_depth_16 + -1; 3579 x_19 = stack[stack_depth_18]; 3580 _20 = x_19 < y_17; 3581 _21 = (signed int) _20; 3582 stack[stack_depth_18] = _21; 3583 stack_depth_23 = stack_depth_18 + 1; 3584 stack_depth_24 = stack_depth_23 + -1; 3585 x_25 = stack[stack_depth_24]; 3586 if (x_25 != 0) 3587 goto <bb 4> (instr9); 3588 else 3589 goto <bb 3> (instr4); 3590 3591instr4: 3592/* DUP */: 3593 stack_depth_26 = stack_depth_24 + -1; 3594 x_27 = stack[stack_depth_26]; 3595 stack[stack_depth_26] = x_27; 3596 stack_depth_29 = stack_depth_26 + 1; 3597 stack[stack_depth_29] = x_27; 3598 stack_depth_31 = stack_depth_29 + 1; 3599 stack[stack_depth_31] = 1; 3600 stack_depth_33 = stack_depth_31 + 1; 3601 stack_depth_34 = stack_depth_33 + -1; 3602 y_35 = stack[stack_depth_34]; 3603 stack_depth_36 = stack_depth_34 + -1; 3604 x_37 = stack[stack_depth_36]; 3605 _38 = x_37 - y_35; 3606 stack[stack_depth_36] = _38; 3607 stack_depth_40 = stack_depth_36 + 1; 3608 stack_depth_41 = stack_depth_40 + -1; 3609 x_42 = stack[stack_depth_41]; 3610 _44 = factorial (x_42); 3611 stack[stack_depth_41] = _44; 3612 stack_depth_46 = stack_depth_41 + 1; 3613 stack_depth_47 = stack_depth_46 + -1; 3614 y_48 = stack[stack_depth_47]; 3615 stack_depth_49 = stack_depth_47 + -1; 3616 x_50 = stack[stack_depth_49]; 3617 _51 = x_50 * y_48; 3618 stack[stack_depth_49] = _51; 3619 stack_depth_53 = stack_depth_49 + 1; 3620 3621 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)> 3622instr9: 3623/* RETURN */: 3624 stack_depth_54 = stack_depth_1 + -1; 3625 x_55 = stack[stack_depth_54]; 3626 _56 = x_55; 3627 stack =@{v@} @{CLOBBER@}; 3628 return _56; 3629 3630@} 3631@end example 3632 3633@noindent 3634 3635Note in the above how all the @pxref{28,,gcc_jit_block} instances we 3636created have been consolidated into just 3 blocks in GCC's internal 3637representation: @code{initial}, @code{instr4} and @code{instr9}. 3638 3639@menu 3640* Optimizing away stack manipulation:: 3641* Elimination of tail recursion:: 3642 3643@end menu 3644 3645@node Optimizing away stack manipulation,Elimination of tail recursion,,Behind the curtain How does our code get optimized? 3646@anchor{intro/tutorial04 optimizing-away-stack-manipulation}@anchor{46} 3647@subsubsection Optimizing away stack manipulation 3648 3649 3650Recall our simple implementation of stack operations. Let's examine 3651how the stack operations are optimized away. 3652 3653After a pass of constant-propagation, the depth of the stack at each 3654opcode can be determined at compile-time: 3655 3656@example 3657$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1 3658@end example 3659 3660@noindent 3661 3662@example 3663;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3664 3665factorial (signed int arg) 3666@{ 3667 signed int stack[8]; 3668 signed int stack_depth; 3669 signed int x; 3670 signed int y; 3671 <unnamed type> _20; 3672 signed int _21; 3673 signed int _38; 3674 signed int _44; 3675 signed int _51; 3676 3677initial: 3678 stack[0] = arg_5(D); 3679 x_9 = stack[0]; 3680 stack[0] = x_9; 3681 stack[1] = x_9; 3682 stack[2] = 2; 3683 y_17 = stack[2]; 3684 x_19 = stack[1]; 3685 _20 = x_19 < y_17; 3686 _21 = (signed int) _20; 3687 stack[1] = _21; 3688 x_25 = stack[1]; 3689 if (x_25 != 0) 3690 goto <bb 4> (instr9); 3691 else 3692 goto <bb 3> (instr4); 3693 3694instr4: 3695/* DUP */: 3696 x_27 = stack[0]; 3697 stack[0] = x_27; 3698 stack[1] = x_27; 3699 stack[2] = 1; 3700 y_35 = stack[2]; 3701 x_37 = stack[1]; 3702 _38 = x_37 - y_35; 3703 stack[1] = _38; 3704 x_42 = stack[1]; 3705 _44 = factorial (x_42); 3706 stack[1] = _44; 3707 y_48 = stack[1]; 3708 x_50 = stack[0]; 3709 _51 = x_50 * y_48; 3710 stack[0] = _51; 3711 3712instr9: 3713/* RETURN */: 3714 x_55 = stack[0]; 3715 x_56 = x_55; 3716 stack =@{v@} @{CLOBBER@}; 3717 return x_56; 3718 3719@} 3720@end example 3721 3722@noindent 3723 3724Note how, in the above, all those @code{stack_depth} values are now just 3725constants: we're accessing specific stack locations at each opcode. 3726 3727The "esra" pass ("Early Scalar Replacement of Aggregates") breaks 3728out our "stack" array into individual elements: 3729 3730@example 3731$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra 3732@end example 3733 3734@noindent 3735 3736@example 3737;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3738 3739Created a replacement for stack offset: 0, size: 32: stack$0 3740Created a replacement for stack offset: 32, size: 32: stack$1 3741Created a replacement for stack offset: 64, size: 32: stack$2 3742 3743Symbols to be put in SSA form 3744@{ D.89 D.90 D.91 @} 3745Incremental SSA update started at block: 0 3746Number of blocks in CFG: 5 3747Number of blocks to update: 4 ( 80%) 3748 3749 3750factorial (signed int arg) 3751@{ 3752 signed int stack$2; 3753 signed int stack$1; 3754 signed int stack$0; 3755 signed int stack[8]; 3756 signed int stack_depth; 3757 signed int x; 3758 signed int y; 3759 <unnamed type> _20; 3760 signed int _21; 3761 signed int _38; 3762 signed int _44; 3763 signed int _51; 3764 3765initial: 3766 stack$0_45 = arg_5(D); 3767 x_9 = stack$0_45; 3768 stack$0_39 = x_9; 3769 stack$1_32 = x_9; 3770 stack$2_30 = 2; 3771 y_17 = stack$2_30; 3772 x_19 = stack$1_32; 3773 _20 = x_19 < y_17; 3774 _21 = (signed int) _20; 3775 stack$1_28 = _21; 3776 x_25 = stack$1_28; 3777 if (x_25 != 0) 3778 goto <bb 4> (instr9); 3779 else 3780 goto <bb 3> (instr4); 3781 3782instr4: 3783/* DUP */: 3784 x_27 = stack$0_39; 3785 stack$0_22 = x_27; 3786 stack$1_14 = x_27; 3787 stack$2_12 = 1; 3788 y_35 = stack$2_12; 3789 x_37 = stack$1_14; 3790 _38 = x_37 - y_35; 3791 stack$1_10 = _38; 3792 x_42 = stack$1_10; 3793 _44 = factorial (x_42); 3794 stack$1_6 = _44; 3795 y_48 = stack$1_6; 3796 x_50 = stack$0_22; 3797 _51 = x_50 * y_48; 3798 stack$0_1 = _51; 3799 3800 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)> 3801instr9: 3802/* RETURN */: 3803 x_55 = stack$0_52; 3804 x_56 = x_55; 3805 stack =@{v@} @{CLOBBER@}; 3806 return x_56; 3807 3808@} 3809@end example 3810 3811@noindent 3812 3813Hence at this point, all those pushes and pops of the stack are now 3814simply assignments to specific temporary variables. 3815 3816After some copy propagation, the stack manipulation has been completely 3817optimized away: 3818 3819@example 3820$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1 3821@end example 3822 3823@noindent 3824 3825@example 3826;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3827 3828factorial (signed int arg) 3829@{ 3830 signed int stack$2; 3831 signed int stack$1; 3832 signed int stack$0; 3833 signed int stack[8]; 3834 signed int stack_depth; 3835 signed int x; 3836 signed int y; 3837 <unnamed type> _20; 3838 signed int _21; 3839 signed int _38; 3840 signed int _44; 3841 signed int _51; 3842 3843initial: 3844 stack$0_39 = arg_5(D); 3845 _20 = arg_5(D) <= 1; 3846 _21 = (signed int) _20; 3847 if (_21 != 0) 3848 goto <bb 4> (instr9); 3849 else 3850 goto <bb 3> (instr4); 3851 3852instr4: 3853/* DUP */: 3854 _38 = arg_5(D) + -1; 3855 _44 = factorial (_38); 3856 _51 = arg_5(D) * _44; 3857 stack$0_1 = _51; 3858 3859 # stack$0_52 = PHI <arg_5(D)(2), _51(3)> 3860instr9: 3861/* RETURN */: 3862 stack =@{v@} @{CLOBBER@}; 3863 return stack$0_52; 3864 3865@} 3866@end example 3867 3868@noindent 3869 3870Later on, another pass finally eliminated @code{stack_depth} local and the 3871unused parts of the @cite{stack`} array altogether: 3872 3873@example 3874$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa 3875@end example 3876 3877@noindent 3878 3879@example 3880;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3881 3882Released 44 names, 314.29%, removed 44 holes 3883factorial (signed int arg) 3884@{ 3885 signed int stack$0; 3886 signed int mult_acc_1; 3887 <unnamed type> _5; 3888 signed int _6; 3889 signed int _7; 3890 signed int mul_tmp_10; 3891 signed int mult_acc_11; 3892 signed int mult_acc_13; 3893 3894 # arg_9 = PHI <arg_8(D)(0)> 3895 # mult_acc_13 = PHI <1(0)> 3896initial: 3897 3898 <bb 5>: 3899 # arg_4 = PHI <arg_9(2), _7(3)> 3900 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)> 3901 _5 = arg_4 <= 1; 3902 _6 = (signed int) _5; 3903 if (_6 != 0) 3904 goto <bb 4> (instr9); 3905 else 3906 goto <bb 3> (instr4); 3907 3908instr4: 3909/* DUP */: 3910 _7 = arg_4 + -1; 3911 mult_acc_11 = mult_acc_1 * arg_4; 3912 goto <bb 5>; 3913 3914 # stack$0_12 = PHI <arg_4(5)> 3915instr9: 3916/* RETURN */: 3917 mul_tmp_10 = mult_acc_1 * stack$0_12; 3918 return mul_tmp_10; 3919 3920@} 3921@end example 3922 3923@noindent 3924 3925@node Elimination of tail recursion,,Optimizing away stack manipulation,Behind the curtain How does our code get optimized? 3926@anchor{intro/tutorial04 elimination-of-tail-recursion}@anchor{47} 3927@subsubsection Elimination of tail recursion 3928 3929 3930Another significant optimization is the detection that the call to 3931@code{factorial} is tail recursion, which can be eliminated in favor of 3932an iteration: 3933 3934@example 3935$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1 3936@end example 3937 3938@noindent 3939 3940@example 3941;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3942 3943 3944Symbols to be put in SSA form 3945@{ D.88 @} 3946Incremental SSA update started at block: 0 3947Number of blocks in CFG: 5 3948Number of blocks to update: 4 ( 80%) 3949 3950 3951factorial (signed int arg) 3952@{ 3953 signed int stack$2; 3954 signed int stack$1; 3955 signed int stack$0; 3956 signed int stack[8]; 3957 signed int stack_depth; 3958 signed int x; 3959 signed int y; 3960 signed int mult_acc_1; 3961 <unnamed type> _20; 3962 signed int _21; 3963 signed int _38; 3964 signed int mul_tmp_44; 3965 signed int mult_acc_51; 3966 3967 # arg_5 = PHI <arg_39(D)(0), _38(3)> 3968 # mult_acc_1 = PHI <1(0), mult_acc_51(3)> 3969initial: 3970 _20 = arg_5 <= 1; 3971 _21 = (signed int) _20; 3972 if (_21 != 0) 3973 goto <bb 4> (instr9); 3974 else 3975 goto <bb 3> (instr4); 3976 3977instr4: 3978/* DUP */: 3979 _38 = arg_5 + -1; 3980 mult_acc_51 = mult_acc_1 * arg_5; 3981 goto <bb 2> (initial); 3982 3983 # stack$0_52 = PHI <arg_5(2)> 3984instr9: 3985/* RETURN */: 3986 stack =@{v@} @{CLOBBER@}; 3987 mul_tmp_44 = mult_acc_1 * stack$0_52; 3988 return mul_tmp_44; 3989 3990@} 3991@end example 3992 3993@noindent 3994 3995@c Copyright (C) 2015-2018 Free Software Foundation, Inc. 3996@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 3997@c 3998@c This is free software: you can redistribute it and/or modify it 3999@c under the terms of the GNU General Public License as published by 4000@c the Free Software Foundation, either version 3 of the License, or 4001@c (at your option) any later version. 4002@c 4003@c This program is distributed in the hope that it will be useful, but 4004@c WITHOUT ANY WARRANTY; without even the implied warranty of 4005@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4006@c General Public License for more details. 4007@c 4008@c You should have received a copy of the GNU General Public License 4009@c along with this program. If not, see 4010@c <http://www.gnu.org/licenses/>. 4011 4012@node Tutorial part 5 Implementing an Ahead-of-Time compiler,,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial 4013@anchor{intro/tutorial05 doc}@anchor{48}@anchor{intro/tutorial05 tutorial-part-5-implementing-an-ahead-of-time-compiler}@anchor{49} 4014@section Tutorial part 5: Implementing an Ahead-of-Time compiler 4015 4016 4017If you have a pre-existing language frontend that's compatible with 4018libgccjit's license, it's possible to hook it up to libgccjit as a 4019backend. In the previous example we showed 4020how to do that for in-memory JIT-compilation, but libgccjit can also 4021compile code directly to a file, allowing you to implement a more 4022traditional ahead-of-time compiler ("JIT" is something of a misnomer 4023for this use-case). 4024 4025The essential difference is to compile the context using 4026@pxref{4a,,gcc_jit_context_compile_to_file()} rather than 4027@pxref{15,,gcc_jit_context_compile()}. 4028 4029@menu 4030* The "brainf" language:: 4031* Converting a brainf script to libgccjit IR:: 4032* Compiling a context to a file:: 4033* Other forms of ahead-of-time-compilation:: 4034 4035@end menu 4036 4037@node The "brainf" language,Converting a brainf script to libgccjit IR,,Tutorial part 5 Implementing an Ahead-of-Time compiler 4038@anchor{intro/tutorial05 the-brainf-language}@anchor{4b} 4039@subsection The "brainf" language 4040 4041 4042In this example we use libgccjit to construct an ahead-of-time compiler 4043for an esoteric programming language that we shall refer to as "brainf". 4044 4045brainf scripts operate on an array of bytes, with a notional data pointer 4046within the array. 4047 4048brainf is hard for humans to read, but it's trivial to write a parser for 4049it, as there is no lexing; just a stream of bytes. The operations are: 4050 4051 4052@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 4053@headitem 4054 4055Character 4056 4057@tab 4058 4059Meaning 4060 4061@item 4062 4063@code{>} 4064 4065@tab 4066 4067@code{idx += 1} 4068 4069@item 4070 4071@code{<} 4072 4073@tab 4074 4075@code{idx -= 1} 4076 4077@item 4078 4079@code{+} 4080 4081@tab 4082 4083@code{data[idx] += 1} 4084 4085@item 4086 4087@code{-} 4088 4089@tab 4090 4091@code{data[idx] -= 1} 4092 4093@item 4094 4095@code{.} 4096 4097@tab 4098 4099@code{output (data[idx])} 4100 4101@item 4102 4103@code{,} 4104 4105@tab 4106 4107@code{data[idx] = input ()} 4108 4109@item 4110 4111@code{[} 4112 4113@tab 4114 4115loop until @code{data[idx] == 0} 4116 4117@item 4118 4119@code{]} 4120 4121@tab 4122 4123end of loop 4124 4125@item 4126 4127Anything else 4128 4129@tab 4130 4131ignored 4132 4133@end multitable 4134 4135 4136Unlike the previous example, we'll implement an ahead-of-time compiler, 4137which reads @code{.bf} scripts and outputs executables (though it would 4138be trivial to have it run them JIT-compiled in-process). 4139 4140Here's what a simple @code{.bf} script looks like: 4141 4142@quotation 4143 4144@example 4145[ 4146 Emit the uppercase alphabet 4147] 4148 4149cell 0 = 26 4150++++++++++++++++++++++++++ 4151 4152cell 1 = 65 4153>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4154 4155while cell#0 != 0 4156[ 4157 > 4158 . emit cell#1 4159 + increment cell@@1 4160 <- decrement cell@@0 4161] 4162 4163@end example 4164 4165@noindent 4166@end quotation 4167 4168@cartouche 4169@quotation Note 4170This example makes use of whitespace and comments for legibility, but 4171could have been written as: 4172 4173@example 4174++++++++++++++++++++++++++ 4175>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4176[>.+<-] 4177@end example 4178 4179@noindent 4180 4181It's not a particularly useful language, except for providing 4182compiler-writers with a test case that's easy to parse. The point 4183is that you can use @pxref{4a,,gcc_jit_context_compile_to_file()} 4184to use libgccjit as a backend for a pre-existing language frontend 4185(provided that the pre-existing frontend is compatible with libgccjit's 4186license). 4187@end quotation 4188@end cartouche 4189 4190@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 4191@anchor{intro/tutorial05 converting-a-brainf-script-to-libgccjit-ir}@anchor{4c} 4192@subsection Converting a brainf script to libgccjit IR 4193 4194 4195As before we write simple code to populate a @pxref{8,,gcc_jit_context *}. 4196 4197@quotation 4198 4199@example 4200 4201typedef struct bf_compiler 4202@{ 4203 const char *filename; 4204 int line; 4205 int column; 4206 4207 gcc_jit_context *ctxt; 4208 4209 gcc_jit_type *void_type; 4210 gcc_jit_type *int_type; 4211 gcc_jit_type *byte_type; 4212 gcc_jit_type *array_type; 4213 4214 gcc_jit_function *func_getchar; 4215 gcc_jit_function *func_putchar; 4216 4217 gcc_jit_function *func; 4218 gcc_jit_block *curblock; 4219 4220 gcc_jit_rvalue *int_zero; 4221 gcc_jit_rvalue *int_one; 4222 gcc_jit_rvalue *byte_zero; 4223 gcc_jit_rvalue *byte_one; 4224 gcc_jit_lvalue *data_cells; 4225 gcc_jit_lvalue *idx; 4226 4227 int num_open_parens; 4228 gcc_jit_block *paren_test[MAX_OPEN_PARENS]; 4229 gcc_jit_block *paren_body[MAX_OPEN_PARENS]; 4230 gcc_jit_block *paren_after[MAX_OPEN_PARENS]; 4231 4232@} bf_compiler; 4233 4234/* Bail out, with a message on stderr. */ 4235 4236static void 4237fatal_error (bf_compiler *bfc, const char *msg) 4238@{ 4239 fprintf (stderr, 4240 "%s:%i:%i: %s", 4241 bfc->filename, bfc->line, bfc->column, msg); 4242 abort (); 4243@} 4244 4245/* Get "data_cells[idx]" as an lvalue. */ 4246 4247static gcc_jit_lvalue * 4248bf_get_current_data (bf_compiler *bfc, gcc_jit_location *loc) 4249@{ 4250 return gcc_jit_context_new_array_access ( 4251 bfc->ctxt, 4252 loc, 4253 gcc_jit_lvalue_as_rvalue (bfc->data_cells), 4254 gcc_jit_lvalue_as_rvalue (bfc->idx)); 4255@} 4256 4257/* Get "data_cells[idx] == 0" as a boolean rvalue. */ 4258 4259static gcc_jit_rvalue * 4260bf_current_data_is_zero (bf_compiler *bfc, gcc_jit_location *loc) 4261@{ 4262 return gcc_jit_context_new_comparison ( 4263 bfc->ctxt, 4264 loc, 4265 GCC_JIT_COMPARISON_EQ, 4266 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)), 4267 bfc->byte_zero); 4268@} 4269 4270/* Compile one bf character. */ 4271 4272static void 4273bf_compile_char (bf_compiler *bfc, 4274 unsigned char ch) 4275@{ 4276 gcc_jit_location *loc = 4277 gcc_jit_context_new_location (bfc->ctxt, 4278 bfc->filename, 4279 bfc->line, 4280 bfc->column); 4281 4282 /* Turn this on to trace execution, by injecting putchar () 4283 of each source char. */ 4284 if (0) 4285 @{ 4286 gcc_jit_rvalue *arg = 4287 gcc_jit_context_new_rvalue_from_int ( 4288 bfc->ctxt, 4289 bfc->int_type, 4290 ch); 4291 gcc_jit_rvalue *call = 4292 gcc_jit_context_new_call (bfc->ctxt, 4293 loc, 4294 bfc->func_putchar, 4295 1, &arg); 4296 gcc_jit_block_add_eval (bfc->curblock, 4297 loc, 4298 call); 4299 @} 4300 4301 switch (ch) 4302 @{ 4303 case '>': 4304 gcc_jit_block_add_comment (bfc->curblock, 4305 loc, 4306 "'>': idx += 1;"); 4307 gcc_jit_block_add_assignment_op (bfc->curblock, 4308 loc, 4309 bfc->idx, 4310 GCC_JIT_BINARY_OP_PLUS, 4311 bfc->int_one); 4312 break; 4313 4314 case '<': 4315 gcc_jit_block_add_comment (bfc->curblock, 4316 loc, 4317 "'<': idx -= 1;"); 4318 gcc_jit_block_add_assignment_op (bfc->curblock, 4319 loc, 4320 bfc->idx, 4321 GCC_JIT_BINARY_OP_MINUS, 4322 bfc->int_one); 4323 break; 4324 4325 case '+': 4326 gcc_jit_block_add_comment (bfc->curblock, 4327 loc, 4328 "'+': data[idx] += 1;"); 4329 gcc_jit_block_add_assignment_op (bfc->curblock, 4330 loc, 4331 bf_get_current_data (bfc, loc), 4332 GCC_JIT_BINARY_OP_PLUS, 4333 bfc->byte_one); 4334 break; 4335 4336 case '-': 4337 gcc_jit_block_add_comment (bfc->curblock, 4338 loc, 4339 "'-': data[idx] -= 1;"); 4340 gcc_jit_block_add_assignment_op (bfc->curblock, 4341 loc, 4342 bf_get_current_data (bfc, loc), 4343 GCC_JIT_BINARY_OP_MINUS, 4344 bfc->byte_one); 4345 break; 4346 4347 case '.': 4348 @{ 4349 gcc_jit_rvalue *arg = 4350 gcc_jit_context_new_cast ( 4351 bfc->ctxt, 4352 loc, 4353 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)), 4354 bfc->int_type); 4355 gcc_jit_rvalue *call = 4356 gcc_jit_context_new_call (bfc->ctxt, 4357 loc, 4358 bfc->func_putchar, 4359 1, &arg); 4360 gcc_jit_block_add_comment (bfc->curblock, 4361 loc, 4362 "'.': putchar ((int)data[idx]);"); 4363 gcc_jit_block_add_eval (bfc->curblock, 4364 loc, 4365 call); 4366 @} 4367 break; 4368 4369 case ',': 4370 @{ 4371 gcc_jit_rvalue *call = 4372 gcc_jit_context_new_call (bfc->ctxt, 4373 loc, 4374 bfc->func_getchar, 4375 0, NULL); 4376 gcc_jit_block_add_comment ( 4377 bfc->curblock, 4378 loc, 4379 "',': data[idx] = (unsigned char)getchar ();"); 4380 gcc_jit_block_add_assignment (bfc->curblock, 4381 loc, 4382 bf_get_current_data (bfc, loc), 4383 gcc_jit_context_new_cast ( 4384 bfc->ctxt, 4385 loc, 4386 call, 4387 bfc->byte_type)); 4388 @} 4389 break; 4390 4391 case '[': 4392 @{ 4393 gcc_jit_block *loop_test = 4394 gcc_jit_function_new_block (bfc->func, NULL); 4395 gcc_jit_block *on_zero = 4396 gcc_jit_function_new_block (bfc->func, NULL); 4397 gcc_jit_block *on_non_zero = 4398 gcc_jit_function_new_block (bfc->func, NULL); 4399 4400 if (bfc->num_open_parens == MAX_OPEN_PARENS) 4401 fatal_error (bfc, "too many open parens"); 4402 4403 gcc_jit_block_end_with_jump ( 4404 bfc->curblock, 4405 loc, 4406 loop_test); 4407 4408 gcc_jit_block_add_comment ( 4409 loop_test, 4410 loc, 4411 "'['"); 4412 gcc_jit_block_end_with_conditional ( 4413 loop_test, 4414 loc, 4415 bf_current_data_is_zero (bfc, loc), 4416 on_zero, 4417 on_non_zero); 4418 bfc->paren_test[bfc->num_open_parens] = loop_test; 4419 bfc->paren_body[bfc->num_open_parens] = on_non_zero; 4420 bfc->paren_after[bfc->num_open_parens] = on_zero; 4421 bfc->num_open_parens += 1; 4422 bfc->curblock = on_non_zero; 4423 @} 4424 break; 4425 4426 case ']': 4427 @{ 4428 gcc_jit_block_add_comment ( 4429 bfc->curblock, 4430 loc, 4431 "']'"); 4432 4433 if (bfc->num_open_parens == 0) 4434 fatal_error (bfc, "mismatching parens"); 4435 bfc->num_open_parens -= 1; 4436 gcc_jit_block_end_with_jump ( 4437 bfc->curblock, 4438 loc, 4439 bfc->paren_test[bfc->num_open_parens]); 4440 bfc->curblock = bfc->paren_after[bfc->num_open_parens]; 4441 @} 4442 break; 4443 4444 case '\n': 4445 bfc->line +=1; 4446 bfc->column = 0; 4447 break; 4448 @} 4449 4450 if (ch != '\n') 4451 bfc->column += 1; 4452@} 4453 4454/* Compile the given .bf file into a gcc_jit_context, containing a 4455 single "main" function suitable for compiling into an executable. */ 4456 4457gcc_jit_context * 4458bf_compile (const char *filename) 4459@{ 4460 bf_compiler bfc; 4461 FILE *f_in; 4462 int ch; 4463 4464 memset (&bfc, 0, sizeof (bfc)); 4465 4466 bfc.filename = filename; 4467 f_in = fopen (filename, "r"); 4468 if (!f_in) 4469 fatal_error (&bfc, "unable to open file"); 4470 bfc.line = 1; 4471 4472 bfc.ctxt = gcc_jit_context_acquire (); 4473 4474 gcc_jit_context_set_int_option ( 4475 bfc.ctxt, 4476 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 4477 3); 4478 gcc_jit_context_set_bool_option ( 4479 bfc.ctxt, 4480 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 4481 0); 4482 gcc_jit_context_set_bool_option ( 4483 bfc.ctxt, 4484 GCC_JIT_BOOL_OPTION_DEBUGINFO, 4485 1); 4486 gcc_jit_context_set_bool_option ( 4487 bfc.ctxt, 4488 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 4489 0); 4490 gcc_jit_context_set_bool_option ( 4491 bfc.ctxt, 4492 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 4493 0); 4494 4495 bfc.void_type = 4496 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_VOID); 4497 bfc.int_type = 4498 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_INT); 4499 bfc.byte_type = 4500 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR); 4501 bfc.array_type = 4502 gcc_jit_context_new_array_type (bfc.ctxt, 4503 NULL, 4504 bfc.byte_type, 4505 30000); 4506 4507 bfc.func_getchar = 4508 gcc_jit_context_new_function (bfc.ctxt, NULL, 4509 GCC_JIT_FUNCTION_IMPORTED, 4510 bfc.int_type, 4511 "getchar", 4512 0, NULL, 4513 0); 4514 4515 gcc_jit_param *param_c = 4516 gcc_jit_context_new_param (bfc.ctxt, NULL, bfc.int_type, "c"); 4517 bfc.func_putchar = 4518 gcc_jit_context_new_function (bfc.ctxt, NULL, 4519 GCC_JIT_FUNCTION_IMPORTED, 4520 bfc.void_type, 4521 "putchar", 4522 1, ¶m_c, 4523 0); 4524 4525 bfc.func = make_main (bfc.ctxt); 4526 bfc.curblock = 4527 gcc_jit_function_new_block (bfc.func, "initial"); 4528 bfc.int_zero = gcc_jit_context_zero (bfc.ctxt, bfc.int_type); 4529 bfc.int_one = gcc_jit_context_one (bfc.ctxt, bfc.int_type); 4530 bfc.byte_zero = gcc_jit_context_zero (bfc.ctxt, bfc.byte_type); 4531 bfc.byte_one = gcc_jit_context_one (bfc.ctxt, bfc.byte_type); 4532 4533 bfc.data_cells = 4534 gcc_jit_context_new_global (bfc.ctxt, NULL, 4535 GCC_JIT_GLOBAL_INTERNAL, 4536 bfc.array_type, 4537 "data_cells"); 4538 bfc.idx = 4539 gcc_jit_function_new_local (bfc.func, NULL, 4540 bfc.int_type, 4541 "idx"); 4542 4543 gcc_jit_block_add_comment (bfc.curblock, 4544 NULL, 4545 "idx = 0;"); 4546 gcc_jit_block_add_assignment (bfc.curblock, 4547 NULL, 4548 bfc.idx, 4549 bfc.int_zero); 4550 4551 bfc.num_open_parens = 0; 4552 4553 while ( EOF != (ch = fgetc (f_in))) 4554 bf_compile_char (&bfc, (unsigned char)ch); 4555 4556 gcc_jit_block_end_with_return (bfc.curblock, NULL, bfc.int_zero); 4557 4558 fclose (f_in); 4559 4560 return bfc.ctxt; 4561@} 4562 4563 4564@end example 4565 4566@noindent 4567@end quotation 4568 4569@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 4570@anchor{intro/tutorial05 compiling-a-context-to-a-file}@anchor{4d} 4571@subsection Compiling a context to a file 4572 4573 4574Unlike the previous tutorial, this time we'll compile the context 4575directly to an executable, using @pxref{4a,,gcc_jit_context_compile_to_file()}: 4576 4577@example 4578gcc_jit_context_compile_to_file (ctxt, 4579 GCC_JIT_OUTPUT_KIND_EXECUTABLE, 4580 output_file); 4581@end example 4582 4583@noindent 4584 4585Here's the top-level of the compiler, which is what actually calls into 4586@pxref{4a,,gcc_jit_context_compile_to_file()}: 4587 4588@quotation 4589 4590@example 4591 4592int 4593main (int argc, char **argv) 4594@{ 4595 const char *input_file; 4596 const char *output_file; 4597 gcc_jit_context *ctxt; 4598 const char *err; 4599 4600 if (argc != 3) 4601 @{ 4602 fprintf (stderr, "%s: INPUT_FILE OUTPUT_FILE\n", argv[0]); 4603 return 1; 4604 @} 4605 4606 input_file = argv[1]; 4607 output_file = argv[2]; 4608 ctxt = bf_compile (input_file); 4609 4610 gcc_jit_context_compile_to_file (ctxt, 4611 GCC_JIT_OUTPUT_KIND_EXECUTABLE, 4612 output_file); 4613 4614 err = gcc_jit_context_get_first_error (ctxt); 4615 4616 if (err) 4617 @{ 4618 gcc_jit_context_release (ctxt); 4619 return 1; 4620 @} 4621 4622 gcc_jit_context_release (ctxt); 4623 return 0; 4624@} 4625 4626 4627@end example 4628 4629@noindent 4630@end quotation 4631 4632Note how once the context is populated you could trivially instead compile 4633it to memory using @pxref{15,,gcc_jit_context_compile()} and run it in-process 4634as in the previous tutorial. 4635 4636To create an executable, we need to export a @code{main} function. Here's 4637how to create one from the JIT API: 4638 4639@quotation 4640 4641@example 4642 4643/* Make "main" function: 4644 int 4645 main (int argc, char **argv) 4646 @{ 4647 ... 4648 @} 4649*/ 4650static gcc_jit_function * 4651make_main (gcc_jit_context *ctxt) 4652@{ 4653 gcc_jit_type *int_type = 4654 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 4655 gcc_jit_param *param_argc = 4656 gcc_jit_context_new_param (ctxt, NULL, int_type, "argc"); 4657 gcc_jit_type *char_ptr_ptr_type = 4658 gcc_jit_type_get_pointer ( 4659 gcc_jit_type_get_pointer ( 4660 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR))); 4661 gcc_jit_param *param_argv = 4662 gcc_jit_context_new_param (ctxt, NULL, char_ptr_ptr_type, "argv"); 4663 gcc_jit_param *params[2] = @{param_argc, param_argv@}; 4664 gcc_jit_function *func_main = 4665 gcc_jit_context_new_function (ctxt, NULL, 4666 GCC_JIT_FUNCTION_EXPORTED, 4667 int_type, 4668 "main", 4669 2, params, 4670 0); 4671 return func_main; 4672@} 4673 4674 4675@end example 4676 4677@noindent 4678@end quotation 4679 4680@cartouche 4681@quotation Note 4682The above implementation ignores @code{argc} and @code{argv}, but you could 4683make use of them by exposing @code{param_argc} and @code{param_argv} to the 4684caller. 4685@end quotation 4686@end cartouche 4687 4688Upon compiling this C code, we obtain a bf-to-machine-code compiler; 4689let's call it @code{bfc}: 4690 4691@example 4692$ gcc \ 4693 tut05-bf.c \ 4694 -o bfc \ 4695 -lgccjit 4696@end example 4697 4698@noindent 4699 4700We can now use @code{bfc} to compile .bf files into machine code executables: 4701 4702@example 4703$ ./bfc \ 4704 emit-alphabet.bf \ 4705 a.out 4706@end example 4707 4708@noindent 4709 4710which we can run directly: 4711 4712@example 4713$ ./a.out 4714ABCDEFGHIJKLMNOPQRSTUVWXYZ 4715@end example 4716 4717@noindent 4718 4719Success! 4720 4721We can also inspect the generated executable using standard tools: 4722 4723@example 4724$ objdump -d a.out |less 4725@end example 4726 4727@noindent 4728 4729which shows that libgccjit has managed to optimize the function 4730somewhat (for example, the runs of 26 and 65 increment operations 4731have become integer constants 0x1a and 0x41): 4732 4733@example 47340000000000400620 <main>: 4735 400620: 80 3d 39 0a 20 00 00 cmpb $0x0,0x200a39(%rip) # 601060 <data 4736 400627: 74 07 je 400630 <main 4737 400629: eb fe jmp 400629 <main+0x9> 4738 40062b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 4739 400630: 48 83 ec 08 sub $0x8,%rsp 4740 400634: 0f b6 05 26 0a 20 00 movzbl 0x200a26(%rip),%eax # 601061 <data_cells+0x1> 4741 40063b: c6 05 1e 0a 20 00 1a movb $0x1a,0x200a1e(%rip) # 601060 <data_cells> 4742 400642: 8d 78 41 lea 0x41(%rax),%edi 4743 400645: 40 88 3d 15 0a 20 00 mov %dil,0x200a15(%rip) # 601061 <data_cells+0x1> 4744 40064c: 0f 1f 40 00 nopl 0x0(%rax) 4745 400650: 40 0f b6 ff movzbl %dil,%edi 4746 400654: e8 87 fe ff ff callq 4004e0 <putchar@@plt> 4747 400659: 0f b6 05 01 0a 20 00 movzbl 0x200a01(%rip),%eax # 601061 <data_cells+0x1> 4748 400660: 80 2d f9 09 20 00 01 subb $0x1,0x2009f9(%rip) # 601060 <data_cells> 4749 400667: 8d 78 01 lea 0x1(%rax),%edi 4750 40066a: 40 88 3d f0 09 20 00 mov %dil,0x2009f0(%rip) # 601061 <data_cells+0x1> 4751 400671: 75 dd jne 400650 <main+0x30> 4752 400673: 31 c0 xor %eax,%eax 4753 400675: 48 83 c4 08 add $0x8,%rsp 4754 400679: c3 retq 4755 40067a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 4756@end example 4757 4758@noindent 4759 4760We also set up debugging information (via 4761@pxref{41,,gcc_jit_context_new_location()} and 4762@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO}), so it's possible to use @code{gdb} 4763to singlestep through the generated binary and inspect the internal 4764state @code{idx} and @code{data_cells}: 4765 4766@example 4767(gdb) break main 4768Breakpoint 1 at 0x400790 4769(gdb) run 4770Starting program: a.out 4771 4772Breakpoint 1, 0x0000000000400790 in main (argc=1, argv=0x7fffffffe448) 4773(gdb) stepi 47740x0000000000400797 in main (argc=1, argv=0x7fffffffe448) 4775(gdb) stepi 47760x00000000004007a0 in main (argc=1, argv=0x7fffffffe448) 4777(gdb) stepi 47789 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4779(gdb) list 47804 47815 cell 0 = 26 47826 ++++++++++++++++++++++++++ 47837 47848 cell 1 = 65 47859 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 478610 478711 while cell#0 != 0 478812 [ 478913 > 4790(gdb) n 47916 ++++++++++++++++++++++++++ 4792(gdb) n 47939 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4794(gdb) p idx 4795$1 = 1 4796(gdb) p data_cells 4797$2 = "\032", '\000' <repeats 29998 times> 4798(gdb) p data_cells[0] 4799$3 = 26 '\032' 4800(gdb) p data_cells[1] 4801$4 = 0 '\000' 4802(gdb) list 48034 48045 cell 0 = 26 48056 ++++++++++++++++++++++++++ 48067 48078 cell 1 = 65 48089 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 480910 481011 while cell#0 != 0 481112 [ 481213 > 4813@end example 4814 4815@noindent 4816 4817@node Other forms of ahead-of-time-compilation,,Compiling a context to a file,Tutorial part 5 Implementing an Ahead-of-Time compiler 4818@anchor{intro/tutorial05 other-forms-of-ahead-of-time-compilation}@anchor{4e} 4819@subsection Other forms of ahead-of-time-compilation 4820 4821 4822The above demonstrates compiling a @pxref{8,,gcc_jit_context *} directly 4823to an executable. It's also possible to compile it to an object file, 4824and to a dynamic library. See the documentation of 4825@pxref{4a,,gcc_jit_context_compile_to_file()} for more information. 4826 4827@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 4828@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 4829@c 4830@c This is free software: you can redistribute it and/or modify it 4831@c under the terms of the GNU General Public License as published by 4832@c the Free Software Foundation, either version 3 of the License, or 4833@c (at your option) any later version. 4834@c 4835@c This program is distributed in the hope that it will be useful, but 4836@c WITHOUT ANY WARRANTY; without even the implied warranty of 4837@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4838@c General Public License for more details. 4839@c 4840@c You should have received a copy of the GNU General Public License 4841@c along with this program. If not, see 4842@c <http://www.gnu.org/licenses/>. 4843 4844@node Topic Reference,C++ bindings for libgccjit,Tutorial,Top 4845@anchor{topics/index doc}@anchor{4f}@anchor{topics/index topic-reference}@anchor{50} 4846@chapter Topic Reference 4847 4848 4849@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 4850@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 4851@c 4852@c This is free software: you can redistribute it and/or modify it 4853@c under the terms of the GNU General Public License as published by 4854@c the Free Software Foundation, either version 3 of the License, or 4855@c (at your option) any later version. 4856@c 4857@c This program is distributed in the hope that it will be useful, but 4858@c WITHOUT ANY WARRANTY; without even the implied warranty of 4859@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4860@c General Public License for more details. 4861@c 4862@c You should have received a copy of the GNU General Public License 4863@c along with this program. If not, see 4864@c <http://www.gnu.org/licenses/>. 4865 4866@menu 4867* Compilation contexts:: 4868* Objects:: 4869* Types:: 4870* Expressions:: 4871* Creating and using functions:: 4872* Function pointers: Function pointers<2>. 4873* Source Locations:: 4874* Compiling a context:: 4875* ABI and API compatibility:: 4876* Performance:: 4877 4878Compilation contexts 4879 4880* Lifetime-management:: 4881* Thread-safety:: 4882* Error-handling: Error-handling<2>. 4883* Debugging:: 4884* Options: Options<2>. 4885 4886Options 4887 4888* String Options:: 4889* Boolean options:: 4890* Integer options:: 4891* Additional command-line options:: 4892 4893Types 4894 4895* Standard types:: 4896* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 4897* Vector types:: 4898* Structures and unions:: 4899* Function pointer types:: 4900 4901Expressions 4902 4903* Rvalues:: 4904* Lvalues:: 4905* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 4906 4907Rvalues 4908 4909* Simple expressions:: 4910* Vector expressions:: 4911* Unary Operations:: 4912* Binary Operations:: 4913* Comparisons:: 4914* Function calls:: 4915* Function pointers:: 4916* Type-coercion:: 4917 4918Lvalues 4919 4920* Global variables:: 4921 4922Creating and using functions 4923 4924* Params:: 4925* Functions:: 4926* Blocks:: 4927* Statements:: 4928 4929Source Locations 4930 4931* Faking it:: 4932 4933Compiling a context 4934 4935* In-memory compilation:: 4936* Ahead-of-time compilation:: 4937 4938ABI and API compatibility 4939 4940* ABI symbol tags:: 4941 4942ABI symbol tags 4943 4944* LIBGCCJIT_ABI_0:: 4945* LIBGCCJIT_ABI_1:: 4946* LIBGCCJIT_ABI_2:: 4947* LIBGCCJIT_ABI_3:: 4948* LIBGCCJIT_ABI_4:: 4949* LIBGCCJIT_ABI_5:: 4950* LIBGCCJIT_ABI_6:: 4951* LIBGCCJIT_ABI_7:: 4952* LIBGCCJIT_ABI_8:: 4953* LIBGCCJIT_ABI_9:: 4954* LIBGCCJIT_ABI_10:: 4955 4956Performance 4957 4958* The timing API:: 4959 4960@end menu 4961 4962 4963@node Compilation contexts,Objects,,Topic Reference 4964@anchor{topics/contexts compilation-contexts}@anchor{51}@anchor{topics/contexts doc}@anchor{52} 4965@section Compilation contexts 4966 4967 4968@geindex gcc_jit_context (C type) 4969@anchor{topics/contexts gcc_jit_context}@anchor{8} 4970@deffn {C Type} gcc_jit_context 4971@end deffn 4972 4973The top-level of the API is the @pxref{8,,gcc_jit_context} type. 4974 4975A @pxref{8,,gcc_jit_context} instance encapsulates the state of a 4976compilation. 4977 4978You can set up options on it, and add types, functions and code. 4979Invoking @pxref{15,,gcc_jit_context_compile()} on it gives you a 4980@pxref{16,,gcc_jit_result}. 4981 4982@menu 4983* Lifetime-management:: 4984* Thread-safety:: 4985* Error-handling: Error-handling<2>. 4986* Debugging:: 4987* Options: Options<2>. 4988 4989@end menu 4990 4991@node Lifetime-management,Thread-safety,,Compilation contexts 4992@anchor{topics/contexts lifetime-management}@anchor{53} 4993@subsection Lifetime-management 4994 4995 4996Contexts are the unit of lifetime-management within the API: objects 4997have their lifetime bounded by the context they are created within, and 4998cleanup of such objects is done for you when the context is released. 4999 5000@geindex gcc_jit_context_acquire (C function) 5001@anchor{topics/contexts gcc_jit_context_acquire}@anchor{9} 5002@deffn {C Function} gcc_jit_context *gcc_jit_context_acquire (void) 5003 5004This function acquires a new @pxref{8,,gcc_jit_context *} instance, 5005which is independent of any others that may be present within this 5006process. 5007@end deffn 5008 5009@geindex gcc_jit_context_release (C function) 5010@anchor{topics/contexts gcc_jit_context_release}@anchor{c} 5011@deffn {C Function} void gcc_jit_context_release (gcc_jit_context@w{ }*ctxt) 5012 5013This function releases all resources associated with the given context. 5014Both the context itself and all of its @pxref{e,,gcc_jit_object *} 5015instances are cleaned up. It should be called exactly once on a given 5016context. 5017 5018It is invalid to use the context or any of its "contextual" objects 5019after calling this. 5020 5021@example 5022gcc_jit_context_release (ctxt); 5023@end example 5024 5025@noindent 5026@end deffn 5027 5028@geindex gcc_jit_context_new_child_context (C function) 5029@anchor{topics/contexts gcc_jit_context_new_child_context}@anchor{54} 5030@deffn {C Function} gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context@w{ }*parent_ctxt) 5031 5032Given an existing JIT context, create a child context. 5033 5034The child inherits a copy of all option-settings from the parent. 5035 5036The child can reference objects created within the parent, but not 5037vice-versa. 5038 5039The lifetime of the child context must be bounded by that of the 5040parent: you should release a child context before releasing the parent 5041context. 5042 5043If you use a function from a parent context within a child context, 5044you have to compile the parent context before you can compile the 5045child context, and the gcc_jit_result of the parent context must 5046outlive the gcc_jit_result of the child context. 5047 5048This allows caching of shared initializations. For example, you could 5049create types and declarations of global functions in a parent context 5050once within a process, and then create child contexts whenever a 5051function or loop becomes hot. Each such child context can be used for 5052JIT-compiling just one function or loop, but can reference types 5053and helper functions created within the parent context. 5054 5055Contexts can be arbitrarily nested, provided the above rules are 5056followed, but it's probably not worth going above 2 or 3 levels, and 5057there will likely be a performance hit for such nesting. 5058@end deffn 5059 5060@node Thread-safety,Error-handling<2>,Lifetime-management,Compilation contexts 5061@anchor{topics/contexts thread-safety}@anchor{55} 5062@subsection Thread-safety 5063 5064 5065Instances of @pxref{8,,gcc_jit_context *} created via 5066@pxref{9,,gcc_jit_context_acquire()} are independent from each other: 5067only one thread may use a given context at once, but multiple threads 5068could each have their own contexts without needing locks. 5069 5070Contexts created via @pxref{54,,gcc_jit_context_new_child_context()} are 5071related to their parent context. They can be partitioned by their 5072ultimate ancestor into independent "family trees". Only one thread 5073within a process may use a given "family tree" of such contexts at once, 5074and if you're using multiple threads you should provide your own locking 5075around entire such context partitions. 5076 5077@node Error-handling<2>,Debugging,Thread-safety,Compilation contexts 5078@anchor{topics/contexts error-handling}@anchor{19}@anchor{topics/contexts id1}@anchor{56} 5079@subsection Error-handling 5080 5081 5082Various kinds of errors are possible when using the API, such as 5083mismatched types in an assignment. You can only compile and get code from 5084a context if no errors occur. 5085 5086Errors are printed on stderr and can be queried using 5087@pxref{57,,gcc_jit_context_get_first_error()}. 5088 5089They typically contain the name of the API entrypoint where the error 5090occurred, and pertinent information on the problem: 5091 5092@example 5093./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *) 5094@end example 5095 5096@noindent 5097 5098In general, if an error occurs when using an API entrypoint, the 5099entrypoint returns NULL. You don't have to check everywhere for NULL 5100results, since the API handles a NULL being passed in for any 5101argument by issuing another error. This typically leads to a cascade of 5102followup error messages, but is safe (albeit verbose). The first error 5103message is usually the one to pay attention to, since it is likely to 5104be responsible for all of the rest: 5105 5106@geindex gcc_jit_context_get_first_error (C function) 5107@anchor{topics/contexts gcc_jit_context_get_first_error}@anchor{57} 5108@deffn {C Function} const char * gcc_jit_context_get_first_error (gcc_jit_context@w{ }*ctxt) 5109 5110Returns the first error message that occurred on the context. 5111 5112The returned string is valid for the rest of the lifetime of the 5113context. 5114 5115If no errors occurred, this will be NULL. 5116@end deffn 5117 5118If you are wrapping the C API for a higher-level language that supports 5119exception-handling, you may instead be interested in the last error that 5120occurred on the context, so that you can embed this in an exception: 5121 5122@geindex gcc_jit_context_get_last_error (C function) 5123@anchor{topics/contexts gcc_jit_context_get_last_error}@anchor{58} 5124@deffn {C Function} const char * gcc_jit_context_get_last_error (gcc_jit_context@w{ }*ctxt) 5125 5126Returns the last error message that occurred on the context. 5127 5128If no errors occurred, this will be NULL. 5129 5130If non-NULL, the returned string is only guaranteed to be valid until 5131the next call to libgccjit relating to this context. 5132@end deffn 5133 5134@node Debugging,Options<2>,Error-handling<2>,Compilation contexts 5135@anchor{topics/contexts debugging}@anchor{59} 5136@subsection Debugging 5137 5138 5139@geindex gcc_jit_context_dump_to_file (C function) 5140@anchor{topics/contexts gcc_jit_context_dump_to_file}@anchor{5a} 5141@deffn {C Function} void gcc_jit_context_dump_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path, int@w{ }update_locations) 5142 5143To help with debugging: dump a C-like representation to the given path, 5144describing what's been set up on the context. 5145 5146If "update_locations" is true, then also set up @pxref{3b,,gcc_jit_location} 5147information throughout the context, pointing at the dump file as if it 5148were a source file. This may be of use in conjunction with 5149@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to allow stepping through the 5150code in a debugger. 5151@end deffn 5152 5153@geindex gcc_jit_context_set_logfile (C function) 5154@anchor{topics/contexts gcc_jit_context_set_logfile}@anchor{5b} 5155@deffn {C Function} void gcc_jit_context_set_logfile (gcc_jit_context@w{ }*ctxt, FILE@w{ }*logfile, int@w{ }flags, int@w{ }verbosity) 5156 5157To help with debugging; enable ongoing logging of the context's 5158activity to the given file. 5159 5160For example, the following will enable logging to stderr. 5161 5162@example 5163gcc_jit_context_set_logfile (ctxt, stderr, 0, 0); 5164@end example 5165 5166@noindent 5167 5168Examples of information logged include: 5169 5170 5171@itemize * 5172 5173@item 5174API calls 5175 5176@item 5177the various steps involved within compilation 5178 5179@item 5180activity on any @pxref{16,,gcc_jit_result} instances created by 5181the context 5182 5183@item 5184activity within any child contexts 5185@end itemize 5186 5187An example of a log can be seen @pxref{5c,,here}, 5188though the precise format and kinds of information logged is subject 5189to change. 5190 5191The caller remains responsible for closing @cite{logfile}, and it must not 5192be closed until all users are released. In particular, note that 5193child contexts and @pxref{16,,gcc_jit_result} instances created by 5194the context will use the logfile. 5195 5196There may a performance cost for logging. 5197 5198You can turn off logging on @cite{ctxt} by passing @cite{NULL} for @cite{logfile}. 5199Doing so only affects the context; it does not affect child contexts 5200or @pxref{16,,gcc_jit_result} instances already created by 5201the context. 5202 5203The parameters "flags" and "verbosity" are reserved for future 5204expansion, and must be zero for now. 5205@end deffn 5206 5207To contrast the above: @pxref{5a,,gcc_jit_context_dump_to_file()} dumps the 5208current state of a context to the given path, whereas 5209@pxref{5b,,gcc_jit_context_set_logfile()} enables on-going logging of 5210future activies on a context to the given @cite{FILE *}. 5211 5212@geindex gcc_jit_context_dump_reproducer_to_file (C function) 5213@anchor{topics/contexts gcc_jit_context_dump_reproducer_to_file}@anchor{5d} 5214@deffn {C Function} void gcc_jit_context_dump_reproducer_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path) 5215 5216Write C source code into @cite{path} that can be compiled into a 5217self-contained executable (i.e. with libgccjit as the only dependency). 5218The generated code will attempt to replay the API calls that have been 5219made into the given context. 5220 5221This may be useful when debugging the library or client code, for 5222reducing a complicated recipe for reproducing a bug into a simpler 5223form. For example, consider client code that parses some source file 5224into some internal representation, and then walks this IR, calling into 5225libgccjit. If this encounters a bug, a call to 5226@cite{gcc_jit_context_dump_reproducer_to_file} will write out C code for 5227a much simpler executable that performs the equivalent calls into 5228libgccjit, without needing the client code and its data. 5229 5230Typically you need to supply @code{-Wno-unused-variable} when 5231compiling the generated file (since the result of each API call is 5232assigned to a unique variable within the generated C source, and not 5233all are necessarily then used). 5234@end deffn 5235 5236@geindex gcc_jit_context_enable_dump (C function) 5237@anchor{topics/contexts gcc_jit_context_enable_dump}@anchor{5e} 5238@deffn {C Function} void gcc_jit_context_enable_dump (gcc_jit_context@w{ }*ctxt, const char@w{ }*dumpname, char@w{ }**out_ptr) 5239 5240Enable the dumping of a specific set of internal state from the 5241compilation, capturing the result in-memory as a buffer. 5242 5243Parameter "dumpname" corresponds to the equivalent gcc command-line 5244option, without the "-fdump-" prefix. 5245For example, to get the equivalent of @code{-fdump-tree-vrp1}, 5246supply @code{"tree-vrp1"}: 5247 5248@example 5249static char *dump_vrp1; 5250 5251void 5252create_code (gcc_jit_context *ctxt) 5253@{ 5254 gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1); 5255 /* (other API calls omitted for brevity) */ 5256@} 5257@end example 5258 5259@noindent 5260 5261The context directly stores the dumpname as a @code{(const char *)}, so 5262the passed string must outlive the context. 5263 5264@pxref{15,,gcc_jit_context_compile()} will capture the dump as a 5265dynamically-allocated buffer, writing it to @code{*out_ptr}. 5266 5267The caller becomes responsible for calling: 5268 5269@example 5270free (*out_ptr) 5271@end example 5272 5273@noindent 5274 5275each time that @pxref{15,,gcc_jit_context_compile()} is called. 5276@code{*out_ptr} will be written to, either with the address of a buffer, 5277or with @code{NULL} if an error occurred. 5278 5279@cartouche 5280@quotation Warning 5281This API entrypoint is likely to be less stable than the others. 5282In particular, both the precise dumpnames, and the format and content 5283of the dumps are subject to change. 5284 5285It exists primarily for writing the library's own test suite. 5286@end quotation 5287@end cartouche 5288@end deffn 5289 5290@node Options<2>,,Debugging,Compilation contexts 5291@anchor{topics/contexts options}@anchor{5f} 5292@subsection Options 5293 5294 5295Options present in the initial release of libgccjit were handled using 5296enums, whereas those added subsequently have their own per-option API 5297entrypoints. 5298 5299Adding entrypoints for each new option means that client code that use 5300the new options can be identified directly from binary metadata, which 5301would not be possible if we instead extended the various 5302@code{enum gcc_jit_*_option}. 5303 5304@menu 5305* String Options:: 5306* Boolean options:: 5307* Integer options:: 5308* Additional command-line options:: 5309 5310@end menu 5311 5312@node String Options,Boolean options,,Options<2> 5313@anchor{topics/contexts string-options}@anchor{60} 5314@subsubsection String Options 5315 5316 5317@geindex gcc_jit_context_set_str_option (C function) 5318@anchor{topics/contexts gcc_jit_context_set_str_option}@anchor{61} 5319@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) 5320 5321Set a string option of the context. 5322 5323@geindex gcc_jit_str_option (C type) 5324@anchor{topics/contexts gcc_jit_str_option}@anchor{62} 5325@deffn {C Type} enum gcc_jit_str_option 5326@end deffn 5327 5328The parameter @code{value} can be NULL. If non-NULL, the call takes a 5329copy of the underlying string, so it is valid to pass in a pointer to 5330an on-stack buffer. 5331 5332There is just one string option specified this way: 5333 5334@geindex GCC_JIT_STR_OPTION_PROGNAME (C macro) 5335@anchor{topics/contexts GCC_JIT_STR_OPTION_PROGNAME}@anchor{63} 5336@deffn {C Macro} GCC_JIT_STR_OPTION_PROGNAME 5337 5338The name of the program, for use as a prefix when printing error 5339messages to stderr. If @cite{NULL}, or default, "libgccjit.so" is used. 5340@end deffn 5341@end deffn 5342 5343@node Boolean options,Integer options,String Options,Options<2> 5344@anchor{topics/contexts boolean-options}@anchor{64} 5345@subsubsection Boolean options 5346 5347 5348@geindex gcc_jit_context_set_bool_option (C function) 5349@anchor{topics/contexts gcc_jit_context_set_bool_option}@anchor{1b} 5350@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) 5351 5352Set a boolean option of the context. 5353Zero is "false" (the default), non-zero is "true". 5354 5355@geindex gcc_jit_bool_option (C type) 5356@anchor{topics/contexts gcc_jit_bool_option}@anchor{65} 5357@deffn {C Type} enum gcc_jit_bool_option 5358@end deffn 5359 5360@geindex GCC_JIT_BOOL_OPTION_DEBUGINFO (C macro) 5361@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DEBUGINFO}@anchor{42} 5362@deffn {C Macro} GCC_JIT_BOOL_OPTION_DEBUGINFO 5363 5364If true, @pxref{15,,gcc_jit_context_compile()} will attempt to do the right 5365thing so that if you attach a debugger to the process, it will 5366be able to inspect variables and step through your code. 5367 5368Note that you can't step through code unless you set up source 5369location information for the code (by creating and passing in 5370@pxref{3b,,gcc_jit_location} instances). 5371@end deffn 5372 5373@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE (C macro) 5374@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}@anchor{66} 5375@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE 5376 5377If true, @pxref{15,,gcc_jit_context_compile()} will dump its initial 5378"tree" representation of your code to stderr (before any 5379optimizations). 5380 5381Here's some sample output (from the @cite{square} example): 5382 5383@example 5384<statement_list 0x7f4875a62cc0 5385 type <void_type 0x7f4875a64bd0 VOID 5386 align 8 symtab 0 alias set -1 canonical type 0x7f4875a64bd0 5387 pointer_to_this <pointer_type 0x7f4875a64c78>> 5388 side-effects head 0x7f4875a761e0 tail 0x7f4875a761f8 stmts 0x7f4875a62d20 0x7f4875a62d00 5389 5390 stmt <label_expr 0x7f4875a62d20 type <void_type 0x7f4875a64bd0> 5391 side-effects 5392 arg 0 <label_decl 0x7f4875a79080 entry type <void_type 0x7f4875a64bd0> 5393 VOID file (null) line 0 col 0 5394 align 1 context <function_decl 0x7f4875a77500 square>>> 5395 stmt <return_expr 0x7f4875a62d00 5396 type <integer_type 0x7f4875a645e8 public SI 5397 size <integer_cst 0x7f4875a623a0 constant 32> 5398 unit size <integer_cst 0x7f4875a623c0 constant 4> 5399 align 32 symtab 0 alias set -1 canonical type 0x7f4875a645e8 precision 32 min <integer_cst 0x7f4875a62340 -2147483648> max <integer_cst 0x7f4875a62360 2147483647> 5400 pointer_to_this <pointer_type 0x7f4875a6b348>> 5401 side-effects 5402 arg 0 <modify_expr 0x7f4875a72a78 type <integer_type 0x7f4875a645e8> 5403 side-effects arg 0 <result_decl 0x7f4875a7a000 D.54> 5404 arg 1 <mult_expr 0x7f4875a72a50 type <integer_type 0x7f4875a645e8> 5405 arg 0 <parm_decl 0x7f4875a79000 i> arg 1 <parm_decl 0x7f4875a79000 i>>>>> 5406@end example 5407 5408@noindent 5409@end deffn 5410 5411@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE (C macro) 5412@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}@anchor{1c} 5413@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE 5414 5415If true, @pxref{15,,gcc_jit_context_compile()} will dump the "gimple" 5416representation of your code to stderr, before any optimizations 5417are performed. The dump resembles C code: 5418 5419@example 5420square (signed int i) 5421@{ 5422 signed int D.56; 5423 5424 entry: 5425 D.56 = i * i; 5426 return D.56; 5427@} 5428@end example 5429 5430@noindent 5431@end deffn 5432 5433@geindex GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE (C macro) 5434@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE}@anchor{1d} 5435@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE 5436 5437If true, @pxref{15,,gcc_jit_context_compile()} will dump the final 5438generated code to stderr, in the form of assembly language: 5439 5440@example 5441 .file "fake.c" 5442 .text 5443 .globl square 5444 .type square, @@function 5445square: 5446.LFB0: 5447 .cfi_startproc 5448 pushq %rbp 5449 .cfi_def_cfa_offset 16 5450 .cfi_offset 6, -16 5451 movq %rsp, %rbp 5452 .cfi_def_cfa_register 6 5453 movl %edi, -4(%rbp) 5454.L2: 5455 movl -4(%rbp), %eax 5456 imull -4(%rbp), %eax 5457 popq %rbp 5458 .cfi_def_cfa 7, 8 5459 ret 5460 .cfi_endproc 5461.LFE0: 5462 .size square, .-square 5463 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.1-%@{gcc_release@})" 5464 .section .note.GNU-stack,"",@@progbits 5465@end example 5466 5467@noindent 5468@end deffn 5469 5470@geindex GCC_JIT_BOOL_OPTION_DUMP_SUMMARY (C macro) 5471@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_SUMMARY}@anchor{67} 5472@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_SUMMARY 5473 5474If true, @pxref{15,,gcc_jit_context_compile()} will print information to stderr 5475on the actions it is performing. 5476@end deffn 5477 5478@geindex GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING (C macro) 5479@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING}@anchor{68} 5480@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING 5481 5482If true, @pxref{15,,gcc_jit_context_compile()} will dump copious 5483amount of information on what it's doing to various 5484files within a temporary directory. Use 5485@pxref{69,,GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES} (see below) to 5486see the results. The files are intended to be human-readable, 5487but the exact files and their formats are subject to change. 5488@end deffn 5489 5490@geindex GCC_JIT_BOOL_OPTION_SELFCHECK_GC (C macro) 5491@anchor{topics/contexts GCC_JIT_BOOL_OPTION_SELFCHECK_GC}@anchor{6a} 5492@deffn {C Macro} GCC_JIT_BOOL_OPTION_SELFCHECK_GC 5493 5494If true, libgccjit will aggressively run its garbage collector, to 5495shake out bugs (greatly slowing down the compile). This is likely 5496to only be of interest to developers @emph{of} the library. It is 5497used when running the selftest suite. 5498@end deffn 5499 5500@geindex GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES (C macro) 5501@anchor{topics/contexts GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES}@anchor{69} 5502@deffn {C Macro} GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES 5503 5504If true, the @pxref{8,,gcc_jit_context} will not clean up intermediate files 5505written to the filesystem, and will display their location on stderr. 5506@end deffn 5507@end deffn 5508 5509@geindex gcc_jit_context_set_bool_allow_unreachable_blocks (C function) 5510@anchor{topics/contexts gcc_jit_context_set_bool_allow_unreachable_blocks}@anchor{6b} 5511@deffn {C Function} void gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value) 5512 5513By default, libgccjit will issue an error about unreachable blocks 5514within a function. 5515 5516This entrypoint can be used to disable that error. 5517 5518This entrypoint was added in @pxref{6c,,LIBGCCJIT_ABI_2}; you can test for 5519its presence using 5520 5521@example 5522#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 5523@end example 5524 5525@noindent 5526@end deffn 5527 5528@geindex gcc_jit_context_set_bool_use_external_driver (C function) 5529@anchor{topics/contexts gcc_jit_context_set_bool_use_external_driver}@anchor{6d} 5530@deffn {C Function} void gcc_jit_context_set_bool_use_external_driver (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value) 5531 5532libgccjit internally generates assembler, and uses "driver" code 5533for converting it to other formats (e.g. shared libraries). 5534 5535By default, libgccjit will use an embedded copy of the driver 5536code. 5537 5538This option can be used to instead invoke an external driver executable 5539as a subprocess. 5540 5541This entrypoint was added in @pxref{6e,,LIBGCCJIT_ABI_5}; you can test for 5542its presence using 5543 5544@example 5545#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver 5546@end example 5547 5548@noindent 5549@end deffn 5550 5551@node Integer options,Additional command-line options,Boolean options,Options<2> 5552@anchor{topics/contexts integer-options}@anchor{6f} 5553@subsubsection Integer options 5554 5555 5556@geindex gcc_jit_context_set_int_option (C function) 5557@anchor{topics/contexts gcc_jit_context_set_int_option}@anchor{1e} 5558@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) 5559 5560Set an integer option of the context. 5561 5562@geindex gcc_jit_int_option (C type) 5563@anchor{topics/contexts gcc_jit_int_option}@anchor{70} 5564@deffn {C Type} enum gcc_jit_int_option 5565@end deffn 5566 5567There is just one integer option specified this way: 5568 5569@geindex GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL (C macro) 5570@anchor{topics/contexts GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}@anchor{1f} 5571@deffn {C Macro} GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL 5572 5573How much to optimize the code. 5574 5575Valid values are 0-3, corresponding to GCC's command-line options 5576-O0 through -O3. 5577 5578The default value is 0 (unoptimized). 5579@end deffn 5580@end deffn 5581 5582@node Additional command-line options,,Integer options,Options<2> 5583@anchor{topics/contexts additional-command-line-options}@anchor{71} 5584@subsubsection Additional command-line options 5585 5586 5587@geindex gcc_jit_context_add_command_line_option (C function) 5588@anchor{topics/contexts gcc_jit_context_add_command_line_option}@anchor{72} 5589@deffn {C Function} void gcc_jit_context_add_command_line_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname) 5590 5591Add an arbitrary gcc command-line option to the context, for use 5592by @pxref{15,,gcc_jit_context_compile()} and 5593@pxref{4a,,gcc_jit_context_compile_to_file()}. 5594 5595The parameter @code{optname} must be non-NULL. The underlying buffer is 5596copied, so that it does not need to outlive the call. 5597 5598Extra options added by @cite{gcc_jit_context_add_command_line_option} are 5599applied @emph{after} the regular options above, potentially overriding them. 5600Options from parent contexts are inherited by child contexts; options 5601from the parent are applied @emph{before} those from the child. 5602 5603For example: 5604 5605@example 5606gcc_jit_context_add_command_line_option (ctxt, "-ffast-math"); 5607gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm"); 5608@end example 5609 5610@noindent 5611 5612Note that only some options are likely to be meaningful; there is no 5613"frontend" within libgccjit, so typically only those affecting 5614optimization and code-generation are likely to be useful. 5615 5616This entrypoint was added in @pxref{73,,LIBGCCJIT_ABI_1}; you can test for 5617its presence using 5618 5619@example 5620#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 5621@end example 5622 5623@noindent 5624@end deffn 5625 5626@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 5627@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 5628@c 5629@c This is free software: you can redistribute it and/or modify it 5630@c under the terms of the GNU General Public License as published by 5631@c the Free Software Foundation, either version 3 of the License, or 5632@c (at your option) any later version. 5633@c 5634@c This program is distributed in the hope that it will be useful, but 5635@c WITHOUT ANY WARRANTY; without even the implied warranty of 5636@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5637@c General Public License for more details. 5638@c 5639@c You should have received a copy of the GNU General Public License 5640@c along with this program. If not, see 5641@c <http://www.gnu.org/licenses/>. 5642 5643@node Objects,Types,Compilation contexts,Topic Reference 5644@anchor{topics/objects objects}@anchor{74}@anchor{topics/objects doc}@anchor{75} 5645@section Objects 5646 5647 5648@geindex gcc_jit_object (C type) 5649@anchor{topics/objects gcc_jit_object}@anchor{e} 5650@deffn {C Type} gcc_jit_object 5651@end deffn 5652 5653Almost every entity in the API (with the exception of 5654@pxref{8,,gcc_jit_context *} and @pxref{16,,gcc_jit_result *}) is a 5655"contextual" object, a @pxref{e,,gcc_jit_object *} 5656 5657A JIT object: 5658 5659@quotation 5660 5661 5662@itemize * 5663 5664@item 5665is associated with a @pxref{8,,gcc_jit_context *}. 5666 5667@item 5668is automatically cleaned up for you when its context is released so 5669you don't need to manually track and cleanup all objects, just the 5670contexts. 5671@end itemize 5672@end quotation 5673 5674Although the API is C-based, there is a form of class hierarchy, which 5675looks like this: 5676 5677@example 5678+- gcc_jit_object 5679 +- gcc_jit_location 5680 +- gcc_jit_type 5681 +- gcc_jit_struct 5682 +- gcc_jit_field 5683 +- gcc_jit_function 5684 +- gcc_jit_block 5685 +- gcc_jit_rvalue 5686 +- gcc_jit_lvalue 5687 +- gcc_jit_param 5688 +- gcc_jit_case 5689@end example 5690 5691@noindent 5692 5693There are casting methods for upcasting from subclasses to parent classes. 5694For example, @pxref{d,,gcc_jit_type_as_object()}: 5695 5696@example 5697gcc_jit_object *obj = gcc_jit_type_as_object (int_type); 5698@end example 5699 5700@noindent 5701 5702The object "base class" has the following operations: 5703 5704@geindex gcc_jit_object_get_context (C function) 5705@anchor{topics/objects gcc_jit_object_get_context}@anchor{76} 5706@deffn {C Function} gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object@w{ }*obj) 5707 5708Which context is "obj" within? 5709@end deffn 5710 5711@geindex gcc_jit_object_get_debug_string (C function) 5712@anchor{topics/objects gcc_jit_object_get_debug_string}@anchor{f} 5713@deffn {C Function} const char *gcc_jit_object_get_debug_string (gcc_jit_object@w{ }*obj) 5714 5715Generate a human-readable description for the given object. 5716 5717For example, 5718 5719@example 5720printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); 5721@end example 5722 5723@noindent 5724 5725might give this text on stdout: 5726 5727@example 5728obj: 4.0 * (float)i 5729@end example 5730 5731@noindent 5732 5733@cartouche 5734@quotation Note 5735If you call this on an object, the @cite{const char *} buffer is allocated 5736and generated on the first call for that object, and the buffer will 5737have the same lifetime as the object i.e. it will exist until the 5738object's context is released. 5739@end quotation 5740@end cartouche 5741@end deffn 5742 5743@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 5744@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 5745@c 5746@c This is free software: you can redistribute it and/or modify it 5747@c under the terms of the GNU General Public License as published by 5748@c the Free Software Foundation, either version 3 of the License, or 5749@c (at your option) any later version. 5750@c 5751@c This program is distributed in the hope that it will be useful, but 5752@c WITHOUT ANY WARRANTY; without even the implied warranty of 5753@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5754@c General Public License for more details. 5755@c 5756@c You should have received a copy of the GNU General Public License 5757@c along with this program. If not, see 5758@c <http://www.gnu.org/licenses/>. 5759 5760@node Types,Expressions,Objects,Topic Reference 5761@anchor{topics/types doc}@anchor{77}@anchor{topics/types types}@anchor{78} 5762@section Types 5763 5764 5765@geindex gcc_jit_type (C type) 5766@anchor{topics/types gcc_jit_type}@anchor{a} 5767@deffn {C Type} gcc_jit_type 5768 5769gcc_jit_type represents a type within the library. 5770@end deffn 5771 5772@geindex gcc_jit_type_as_object (C function) 5773@anchor{topics/types gcc_jit_type_as_object}@anchor{d} 5774@deffn {C Function} gcc_jit_object *gcc_jit_type_as_object (gcc_jit_type@w{ }*type) 5775 5776Upcast a type to an object. 5777@end deffn 5778 5779Types can be created in several ways: 5780 5781 5782@itemize * 5783 5784@item 5785fundamental types can be accessed using 5786@pxref{b,,gcc_jit_context_get_type()}: 5787 5788@example 5789gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 5790@end example 5791 5792@noindent 5793 5794See @pxref{b,,gcc_jit_context_get_type()} for the available types. 5795 5796@item 5797derived types can be accessed by using functions such as 5798@pxref{79,,gcc_jit_type_get_pointer()} and @pxref{7a,,gcc_jit_type_get_const()}: 5799 5800@example 5801gcc_jit_type *const_int_star = gcc_jit_type_get_pointer (gcc_jit_type_get_const (int_type)); 5802gcc_jit_type *int_const_star = gcc_jit_type_get_const (gcc_jit_type_get_pointer (int_type)); 5803@end example 5804 5805@noindent 5806 5807@item 5808by creating structures (see below). 5809@end itemize 5810 5811@menu 5812* Standard types:: 5813* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 5814* Vector types:: 5815* Structures and unions:: 5816* Function pointer types:: 5817 5818@end menu 5819 5820@node Standard types,Pointers const and volatile,,Types 5821@anchor{topics/types standard-types}@anchor{7b} 5822@subsection Standard types 5823 5824 5825@geindex gcc_jit_context_get_type (C function) 5826@anchor{topics/types gcc_jit_context_get_type}@anchor{b} 5827@deffn {C Function} gcc_jit_type *gcc_jit_context_get_type (gcc_jit_context@w{ }*ctxt, enum gcc_jit_types@w{ }type_) 5828 5829Access a specific type. The available types are: 5830 5831 5832@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 5833@headitem 5834 5835@cite{enum gcc_jit_types} value 5836 5837@tab 5838 5839Meaning 5840 5841@item 5842 5843@code{GCC_JIT_TYPE_VOID} 5844 5845@tab 5846 5847C's @code{void} type. 5848 5849@item 5850 5851@code{GCC_JIT_TYPE_VOID_PTR} 5852 5853@tab 5854 5855C's @code{void *}. 5856 5857@item 5858 5859@code{GCC_JIT_TYPE_BOOL} 5860 5861@tab 5862 5863C++'s @code{bool} type; also C99's 5864@code{_Bool} type, aka @code{bool} if 5865using stdbool.h. 5866 5867@item 5868 5869@code{GCC_JIT_TYPE_CHAR} 5870 5871@tab 5872 5873C's @code{char} (of some signedness) 5874 5875@item 5876 5877@code{GCC_JIT_TYPE_SIGNED_CHAR} 5878 5879@tab 5880 5881C's @code{signed char} 5882 5883@item 5884 5885@code{GCC_JIT_TYPE_UNSIGNED_CHAR} 5886 5887@tab 5888 5889C's @code{unsigned char} 5890 5891@item 5892 5893@code{GCC_JIT_TYPE_SHORT} 5894 5895@tab 5896 5897C's @code{short} (signed) 5898 5899@item 5900 5901@code{GCC_JIT_TYPE_UNSIGNED_SHORT} 5902 5903@tab 5904 5905C's @code{unsigned short} 5906 5907@item 5908 5909@code{GCC_JIT_TYPE_INT} 5910 5911@tab 5912 5913C's @code{int} (signed) 5914 5915@item 5916 5917@code{GCC_JIT_TYPE_UNSIGNED_INT} 5918 5919@tab 5920 5921C's @code{unsigned int} 5922 5923@item 5924 5925@code{GCC_JIT_TYPE_LONG} 5926 5927@tab 5928 5929C's @code{long} (signed) 5930 5931@item 5932 5933@code{GCC_JIT_TYPE_UNSIGNED_LONG} 5934 5935@tab 5936 5937C's @code{unsigned long} 5938 5939@item 5940 5941@code{GCC_JIT_TYPE_LONG_LONG} 5942 5943@tab 5944 5945C99's @code{long long} (signed) 5946 5947@item 5948 5949@code{GCC_JIT_TYPE_UNSIGNED_LONG_LONG} 5950 5951@tab 5952 5953C99's @code{unsigned long long} 5954 5955@item 5956 5957@code{GCC_JIT_TYPE_FLOAT} 5958 5959@tab 5960 5961@item 5962 5963@code{GCC_JIT_TYPE_DOUBLE} 5964 5965@tab 5966 5967@item 5968 5969@code{GCC_JIT_TYPE_LONG_DOUBLE} 5970 5971@tab 5972 5973@item 5974 5975@code{GCC_JIT_TYPE_CONST_CHAR_PTR} 5976 5977@tab 5978 5979C type: @code{(const char *)} 5980 5981@item 5982 5983@code{GCC_JIT_TYPE_SIZE_T} 5984 5985@tab 5986 5987C's @code{size_t} type 5988 5989@item 5990 5991@code{GCC_JIT_TYPE_FILE_PTR} 5992 5993@tab 5994 5995C type: @code{(FILE *)} 5996 5997@item 5998 5999@code{GCC_JIT_TYPE_COMPLEX_FLOAT} 6000 6001@tab 6002 6003C99's @code{_Complex float} 6004 6005@item 6006 6007@code{GCC_JIT_TYPE_COMPLEX_DOUBLE} 6008 6009@tab 6010 6011C99's @code{_Complex double} 6012 6013@item 6014 6015@code{GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE} 6016 6017@tab 6018 6019C99's @code{_Complex long double} 6020 6021@end multitable 6022 6023@end deffn 6024 6025@geindex gcc_jit_context_get_int_type (C function) 6026@anchor{topics/types gcc_jit_context_get_int_type}@anchor{7c} 6027@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) 6028 6029Access the integer type of the given size. 6030@end deffn 6031 6032@node Pointers const and volatile,Vector types,Standard types,Types 6033@anchor{topics/types pointers-const-and-volatile}@anchor{7d} 6034@subsection Pointers, @cite{const}, and @cite{volatile} 6035 6036 6037@geindex gcc_jit_type_get_pointer (C function) 6038@anchor{topics/types gcc_jit_type_get_pointer}@anchor{79} 6039@deffn {C Function} gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type@w{ }*type) 6040 6041Given type "T", get type "T*". 6042@end deffn 6043 6044@geindex gcc_jit_type_get_const (C function) 6045@anchor{topics/types gcc_jit_type_get_const}@anchor{7a} 6046@deffn {C Function} gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type@w{ }*type) 6047 6048Given type "T", get type "const T". 6049@end deffn 6050 6051@geindex gcc_jit_type_get_volatile (C function) 6052@anchor{topics/types gcc_jit_type_get_volatile}@anchor{7e} 6053@deffn {C Function} gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type@w{ }*type) 6054 6055Given type "T", get type "volatile T". 6056@end deffn 6057 6058@geindex gcc_jit_context_new_array_type (C function) 6059@anchor{topics/types gcc_jit_context_new_array_type}@anchor{7f} 6060@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) 6061 6062Given type "T", get type "T[N]" (for a constant N). 6063@end deffn 6064 6065@geindex gcc_jit_type_get_aligned (C function) 6066@anchor{topics/types gcc_jit_type_get_aligned}@anchor{80} 6067@deffn {C Function} gcc_jit_type * gcc_jit_type_get_aligned (gcc_jit_type@w{ }*type, size_t@w{ }alignment_in_bytes) 6068 6069Given type "T", get type: 6070 6071@example 6072T __attribute__ ((aligned (ALIGNMENT_IN_BYTES))) 6073@end example 6074 6075@noindent 6076 6077The alignment must be a power of two. 6078 6079This entrypoint was added in @pxref{81,,LIBGCCJIT_ABI_7}; you can test for 6080its presence using 6081 6082@example 6083#ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_aligned 6084@end example 6085 6086@noindent 6087@end deffn 6088 6089@node Vector types,Structures and unions,Pointers const and volatile,Types 6090@anchor{topics/types vector-types}@anchor{82} 6091@subsection Vector types 6092 6093 6094@geindex gcc_jit_type_get_vector (C function) 6095@anchor{topics/types gcc_jit_type_get_vector}@anchor{83} 6096@deffn {C Function} gcc_jit_type * gcc_jit_type_get_vector (gcc_jit_type@w{ }*type, size_t@w{ }num_units) 6097 6098Given type "T", get type: 6099 6100@example 6101T __attribute__ ((vector_size (sizeof(T) * num_units)) 6102@end example 6103 6104@noindent 6105 6106T must be integral or floating point; num_units must be a power of two. 6107 6108This can be used to construct a vector type in which operations 6109are applied element-wise. The compiler will automatically 6110use SIMD instructions where possible. See: 6111@indicateurl{https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html} 6112 6113For example, assuming 4-byte @code{ints}, then: 6114 6115@example 6116typedef int v4si __attribute__ ((vector_size (16))); 6117@end example 6118 6119@noindent 6120 6121can be obtained using: 6122 6123@example 6124gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, 6125 GCC_JIT_TYPE_INT); 6126gcc_jit_type *v4si_type = gcc_jit_type_get_vector (int_type, 4); 6127@end example 6128 6129@noindent 6130 6131This API entrypoint was added in @pxref{84,,LIBGCCJIT_ABI_8}; you can test 6132for its presence using 6133 6134@example 6135#ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_vector 6136@end example 6137 6138@noindent 6139 6140Vector rvalues can be generated using 6141@pxref{85,,gcc_jit_context_new_rvalue_from_vector()}. 6142@end deffn 6143 6144@node Structures and unions,Function pointer types,Vector types,Types 6145@anchor{topics/types structures-and-unions}@anchor{86} 6146@subsection Structures and unions 6147 6148 6149@geindex gcc_jit_struct (C type) 6150@anchor{topics/types gcc_jit_struct}@anchor{87} 6151@deffn {C Type} gcc_jit_struct 6152@end deffn 6153 6154A compound type analagous to a C @cite{struct}. 6155 6156@geindex gcc_jit_field (C type) 6157@anchor{topics/types gcc_jit_field}@anchor{88} 6158@deffn {C Type} gcc_jit_field 6159@end deffn 6160 6161A field within a @pxref{87,,gcc_jit_struct}. 6162 6163You can model C @cite{struct} types by creating @pxref{87,,gcc_jit_struct *} and 6164@pxref{88,,gcc_jit_field} instances, in either order: 6165 6166 6167@itemize * 6168 6169@item 6170by creating the fields, then the structure. For example, to model: 6171 6172@example 6173struct coord @{double x; double y; @}; 6174@end example 6175 6176@noindent 6177 6178you could call: 6179 6180@example 6181gcc_jit_field *field_x = 6182 gcc_jit_context_new_field (ctxt, NULL, double_type, "x"); 6183gcc_jit_field *field_y = 6184 gcc_jit_context_new_field (ctxt, NULL, double_type, "y"); 6185gcc_jit_field *fields[2] = @{field_x, field_y@}; 6186gcc_jit_struct *coord = 6187 gcc_jit_context_new_struct_type (ctxt, NULL, "coord", 2, fields); 6188@end example 6189 6190@noindent 6191 6192@item 6193by creating the structure, then populating it with fields, typically 6194to allow modelling self-referential structs such as: 6195 6196@example 6197struct node @{ int m_hash; struct node *m_next; @}; 6198@end example 6199 6200@noindent 6201 6202like this: 6203 6204@example 6205gcc_jit_type *node = 6206 gcc_jit_context_new_opaque_struct (ctxt, NULL, "node"); 6207gcc_jit_type *node_ptr = 6208 gcc_jit_type_get_pointer (node); 6209gcc_jit_field *field_hash = 6210 gcc_jit_context_new_field (ctxt, NULL, int_type, "m_hash"); 6211gcc_jit_field *field_next = 6212 gcc_jit_context_new_field (ctxt, NULL, node_ptr, "m_next"); 6213gcc_jit_field *fields[2] = @{field_hash, field_next@}; 6214gcc_jit_struct_set_fields (node, NULL, 2, fields); 6215@end example 6216 6217@noindent 6218@end itemize 6219 6220@geindex gcc_jit_context_new_field (C function) 6221@anchor{topics/types gcc_jit_context_new_field}@anchor{89} 6222@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) 6223 6224Construct a new field, with the given type and name. 6225 6226The parameter @code{name} must be non-NULL. The call takes a copy of the 6227underlying string, so it is valid to pass in a pointer to an on-stack 6228buffer. 6229@end deffn 6230 6231@geindex gcc_jit_field_as_object (C function) 6232@anchor{topics/types gcc_jit_field_as_object}@anchor{8a} 6233@deffn {C Function} gcc_jit_object * gcc_jit_field_as_object (gcc_jit_field@w{ }*field) 6234 6235Upcast from field to object. 6236@end deffn 6237 6238@geindex gcc_jit_context_new_struct_type (C function) 6239@anchor{topics/types gcc_jit_context_new_struct_type}@anchor{8b} 6240@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) 6241 6242@quotation 6243 6244Construct a new struct type, with the given name and fields. 6245 6246The parameter @code{name} must be non-NULL. The call takes a copy of 6247the underlying string, so it is valid to pass in a pointer to an 6248on-stack buffer. 6249@end quotation 6250@end deffn 6251 6252@geindex gcc_jit_context_new_opaque_struct (C function) 6253@anchor{topics/types gcc_jit_context_new_opaque_struct}@anchor{8c} 6254@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) 6255 6256Construct a new struct type, with the given name, but without 6257specifying the fields. The fields can be omitted (in which case the 6258size of the struct is not known), or later specified using 6259@pxref{8d,,gcc_jit_struct_set_fields()}. 6260 6261The parameter @code{name} must be non-NULL. The call takes a copy of 6262the underlying string, so it is valid to pass in a pointer to an 6263on-stack buffer. 6264@end deffn 6265 6266@geindex gcc_jit_struct_as_type (C function) 6267@anchor{topics/types gcc_jit_struct_as_type}@anchor{8e} 6268@deffn {C Function} gcc_jit_type * gcc_jit_struct_as_type (gcc_jit_struct@w{ }*struct_type) 6269 6270Upcast from struct to type. 6271@end deffn 6272 6273@geindex gcc_jit_struct_set_fields (C function) 6274@anchor{topics/types gcc_jit_struct_set_fields}@anchor{8d} 6275@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) 6276 6277Populate the fields of a formerly-opaque struct type. 6278 6279This can only be called once on a given struct type. 6280@end deffn 6281 6282@geindex gcc_jit_context_new_union_type (C function) 6283@anchor{topics/types gcc_jit_context_new_union_type}@anchor{8f} 6284@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) 6285 6286Construct a new union type, with the given name and fields. 6287 6288The parameter @code{name} must be non-NULL. It is copied, so the input 6289buffer does not need to outlive the call. 6290 6291Example of use: 6292 6293@example 6294 6295union int_or_float 6296@{ 6297 int as_int; 6298 float as_float; 6299@}; 6300 6301void 6302create_code (gcc_jit_context *ctxt, void *user_data) 6303@{ 6304 /* Let's try to inject the equivalent of: 6305 float 6306 test_union (int i) 6307 @{ 6308 union int_or_float u; 6309 u.as_int = i; 6310 return u.as_float; 6311 @} 6312 */ 6313 gcc_jit_type *int_type = 6314 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 6315 gcc_jit_type *float_type = 6316 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); 6317 gcc_jit_field *as_int = 6318 gcc_jit_context_new_field (ctxt, 6319 NULL, 6320 int_type, 6321 "as_int"); 6322 gcc_jit_field *as_float = 6323 gcc_jit_context_new_field (ctxt, 6324 NULL, 6325 float_type, 6326 "as_float"); 6327 gcc_jit_field *fields[] = @{as_int, as_float@}; 6328 gcc_jit_type *union_type = 6329 gcc_jit_context_new_union_type (ctxt, NULL, 6330 "int_or_float", 2, fields); 6331 6332 /* Build the test function. */ 6333 gcc_jit_param *param_i = 6334 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 6335 gcc_jit_function *test_fn = 6336 gcc_jit_context_new_function (ctxt, NULL, 6337 GCC_JIT_FUNCTION_EXPORTED, 6338 float_type, 6339 "test_union", 6340 1, ¶m_i, 6341 0); 6342 6343 gcc_jit_lvalue *u = 6344 gcc_jit_function_new_local (test_fn, NULL, 6345 union_type, "u"); 6346 6347 gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); 6348 6349 /* u.as_int = i; */ 6350 gcc_jit_block_add_assignment ( 6351 block, 6352 NULL, 6353 /* "u.as_int = ..." */ 6354 gcc_jit_lvalue_access_field (u, 6355 NULL, 6356 as_int), 6357 gcc_jit_param_as_rvalue (param_i)); 6358 6359 /* return u.as_float; */ 6360 gcc_jit_block_end_with_return ( 6361 block, NULL, 6362 gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (u), 6363 NULL, 6364 as_float)); 6365@} 6366 6367 6368@end example 6369 6370@noindent 6371@end deffn 6372 6373@node Function pointer types,,Structures and unions,Types 6374@anchor{topics/types function-pointer-types}@anchor{90} 6375@subsection Function pointer types 6376 6377 6378Function pointer types can be created using 6379@pxref{91,,gcc_jit_context_new_function_ptr_type()}. 6380 6381@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 6382@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 6383@c 6384@c This is free software: you can redistribute it and/or modify it 6385@c under the terms of the GNU General Public License as published by 6386@c the Free Software Foundation, either version 3 of the License, or 6387@c (at your option) any later version. 6388@c 6389@c This program is distributed in the hope that it will be useful, but 6390@c WITHOUT ANY WARRANTY; without even the implied warranty of 6391@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 6392@c General Public License for more details. 6393@c 6394@c You should have received a copy of the GNU General Public License 6395@c along with this program. If not, see 6396@c <http://www.gnu.org/licenses/>. 6397 6398@node Expressions,Creating and using functions,Types,Topic Reference 6399@anchor{topics/expressions expressions}@anchor{92}@anchor{topics/expressions doc}@anchor{93} 6400@section Expressions 6401 6402 6403@menu 6404* Rvalues:: 6405* Lvalues:: 6406* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 6407 6408Rvalues 6409 6410* Simple expressions:: 6411* Vector expressions:: 6412* Unary Operations:: 6413* Binary Operations:: 6414* Comparisons:: 6415* Function calls:: 6416* Function pointers:: 6417* Type-coercion:: 6418 6419Lvalues 6420 6421* Global variables:: 6422 6423@end menu 6424 6425 6426@node Rvalues,Lvalues,,Expressions 6427@anchor{topics/expressions rvalues}@anchor{94} 6428@subsection Rvalues 6429 6430 6431@geindex gcc_jit_rvalue (C type) 6432@anchor{topics/expressions gcc_jit_rvalue}@anchor{13} 6433@deffn {C Type} gcc_jit_rvalue 6434@end deffn 6435 6436A @pxref{13,,gcc_jit_rvalue *} is an expression that can be computed. 6437 6438It can be simple, e.g.: 6439 6440@quotation 6441 6442 6443@itemize * 6444 6445@item 6446an integer value e.g. @cite{0} or @cite{42} 6447 6448@item 6449a string literal e.g. @cite{"Hello world"} 6450 6451@item 6452a variable e.g. @cite{i}. These are also lvalues (see below). 6453@end itemize 6454@end quotation 6455 6456or compound e.g.: 6457 6458@quotation 6459 6460 6461@itemize * 6462 6463@item 6464a unary expression e.g. @cite{!cond} 6465 6466@item 6467a binary expression e.g. @cite{(a + b)} 6468 6469@item 6470a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} 6471 6472@item 6473etc. 6474@end itemize 6475@end quotation 6476 6477Every rvalue has an associated type, and the API will check to ensure 6478that types match up correctly (otherwise the context will emit an error). 6479 6480@geindex gcc_jit_rvalue_get_type (C function) 6481@anchor{topics/expressions gcc_jit_rvalue_get_type}@anchor{95} 6482@deffn {C Function} gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue@w{ }*rvalue) 6483 6484Get the type of this rvalue. 6485@end deffn 6486 6487@geindex gcc_jit_rvalue_as_object (C function) 6488@anchor{topics/expressions gcc_jit_rvalue_as_object}@anchor{14} 6489@deffn {C Function} gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue@w{ }*rvalue) 6490 6491Upcast the given rvalue to be an object. 6492@end deffn 6493 6494@menu 6495* Simple expressions:: 6496* Vector expressions:: 6497* Unary Operations:: 6498* Binary Operations:: 6499* Comparisons:: 6500* Function calls:: 6501* Function pointers:: 6502* Type-coercion:: 6503 6504@end menu 6505 6506@node Simple expressions,Vector expressions,,Rvalues 6507@anchor{topics/expressions simple-expressions}@anchor{96} 6508@subsubsection Simple expressions 6509 6510 6511@geindex gcc_jit_context_new_rvalue_from_int (C function) 6512@anchor{topics/expressions gcc_jit_context_new_rvalue_from_int}@anchor{30} 6513@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) 6514 6515Given a numeric type (integer or floating point), build an rvalue for 6516the given constant @code{int} value. 6517@end deffn 6518 6519@geindex gcc_jit_context_new_rvalue_from_long (C function) 6520@anchor{topics/expressions gcc_jit_context_new_rvalue_from_long}@anchor{97} 6521@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) 6522 6523Given a numeric type (integer or floating point), build an rvalue for 6524the given constant @code{long} value. 6525@end deffn 6526 6527@geindex gcc_jit_context_zero (C function) 6528@anchor{topics/expressions gcc_jit_context_zero}@anchor{2b} 6529@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) 6530 6531Given a numeric type (integer or floating point), get the rvalue for 6532zero. Essentially this is just a shortcut for: 6533 6534@example 6535gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0) 6536@end example 6537 6538@noindent 6539@end deffn 6540 6541@geindex gcc_jit_context_one (C function) 6542@anchor{topics/expressions gcc_jit_context_one}@anchor{2f} 6543@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_one (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) 6544 6545Given a numeric type (integer or floating point), get the rvalue for 6546one. Essentially this is just a shortcut for: 6547 6548@example 6549gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1) 6550@end example 6551 6552@noindent 6553@end deffn 6554 6555@geindex gcc_jit_context_new_rvalue_from_double (C function) 6556@anchor{topics/expressions gcc_jit_context_new_rvalue_from_double}@anchor{31} 6557@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) 6558 6559Given a numeric type (integer or floating point), build an rvalue for 6560the given constant @code{double} value. 6561@end deffn 6562 6563@geindex gcc_jit_context_new_rvalue_from_ptr (C function) 6564@anchor{topics/expressions gcc_jit_context_new_rvalue_from_ptr}@anchor{98} 6565@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) 6566 6567Given a pointer type, build an rvalue for the given address. 6568@end deffn 6569 6570@geindex gcc_jit_context_null (C function) 6571@anchor{topics/expressions gcc_jit_context_null}@anchor{99} 6572@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type) 6573 6574Given a pointer type, build an rvalue for @code{NULL}. Essentially this 6575is just a shortcut for: 6576 6577@example 6578gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL) 6579@end example 6580 6581@noindent 6582@end deffn 6583 6584@geindex gcc_jit_context_new_string_literal (C function) 6585@anchor{topics/expressions gcc_jit_context_new_string_literal}@anchor{9a} 6586@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_string_literal (gcc_jit_context@w{ }*ctxt, const char@w{ }*value) 6587 6588Generate an rvalue for the given NIL-terminated string, of type 6589@code{GCC_JIT_TYPE_CONST_CHAR_PTR}. 6590 6591The parameter @code{value} must be non-NULL. The call takes a copy of the 6592underlying string, so it is valid to pass in a pointer to an on-stack 6593buffer. 6594@end deffn 6595 6596@node Vector expressions,Unary Operations,Simple expressions,Rvalues 6597@anchor{topics/expressions vector-expressions}@anchor{9b} 6598@subsubsection Vector expressions 6599 6600 6601@geindex gcc_jit_context_new_rvalue_from_vector (C function) 6602@anchor{topics/expressions gcc_jit_context_new_rvalue_from_vector}@anchor{85} 6603@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_vector (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*vec_type, size_t@w{ }num_elements, gcc_jit_rvalue@w{ }**elements) 6604 6605Build a vector rvalue from an array of elements. 6606 6607"vec_type" should be a vector type, created using 6608@pxref{83,,gcc_jit_type_get_vector()}. 6609 6610"num_elements" should match that of the vector type. 6611 6612This entrypoint was added in @pxref{9c,,LIBGCCJIT_ABI_10}; you can test for 6613its presence using 6614 6615@example 6616#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector 6617@end example 6618 6619@noindent 6620@end deffn 6621 6622@node Unary Operations,Binary Operations,Vector expressions,Rvalues 6623@anchor{topics/expressions unary-operations}@anchor{9d} 6624@subsubsection Unary Operations 6625 6626 6627@geindex gcc_jit_context_new_unary_op (C function) 6628@anchor{topics/expressions gcc_jit_context_new_unary_op}@anchor{9e} 6629@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) 6630 6631Build a unary operation out of an input rvalue. 6632@end deffn 6633 6634@geindex gcc_jit_unary_op (C type) 6635@anchor{topics/expressions gcc_jit_unary_op}@anchor{9f} 6636@deffn {C Type} enum gcc_jit_unary_op 6637@end deffn 6638 6639The available unary operations are: 6640 6641 6642@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6643@headitem 6644 6645Unary Operation 6646 6647@tab 6648 6649C equivalent 6650 6651@item 6652 6653@pxref{a0,,GCC_JIT_UNARY_OP_MINUS} 6654 6655@tab 6656 6657@cite{-(EXPR)} 6658 6659@item 6660 6661@pxref{a1,,GCC_JIT_UNARY_OP_BITWISE_NEGATE} 6662 6663@tab 6664 6665@cite{~(EXPR)} 6666 6667@item 6668 6669@pxref{a2,,GCC_JIT_UNARY_OP_LOGICAL_NEGATE} 6670 6671@tab 6672 6673@cite{!(EXPR)} 6674 6675@item 6676 6677@pxref{a3,,GCC_JIT_UNARY_OP_ABS} 6678 6679@tab 6680 6681@cite{abs (EXPR)} 6682 6683@end multitable 6684 6685 6686@geindex GCC_JIT_UNARY_OP_MINUS (C macro) 6687@anchor{topics/expressions GCC_JIT_UNARY_OP_MINUS}@anchor{a0} 6688@deffn {C Macro} GCC_JIT_UNARY_OP_MINUS 6689 6690Negate an arithmetic value; analogous to: 6691 6692@example 6693-(EXPR) 6694@end example 6695 6696@noindent 6697 6698in C. 6699@end deffn 6700 6701@geindex GCC_JIT_UNARY_OP_BITWISE_NEGATE (C macro) 6702@anchor{topics/expressions GCC_JIT_UNARY_OP_BITWISE_NEGATE}@anchor{a1} 6703@deffn {C Macro} GCC_JIT_UNARY_OP_BITWISE_NEGATE 6704 6705Bitwise negation of an integer value (one's complement); analogous 6706to: 6707 6708@example 6709~(EXPR) 6710@end example 6711 6712@noindent 6713 6714in C. 6715@end deffn 6716 6717@geindex GCC_JIT_UNARY_OP_LOGICAL_NEGATE (C macro) 6718@anchor{topics/expressions GCC_JIT_UNARY_OP_LOGICAL_NEGATE}@anchor{a2} 6719@deffn {C Macro} GCC_JIT_UNARY_OP_LOGICAL_NEGATE 6720 6721Logical negation of an arithmetic or pointer value; analogous to: 6722 6723@example 6724!(EXPR) 6725@end example 6726 6727@noindent 6728 6729in C. 6730@end deffn 6731 6732@geindex GCC_JIT_UNARY_OP_ABS (C macro) 6733@anchor{topics/expressions GCC_JIT_UNARY_OP_ABS}@anchor{a3} 6734@deffn {C Macro} GCC_JIT_UNARY_OP_ABS 6735 6736Absolute value of an arithmetic expression; analogous to: 6737 6738@example 6739abs (EXPR) 6740@end example 6741 6742@noindent 6743 6744in C. 6745@end deffn 6746 6747@node Binary Operations,Comparisons,Unary Operations,Rvalues 6748@anchor{topics/expressions binary-operations}@anchor{a4} 6749@subsubsection Binary Operations 6750 6751 6752@geindex gcc_jit_context_new_binary_op (C function) 6753@anchor{topics/expressions gcc_jit_context_new_binary_op}@anchor{12} 6754@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) 6755 6756Build a binary operation out of two constituent rvalues. 6757@end deffn 6758 6759@geindex gcc_jit_binary_op (C type) 6760@anchor{topics/expressions gcc_jit_binary_op}@anchor{a5} 6761@deffn {C Type} enum gcc_jit_binary_op 6762@end deffn 6763 6764The available binary operations are: 6765 6766 6767@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6768@headitem 6769 6770Binary Operation 6771 6772@tab 6773 6774C equivalent 6775 6776@item 6777 6778@pxref{a6,,GCC_JIT_BINARY_OP_PLUS} 6779 6780@tab 6781 6782@cite{x + y} 6783 6784@item 6785 6786@pxref{a7,,GCC_JIT_BINARY_OP_MINUS} 6787 6788@tab 6789 6790@cite{x - y} 6791 6792@item 6793 6794@pxref{a8,,GCC_JIT_BINARY_OP_MULT} 6795 6796@tab 6797 6798@cite{x * y} 6799 6800@item 6801 6802@pxref{a9,,GCC_JIT_BINARY_OP_DIVIDE} 6803 6804@tab 6805 6806@cite{x / y} 6807 6808@item 6809 6810@pxref{aa,,GCC_JIT_BINARY_OP_MODULO} 6811 6812@tab 6813 6814@cite{x % y} 6815 6816@item 6817 6818@pxref{ab,,GCC_JIT_BINARY_OP_BITWISE_AND} 6819 6820@tab 6821 6822@cite{x & y} 6823 6824@item 6825 6826@pxref{ac,,GCC_JIT_BINARY_OP_BITWISE_XOR} 6827 6828@tab 6829 6830@cite{x ^ y} 6831 6832@item 6833 6834@pxref{ad,,GCC_JIT_BINARY_OP_BITWISE_OR} 6835 6836@tab 6837 6838@cite{x | y} 6839 6840@item 6841 6842@pxref{ae,,GCC_JIT_BINARY_OP_LOGICAL_AND} 6843 6844@tab 6845 6846@cite{x && y} 6847 6848@item 6849 6850@pxref{af,,GCC_JIT_BINARY_OP_LOGICAL_OR} 6851 6852@tab 6853 6854@cite{x || y} 6855 6856@item 6857 6858@pxref{b0,,GCC_JIT_BINARY_OP_LSHIFT} 6859 6860@tab 6861 6862@cite{x << y} 6863 6864@item 6865 6866@pxref{b1,,GCC_JIT_BINARY_OP_RSHIFT} 6867 6868@tab 6869 6870@cite{x >> y} 6871 6872@end multitable 6873 6874 6875@geindex GCC_JIT_BINARY_OP_PLUS (C macro) 6876@anchor{topics/expressions GCC_JIT_BINARY_OP_PLUS}@anchor{a6} 6877@deffn {C Macro} GCC_JIT_BINARY_OP_PLUS 6878 6879Addition of arithmetic values; analogous to: 6880 6881@example 6882(EXPR_A) + (EXPR_B) 6883@end example 6884 6885@noindent 6886 6887in C. 6888 6889For pointer addition, use @pxref{b2,,gcc_jit_context_new_array_access()}. 6890@end deffn 6891 6892@geindex GCC_JIT_BINARY_OP_MINUS (C macro) 6893@anchor{topics/expressions GCC_JIT_BINARY_OP_MINUS}@anchor{a7} 6894@deffn {C Macro} GCC_JIT_BINARY_OP_MINUS 6895 6896Subtraction of arithmetic values; analogous to: 6897 6898@example 6899(EXPR_A) - (EXPR_B) 6900@end example 6901 6902@noindent 6903 6904in C. 6905@end deffn 6906 6907@geindex GCC_JIT_BINARY_OP_MULT (C macro) 6908@anchor{topics/expressions GCC_JIT_BINARY_OP_MULT}@anchor{a8} 6909@deffn {C Macro} GCC_JIT_BINARY_OP_MULT 6910 6911Multiplication of a pair of arithmetic values; analogous to: 6912 6913@example 6914(EXPR_A) * (EXPR_B) 6915@end example 6916 6917@noindent 6918 6919in C. 6920@end deffn 6921 6922@geindex GCC_JIT_BINARY_OP_DIVIDE (C macro) 6923@anchor{topics/expressions GCC_JIT_BINARY_OP_DIVIDE}@anchor{a9} 6924@deffn {C Macro} GCC_JIT_BINARY_OP_DIVIDE 6925 6926Quotient of division of arithmetic values; analogous to: 6927 6928@example 6929(EXPR_A) / (EXPR_B) 6930@end example 6931 6932@noindent 6933 6934in C. 6935 6936The result type affects the kind of division: if the result type is 6937integer-based, then the result is truncated towards zero, whereas 6938a floating-point result type indicates floating-point division. 6939@end deffn 6940 6941@geindex GCC_JIT_BINARY_OP_MODULO (C macro) 6942@anchor{topics/expressions GCC_JIT_BINARY_OP_MODULO}@anchor{aa} 6943@deffn {C Macro} GCC_JIT_BINARY_OP_MODULO 6944 6945Remainder of division of arithmetic values; analogous to: 6946 6947@example 6948(EXPR_A) % (EXPR_B) 6949@end example 6950 6951@noindent 6952 6953in C. 6954@end deffn 6955 6956@geindex GCC_JIT_BINARY_OP_BITWISE_AND (C macro) 6957@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_AND}@anchor{ab} 6958@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_AND 6959 6960Bitwise AND; analogous to: 6961 6962@example 6963(EXPR_A) & (EXPR_B) 6964@end example 6965 6966@noindent 6967 6968in C. 6969@end deffn 6970 6971@geindex GCC_JIT_BINARY_OP_BITWISE_XOR (C macro) 6972@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_XOR}@anchor{ac} 6973@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_XOR 6974 6975Bitwise exclusive OR; analogous to: 6976 6977@example 6978(EXPR_A) ^ (EXPR_B) 6979@end example 6980 6981@noindent 6982 6983in C. 6984@end deffn 6985 6986@geindex GCC_JIT_BINARY_OP_BITWISE_OR (C macro) 6987@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_OR}@anchor{ad} 6988@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_OR 6989 6990Bitwise inclusive OR; analogous to: 6991 6992@example 6993(EXPR_A) | (EXPR_B) 6994@end example 6995 6996@noindent 6997 6998in C. 6999@end deffn 7000 7001@geindex GCC_JIT_BINARY_OP_LOGICAL_AND (C macro) 7002@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_AND}@anchor{ae} 7003@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_AND 7004 7005Logical AND; analogous to: 7006 7007@example 7008(EXPR_A) && (EXPR_B) 7009@end example 7010 7011@noindent 7012 7013in C. 7014@end deffn 7015 7016@geindex GCC_JIT_BINARY_OP_LOGICAL_OR (C macro) 7017@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_OR}@anchor{af} 7018@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_OR 7019 7020Logical OR; analogous to: 7021 7022@example 7023(EXPR_A) || (EXPR_B) 7024@end example 7025 7026@noindent 7027 7028in C. 7029@end deffn 7030 7031@geindex GCC_JIT_BINARY_OP_LSHIFT (C macro) 7032@anchor{topics/expressions GCC_JIT_BINARY_OP_LSHIFT}@anchor{b0} 7033@deffn {C Macro} GCC_JIT_BINARY_OP_LSHIFT 7034 7035Left shift; analogous to: 7036 7037@example 7038(EXPR_A) << (EXPR_B) 7039@end example 7040 7041@noindent 7042 7043in C. 7044@end deffn 7045 7046@geindex GCC_JIT_BINARY_OP_RSHIFT (C macro) 7047@anchor{topics/expressions GCC_JIT_BINARY_OP_RSHIFT}@anchor{b1} 7048@deffn {C Macro} GCC_JIT_BINARY_OP_RSHIFT 7049 7050Right shift; analogous to: 7051 7052@example 7053(EXPR_A) >> (EXPR_B) 7054@end example 7055 7056@noindent 7057 7058in C. 7059@end deffn 7060 7061@node Comparisons,Function calls,Binary Operations,Rvalues 7062@anchor{topics/expressions comparisons}@anchor{b3} 7063@subsubsection Comparisons 7064 7065 7066@geindex gcc_jit_context_new_comparison (C function) 7067@anchor{topics/expressions gcc_jit_context_new_comparison}@anchor{2c} 7068@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) 7069 7070Build a boolean rvalue out of the comparison of two other rvalues. 7071@end deffn 7072 7073@geindex gcc_jit_comparison (C type) 7074@anchor{topics/expressions gcc_jit_comparison}@anchor{b4} 7075@deffn {C Type} enum gcc_jit_comparison 7076@end deffn 7077 7078 7079@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 7080@headitem 7081 7082Comparison 7083 7084@tab 7085 7086C equivalent 7087 7088@item 7089 7090@code{GCC_JIT_COMPARISON_EQ} 7091 7092@tab 7093 7094@cite{x == y} 7095 7096@item 7097 7098@code{GCC_JIT_COMPARISON_NE} 7099 7100@tab 7101 7102@cite{x != y} 7103 7104@item 7105 7106@code{GCC_JIT_COMPARISON_LT} 7107 7108@tab 7109 7110@cite{x < y} 7111 7112@item 7113 7114@code{GCC_JIT_COMPARISON_LE} 7115 7116@tab 7117 7118@cite{x <= y} 7119 7120@item 7121 7122@code{GCC_JIT_COMPARISON_GT} 7123 7124@tab 7125 7126@cite{x > y} 7127 7128@item 7129 7130@code{GCC_JIT_COMPARISON_GE} 7131 7132@tab 7133 7134@cite{x >= y} 7135 7136@end multitable 7137 7138 7139@node Function calls,Function pointers,Comparisons,Rvalues 7140@anchor{topics/expressions function-calls}@anchor{b5} 7141@subsubsection Function calls 7142 7143 7144@geindex gcc_jit_context_new_call (C function) 7145@anchor{topics/expressions gcc_jit_context_new_call}@anchor{b6} 7146@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) 7147 7148Given a function and the given table of argument rvalues, construct a 7149call to the function, with the result as an rvalue. 7150 7151@cartouche 7152@quotation Note 7153@pxref{b6,,gcc_jit_context_new_call()} merely builds a 7154@pxref{13,,gcc_jit_rvalue} i.e. an expression that can be evaluated, 7155perhaps as part of a more complicated expression. 7156The call @emph{won't} happen unless you add a statement to a function 7157that evaluates the expression. 7158 7159For example, if you want to call a function and discard the result 7160(or to call a function with @code{void} return type), use 7161@pxref{b7,,gcc_jit_block_add_eval()}: 7162 7163@example 7164/* Add "(void)printf (arg0, arg1);". */ 7165gcc_jit_block_add_eval ( 7166 block, NULL, 7167 gcc_jit_context_new_call ( 7168 ctxt, 7169 NULL, 7170 printf_func, 7171 2, args)); 7172@end example 7173 7174@noindent 7175@end quotation 7176@end cartouche 7177@end deffn 7178 7179@geindex gcc_jit_context_new_call_through_ptr (C function) 7180@anchor{topics/expressions gcc_jit_context_new_call_through_ptr}@anchor{b8} 7181@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) 7182 7183Given an rvalue of function pointer type (e.g. from 7184@pxref{91,,gcc_jit_context_new_function_ptr_type()}), and the given table of 7185argument rvalues, construct a call to the function pointer, with the 7186result as an rvalue. 7187 7188@cartouche 7189@quotation Note 7190The same caveat as for @pxref{b6,,gcc_jit_context_new_call()} applies. 7191@end quotation 7192@end cartouche 7193@end deffn 7194 7195@geindex gcc_jit_rvalue_set_bool_require_tail_call (C function) 7196@anchor{topics/expressions gcc_jit_rvalue_set_bool_require_tail_call}@anchor{b9} 7197@deffn {C Function} void gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue@w{ }*call, int@w{ }require_tail_call) 7198 7199Given an @pxref{13,,gcc_jit_rvalue *} for a call created through 7200@pxref{b6,,gcc_jit_context_new_call()} or 7201@pxref{b8,,gcc_jit_context_new_call_through_ptr()}, mark/clear the 7202call as needing tail-call optimization. The optimizer will 7203attempt to optimize the call into a jump instruction; if it is 7204unable to do do, an error will be emitted. 7205 7206This may be useful when implementing functions that use the 7207continuation-passing style (e.g. for functional programming 7208languages), in which every function "returns" by calling a 7209"continuation" function pointer. This call must be 7210guaranteed to be implemented as a jump, otherwise the program 7211could consume an arbitrary amount of stack space as it executed. 7212 7213This entrypoint was added in @pxref{ba,,LIBGCCJIT_ABI_6}; you can test for 7214its presence using 7215 7216@example 7217#ifdef LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call 7218@end example 7219 7220@noindent 7221@end deffn 7222 7223@node Function pointers,Type-coercion,Function calls,Rvalues 7224@anchor{topics/expressions function-pointers}@anchor{bb} 7225@subsubsection Function pointers 7226 7227 7228Function pointers can be obtained: 7229 7230@quotation 7231 7232 7233@itemize * 7234 7235@item 7236from a @pxref{29,,gcc_jit_function} using 7237@pxref{bc,,gcc_jit_function_get_address()}, or 7238 7239@item 7240from an existing function using 7241@pxref{98,,gcc_jit_context_new_rvalue_from_ptr()}, 7242using a function pointer type obtained using 7243@pxref{91,,gcc_jit_context_new_function_ptr_type()}. 7244@end itemize 7245@end quotation 7246 7247@node Type-coercion,,Function pointers,Rvalues 7248@anchor{topics/expressions type-coercion}@anchor{bd} 7249@subsubsection Type-coercion 7250 7251 7252@geindex gcc_jit_context_new_cast (C function) 7253@anchor{topics/expressions gcc_jit_context_new_cast}@anchor{be} 7254@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) 7255 7256Given an rvalue of T, construct another rvalue of another type. 7257 7258Currently only a limited set of conversions are possible: 7259 7260@quotation 7261 7262 7263@itemize * 7264 7265@item 7266int <-> float 7267 7268@item 7269int <-> bool 7270 7271@item 7272P* <-> Q*, for pointer types P and Q 7273@end itemize 7274@end quotation 7275@end deffn 7276 7277@node Lvalues,Working with pointers structs and unions,Rvalues,Expressions 7278@anchor{topics/expressions lvalues}@anchor{bf} 7279@subsection Lvalues 7280 7281 7282@geindex gcc_jit_lvalue (C type) 7283@anchor{topics/expressions gcc_jit_lvalue}@anchor{24} 7284@deffn {C Type} gcc_jit_lvalue 7285@end deffn 7286 7287An lvalue is something that can of the @emph{left}-hand side of an assignment: 7288a storage area (such as a variable). It is also usable as an rvalue, 7289where the rvalue is computed by reading from the storage area. 7290 7291@geindex gcc_jit_lvalue_as_object (C function) 7292@anchor{topics/expressions gcc_jit_lvalue_as_object}@anchor{c0} 7293@deffn {C Function} gcc_jit_object * gcc_jit_lvalue_as_object (gcc_jit_lvalue@w{ }*lvalue) 7294 7295Upcast an lvalue to be an object. 7296@end deffn 7297 7298@geindex gcc_jit_lvalue_as_rvalue (C function) 7299@anchor{topics/expressions gcc_jit_lvalue_as_rvalue}@anchor{c1} 7300@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue@w{ }*lvalue) 7301 7302Upcast an lvalue to be an rvalue. 7303@end deffn 7304 7305@geindex gcc_jit_lvalue_get_address (C function) 7306@anchor{topics/expressions gcc_jit_lvalue_get_address}@anchor{c2} 7307@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_get_address (gcc_jit_lvalue@w{ }*lvalue, gcc_jit_location@w{ }*loc) 7308 7309Take the address of an lvalue; analogous to: 7310 7311@example 7312&(EXPR) 7313@end example 7314 7315@noindent 7316 7317in C. 7318@end deffn 7319 7320@menu 7321* Global variables:: 7322 7323@end menu 7324 7325@node Global variables,,,Lvalues 7326@anchor{topics/expressions global-variables}@anchor{c3} 7327@subsubsection Global variables 7328 7329 7330@geindex gcc_jit_context_new_global (C function) 7331@anchor{topics/expressions gcc_jit_context_new_global}@anchor{c4} 7332@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) 7333 7334Add a new global variable of the given type and name to the context. 7335 7336The parameter @code{name} must be non-NULL. The call takes a copy of the 7337underlying string, so it is valid to pass in a pointer to an on-stack 7338buffer. 7339 7340The "kind" parameter determines the visibility of the "global" outside 7341of the @pxref{16,,gcc_jit_result}: 7342 7343@geindex gcc_jit_global_kind (C type) 7344@anchor{topics/expressions gcc_jit_global_kind}@anchor{c5} 7345@deffn {C Type} enum gcc_jit_global_kind 7346@end deffn 7347 7348@geindex GCC_JIT_GLOBAL_EXPORTED (C macro) 7349@anchor{topics/expressions GCC_JIT_GLOBAL_EXPORTED}@anchor{c6} 7350@deffn {C Macro} GCC_JIT_GLOBAL_EXPORTED 7351 7352Global is defined by the client code and is visible 7353by name outside of this JIT context via 7354@pxref{c7,,gcc_jit_result_get_global()} (and this value is required for 7355the global to be accessible via that entrypoint). 7356@end deffn 7357 7358@geindex GCC_JIT_GLOBAL_INTERNAL (C macro) 7359@anchor{topics/expressions GCC_JIT_GLOBAL_INTERNAL}@anchor{c8} 7360@deffn {C Macro} GCC_JIT_GLOBAL_INTERNAL 7361 7362Global is defined by the client code, but is invisible 7363outside of it. Analogous to a "static" global within a .c file. 7364Specifically, the variable will only be visible within this 7365context and within child contexts. 7366@end deffn 7367 7368@geindex GCC_JIT_GLOBAL_IMPORTED (C macro) 7369@anchor{topics/expressions GCC_JIT_GLOBAL_IMPORTED}@anchor{c9} 7370@deffn {C Macro} GCC_JIT_GLOBAL_IMPORTED 7371 7372Global is not defined by the client code; we're merely 7373referring to it. Analogous to using an "extern" global from a 7374header file. 7375@end deffn 7376@end deffn 7377 7378@node Working with pointers structs and unions,,Lvalues,Expressions 7379@anchor{topics/expressions working-with-pointers-structs-and-unions}@anchor{ca} 7380@subsection Working with pointers, structs and unions 7381 7382 7383@geindex gcc_jit_rvalue_dereference (C function) 7384@anchor{topics/expressions gcc_jit_rvalue_dereference}@anchor{cb} 7385@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference (gcc_jit_rvalue@w{ }*rvalue, gcc_jit_location@w{ }*loc) 7386 7387Given an rvalue of pointer type @code{T *}, dereferencing the pointer, 7388getting an lvalue of type @code{T}. Analogous to: 7389 7390@example 7391*(EXPR) 7392@end example 7393 7394@noindent 7395 7396in C. 7397@end deffn 7398 7399Field access is provided separately for both lvalues and rvalues. 7400 7401@geindex gcc_jit_lvalue_access_field (C function) 7402@anchor{topics/expressions gcc_jit_lvalue_access_field}@anchor{cc} 7403@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) 7404 7405Given an lvalue of struct or union type, access the given field, 7406getting an lvalue of the field's type. Analogous to: 7407 7408@example 7409(EXPR).field = ...; 7410@end example 7411 7412@noindent 7413 7414in C. 7415@end deffn 7416 7417@geindex gcc_jit_rvalue_access_field (C function) 7418@anchor{topics/expressions gcc_jit_rvalue_access_field}@anchor{cd} 7419@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) 7420 7421Given an rvalue of struct or union type, access the given field 7422as an rvalue. Analogous to: 7423 7424@example 7425(EXPR).field 7426@end example 7427 7428@noindent 7429 7430in C. 7431@end deffn 7432 7433@geindex gcc_jit_rvalue_dereference_field (C function) 7434@anchor{topics/expressions gcc_jit_rvalue_dereference_field}@anchor{ce} 7435@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) 7436 7437Given an rvalue of pointer type @code{T *} where T is of struct or union 7438type, access the given field as an lvalue. Analogous to: 7439 7440@example 7441(EXPR)->field 7442@end example 7443 7444@noindent 7445 7446in C, itself equivalent to @code{(*EXPR).FIELD}. 7447@end deffn 7448 7449@geindex gcc_jit_context_new_array_access (C function) 7450@anchor{topics/expressions gcc_jit_context_new_array_access}@anchor{b2} 7451@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) 7452 7453Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at 7454the given index, using standard C array indexing rules i.e. each 7455increment of @code{index} corresponds to @code{sizeof(T)} bytes. 7456Analogous to: 7457 7458@example 7459PTR[INDEX] 7460@end example 7461 7462@noindent 7463 7464in C (or, indeed, to @code{PTR + INDEX}). 7465@end deffn 7466 7467@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 7468@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7469@c 7470@c This is free software: you can redistribute it and/or modify it 7471@c under the terms of the GNU General Public License as published by 7472@c the Free Software Foundation, either version 3 of the License, or 7473@c (at your option) any later version. 7474@c 7475@c This program is distributed in the hope that it will be useful, but 7476@c WITHOUT ANY WARRANTY; without even the implied warranty of 7477@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7478@c General Public License for more details. 7479@c 7480@c You should have received a copy of the GNU General Public License 7481@c along with this program. If not, see 7482@c <http://www.gnu.org/licenses/>. 7483 7484@node Creating and using functions,Function pointers<2>,Expressions,Topic Reference 7485@anchor{topics/functions doc}@anchor{cf}@anchor{topics/functions creating-and-using-functions}@anchor{d0} 7486@section Creating and using functions 7487 7488 7489@menu 7490* Params:: 7491* Functions:: 7492* Blocks:: 7493* Statements:: 7494 7495@end menu 7496 7497@node Params,Functions,,Creating and using functions 7498@anchor{topics/functions params}@anchor{d1} 7499@subsection Params 7500 7501 7502@geindex gcc_jit_param (C type) 7503@anchor{topics/functions gcc_jit_param}@anchor{25} 7504@deffn {C Type} gcc_jit_param 7505 7506A @cite{gcc_jit_param} represents a parameter to a function. 7507@end deffn 7508 7509@geindex gcc_jit_context_new_param (C function) 7510@anchor{topics/functions gcc_jit_context_new_param}@anchor{10} 7511@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) 7512 7513In preparation for creating a function, create a new parameter of the 7514given type and name. 7515 7516The parameter @code{name} must be non-NULL. The call takes a copy of the 7517underlying string, so it is valid to pass in a pointer to an on-stack 7518buffer. 7519@end deffn 7520 7521Parameters are lvalues, and thus are also rvalues (and objects), so the 7522following upcasts are available: 7523 7524@geindex gcc_jit_param_as_lvalue (C function) 7525@anchor{topics/functions gcc_jit_param_as_lvalue}@anchor{d2} 7526@deffn {C Function} gcc_jit_lvalue * gcc_jit_param_as_lvalue (gcc_jit_param@w{ }*param) 7527 7528Upcasting from param to lvalue. 7529@end deffn 7530 7531@geindex gcc_jit_param_as_rvalue (C function) 7532@anchor{topics/functions gcc_jit_param_as_rvalue}@anchor{d3} 7533@deffn {C Function} gcc_jit_rvalue * gcc_jit_param_as_rvalue (gcc_jit_param@w{ }*param) 7534 7535Upcasting from param to rvalue. 7536@end deffn 7537 7538@geindex gcc_jit_param_as_object (C function) 7539@anchor{topics/functions gcc_jit_param_as_object}@anchor{d4} 7540@deffn {C Function} gcc_jit_object * gcc_jit_param_as_object (gcc_jit_param@w{ }*param) 7541 7542Upcasting from param to object. 7543@end deffn 7544 7545@node Functions,Blocks,Params,Creating and using functions 7546@anchor{topics/functions functions}@anchor{d5} 7547@subsection Functions 7548 7549 7550@geindex gcc_jit_function (C type) 7551@anchor{topics/functions gcc_jit_function}@anchor{29} 7552@deffn {C Type} gcc_jit_function 7553 7554A @cite{gcc_jit_function} represents a function - either one that we're 7555creating ourselves, or one that we're referencing. 7556@end deffn 7557 7558@geindex gcc_jit_context_new_function (C function) 7559@anchor{topics/functions gcc_jit_context_new_function}@anchor{11} 7560@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) 7561 7562Create a gcc_jit_function with the given name and parameters. 7563 7564@geindex gcc_jit_function_kind (C type) 7565@anchor{topics/functions gcc_jit_function_kind}@anchor{d6} 7566@deffn {C Type} enum gcc_jit_function_kind 7567@end deffn 7568 7569This enum controls the kind of function created, and has the following 7570values: 7571 7572@quotation 7573 7574@geindex GCC_JIT_FUNCTION_EXPORTED (C macro) 7575@anchor{topics/functions GCC_JIT_FUNCTION_EXPORTED}@anchor{d7} 7576@deffn {C Macro} GCC_JIT_FUNCTION_EXPORTED 7577 7578Function is defined by the client code and visible 7579by name outside of the JIT. 7580 7581This value is required if you want to extract machine code 7582for this function from a @pxref{16,,gcc_jit_result} via 7583@pxref{17,,gcc_jit_result_get_code()}. 7584@end deffn 7585 7586@geindex GCC_JIT_FUNCTION_INTERNAL (C macro) 7587@anchor{topics/functions GCC_JIT_FUNCTION_INTERNAL}@anchor{d8} 7588@deffn {C Macro} GCC_JIT_FUNCTION_INTERNAL 7589 7590Function is defined by the client code, but is invisible 7591outside of the JIT. Analogous to a "static" function. 7592@end deffn 7593 7594@geindex GCC_JIT_FUNCTION_IMPORTED (C macro) 7595@anchor{topics/functions GCC_JIT_FUNCTION_IMPORTED}@anchor{d9} 7596@deffn {C Macro} GCC_JIT_FUNCTION_IMPORTED 7597 7598Function is not defined by the client code; we're merely 7599referring to it. Analogous to using an "extern" function from a 7600header file. 7601@end deffn 7602 7603@geindex GCC_JIT_FUNCTION_ALWAYS_INLINE (C macro) 7604@anchor{topics/functions GCC_JIT_FUNCTION_ALWAYS_INLINE}@anchor{da} 7605@deffn {C Macro} GCC_JIT_FUNCTION_ALWAYS_INLINE 7606 7607Function is only ever inlined into other functions, and is 7608invisible outside of the JIT. 7609 7610Analogous to prefixing with @code{inline} and adding 7611@code{__attribute__((always_inline))} 7612 7613Inlining will only occur when the optimization level is 7614above 0; when optimization is off, this is essentially the 7615same as GCC_JIT_FUNCTION_INTERNAL. 7616@end deffn 7617@end quotation 7618 7619The parameter @code{name} must be non-NULL. The call takes a copy of the 7620underlying string, so it is valid to pass in a pointer to an on-stack 7621buffer. 7622@end deffn 7623 7624@geindex gcc_jit_context_get_builtin_function (C function) 7625@anchor{topics/functions gcc_jit_context_get_builtin_function}@anchor{db} 7626@deffn {C Function} gcc_jit_function *gcc_jit_context_get_builtin_function (gcc_jit_context@w{ }*ctxt, const char@w{ }*name) 7627@end deffn 7628 7629@geindex gcc_jit_function_as_object (C function) 7630@anchor{topics/functions gcc_jit_function_as_object}@anchor{dc} 7631@deffn {C Function} gcc_jit_object * gcc_jit_function_as_object (gcc_jit_function@w{ }*func) 7632 7633Upcasting from function to object. 7634@end deffn 7635 7636@geindex gcc_jit_function_get_param (C function) 7637@anchor{topics/functions gcc_jit_function_get_param}@anchor{dd} 7638@deffn {C Function} gcc_jit_param * gcc_jit_function_get_param (gcc_jit_function@w{ }*func, int@w{ }index) 7639 7640Get the param of the given index (0-based). 7641@end deffn 7642 7643@geindex gcc_jit_function_dump_to_dot (C function) 7644@anchor{topics/functions gcc_jit_function_dump_to_dot}@anchor{33} 7645@deffn {C Function} void gcc_jit_function_dump_to_dot (gcc_jit_function@w{ }*func, const char@w{ }*path) 7646 7647Emit the function in graphviz format to the given path. 7648@end deffn 7649 7650@geindex gcc_jit_function_new_local (C function) 7651@anchor{topics/functions gcc_jit_function_new_local}@anchor{26} 7652@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) 7653 7654Create a new local variable within the function, of the given type and 7655name. 7656 7657The parameter @code{name} must be non-NULL. The call takes a copy of the 7658underlying string, so it is valid to pass in a pointer to an on-stack 7659buffer. 7660@end deffn 7661 7662@node Blocks,Statements,Functions,Creating and using functions 7663@anchor{topics/functions blocks}@anchor{de} 7664@subsection Blocks 7665 7666 7667@geindex gcc_jit_block (C type) 7668@anchor{topics/functions gcc_jit_block}@anchor{28} 7669@deffn {C Type} gcc_jit_block 7670 7671A @cite{gcc_jit_block} represents a basic block within a function i.e. a 7672sequence of statements with a single entry point and a single exit 7673point. 7674 7675The first basic block that you create within a function will 7676be the entrypoint. 7677 7678Each basic block that you create within a function must be 7679terminated, either with a conditional, a jump, a return, or a 7680switch. 7681 7682It's legal to have multiple basic blocks that return within 7683one function. 7684@end deffn 7685 7686@geindex gcc_jit_function_new_block (C function) 7687@anchor{topics/functions gcc_jit_function_new_block}@anchor{df} 7688@deffn {C Function} gcc_jit_block * gcc_jit_function_new_block (gcc_jit_function@w{ }*func, const char@w{ }*name) 7689 7690Create a basic block of the given name. The name may be NULL, but 7691providing meaningful names is often helpful when debugging: it may 7692show up in dumps of the internal representation, and in error 7693messages. It is copied, so the input buffer does not need to outlive 7694the call; you can pass in a pointer to an on-stack buffer, e.g.: 7695 7696@example 7697for (pc = 0; pc < fn->fn_num_ops; pc++) 7698 @{ 7699 char buf[16]; 7700 sprintf (buf, "instr%i", pc); 7701 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); 7702 @} 7703@end example 7704 7705@noindent 7706@end deffn 7707 7708@geindex gcc_jit_block_as_object (C function) 7709@anchor{topics/functions gcc_jit_block_as_object}@anchor{e0} 7710@deffn {C Function} gcc_jit_object * gcc_jit_block_as_object (gcc_jit_block@w{ }*block) 7711 7712Upcast from block to object. 7713@end deffn 7714 7715@geindex gcc_jit_block_get_function (C function) 7716@anchor{topics/functions gcc_jit_block_get_function}@anchor{e1} 7717@deffn {C Function} gcc_jit_function * gcc_jit_block_get_function (gcc_jit_block@w{ }*block) 7718 7719Which function is this block within? 7720@end deffn 7721 7722@node Statements,,Blocks,Creating and using functions 7723@anchor{topics/functions statements}@anchor{e2} 7724@subsection Statements 7725 7726 7727@geindex gcc_jit_block_add_eval (C function) 7728@anchor{topics/functions gcc_jit_block_add_eval}@anchor{b7} 7729@deffn {C Function} void gcc_jit_block_add_eval (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue) 7730 7731Add evaluation of an rvalue, discarding the result 7732(e.g. a function call that "returns" void). 7733 7734This is equivalent to this C code: 7735 7736@example 7737(void)expression; 7738@end example 7739 7740@noindent 7741@end deffn 7742 7743@geindex gcc_jit_block_add_assignment (C function) 7744@anchor{topics/functions gcc_jit_block_add_assignment}@anchor{2a} 7745@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) 7746 7747Add evaluation of an rvalue, assigning the result to the given 7748lvalue. 7749 7750This is roughly equivalent to this C code: 7751 7752@example 7753lvalue = rvalue; 7754@end example 7755 7756@noindent 7757@end deffn 7758 7759@geindex gcc_jit_block_add_assignment_op (C function) 7760@anchor{topics/functions gcc_jit_block_add_assignment_op}@anchor{2e} 7761@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) 7762 7763Add evaluation of an rvalue, using the result to modify an 7764lvalue. 7765 7766This is analogous to "+=" and friends: 7767 7768@example 7769lvalue += rvalue; 7770lvalue *= rvalue; 7771lvalue /= rvalue; 7772@end example 7773 7774@noindent 7775 7776etc. For example: 7777 7778@example 7779/* "i++" */ 7780gcc_jit_block_add_assignment_op ( 7781 loop_body, NULL, 7782 i, 7783 GCC_JIT_BINARY_OP_PLUS, 7784 gcc_jit_context_one (ctxt, int_type)); 7785@end example 7786 7787@noindent 7788@end deffn 7789 7790@geindex gcc_jit_block_add_comment (C function) 7791@anchor{topics/functions gcc_jit_block_add_comment}@anchor{3d} 7792@deffn {C Function} void gcc_jit_block_add_comment (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*text) 7793 7794Add a no-op textual comment to the internal representation of the 7795code. It will be optimized away, but will be visible in the dumps 7796seen via @pxref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} 7797and @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, 7798and thus may be of use when debugging how your project's internal 7799representation gets converted to the libgccjit IR. 7800 7801The parameter @code{text} must be non-NULL. It is copied, so the input 7802buffer does not need to outlive the call. For example: 7803 7804@example 7805char buf[100]; 7806snprintf (buf, sizeof (buf), 7807 "op%i: %s", 7808 pc, opcode_names[op->op_opcode]); 7809gcc_jit_block_add_comment (block, loc, buf); 7810@end example 7811 7812@noindent 7813@end deffn 7814 7815@geindex gcc_jit_block_end_with_conditional (C function) 7816@anchor{topics/functions gcc_jit_block_end_with_conditional}@anchor{2d} 7817@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) 7818 7819Terminate a block by adding evaluation of an rvalue, branching on the 7820result to the appropriate successor block. 7821 7822This is roughly equivalent to this C code: 7823 7824@example 7825if (boolval) 7826 goto on_true; 7827else 7828 goto on_false; 7829@end example 7830 7831@noindent 7832 7833block, boolval, on_true, and on_false must be non-NULL. 7834@end deffn 7835 7836@geindex gcc_jit_block_end_with_jump (C function) 7837@anchor{topics/functions gcc_jit_block_end_with_jump}@anchor{e3} 7838@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) 7839 7840Terminate a block by adding a jump to the given target block. 7841 7842This is roughly equivalent to this C code: 7843 7844@example 7845goto target; 7846@end example 7847 7848@noindent 7849@end deffn 7850 7851@geindex gcc_jit_block_end_with_return (C function) 7852@anchor{topics/functions gcc_jit_block_end_with_return}@anchor{e4} 7853@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) 7854 7855Terminate a block by adding evaluation of an rvalue, returning the value. 7856 7857This is roughly equivalent to this C code: 7858 7859@example 7860return expression; 7861@end example 7862 7863@noindent 7864@end deffn 7865 7866@geindex gcc_jit_block_end_with_void_return (C function) 7867@anchor{topics/functions gcc_jit_block_end_with_void_return}@anchor{e5} 7868@deffn {C Function} void gcc_jit_block_end_with_void_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc) 7869 7870Terminate a block by adding a valueless return, for use within a function 7871with "void" return type. 7872 7873This is equivalent to this C code: 7874 7875@example 7876return; 7877@end example 7878 7879@noindent 7880@end deffn 7881 7882@geindex gcc_jit_block_end_with_switch (C function) 7883@anchor{topics/functions gcc_jit_block_end_with_switch}@anchor{e6} 7884@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) 7885 7886Terminate a block by adding evalation of an rvalue, then performing 7887a multiway branch. 7888 7889This is roughly equivalent to this C code: 7890 7891@example 7892switch (expr) 7893 @{ 7894 default: 7895 goto default_block; 7896 7897 case C0.min_value ... C0.max_value: 7898 goto C0.dest_block; 7899 7900 case C1.min_value ... C1.max_value: 7901 goto C1.dest_block; 7902 7903 ...etc... 7904 7905 case C[N - 1].min_value ... C[N - 1].max_value: 7906 goto C[N - 1].dest_block; 7907@} 7908@end example 7909 7910@noindent 7911 7912@code{block}, @code{expr}, @code{default_block} and @code{cases} must all be 7913non-NULL. 7914 7915@code{expr} must be of the same integer type as all of the @code{min_value} 7916and @code{max_value} within the cases. 7917 7918@code{num_cases} must be >= 0. 7919 7920The ranges of the cases must not overlap (or have duplicate 7921values). 7922 7923The API entrypoints relating to switch statements and cases: 7924 7925@quotation 7926 7927 7928@itemize * 7929 7930@item 7931@pxref{e6,,gcc_jit_block_end_with_switch()} 7932 7933@item 7934@pxref{e7,,gcc_jit_case_as_object()} 7935 7936@item 7937@pxref{e8,,gcc_jit_context_new_case()} 7938@end itemize 7939@end quotation 7940 7941were added in @pxref{e9,,LIBGCCJIT_ABI_3}; you can test for their presence 7942using 7943 7944@example 7945#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 7946@end example 7947 7948@noindent 7949 7950@geindex gcc_jit_case (C type) 7951@anchor{topics/functions gcc_jit_case}@anchor{ea} 7952@deffn {C Type} gcc_jit_case 7953@end deffn 7954 7955A @cite{gcc_jit_case} represents a case within a switch statement, and 7956is created within a particular @pxref{8,,gcc_jit_context} using 7957@pxref{e8,,gcc_jit_context_new_case()}. 7958 7959Each case expresses a multivalued range of integer values. You 7960can express single-valued cases by passing in the same value for 7961both @cite{min_value} and @cite{max_value}. 7962 7963@geindex gcc_jit_context_new_case (C function) 7964@anchor{topics/functions gcc_jit_context_new_case}@anchor{e8} 7965@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) 7966 7967Create a new gcc_jit_case instance for use in a switch statement. 7968@cite{min_value} and @cite{max_value} must be constants of an integer type, 7969which must match that of the expression of the switch statement. 7970 7971@cite{dest_block} must be within the same function as the switch 7972statement. 7973@end deffn 7974 7975@geindex gcc_jit_case_as_object (C function) 7976@anchor{topics/functions gcc_jit_case_as_object}@anchor{e7} 7977@deffn {C Function} gcc_jit_object * gcc_jit_case_as_object (gcc_jit_case@w{ }*case_) 7978 7979Upcast from a case to an object. 7980@end deffn 7981 7982Here's an example of creating a switch statement: 7983 7984@quotation 7985 7986@example 7987 7988void 7989create_code (gcc_jit_context *ctxt, void *user_data) 7990@{ 7991 /* Let's try to inject the equivalent of: 7992 int 7993 test_switch (int x) 7994 @{ 7995 switch (x) 7996 @{ 7997 case 0 ... 5: 7998 return 3; 7999 8000 case 25 ... 27: 8001 return 4; 8002 8003 case -42 ... -17: 8004 return 83; 8005 8006 case 40: 8007 return 8; 8008 8009 default: 8010 return 10; 8011 @} 8012 @} 8013 */ 8014 gcc_jit_type *t_int = 8015 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 8016 gcc_jit_type *return_type = t_int; 8017 gcc_jit_param *x = 8018 gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); 8019 gcc_jit_param *params[1] = @{x@}; 8020 gcc_jit_function *func = 8021 gcc_jit_context_new_function (ctxt, NULL, 8022 GCC_JIT_FUNCTION_EXPORTED, 8023 return_type, 8024 "test_switch", 8025 1, params, 0); 8026 8027 gcc_jit_block *b_initial = 8028 gcc_jit_function_new_block (func, "initial"); 8029 8030 gcc_jit_block *b_default = 8031 gcc_jit_function_new_block (func, "default"); 8032 gcc_jit_block *b_case_0_5 = 8033 gcc_jit_function_new_block (func, "case_0_5"); 8034 gcc_jit_block *b_case_25_27 = 8035 gcc_jit_function_new_block (func, "case_25_27"); 8036 gcc_jit_block *b_case_m42_m17 = 8037 gcc_jit_function_new_block (func, "case_m42_m17"); 8038 gcc_jit_block *b_case_40 = 8039 gcc_jit_function_new_block (func, "case_40"); 8040 8041 gcc_jit_case *cases[4] = @{ 8042 gcc_jit_context_new_case ( 8043 ctxt, 8044 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0), 8045 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5), 8046 b_case_0_5), 8047 gcc_jit_context_new_case ( 8048 ctxt, 8049 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 25), 8050 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 27), 8051 b_case_25_27), 8052 gcc_jit_context_new_case ( 8053 ctxt, 8054 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -42), 8055 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -17), 8056 b_case_m42_m17), 8057 gcc_jit_context_new_case ( 8058 ctxt, 8059 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), 8060 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), 8061 b_case_40) 8062 @}; 8063 gcc_jit_block_end_with_switch ( 8064 b_initial, NULL, 8065 gcc_jit_param_as_rvalue (x), 8066 b_default, 8067 4, cases); 8068 8069 gcc_jit_block_end_with_return ( 8070 b_case_0_5, NULL, 8071 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); 8072 gcc_jit_block_end_with_return ( 8073 b_case_25_27, NULL, 8074 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4)); 8075 gcc_jit_block_end_with_return ( 8076 b_case_m42_m17, NULL, 8077 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 83)); 8078 gcc_jit_block_end_with_return ( 8079 b_case_40, NULL, 8080 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 8)); 8081 gcc_jit_block_end_with_return ( 8082 b_default, NULL, 8083 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); 8084@} 8085 8086 8087@end example 8088 8089@noindent 8090@end quotation 8091@end deffn 8092 8093@c Copyright (C) 2017-2018 Free Software Foundation, Inc. 8094@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8095@c 8096@c This is free software: you can redistribute it and/or modify it 8097@c under the terms of the GNU General Public License as published by 8098@c the Free Software Foundation, either version 3 of the License, or 8099@c (at your option) any later version. 8100@c 8101@c This program is distributed in the hope that it will be useful, but 8102@c WITHOUT ANY WARRANTY; without even the implied warranty of 8103@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8104@c General Public License for more details. 8105@c 8106@c You should have received a copy of the GNU General Public License 8107@c along with this program. If not, see 8108@c <http://www.gnu.org/licenses/>. 8109 8110@node Function pointers<2>,Source Locations,Creating and using functions,Topic Reference 8111@anchor{topics/function-pointers doc}@anchor{eb}@anchor{topics/function-pointers function-pointers}@anchor{ec} 8112@section Function pointers 8113 8114 8115You can generate calls that use a function pointer via 8116@pxref{b8,,gcc_jit_context_new_call_through_ptr()}. 8117 8118To do requires a @pxref{13,,gcc_jit_rvalue} of the correct function pointer type. 8119 8120Function pointers for a @pxref{29,,gcc_jit_function} can be obtained 8121via @pxref{bc,,gcc_jit_function_get_address()}. 8122 8123@geindex gcc_jit_function_get_address (C function) 8124@anchor{topics/function-pointers gcc_jit_function_get_address}@anchor{bc} 8125@deffn {C Function} gcc_jit_rvalue * gcc_jit_function_get_address (gcc_jit_function@w{ }*fn, gcc_jit_location@w{ }*loc) 8126 8127Get the address of a function as an rvalue, of function pointer 8128type. 8129 8130This entrypoint was added in @pxref{ed,,LIBGCCJIT_ABI_9}; you can test 8131for its presence using 8132 8133@example 8134#ifdef LIBGCCJIT_HAVE_gcc_jit_function_get_address 8135@end example 8136 8137@noindent 8138@end deffn 8139 8140Alternatively, given an existing function, you can obtain a pointer 8141to it in @pxref{13,,gcc_jit_rvalue} form using 8142@pxref{98,,gcc_jit_context_new_rvalue_from_ptr()}, using a function pointer 8143type obtained using @pxref{91,,gcc_jit_context_new_function_ptr_type()}. 8144 8145Here's an example of creating a function pointer type corresponding to C's 8146@code{void (*) (int, int, int)}: 8147 8148@example 8149gcc_jit_type *void_type = 8150 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); 8151gcc_jit_type *int_type = 8152 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 8153 8154/* Build the function ptr type. */ 8155gcc_jit_type *param_types[3]; 8156param_types[0] = int_type; 8157param_types[1] = int_type; 8158param_types[2] = int_type; 8159 8160gcc_jit_type *fn_ptr_type = 8161 gcc_jit_context_new_function_ptr_type (ctxt, NULL, 8162 void_type, 8163 3, param_types, 0); 8164@end example 8165 8166@noindent 8167 8168@geindex gcc_jit_context_new_function_ptr_type (C function) 8169@anchor{topics/function-pointers gcc_jit_context_new_function_ptr_type}@anchor{91} 8170@deffn {C Function} gcc_jit_type * gcc_jit_context_new_function_ptr_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*return_type, int@w{ }num_params, gcc_jit_type@w{ }**param_types, int@w{ }is_variadic) 8171 8172Generate a @pxref{a,,gcc_jit_type} for a function pointer with the 8173given return type and parameters. 8174@end deffn 8175 8176@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 8177@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8178@c 8179@c This is free software: you can redistribute it and/or modify it 8180@c under the terms of the GNU General Public License as published by 8181@c the Free Software Foundation, either version 3 of the License, or 8182@c (at your option) any later version. 8183@c 8184@c This program is distributed in the hope that it will be useful, but 8185@c WITHOUT ANY WARRANTY; without even the implied warranty of 8186@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8187@c General Public License for more details. 8188@c 8189@c You should have received a copy of the GNU General Public License 8190@c along with this program. If not, see 8191@c <http://www.gnu.org/licenses/>. 8192 8193@node Source Locations,Compiling a context,Function pointers<2>,Topic Reference 8194@anchor{topics/locations source-locations}@anchor{ee}@anchor{topics/locations doc}@anchor{ef} 8195@section Source Locations 8196 8197 8198@geindex gcc_jit_location (C type) 8199@anchor{topics/locations gcc_jit_location}@anchor{3b} 8200@deffn {C Type} gcc_jit_location 8201 8202A @cite{gcc_jit_location} encapsulates a source code location, so that 8203you can (optionally) associate locations in your language with 8204statements in the JIT-compiled code, allowing the debugger to 8205single-step through your language. 8206 8207@cite{gcc_jit_location} instances are optional: you can always pass NULL to 8208any API entrypoint accepting one. 8209 8210You can construct them using @pxref{41,,gcc_jit_context_new_location()}. 8211 8212You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 8213@pxref{8,,gcc_jit_context} for these locations to actually be usable by 8214the debugger: 8215 8216@example 8217gcc_jit_context_set_bool_option ( 8218 ctxt, 8219 GCC_JIT_BOOL_OPTION_DEBUGINFO, 8220 1); 8221@end example 8222 8223@noindent 8224@end deffn 8225 8226@geindex gcc_jit_context_new_location (C function) 8227@anchor{topics/locations gcc_jit_context_new_location}@anchor{41} 8228@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) 8229 8230Create a @cite{gcc_jit_location} instance representing the given source 8231location. 8232 8233The parameter @code{filename} must be non-NULL. The call takes a copy of 8234the underlying string, so it is valid to pass in a pointer to an 8235on-stack buffer. 8236@end deffn 8237 8238@menu 8239* Faking it:: 8240 8241@end menu 8242 8243@node Faking it,,,Source Locations 8244@anchor{topics/locations faking-it}@anchor{f0} 8245@subsection Faking it 8246 8247 8248If you don't have source code for your internal representation, but need 8249to debug, you can generate a C-like representation of the functions in 8250your context using @pxref{5a,,gcc_jit_context_dump_to_file()}: 8251 8252@example 8253gcc_jit_context_dump_to_file (ctxt, "/tmp/something.c", 8254 1 /* update_locations */); 8255@end example 8256 8257@noindent 8258 8259This will dump C-like code to the given path. If the @cite{update_locations} 8260argument is true, this will also set up @cite{gcc_jit_location} information 8261throughout the context, pointing at the dump file as if it were a source 8262file, giving you @emph{something} you can step through in the debugger. 8263 8264@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 8265@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8266@c 8267@c This is free software: you can redistribute it and/or modify it 8268@c under the terms of the GNU General Public License as published by 8269@c the Free Software Foundation, either version 3 of the License, or 8270@c (at your option) any later version. 8271@c 8272@c This program is distributed in the hope that it will be useful, but 8273@c WITHOUT ANY WARRANTY; without even the implied warranty of 8274@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8275@c General Public License for more details. 8276@c 8277@c You should have received a copy of the GNU General Public License 8278@c along with this program. If not, see 8279@c <http://www.gnu.org/licenses/>. 8280 8281@node Compiling a context,ABI and API compatibility,Source Locations,Topic Reference 8282@anchor{topics/compilation compiling-a-context}@anchor{f1}@anchor{topics/compilation doc}@anchor{f2} 8283@section Compiling a context 8284 8285 8286Once populated, a @pxref{8,,gcc_jit_context *} can be compiled to 8287machine code, either in-memory via @pxref{15,,gcc_jit_context_compile()} or 8288to disk via @pxref{4a,,gcc_jit_context_compile_to_file()}. 8289 8290You can compile a context multiple times (using either form of 8291compilation), although any errors that occur on the context will 8292prevent any future compilation of that context. 8293 8294@menu 8295* In-memory compilation:: 8296* Ahead-of-time compilation:: 8297 8298@end menu 8299 8300@node In-memory compilation,Ahead-of-time compilation,,Compiling a context 8301@anchor{topics/compilation in-memory-compilation}@anchor{f3} 8302@subsection In-memory compilation 8303 8304 8305@geindex gcc_jit_context_compile (C function) 8306@anchor{topics/compilation gcc_jit_context_compile}@anchor{15} 8307@deffn {C Function} gcc_jit_result * gcc_jit_context_compile (gcc_jit_context@w{ }*ctxt) 8308 8309This calls into GCC and builds the code, returning a 8310@cite{gcc_jit_result *}. 8311 8312If the result is non-NULL, the caller becomes responsible for 8313calling @pxref{39,,gcc_jit_result_release()} on it once they're done 8314with it. 8315@end deffn 8316 8317@geindex gcc_jit_result (C type) 8318@anchor{topics/compilation gcc_jit_result}@anchor{16} 8319@deffn {C Type} gcc_jit_result 8320 8321A @cite{gcc_jit_result} encapsulates the result of compiling a context 8322in-memory, and the lifetimes of any machine code functions or globals 8323that are within the result. 8324@end deffn 8325 8326@geindex gcc_jit_result_get_code (C function) 8327@anchor{topics/compilation gcc_jit_result_get_code}@anchor{17} 8328@deffn {C Function} void * gcc_jit_result_get_code (gcc_jit_result@w{ }*result, const char@w{ }*funcname) 8329 8330Locate a given function within the built machine code. 8331 8332Functions are looked up by name. For this to succeed, a function 8333with a name matching @cite{funcname} must have been created on 8334@cite{result}'s context (or a parent context) via a call to 8335@pxref{11,,gcc_jit_context_new_function()} with @cite{kind} 8336@pxref{d7,,GCC_JIT_FUNCTION_EXPORTED}: 8337 8338@example 8339gcc_jit_context_new_function (ctxt, 8340 any_location, /* or NULL */ 8341 /* Required for func to be visible to 8342 gcc_jit_result_get_code: */ 8343 GCC_JIT_FUNCTION_EXPORTED, 8344 any_return_type, 8345 /* Must string-compare equal: */ 8346 funcname, 8347 /* etc */); 8348@end example 8349 8350@noindent 8351 8352If such a function is not found (or @cite{result} or @cite{funcname} are 8353@code{NULL}), an error message will be emitted on stderr and 8354@code{NULL} will be returned. 8355 8356If the function is found, the result will need to be cast to a 8357function pointer of the correct type before it can be called. 8358 8359Note that the resulting machine code becomes invalid after 8360@pxref{39,,gcc_jit_result_release()} is called on the 8361@pxref{16,,gcc_jit_result *}; attempting to call it after that may lead 8362to a segmentation fault. 8363@end deffn 8364 8365@geindex gcc_jit_result_get_global (C function) 8366@anchor{topics/compilation gcc_jit_result_get_global}@anchor{c7} 8367@deffn {C Function} void * gcc_jit_result_get_global (gcc_jit_result@w{ }*result, const char@w{ }*name) 8368 8369Locate a given global within the built machine code. 8370 8371Globals are looked up by name. For this to succeed, a global 8372with a name matching @cite{name} must have been created on 8373@cite{result}'s context (or a parent context) via a call to 8374@pxref{c4,,gcc_jit_context_new_global()} with @cite{kind} 8375@pxref{c6,,GCC_JIT_GLOBAL_EXPORTED}. 8376 8377If the global is found, the result will need to be cast to a 8378pointer of the correct type before it can be called. 8379 8380This is a @emph{pointer} to the global, so e.g. for an @code{int} this is 8381an @code{int *}. 8382 8383For example, given an @code{int foo;} created this way: 8384 8385@example 8386gcc_jit_lvalue *exported_global = 8387 gcc_jit_context_new_global (ctxt, 8388 any_location, /* or NULL */ 8389 GCC_JIT_GLOBAL_EXPORTED, 8390 int_type, 8391 "foo"); 8392@end example 8393 8394@noindent 8395 8396we can access it like this: 8397 8398@example 8399int *ptr_to_foo = 8400 (int *)gcc_jit_result_get_global (result, "foo"); 8401@end example 8402 8403@noindent 8404 8405If such a global is not found (or @cite{result} or @cite{name} are 8406@code{NULL}), an error message will be emitted on stderr and 8407@code{NULL} will be returned. 8408 8409Note that the resulting address becomes invalid after 8410@pxref{39,,gcc_jit_result_release()} is called on the 8411@pxref{16,,gcc_jit_result *}; attempting to use it after that may lead 8412to a segmentation fault. 8413@end deffn 8414 8415@geindex gcc_jit_result_release (C function) 8416@anchor{topics/compilation gcc_jit_result_release}@anchor{39} 8417@deffn {C Function} void gcc_jit_result_release (gcc_jit_result@w{ }*result) 8418 8419Once we're done with the code, this unloads the built .so file. 8420This cleans up the result; after calling this, it's no longer 8421valid to use the result, or any code or globals that were obtained 8422by calling @pxref{17,,gcc_jit_result_get_code()} or 8423@pxref{c7,,gcc_jit_result_get_global()} on it. 8424@end deffn 8425 8426@node Ahead-of-time compilation,,In-memory compilation,Compiling a context 8427@anchor{topics/compilation ahead-of-time-compilation}@anchor{f4} 8428@subsection Ahead-of-time compilation 8429 8430 8431Although libgccjit is primarily aimed at just-in-time compilation, it 8432can also be used for implementing more traditional ahead-of-time 8433compilers, via the @pxref{4a,,gcc_jit_context_compile_to_file()} 8434API entrypoint. 8435 8436@geindex gcc_jit_context_compile_to_file (C function) 8437@anchor{topics/compilation gcc_jit_context_compile_to_file}@anchor{4a} 8438@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) 8439 8440Compile the @pxref{8,,gcc_jit_context *} to a file of the given 8441kind. 8442@end deffn 8443 8444@pxref{4a,,gcc_jit_context_compile_to_file()} ignores the suffix of 8445@code{output_path}, and insteads uses the given 8446@code{enum gcc_jit_output_kind} to decide what to do. 8447 8448@cartouche 8449@quotation Note 8450This is different from the @code{gcc} program, which does make use of the 8451suffix of the output file when determining what to do. 8452@end quotation 8453@end cartouche 8454 8455@geindex gcc_jit_output_kind (C type) 8456@anchor{topics/compilation gcc_jit_output_kind}@anchor{f5} 8457@deffn {C Type} enum gcc_jit_output_kind 8458@end deffn 8459 8460The available kinds of output are: 8461 8462 8463@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxx} 8464@headitem 8465 8466Output kind 8467 8468@tab 8469 8470Typical suffix 8471 8472@item 8473 8474@pxref{f6,,GCC_JIT_OUTPUT_KIND_ASSEMBLER} 8475 8476@tab 8477 8478.s 8479 8480@item 8481 8482@pxref{f7,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE} 8483 8484@tab 8485 8486.o 8487 8488@item 8489 8490@pxref{f8,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY} 8491 8492@tab 8493 8494.so or .dll 8495 8496@item 8497 8498@pxref{f9,,GCC_JIT_OUTPUT_KIND_EXECUTABLE} 8499 8500@tab 8501 8502None, or .exe 8503 8504@end multitable 8505 8506 8507@geindex GCC_JIT_OUTPUT_KIND_ASSEMBLER (C macro) 8508@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{f6} 8509@deffn {C Macro} GCC_JIT_OUTPUT_KIND_ASSEMBLER 8510 8511Compile the context to an assembler file. 8512@end deffn 8513 8514@geindex GCC_JIT_OUTPUT_KIND_OBJECT_FILE (C macro) 8515@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{f7} 8516@deffn {C Macro} GCC_JIT_OUTPUT_KIND_OBJECT_FILE 8517 8518Compile the context to an object file. 8519@end deffn 8520 8521@geindex GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY (C macro) 8522@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{f8} 8523@deffn {C Macro} GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY 8524 8525Compile the context to a dynamic library. 8526 8527There is currently no support for specifying other libraries to link 8528against. 8529@end deffn 8530 8531@geindex GCC_JIT_OUTPUT_KIND_EXECUTABLE (C macro) 8532@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{f9} 8533@deffn {C Macro} GCC_JIT_OUTPUT_KIND_EXECUTABLE 8534 8535Compile the context to an executable. 8536 8537There is currently no support for specifying libraries to link 8538against. 8539@end deffn 8540 8541@c Copyright (C) 2015-2018 Free Software Foundation, Inc. 8542@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8543@c 8544@c This is free software: you can redistribute it and/or modify it 8545@c under the terms of the GNU General Public License as published by 8546@c the Free Software Foundation, either version 3 of the License, or 8547@c (at your option) any later version. 8548@c 8549@c This program is distributed in the hope that it will be useful, but 8550@c WITHOUT ANY WARRANTY; without even the implied warranty of 8551@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8552@c General Public License for more details. 8553@c 8554@c You should have received a copy of the GNU General Public License 8555@c along with this program. If not, see 8556@c <http://www.gnu.org/licenses/>. 8557 8558@node ABI and API compatibility,Performance,Compiling a context,Topic Reference 8559@anchor{topics/compatibility abi-and-api-compatibility}@anchor{fa}@anchor{topics/compatibility doc}@anchor{fb} 8560@section ABI and API compatibility 8561 8562 8563The libgccjit developers strive for ABI and API backward-compatibility: 8564programs built against libgccjit.so stand a good chance of running 8565without recompilation against newer versions of libgccjit.so, and 8566ought to recompile without modification against newer versions of 8567libgccjit.h. 8568 8569@cartouche 8570@quotation Note 8571The libgccjit++.h C++ API is more experimental, and less 8572locked-down at this time. 8573@end quotation 8574@end cartouche 8575 8576API compatibility is achieved by extending the API rather than changing 8577it. For ABI compatiblity, we avoid bumping the SONAME, and instead use 8578symbol versioning to tag each symbol, so that a binary linked against 8579libgccjit.so is tagged according to the symbols that it uses. 8580 8581For example, @pxref{72,,gcc_jit_context_add_command_line_option()} was added in 8582@code{LIBGCCJIT_ABI_1}. If a client program uses it, this can be detected 8583from metadata by using @code{objdump}: 8584 8585@example 8586$ objdump -p testsuite/jit/test-extra-options.c.exe | tail -n 8 8587 8588Version References: 8589 required from libgccjit.so.0: 8590 0x00824161 0x00 04 LIBGCCJIT_ABI_1 8591 0x00824160 0x00 03 LIBGCCJIT_ABI_0 8592 required from libc.so.6: 8593@end example 8594 8595@noindent 8596 8597You can see the symbol tags provided by libgccjit.so using @code{objdump}: 8598 8599@example 8600$ objdump -p libgccjit.so | less 8601[...snip...] 8602Version definitions: 86031 0x01 0x0ff81f20 libgccjit.so.0 86042 0x00 0x00824160 LIBGCCJIT_ABI_0 86053 0x00 0x00824161 LIBGCCJIT_ABI_1 8606 LIBGCCJIT_ABI_0 8607[...snip...] 8608@end example 8609 8610@noindent 8611 8612@menu 8613* ABI symbol tags:: 8614 8615ABI symbol tags 8616 8617* LIBGCCJIT_ABI_0:: 8618* LIBGCCJIT_ABI_1:: 8619* LIBGCCJIT_ABI_2:: 8620* LIBGCCJIT_ABI_3:: 8621* LIBGCCJIT_ABI_4:: 8622* LIBGCCJIT_ABI_5:: 8623* LIBGCCJIT_ABI_6:: 8624* LIBGCCJIT_ABI_7:: 8625* LIBGCCJIT_ABI_8:: 8626* LIBGCCJIT_ABI_9:: 8627* LIBGCCJIT_ABI_10:: 8628 8629@end menu 8630 8631 8632@node ABI symbol tags,,,ABI and API compatibility 8633@anchor{topics/compatibility abi-symbol-tags}@anchor{fc} 8634@subsection ABI symbol tags 8635 8636 8637The initial release of libgccjit (in gcc 5.1) did not use symbol versioning. 8638 8639Newer releases use the following tags. 8640 8641@menu 8642* LIBGCCJIT_ABI_0:: 8643* LIBGCCJIT_ABI_1:: 8644* LIBGCCJIT_ABI_2:: 8645* LIBGCCJIT_ABI_3:: 8646* LIBGCCJIT_ABI_4:: 8647* LIBGCCJIT_ABI_5:: 8648* LIBGCCJIT_ABI_6:: 8649* LIBGCCJIT_ABI_7:: 8650* LIBGCCJIT_ABI_8:: 8651* LIBGCCJIT_ABI_9:: 8652* LIBGCCJIT_ABI_10:: 8653 8654@end menu 8655 8656@node LIBGCCJIT_ABI_0,LIBGCCJIT_ABI_1,,ABI symbol tags 8657@anchor{topics/compatibility libgccjit-abi-0}@anchor{fd}@anchor{topics/compatibility id1}@anchor{fe} 8658@subsubsection @code{LIBGCCJIT_ABI_0} 8659 8660 8661All entrypoints in the initial release of libgccjit are tagged with 8662@code{LIBGCCJIT_ABI_0}, to signify the transition to symbol versioning. 8663 8664Binaries built against older copies of @code{libgccjit.so} should 8665continue to work, with this being handled transparently by the linker 8666(see this post@footnote{https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html}) 8667 8668@node LIBGCCJIT_ABI_1,LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_0,ABI symbol tags 8669@anchor{topics/compatibility libgccjit-abi-1}@anchor{73}@anchor{topics/compatibility id2}@anchor{ff} 8670@subsubsection @code{LIBGCCJIT_ABI_1} 8671 8672 8673@code{LIBGCCJIT_ABI_1} covers the addition of 8674@pxref{72,,gcc_jit_context_add_command_line_option()} 8675 8676@node LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_1,ABI symbol tags 8677@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c}@anchor{topics/compatibility id3}@anchor{100} 8678@subsubsection @code{LIBGCCJIT_ABI_2} 8679 8680 8681@code{LIBGCCJIT_ABI_2} covers the addition of 8682@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()} 8683 8684@node LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_2,ABI symbol tags 8685@anchor{topics/compatibility libgccjit-abi-3}@anchor{e9}@anchor{topics/compatibility id4}@anchor{101} 8686@subsubsection @code{LIBGCCJIT_ABI_3} 8687 8688 8689@code{LIBGCCJIT_ABI_3} covers the addition of switch statements via API 8690entrypoints: 8691 8692@quotation 8693 8694 8695@itemize * 8696 8697@item 8698@pxref{e6,,gcc_jit_block_end_with_switch()} 8699 8700@item 8701@pxref{e7,,gcc_jit_case_as_object()} 8702 8703@item 8704@pxref{e8,,gcc_jit_context_new_case()} 8705@end itemize 8706@end quotation 8707 8708@node LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_3,ABI symbol tags 8709@anchor{topics/compatibility id5}@anchor{102}@anchor{topics/compatibility libgccjit-abi-4}@anchor{103} 8710@subsubsection @code{LIBGCCJIT_ABI_4} 8711 8712 8713@code{LIBGCCJIT_ABI_4} covers the addition of timers via API 8714entrypoints: 8715 8716@quotation 8717 8718 8719@itemize * 8720 8721@item 8722@pxref{104,,gcc_jit_context_get_timer()} 8723 8724@item 8725@pxref{105,,gcc_jit_context_set_timer()} 8726 8727@item 8728@pxref{106,,gcc_jit_timer_new()} 8729 8730@item 8731@pxref{107,,gcc_jit_timer_release()} 8732 8733@item 8734@pxref{108,,gcc_jit_timer_push()} 8735 8736@item 8737@pxref{109,,gcc_jit_timer_pop()} 8738 8739@item 8740@pxref{10a,,gcc_jit_timer_print()} 8741@end itemize 8742@end quotation 8743 8744@node LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_6,LIBGCCJIT_ABI_4,ABI symbol tags 8745@anchor{topics/compatibility id6}@anchor{10b}@anchor{topics/compatibility libgccjit-abi-5}@anchor{6e} 8746@subsubsection @code{LIBGCCJIT_ABI_5} 8747 8748 8749@code{LIBGCCJIT_ABI_5} covers the addition of 8750@pxref{6d,,gcc_jit_context_set_bool_use_external_driver()} 8751 8752@node LIBGCCJIT_ABI_6,LIBGCCJIT_ABI_7,LIBGCCJIT_ABI_5,ABI symbol tags 8753@anchor{topics/compatibility id7}@anchor{10c}@anchor{topics/compatibility libgccjit-abi-6}@anchor{ba} 8754@subsubsection @code{LIBGCCJIT_ABI_6} 8755 8756 8757@code{LIBGCCJIT_ABI_6} covers the addition of 8758@pxref{b9,,gcc_jit_rvalue_set_bool_require_tail_call()} 8759 8760@node LIBGCCJIT_ABI_7,LIBGCCJIT_ABI_8,LIBGCCJIT_ABI_6,ABI symbol tags 8761@anchor{topics/compatibility libgccjit-abi-7}@anchor{81}@anchor{topics/compatibility id8}@anchor{10d} 8762@subsubsection @code{LIBGCCJIT_ABI_7} 8763 8764 8765@code{LIBGCCJIT_ABI_7} covers the addition of 8766@pxref{80,,gcc_jit_type_get_aligned()} 8767 8768@node LIBGCCJIT_ABI_8,LIBGCCJIT_ABI_9,LIBGCCJIT_ABI_7,ABI symbol tags 8769@anchor{topics/compatibility libgccjit-abi-8}@anchor{84}@anchor{topics/compatibility id9}@anchor{10e} 8770@subsubsection @code{LIBGCCJIT_ABI_8} 8771 8772 8773@code{LIBGCCJIT_ABI_8} covers the addition of 8774@pxref{83,,gcc_jit_type_get_vector()} 8775 8776@node LIBGCCJIT_ABI_9,LIBGCCJIT_ABI_10,LIBGCCJIT_ABI_8,ABI symbol tags 8777@anchor{topics/compatibility id10}@anchor{10f}@anchor{topics/compatibility libgccjit-abi-9}@anchor{ed} 8778@subsubsection @code{LIBGCCJIT_ABI_9} 8779 8780 8781@code{LIBGCCJIT_ABI_9} covers the addition of 8782@pxref{bc,,gcc_jit_function_get_address()} 8783 8784@node LIBGCCJIT_ABI_10,,LIBGCCJIT_ABI_9,ABI symbol tags 8785@anchor{topics/compatibility id11}@anchor{110}@anchor{topics/compatibility libgccjit-abi-10}@anchor{9c} 8786@subsubsection @code{LIBGCCJIT_ABI_10} 8787 8788 8789@code{LIBGCCJIT_ABI_10} covers the addition of 8790@pxref{85,,gcc_jit_context_new_rvalue_from_vector()} 8791 8792@c Copyright (C) 2015-2018 Free Software Foundation, Inc. 8793@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8794@c 8795@c This is free software: you can redistribute it and/or modify it 8796@c under the terms of the GNU General Public License as published by 8797@c the Free Software Foundation, either version 3 of the License, or 8798@c (at your option) any later version. 8799@c 8800@c This program is distributed in the hope that it will be useful, but 8801@c WITHOUT ANY WARRANTY; without even the implied warranty of 8802@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8803@c General Public License for more details. 8804@c 8805@c You should have received a copy of the GNU General Public License 8806@c along with this program. If not, see 8807@c <http://www.gnu.org/licenses/>. 8808 8809@node Performance,,ABI and API compatibility,Topic Reference 8810@anchor{topics/performance performance}@anchor{111}@anchor{topics/performance doc}@anchor{112} 8811@section Performance 8812 8813 8814@menu 8815* The timing API:: 8816 8817@end menu 8818 8819@node The timing API,,,Performance 8820@anchor{topics/performance the-timing-api}@anchor{113} 8821@subsection The timing API 8822 8823 8824As of GCC 6, libgccjit exposes a timing API, for printing reports on 8825how long was spent in different parts of code. 8826 8827You can create a @pxref{114,,gcc_jit_timer} instance, which will 8828measure time spent since its creation. The timer maintains a stack 8829of "timer items": as control flow moves through your code, you can push 8830and pop named items relating to your code onto the stack, and the timer 8831will account the time spent accordingly. 8832 8833You can also asssociate a timer with a @pxref{8,,gcc_jit_context}, in 8834which case the time spent inside compilation will be subdivided. 8835 8836For example, the following code uses a timer, recording client items 8837"create_code", "compile", and "running code": 8838 8839@example 8840/* Create a timer. */ 8841gcc_jit_timer *timer = gcc_jit_timer_new (); 8842if (!timer) 8843 @{ 8844 error ("gcc_jit_timer_new failed"); 8845 return -1; 8846 @} 8847 8848/* Let's repeatedly compile and run some code, accumulating it 8849 all into the timer. */ 8850for (int i = 0; i < num_iterations; i++) 8851 @{ 8852 /* Create a context and associate it with the timer. */ 8853 gcc_jit_context *ctxt = gcc_jit_context_acquire (); 8854 if (!ctxt) 8855 @{ 8856 error ("gcc_jit_context_acquire failed"); 8857 return -1; 8858 @} 8859 gcc_jit_context_set_timer (ctxt, timer); 8860 8861 /* Populate the context, timing it as client item "create_code". */ 8862 gcc_jit_timer_push (timer, "create_code"); 8863 create_code (ctxt); 8864 gcc_jit_timer_pop (timer, "create_code"); 8865 8866 /* Compile the context, timing it as client item "compile". */ 8867 gcc_jit_timer_push (timer, "compile"); 8868 result = gcc_jit_context_compile (ctxt); 8869 gcc_jit_timer_pop (timer, "compile"); 8870 8871 /* Run the generated code, timing it as client item "running code". */ 8872 gcc_jit_timer_push (timer, "running code"); 8873 run_the_code (ctxt, result); 8874 gcc_jit_timer_pop (timer, "running code"); 8875 8876 /* Clean up. */ 8877 gcc_jit_context_release (ctxt); 8878 gcc_jit_result_release (result); 8879@} 8880 8881/* Print the accumulated timings. */ 8882gcc_jit_timer_print (timer, stderr); 8883gcc_jit_timer_release (timer); 8884@end example 8885 8886@noindent 8887 8888giving output like this, showing the internal GCC items at the top, then 8889client items, then the total: 8890 8891@example 8892Execution times (seconds) 8893GCC items: 8894 phase setup : 0.29 (14%) usr 0.00 ( 0%) sys 0.32 ( 5%) wall 10661 kB (50%) ggc 8895 phase parsing : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 653 kB ( 3%) ggc 8896 phase finalize : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8897 dump files : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc 8898 callgraph construction : 0.02 ( 1%) usr 0.01 ( 6%) sys 0.01 ( 0%) wall 242 kB ( 1%) ggc 8899 callgraph optimization : 0.03 ( 2%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 142 kB ( 1%) ggc 8900 trivially dead code : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8901 df scan insns : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 9 kB ( 0%) ggc 8902 df live regs : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc 8903 inline parameters : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 82 kB ( 0%) ggc 8904 tree CFG cleanup : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8905 tree PHI insertion : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 64 kB ( 0%) ggc 8906 tree SSA other : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 18 kB ( 0%) ggc 8907 expand : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 398 kB ( 2%) ggc 8908 jump : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8909 loop init : 0.01 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 67 kB ( 0%) ggc 8910 integrated RA : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 2468 kB (12%) ggc 8911 thread pro- & epilogue : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 162 kB ( 1%) ggc 8912 final : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 216 kB ( 1%) ggc 8913 rest of compilation : 1.37 (69%) usr 0.00 ( 0%) sys 1.13 (18%) wall 1391 kB ( 6%) ggc 8914 assemble JIT code : 0.01 ( 1%) usr 0.00 ( 0%) sys 4.04 (66%) wall 0 kB ( 0%) ggc 8915 load JIT result : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8916 JIT client code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8917Client items: 8918 create_code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8919 compile : 0.36 (18%) usr 0.15 (83%) sys 0.86 (14%) wall 14939 kB (70%) ggc 8920 running code : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8921 TOTAL : 2.00 0.18 6.12 21444 kB 8922@end example 8923 8924@noindent 8925 8926The exact format is intended to be human-readable, and is subject to change. 8927 8928@geindex LIBGCCJIT_HAVE_TIMING_API (C macro) 8929@anchor{topics/performance LIBGCCJIT_HAVE_TIMING_API}@anchor{115} 8930@deffn {C Macro} LIBGCCJIT_HAVE_TIMING_API 8931 8932The timer API was added to libgccjit in GCC 6. 8933This macro is only defined in versions of libgccjit.h which have the 8934timer API, and so can be used to guard code that may need to compile 8935against earlier releases: 8936 8937@example 8938#ifdef LIBGCCJIT_HAVE_TIMING_API 8939gcc_jit_timer *t = gcc_jit_timer_new (); 8940gcc_jit_context_set_timer (ctxt, t); 8941#endif 8942@end example 8943 8944@noindent 8945@end deffn 8946 8947@geindex gcc_jit_timer (C type) 8948@anchor{topics/performance gcc_jit_timer}@anchor{114} 8949@deffn {C Type} gcc_jit_timer 8950@end deffn 8951 8952@geindex gcc_jit_timer_new (C function) 8953@anchor{topics/performance gcc_jit_timer_new}@anchor{106} 8954@deffn {C Function} gcc_jit_timer * gcc_jit_timer_new (void) 8955 8956Create a @pxref{114,,gcc_jit_timer} instance, and start timing: 8957 8958@example 8959gcc_jit_timer *t = gcc_jit_timer_new (); 8960@end example 8961 8962@noindent 8963 8964This API entrypoint was added in @pxref{103,,LIBGCCJIT_ABI_4}; you can test 8965for its presence using 8966 8967@example 8968#ifdef LIBGCCJIT_HAVE_TIMING_API 8969@end example 8970 8971@noindent 8972@end deffn 8973 8974@geindex gcc_jit_timer_release (C function) 8975@anchor{topics/performance gcc_jit_timer_release}@anchor{107} 8976@deffn {C Function} void gcc_jit_timer_release (gcc_jit_timer@w{ }*timer) 8977 8978Release a @pxref{114,,gcc_jit_timer} instance: 8979 8980@example 8981gcc_jit_timer_release (t); 8982@end example 8983 8984@noindent 8985 8986This should be called exactly once on a timer. 8987 8988This API entrypoint was added in @pxref{103,,LIBGCCJIT_ABI_4}; you can test 8989for its presence using 8990 8991@example 8992#ifdef LIBGCCJIT_HAVE_TIMING_API 8993@end example 8994 8995@noindent 8996@end deffn 8997 8998@geindex gcc_jit_context_set_timer (C function) 8999@anchor{topics/performance gcc_jit_context_set_timer}@anchor{105} 9000@deffn {C Function} void gcc_jit_context_set_timer (gcc_jit_context@w{ }*ctxt, gcc_jit_timer@w{ }*timer) 9001 9002Associate a @pxref{114,,gcc_jit_timer} instance with a context: 9003 9004@example 9005gcc_jit_context_set_timer (ctxt, t); 9006@end example 9007 9008@noindent 9009 9010A timer instance can be shared between multiple 9011@pxref{8,,gcc_jit_context} instances. 9012 9013Timers have no locking, so if you have a multithreaded program, you 9014must provide your own locks if more than one thread could be working 9015with the same timer via timer-associated contexts. 9016 9017This API entrypoint was added in @pxref{103,,LIBGCCJIT_ABI_4}; you can test 9018for its presence using 9019 9020@example 9021#ifdef LIBGCCJIT_HAVE_TIMING_API 9022@end example 9023 9024@noindent 9025@end deffn 9026 9027@geindex gcc_jit_context_get_timer (C function) 9028@anchor{topics/performance gcc_jit_context_get_timer}@anchor{104} 9029@deffn {C Function} gcc_jit_timer *gcc_jit_context_get_timer (gcc_jit_context@w{ }*ctxt) 9030 9031Get the timer associated with a context (if any). 9032 9033This API entrypoint was added in @pxref{103,,LIBGCCJIT_ABI_4}; you can test 9034for its presence using 9035 9036@example 9037#ifdef LIBGCCJIT_HAVE_TIMING_API 9038@end example 9039 9040@noindent 9041@end deffn 9042 9043@geindex gcc_jit_timer_push (C function) 9044@anchor{topics/performance gcc_jit_timer_push}@anchor{108} 9045@deffn {C Function} void gcc_jit_timer_push (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name) 9046 9047Push the given item onto the timer's stack: 9048 9049@example 9050gcc_jit_timer_push (t, "running code"); 9051run_the_code (ctxt, result); 9052gcc_jit_timer_pop (t, "running code"); 9053@end example 9054 9055@noindent 9056 9057This API entrypoint was added in @pxref{103,,LIBGCCJIT_ABI_4}; you can test 9058for its presence using 9059 9060@example 9061#ifdef LIBGCCJIT_HAVE_TIMING_API 9062@end example 9063 9064@noindent 9065@end deffn 9066 9067@geindex gcc_jit_timer_pop (C function) 9068@anchor{topics/performance gcc_jit_timer_pop}@anchor{109} 9069@deffn {C Function} void gcc_jit_timer_pop (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name) 9070 9071Pop the top item from the timer's stack. 9072 9073If "item_name" is provided, it must match that of the top item. 9074Alternatively, @code{NULL} can be passed in, to suppress checking. 9075 9076This API entrypoint was added in @pxref{103,,LIBGCCJIT_ABI_4}; you can test 9077for its presence using 9078 9079@example 9080#ifdef LIBGCCJIT_HAVE_TIMING_API 9081@end example 9082 9083@noindent 9084@end deffn 9085 9086@geindex gcc_jit_timer_print (C function) 9087@anchor{topics/performance gcc_jit_timer_print}@anchor{10a} 9088@deffn {C Function} void gcc_jit_timer_print (gcc_jit_timer@w{ }*timer, FILE@w{ }*f_out) 9089 9090Print timing information to the given stream about activity since 9091the timer was started. 9092 9093This API entrypoint was added in @pxref{103,,LIBGCCJIT_ABI_4}; you can test 9094for its presence using 9095 9096@example 9097#ifdef LIBGCCJIT_HAVE_TIMING_API 9098@end example 9099 9100@noindent 9101@end deffn 9102 9103@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 9104@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9105@c 9106@c This is free software: you can redistribute it and/or modify it 9107@c under the terms of the GNU General Public License as published by 9108@c the Free Software Foundation, either version 3 of the License, or 9109@c (at your option) any later version. 9110@c 9111@c This program is distributed in the hope that it will be useful, but 9112@c WITHOUT ANY WARRANTY; without even the implied warranty of 9113@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9114@c General Public License for more details. 9115@c 9116@c You should have received a copy of the GNU General Public License 9117@c along with this program. If not, see 9118@c <http://www.gnu.org/licenses/>. 9119 9120@node C++ bindings for libgccjit,Internals,Topic Reference,Top 9121@anchor{cp/index c-bindings-for-libgccjit}@anchor{116}@anchor{cp/index doc}@anchor{117} 9122@chapter C++ bindings for libgccjit 9123 9124 9125This document describes the C++ bindings to 9126libgccjit@footnote{http://gcc.gnu.org/wiki/JIT}, an API for embedding GCC 9127inside programs and libraries. 9128 9129The C++ bindings consist of a single header file @code{libgccjit++.h}. 9130 9131This is a collection of "thin" wrapper classes around the C API. 9132Everything is an inline function, implemented in terms of the C API, 9133so there is nothing extra to link against. 9134 9135Note that libgccjit is currently of "Alpha" quality; 9136the APIs are not yet set in stone, and they shouldn't be used in 9137production yet. 9138 9139Contents: 9140 9141@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 9142@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9143@c 9144@c This is free software: you can redistribute it and/or modify it 9145@c under the terms of the GNU General Public License as published by 9146@c the Free Software Foundation, either version 3 of the License, or 9147@c (at your option) any later version. 9148@c 9149@c This program is distributed in the hope that it will be useful, but 9150@c WITHOUT ANY WARRANTY; without even the implied warranty of 9151@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9152@c General Public License for more details. 9153@c 9154@c You should have received a copy of the GNU General Public License 9155@c along with this program. If not, see 9156@c <http://www.gnu.org/licenses/>. 9157 9158@menu 9159* Tutorial: Tutorial<2>. 9160* Topic Reference: Topic Reference<2>. 9161 9162Tutorial 9163 9164* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 9165* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 9166* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 9167* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 9168 9169Tutorial part 2: Creating a trivial machine code function 9170 9171* Options: Options<3>. 9172* Full example: Full example<3>. 9173 9174Tutorial part 3: Loops and variables 9175 9176* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 9177* Control flow: Control flow<2>. 9178* Visualizing the control flow graph: Visualizing the control flow graph<2>. 9179* Full example: Full example<4>. 9180 9181Tutorial part 4: Adding JIT-compilation to a toy interpreter 9182 9183* Our toy interpreter: Our toy interpreter<2>. 9184* Compiling to machine code: Compiling to machine code<2>. 9185* Setting things up: Setting things up<2>. 9186* Populating the function: Populating the function<2>. 9187* Verifying the control flow graph: Verifying the control flow graph<2>. 9188* Compiling the context: Compiling the context<2>. 9189* Single-stepping through the generated code: Single-stepping through the generated code<2>. 9190* Examining the generated code: Examining the generated code<2>. 9191* Putting it all together: Putting it all together<2>. 9192* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 9193 9194Behind the curtain: How does our code get optimized? 9195 9196* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 9197* Elimination of tail recursion: Elimination of tail recursion<2>. 9198 9199Topic Reference 9200 9201* Compilation contexts: Compilation contexts<2>. 9202* Objects: Objects<2>. 9203* Types: Types<2>. 9204* Expressions: Expressions<2>. 9205* Creating and using functions: Creating and using functions<2>. 9206* Source Locations: Source Locations<2>. 9207* Compiling a context: Compiling a context<2>. 9208 9209Compilation contexts 9210 9211* Lifetime-management: Lifetime-management<2>. 9212* Thread-safety: Thread-safety<2>. 9213* Error-handling: Error-handling<3>. 9214* Debugging: Debugging<2>. 9215* Options: Options<4>. 9216 9217Options 9218 9219* String Options: String Options<2>. 9220* Boolean options: Boolean options<2>. 9221* Integer options: Integer options<2>. 9222* Additional command-line options: Additional command-line options<2>. 9223 9224Types 9225 9226* Standard types: Standard types<2>. 9227* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 9228* Vector types: Vector types<2>. 9229* Structures and unions: Structures and unions<2>. 9230 9231Expressions 9232 9233* Rvalues: Rvalues<2>. 9234* Lvalues: Lvalues<2>. 9235* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 9236 9237Rvalues 9238 9239* Simple expressions: Simple expressions<2>. 9240* Vector expressions: Vector expressions<2>. 9241* Unary Operations: Unary Operations<2>. 9242* Binary Operations: Binary Operations<2>. 9243* Comparisons: Comparisons<2>. 9244* Function calls: Function calls<2>. 9245* Function pointers: Function pointers<3>. 9246* Type-coercion: Type-coercion<2>. 9247 9248Lvalues 9249 9250* Global variables: Global variables<2>. 9251 9252Creating and using functions 9253 9254* Params: Params<2>. 9255* Functions: Functions<2>. 9256* Blocks: Blocks<2>. 9257* Statements: Statements<2>. 9258 9259Source Locations 9260 9261* Faking it: Faking it<2>. 9262 9263Compiling a context 9264 9265* In-memory compilation: In-memory compilation<2>. 9266* Ahead-of-time compilation: Ahead-of-time compilation<2>. 9267 9268@end menu 9269 9270 9271@node Tutorial<2>,Topic Reference<2>,,C++ bindings for libgccjit 9272@anchor{cp/intro/index doc}@anchor{118}@anchor{cp/intro/index tutorial}@anchor{119} 9273@section Tutorial 9274 9275 9276@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 9277@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9278@c 9279@c This is free software: you can redistribute it and/or modify it 9280@c under the terms of the GNU General Public License as published by 9281@c the Free Software Foundation, either version 3 of the License, or 9282@c (at your option) any later version. 9283@c 9284@c This program is distributed in the hope that it will be useful, but 9285@c WITHOUT ANY WARRANTY; without even the implied warranty of 9286@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9287@c General Public License for more details. 9288@c 9289@c You should have received a copy of the GNU General Public License 9290@c along with this program. If not, see 9291@c <http://www.gnu.org/licenses/>. 9292 9293@menu 9294* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 9295* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 9296* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 9297* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 9298 9299@end menu 9300 9301@node Tutorial part 1 "Hello world"<2>,Tutorial part 2 Creating a trivial machine code function<2>,,Tutorial<2> 9302@anchor{cp/intro/tutorial01 doc}@anchor{11a}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{11b} 9303@subsection Tutorial part 1: "Hello world" 9304 9305 9306Before we look at the details of the API, let's look at building and 9307running programs that use the library. 9308 9309Here's a toy "hello world" program that uses the library's C++ API to 9310synthesize a call to @cite{printf} and uses it to write a message to stdout. 9311 9312Don't worry about the content of the program for now; we'll cover 9313the details in later parts of this tutorial. 9314 9315@quotation 9316 9317@example 9318/* Smoketest example for libgccjit.so C++ API 9319 Copyright (C) 2014-2018 Free Software Foundation, Inc. 9320 9321This file is part of GCC. 9322 9323GCC is free software; you can redistribute it and/or modify it 9324under the terms of the GNU General Public License as published by 9325the Free Software Foundation; either version 3, or (at your option) 9326any later version. 9327 9328GCC is distributed in the hope that it will be useful, but 9329WITHOUT ANY WARRANTY; without even the implied warranty of 9330MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9331General Public License for more details. 9332 9333You should have received a copy of the GNU General Public License 9334along with GCC; see the file COPYING3. If not see 9335<http://www.gnu.org/licenses/>. */ 9336 9337#include <libgccjit++.h> 9338 9339#include <stdlib.h> 9340#include <stdio.h> 9341 9342static void 9343create_code (gccjit::context ctxt) 9344@{ 9345 /* Let's try to inject the equivalent of this C code: 9346 void 9347 greet (const char *name) 9348 @{ 9349 printf ("hello %s\n", name); 9350 @} 9351 */ 9352 gccjit::type void_type = ctxt.get_type (GCC_JIT_TYPE_VOID); 9353 gccjit::type const_char_ptr_type = 9354 ctxt.get_type (GCC_JIT_TYPE_CONST_CHAR_PTR); 9355 gccjit::param param_name = 9356 ctxt.new_param (const_char_ptr_type, "name"); 9357 std::vector<gccjit::param> func_params; 9358 func_params.push_back (param_name); 9359 gccjit::function func = 9360 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9361 void_type, 9362 "greet", 9363 func_params, 0); 9364 9365 gccjit::param param_format = 9366 ctxt.new_param (const_char_ptr_type, "format"); 9367 std::vector<gccjit::param> printf_params; 9368 printf_params.push_back (param_format); 9369 gccjit::function printf_func = 9370 ctxt.new_function (GCC_JIT_FUNCTION_IMPORTED, 9371 ctxt.get_type (GCC_JIT_TYPE_INT), 9372 "printf", 9373 printf_params, 1); 9374 9375 gccjit::block block = func.new_block (); 9376 block.add_eval (ctxt.new_call (printf_func, 9377 ctxt.new_rvalue ("hello %s\n"), 9378 param_name)); 9379 block.end_with_return (); 9380@} 9381 9382int 9383main (int argc, char **argv) 9384@{ 9385 gccjit::context ctxt; 9386 gcc_jit_result *result; 9387 9388 /* Get a "context" object for working with the library. */ 9389 ctxt = gccjit::context::acquire (); 9390 9391 /* Set some options on the context. 9392 Turn this on to see the code being generated, in assembler form. */ 9393 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 0); 9394 9395 /* Populate the context. */ 9396 create_code (ctxt); 9397 9398 /* Compile the code. */ 9399 result = ctxt.compile (); 9400 if (!result) 9401 @{ 9402 fprintf (stderr, "NULL result"); 9403 exit (1); 9404 @} 9405 9406 ctxt.release (); 9407 9408 /* Extract the generated code from "result". */ 9409 typedef void (*fn_type) (const char *); 9410 fn_type greet = 9411 (fn_type)gcc_jit_result_get_code (result, "greet"); 9412 if (!greet) 9413 @{ 9414 fprintf (stderr, "NULL greet"); 9415 exit (1); 9416 @} 9417 9418 /* Now call the generated function: */ 9419 greet ("world"); 9420 fflush (stdout); 9421 9422 gcc_jit_result_release (result); 9423 return 0; 9424@} 9425 9426@end example 9427 9428@noindent 9429@end quotation 9430 9431Copy the above to @cite{tut01-hello-world.cc}. 9432 9433Assuming you have the jit library installed, build the test program 9434using: 9435 9436@example 9437$ gcc \ 9438 tut01-hello-world.cc \ 9439 -o tut01-hello-world \ 9440 -lgccjit 9441@end example 9442 9443@noindent 9444 9445You should then be able to run the built program: 9446 9447@example 9448$ ./tut01-hello-world 9449hello world 9450@end example 9451 9452@noindent 9453 9454@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 9455@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9456@c 9457@c This is free software: you can redistribute it and/or modify it 9458@c under the terms of the GNU General Public License as published by 9459@c the Free Software Foundation, either version 3 of the License, or 9460@c (at your option) any later version. 9461@c 9462@c This program is distributed in the hope that it will be useful, but 9463@c WITHOUT ANY WARRANTY; without even the implied warranty of 9464@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9465@c General Public License for more details. 9466@c 9467@c You should have received a copy of the GNU General Public License 9468@c along with this program. If not, see 9469@c <http://www.gnu.org/licenses/>. 9470 9471@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> 9472@anchor{cp/intro/tutorial02 doc}@anchor{11c}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{11d} 9473@subsection Tutorial part 2: Creating a trivial machine code function 9474 9475 9476Consider this C function: 9477 9478@example 9479int square (int i) 9480@{ 9481 return i * i; 9482@} 9483@end example 9484 9485@noindent 9486 9487How can we construct this at run-time using libgccjit's C++ API? 9488 9489First we need to include the relevant header: 9490 9491@example 9492#include <libgccjit++.h> 9493@end example 9494 9495@noindent 9496 9497All state associated with compilation is associated with a 9498@code{gccjit::context}, which is a thin C++ wrapper around the C API's 9499@pxref{8,,gcc_jit_context *}. 9500 9501Create one using @pxref{11e,,gccjit;;context;;acquire()}: 9502 9503@example 9504gccjit::context ctxt; 9505ctxt = gccjit::context::acquire (); 9506@end example 9507 9508@noindent 9509 9510The JIT library has a system of types. It is statically-typed: every 9511expression is of a specific type, fixed at compile-time. In our example, 9512all of the expressions are of the C @cite{int} type, so let's obtain this from 9513the context, as a @code{gccjit::type}, using 9514@pxref{11f,,gccjit;;context;;get_type()}: 9515 9516@example 9517gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 9518@end example 9519 9520@noindent 9521 9522@code{gccjit::type} is an example of a "contextual" object: every 9523entity in the API is associated with a @code{gccjit::context}. 9524 9525Memory management is easy: all such "contextual" objects are automatically 9526cleaned up for you when the context is released, using 9527@pxref{120,,gccjit;;context;;release()}: 9528 9529@example 9530ctxt.release (); 9531@end example 9532 9533@noindent 9534 9535so you don't need to manually track and cleanup all objects, just the 9536contexts. 9537 9538All of the C++ classes in the API are thin wrappers around pointers to 9539types in the C API. 9540 9541The C++ class hierarchy within the @code{gccjit} namespace looks like this: 9542 9543@example 9544+- object 9545 +- location 9546 +- type 9547 +- struct 9548 +- field 9549 +- function 9550 +- block 9551 +- rvalue 9552 +- lvalue 9553 +- param 9554@end example 9555 9556@noindent 9557 9558One thing you can do with a @code{gccjit::object} is 9559to ask it for a human-readable description as a @code{std::string}, using 9560@pxref{121,,gccjit;;object;;get_debug_string()}: 9561 9562@example 9563printf ("obj: %s\n", obj.get_debug_string ().c_str ()); 9564@end example 9565 9566@noindent 9567 9568giving this text on stdout: 9569 9570@example 9571obj: int 9572@end example 9573 9574@noindent 9575 9576This is invaluable when debugging. 9577 9578Let's create the function. To do so, we first need to construct 9579its single parameter, specifying its type and giving it a name, 9580using @pxref{122,,gccjit;;context;;new_param()}: 9581 9582@example 9583gccjit::param param_i = ctxt.new_param (int_type, "i"); 9584@end example 9585 9586@noindent 9587 9588and we can then make a vector of all of the params of the function, 9589in this case just one: 9590 9591@example 9592std::vector<gccjit::param> params; 9593params.push_back (param_i); 9594@end example 9595 9596@noindent 9597 9598Now we can create the function, using 9599@code{gccjit::context::new_function()}: 9600 9601@example 9602gccjit::function func = 9603 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9604 int_type, 9605 "square", 9606 params, 9607 0); 9608@end example 9609 9610@noindent 9611 9612To define the code within the function, we must create basic blocks 9613containing statements. 9614 9615Every basic block contains a list of statements, eventually terminated 9616by a statement that either returns, or jumps to another basic block. 9617 9618Our function has no control-flow, so we just need one basic block: 9619 9620@example 9621gccjit::block block = func.new_block (); 9622@end example 9623 9624@noindent 9625 9626Our basic block is relatively simple: it immediately terminates by 9627returning the value of an expression. 9628 9629We can build the expression using @pxref{123,,gccjit;;context;;new_binary_op()}: 9630 9631@example 9632gccjit::rvalue expr = 9633 ctxt.new_binary_op ( 9634 GCC_JIT_BINARY_OP_MULT, int_type, 9635 param_i, param_i); 9636@end example 9637 9638@noindent 9639 9640A @code{gccjit::rvalue} is another example of a 9641@code{gccjit::object} subclass. As before, we can print it with 9642@pxref{121,,gccjit;;object;;get_debug_string()}. 9643 9644@example 9645printf ("expr: %s\n", expr.get_debug_string ().c_str ()); 9646@end example 9647 9648@noindent 9649 9650giving this output: 9651 9652@example 9653expr: i * i 9654@end example 9655 9656@noindent 9657 9658Note that @code{gccjit::rvalue} provides numerous overloaded operators 9659which can be used to dramatically reduce the amount of typing needed. 9660We can build the above binary operation more directly with this one-liner: 9661 9662@example 9663gccjit::rvalue expr = param_i * param_i; 9664@end example 9665 9666@noindent 9667 9668Creating the expression in itself doesn't do anything; we have to add 9669this expression to a statement within the block. In this case, we use it 9670to build a return statement, which terminates the basic block: 9671 9672@example 9673block.end_with_return (expr); 9674@end example 9675 9676@noindent 9677 9678OK, we've populated the context. We can now compile it using 9679@pxref{124,,gccjit;;context;;compile()}: 9680 9681@example 9682gcc_jit_result *result; 9683result = ctxt.compile (); 9684@end example 9685 9686@noindent 9687 9688and get a @pxref{16,,gcc_jit_result *}. 9689 9690We can now use @pxref{17,,gcc_jit_result_get_code()} to look up a specific 9691machine code routine within the result, in this case, the function we 9692created above. 9693 9694@example 9695void *fn_ptr = gcc_jit_result_get_code (result, "square"); 9696if (!fn_ptr) 9697 @{ 9698 fprintf (stderr, "NULL fn_ptr"); 9699 goto error; 9700 @} 9701@end example 9702 9703@noindent 9704 9705We can now cast the pointer to an appropriate function pointer type, and 9706then call it: 9707 9708@example 9709typedef int (*fn_type) (int); 9710fn_type square = (fn_type)fn_ptr; 9711printf ("result: %d", square (5)); 9712@end example 9713 9714@noindent 9715 9716@example 9717result: 25 9718@end example 9719 9720@noindent 9721 9722@menu 9723* Options: Options<3>. 9724* Full example: Full example<3>. 9725 9726@end menu 9727 9728@node Options<3>,Full example<3>,,Tutorial part 2 Creating a trivial machine code function<2> 9729@anchor{cp/intro/tutorial02 options}@anchor{125} 9730@subsubsection Options 9731 9732 9733To get more information on what's going on, you can set debugging flags 9734on the context using @pxref{126,,gccjit;;context;;set_bool_option()}. 9735 9736@c (I'm deliberately not mentioning 9737@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think 9738@c it's probably more of use to implementors than to users) 9739 9740Setting @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a 9741C-like representation to stderr when you compile (GCC's "GIMPLE" 9742representation): 9743 9744@example 9745ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); 9746result = ctxt.compile (); 9747@end example 9748 9749@noindent 9750 9751@example 9752square (signed int i) 9753@{ 9754 signed int D.260; 9755 9756 entry: 9757 D.260 = i * i; 9758 return D.260; 9759@} 9760@end example 9761 9762@noindent 9763 9764We can see the generated machine code in assembler form (on stderr) by 9765setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context 9766before compiling: 9767 9768@example 9769ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); 9770result = ctxt.compile (); 9771@end example 9772 9773@noindent 9774 9775@example 9776 .file "fake.c" 9777 .text 9778 .globl square 9779 .type square, @@function 9780square: 9781.LFB6: 9782 .cfi_startproc 9783 pushq %rbp 9784 .cfi_def_cfa_offset 16 9785 .cfi_offset 6, -16 9786 movq %rsp, %rbp 9787 .cfi_def_cfa_register 6 9788 movl %edi, -4(%rbp) 9789.L14: 9790 movl -4(%rbp), %eax 9791 imull -4(%rbp), %eax 9792 popq %rbp 9793 .cfi_def_cfa 7, 8 9794 ret 9795 .cfi_endproc 9796.LFE6: 9797 .size square, .-square 9798 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 9799 .section .note.GNU-stack,"",@@progbits 9800@end example 9801 9802@noindent 9803 9804By default, no optimizations are performed, the equivalent of GCC's 9805@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling 9806@pxref{127,,gccjit;;context;;set_int_option()} with 9807@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 9808 9809@example 9810ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); 9811@end example 9812 9813@noindent 9814 9815@example 9816 .file "fake.c" 9817 .text 9818 .p2align 4,,15 9819 .globl square 9820 .type square, @@function 9821square: 9822.LFB7: 9823 .cfi_startproc 9824.L16: 9825 movl %edi, %eax 9826 imull %edi, %eax 9827 ret 9828 .cfi_endproc 9829.LFE7: 9830 .size square, .-square 9831 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 9832 .section .note.GNU-stack,"",@@progbits 9833@end example 9834 9835@noindent 9836 9837Naturally this has only a small effect on such a trivial function. 9838 9839@node Full example<3>,,Options<3>,Tutorial part 2 Creating a trivial machine code function<2> 9840@anchor{cp/intro/tutorial02 full-example}@anchor{128} 9841@subsubsection Full example 9842 9843 9844Here's what the above looks like as a complete program: 9845 9846@quotation 9847 9848@example 9849/* Usage example for libgccjit.so's C++ API 9850 Copyright (C) 2014-2018 Free Software Foundation, Inc. 9851 9852This file is part of GCC. 9853 9854GCC is free software; you can redistribute it and/or modify it 9855under the terms of the GNU General Public License as published by 9856the Free Software Foundation; either version 3, or (at your option) 9857any later version. 9858 9859GCC is distributed in the hope that it will be useful, but 9860WITHOUT ANY WARRANTY; without even the implied warranty of 9861MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9862General Public License for more details. 9863 9864You should have received a copy of the GNU General Public License 9865along with GCC; see the file COPYING3. If not see 9866<http://www.gnu.org/licenses/>. */ 9867 9868#include <libgccjit++.h> 9869 9870#include <stdlib.h> 9871#include <stdio.h> 9872 9873void 9874create_code (gccjit::context ctxt) 9875@{ 9876 /* Let's try to inject the equivalent of this C code: 9877 9878 int square (int i) 9879 @{ 9880 return i * i; 9881 @} 9882 */ 9883 gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 9884 gccjit::param param_i = ctxt.new_param (int_type, "i"); 9885 std::vector<gccjit::param> params; 9886 params.push_back (param_i); 9887 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9888 int_type, 9889 "square", 9890 params, 0); 9891 9892 gccjit::block block = func.new_block (); 9893 9894 gccjit::rvalue expr = 9895 ctxt.new_binary_op (GCC_JIT_BINARY_OP_MULT, int_type, 9896 param_i, param_i); 9897 9898 block.end_with_return (expr); 9899@} 9900 9901int 9902main (int argc, char **argv) 9903@{ 9904 /* Get a "context" object for working with the library. */ 9905 gccjit::context ctxt = gccjit::context::acquire (); 9906 9907 /* Set some options on the context. 9908 Turn this on to see the code being generated, in assembler form. */ 9909 ctxt.set_bool_option ( 9910 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 9911 0); 9912 9913 /* Populate the context. */ 9914 create_code (ctxt); 9915 9916 /* Compile the code. */ 9917 gcc_jit_result *result = ctxt.compile (); 9918 9919 /* We're done with the context; we can release it: */ 9920 ctxt.release (); 9921 9922 if (!result) 9923 @{ 9924 fprintf (stderr, "NULL result"); 9925 return 1; 9926 @} 9927 9928 /* Extract the generated code from "result". */ 9929 void *fn_ptr = gcc_jit_result_get_code (result, "square"); 9930 if (!fn_ptr) 9931 @{ 9932 fprintf (stderr, "NULL fn_ptr"); 9933 gcc_jit_result_release (result); 9934 return 1; 9935 @} 9936 9937 typedef int (*fn_type) (int); 9938 fn_type square = (fn_type)fn_ptr; 9939 printf ("result: %d\n", square (5)); 9940 9941 gcc_jit_result_release (result); 9942 return 0; 9943@} 9944 9945@end example 9946 9947@noindent 9948@end quotation 9949 9950Building and running it: 9951 9952@example 9953$ gcc \ 9954 tut02-square.cc \ 9955 -o tut02-square \ 9956 -lgccjit 9957 9958# Run the built program: 9959$ ./tut02-square 9960result: 25 9961@end example 9962 9963@noindent 9964 9965@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 9966@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9967@c 9968@c This is free software: you can redistribute it and/or modify it 9969@c under the terms of the GNU General Public License as published by 9970@c the Free Software Foundation, either version 3 of the License, or 9971@c (at your option) any later version. 9972@c 9973@c This program is distributed in the hope that it will be useful, but 9974@c WITHOUT ANY WARRANTY; without even the implied warranty of 9975@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9976@c General Public License for more details. 9977@c 9978@c You should have received a copy of the GNU General Public License 9979@c along with this program. If not, see 9980@c <http://www.gnu.org/licenses/>. 9981 9982@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> 9983@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{129}@anchor{cp/intro/tutorial03 doc}@anchor{12a} 9984@subsection Tutorial part 3: Loops and variables 9985 9986 9987Consider this C function: 9988 9989@quotation 9990 9991@example 9992int loop_test (int n) 9993@{ 9994 int sum = 0; 9995 for (int i = 0; i < n; i++) 9996 sum += i * i; 9997 return sum; 9998@} 9999@end example 10000 10001@noindent 10002@end quotation 10003 10004This example demonstrates some more features of libgccjit, with local 10005variables and a loop. 10006 10007To break this down into libgccjit terms, it's usually easier to reword 10008the @cite{for} loop as a @cite{while} loop, giving: 10009 10010@quotation 10011 10012@example 10013int loop_test (int n) 10014@{ 10015 int sum = 0; 10016 int i = 0; 10017 while (i < n) 10018 @{ 10019 sum += i * i; 10020 i++; 10021 @} 10022 return sum; 10023@} 10024@end example 10025 10026@noindent 10027@end quotation 10028 10029Here's what the final control flow graph will look like: 10030 10031@quotation 10032 10033 10034@float Figure 10035 10036@image{sum-of-squares,,,image of a control flow graph,png} 10037 10038@end float 10039 10040@end quotation 10041 10042As before, we include the libgccjit++ header and make a 10043@code{gccjit::context}. 10044 10045@example 10046#include <libgccjit++.h> 10047 10048void test (void) 10049@{ 10050 gccjit::context ctxt; 10051 ctxt = gccjit::context::acquire (); 10052@end example 10053 10054@noindent 10055 10056The function works with the C @cite{int} type. 10057 10058In the previous tutorial we acquired this via 10059 10060@example 10061gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_INT); 10062@end example 10063 10064@noindent 10065 10066though we could equally well make it work on, say, @cite{double}: 10067 10068@example 10069gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_DOUBLE); 10070@end example 10071 10072@noindent 10073 10074For integer types we can use @code{gccjit::context::get_int_type} 10075to directly bind a specific type: 10076 10077@example 10078gccjit::type the_type = ctxt.get_int_type <int> (); 10079@end example 10080 10081@noindent 10082 10083Let's build the function: 10084 10085@example 10086gcc_jit_param n = ctxt.new_param (the_type, "n"); 10087std::vector<gccjit::param> params; 10088params.push_back (n); 10089gccjit::function func = 10090 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10091 return_type, 10092 "loop_test", 10093 params, 0); 10094@end example 10095 10096@noindent 10097 10098@menu 10099* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 10100* Control flow: Control flow<2>. 10101* Visualizing the control flow graph: Visualizing the control flow graph<2>. 10102* Full example: Full example<4>. 10103 10104@end menu 10105 10106@node Expressions lvalues and rvalues<2>,Control flow<2>,,Tutorial part 3 Loops and variables<2> 10107@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{12b} 10108@subsubsection Expressions: lvalues and rvalues 10109 10110 10111The base class of expression is the @code{gccjit::rvalue}, 10112representing an expression that can be on the @emph{right}-hand side of 10113an assignment: a value that can be computed somehow, and assigned 10114@emph{to} a storage area (such as a variable). It has a specific 10115@code{gccjit::type}. 10116 10117Anothe important class is @code{gccjit::lvalue}. 10118A @code{gccjit::lvalue}. is something that can of the @emph{left}-hand 10119side of an assignment: a storage area (such as a variable). 10120 10121In other words, every assignment can be thought of as: 10122 10123@example 10124LVALUE = RVALUE; 10125@end example 10126 10127@noindent 10128 10129Note that @code{gccjit::lvalue} is a subclass of 10130@code{gccjit::rvalue}, where in an assignment of the form: 10131 10132@example 10133LVALUE_A = LVALUE_B; 10134@end example 10135 10136@noindent 10137 10138the @cite{LVALUE_B} implies reading the current value of that storage 10139area, assigning it into the @cite{LVALUE_A}. 10140 10141So far the only expressions we've seen are from the previous tutorial: 10142 10143 10144@enumerate 10145 10146@item 10147the multiplication @cite{i * i}: 10148@end enumerate 10149 10150@quotation 10151 10152@example 10153gccjit::rvalue expr = 10154 ctxt.new_binary_op ( 10155 GCC_JIT_BINARY_OP_MULT, int_type, 10156 param_i, param_i); 10157 10158/* Alternatively, using operator-overloading: */ 10159gccjit::rvalue expr = param_i * param_i; 10160@end example 10161 10162@noindent 10163 10164which is a @code{gccjit::rvalue}, and 10165@end quotation 10166 10167 10168@enumerate 2 10169 10170@item 10171the various function parameters: @cite{param_i} and @cite{param_n}, instances of 10172@code{gccjit::param}, which is a subclass of @code{gccjit::lvalue} 10173(and, in turn, of @code{gccjit::rvalue}): 10174we can both read from and write to function parameters within the 10175body of a function. 10176@end enumerate 10177 10178Our new example has a new kind of expression: we have two local 10179variables. We create them by calling 10180@pxref{12c,,gccjit;;function;;new_local()}, supplying a type and a name: 10181 10182@example 10183/* Build locals: */ 10184gccjit::lvalue i = func.new_local (the_type, "i"); 10185gccjit::lvalue sum = func.new_local (the_type, "sum"); 10186@end example 10187 10188@noindent 10189 10190These are instances of @code{gccjit::lvalue} - they can be read from 10191and written to. 10192 10193Note that there is no precanned way to create @emph{and} initialize a variable 10194like in C: 10195 10196@example 10197int i = 0; 10198@end example 10199 10200@noindent 10201 10202Instead, having added the local to the function, we have to separately add 10203an assignment of @cite{0} to @cite{local_i} at the beginning of the function. 10204 10205@node Control flow<2>,Visualizing the control flow graph<2>,Expressions lvalues and rvalues<2>,Tutorial part 3 Loops and variables<2> 10206@anchor{cp/intro/tutorial03 control-flow}@anchor{12d} 10207@subsubsection Control flow 10208 10209 10210This function has a loop, so we need to build some basic blocks to 10211handle the control flow. In this case, we need 4 blocks: 10212 10213 10214@enumerate 10215 10216@item 10217before the loop (initializing the locals) 10218 10219@item 10220the conditional at the top of the loop (comparing @cite{i < n}) 10221 10222@item 10223the body of the loop 10224 10225@item 10226after the loop terminates (@cite{return sum}) 10227@end enumerate 10228 10229so we create these as @code{gccjit::block} instances within the 10230@code{gccjit::function}: 10231 10232@example 10233gccjit::block b_initial = func.new_block ("initial"); 10234gccjit::block b_loop_cond = func.new_block ("loop_cond"); 10235gccjit::block b_loop_body = func.new_block ("loop_body"); 10236gccjit::block b_after_loop = func.new_block ("after_loop"); 10237@end example 10238 10239@noindent 10240 10241We now populate each block with statements. 10242 10243The entry block @cite{b_initial} consists of initializations followed by a jump 10244to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using 10245@pxref{12e,,gccjit;;block;;add_assignment()} to add 10246an assignment statement, and using @pxref{12f,,gccjit;;context;;zero()} to get 10247the constant value @cite{0} for the relevant type for the right-hand side of 10248the assignment: 10249 10250@example 10251/* sum = 0; */ 10252b_initial.add_assignment (sum, ctxt.zero (the_type)); 10253 10254/* i = 0; */ 10255b_initial.add_assignment (i, ctxt.zero (the_type)); 10256@end example 10257 10258@noindent 10259 10260We can then terminate the entry block by jumping to the conditional: 10261 10262@example 10263b_initial.end_with_jump (b_loop_cond); 10264@end example 10265 10266@noindent 10267 10268The conditional block is equivalent to the line @cite{while (i < n)} from our 10269C example. It contains a single statement: a conditional, which jumps to 10270one of two destination blocks depending on a boolean 10271@code{gccjit::rvalue}, in this case the comparison of @cite{i} and @cite{n}. 10272 10273We could build the comparison using @pxref{130,,gccjit;;context;;new_comparison()}: 10274 10275@example 10276gccjit::rvalue guard = 10277 ctxt.new_comparison (GCC_JIT_COMPARISON_GE, 10278 i, n); 10279@end example 10280 10281@noindent 10282 10283and can then use this to add @cite{b_loop_cond}'s sole statement, via 10284@pxref{131,,gccjit;;block;;end_with_conditional()}: 10285 10286@example 10287b_loop_cond.end_with_conditional (guard, 10288 b_after_loop, // on_true 10289 b_loop_body); // on_false 10290@end example 10291 10292@noindent 10293 10294However @code{gccjit::rvalue} has overloaded operators for this, so we 10295express the conditional as 10296 10297@example 10298gccjit::rvalue guard = (i >= n); 10299@end example 10300 10301@noindent 10302 10303and hence we can write the block more concisely as: 10304 10305@example 10306b_loop_cond.end_with_conditional ( 10307 i >= n, 10308 b_after_loop, // on_true 10309 b_loop_body); // on_false 10310@end example 10311 10312@noindent 10313 10314Next, we populate the body of the loop. 10315 10316The C statement @cite{sum += i * i;} is an assignment operation, where an 10317lvalue is modified "in-place". We use 10318@pxref{132,,gccjit;;block;;add_assignment_op()} to handle these operations: 10319 10320@example 10321/* sum += i * i */ 10322b_loop_body.add_assignment_op (sum, 10323 GCC_JIT_BINARY_OP_PLUS, 10324 i * i); 10325@end example 10326 10327@noindent 10328 10329The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in 10330a similar way. We use @pxref{2f,,gcc_jit_context_one()} to get the constant 10331value @cite{1} (for the relevant type) for the right-hand side 10332of the assignment. 10333 10334@example 10335/* i++ */ 10336b_loop_body.add_assignment_op (i, 10337 GCC_JIT_BINARY_OP_PLUS, 10338 ctxt.one (the_type)); 10339@end example 10340 10341@noindent 10342 10343@cartouche 10344@quotation Note 10345For numeric constants other than 0 or 1, we could use 10346@pxref{133,,gccjit;;context;;new_rvalue()}, which has overloads 10347for both @code{int} and @code{double}. 10348@end quotation 10349@end cartouche 10350 10351The loop body completes by jumping back to the conditional: 10352 10353@example 10354b_loop_body.end_with_jump (b_loop_cond); 10355@end example 10356 10357@noindent 10358 10359Finally, we populate the @cite{b_after_loop} block, reached when the loop 10360conditional is false. We want to generate the equivalent of: 10361 10362@example 10363return sum; 10364@end example 10365 10366@noindent 10367 10368so the block is just one statement: 10369 10370@example 10371/* return sum */ 10372b_after_loop.end_with_return (sum); 10373@end example 10374 10375@noindent 10376 10377@cartouche 10378@quotation Note 10379You can intermingle block creation with statement creation, 10380but given that the terminator statements generally include references 10381to other blocks, I find it's clearer to create all the blocks, 10382@emph{then} all the statements. 10383@end quotation 10384@end cartouche 10385 10386We've finished populating the function. As before, we can now compile it 10387to machine code: 10388 10389@example 10390gcc_jit_result *result; 10391result = ctxt.compile (); 10392 10393ctxt.release (); 10394 10395if (!result) 10396 @{ 10397 fprintf (stderr, "NULL result"); 10398 return 1; 10399 @} 10400 10401typedef int (*loop_test_fn_type) (int); 10402loop_test_fn_type loop_test = 10403 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 10404if (!loop_test) 10405 @{ 10406 fprintf (stderr, "NULL loop_test"); 10407 gcc_jit_result_release (result); 10408 return 1; 10409 @} 10410printf ("result: %d", loop_test (10)); 10411@end example 10412 10413@noindent 10414 10415@example 10416result: 285 10417@end example 10418 10419@noindent 10420 10421@node Visualizing the control flow graph<2>,Full example<4>,Control flow<2>,Tutorial part 3 Loops and variables<2> 10422@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{134} 10423@subsubsection Visualizing the control flow graph 10424 10425 10426You can see the control flow graph of a function using 10427@pxref{135,,gccjit;;function;;dump_to_dot()}: 10428 10429@example 10430func.dump_to_dot ("/tmp/sum-of-squares.dot"); 10431@end example 10432 10433@noindent 10434 10435giving a .dot file in GraphViz format. 10436 10437You can convert this to an image using @cite{dot}: 10438 10439@example 10440$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png 10441@end example 10442 10443@noindent 10444 10445or use a viewer (my preferred one is xdot.py; see 10446@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can 10447install it with @cite{yum install python-xdot}): 10448 10449@quotation 10450 10451 10452@float Figure 10453 10454@image{sum-of-squares,,,image of a control flow graph,png} 10455 10456@end float 10457 10458@end quotation 10459 10460@node Full example<4>,,Visualizing the control flow graph<2>,Tutorial part 3 Loops and variables<2> 10461@anchor{cp/intro/tutorial03 full-example}@anchor{136} 10462@subsubsection Full example 10463 10464 10465@quotation 10466 10467@example 10468/* Usage example for libgccjit.so's C++ API 10469 Copyright (C) 2014-2018 Free Software Foundation, Inc. 10470 10471This file is part of GCC. 10472 10473GCC is free software; you can redistribute it and/or modify it 10474under the terms of the GNU General Public License as published by 10475the Free Software Foundation; either version 3, or (at your option) 10476any later version. 10477 10478GCC is distributed in the hope that it will be useful, but 10479WITHOUT ANY WARRANTY; without even the implied warranty of 10480MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10481General Public License for more details. 10482 10483You should have received a copy of the GNU General Public License 10484along with GCC; see the file COPYING3. If not see 10485<http://www.gnu.org/licenses/>. */ 10486 10487#include <libgccjit++.h> 10488 10489#include <stdlib.h> 10490#include <stdio.h> 10491 10492void 10493create_code (gccjit::context ctxt) 10494@{ 10495 /* 10496 Simple sum-of-squares, to test conditionals and looping 10497 10498 int loop_test (int n) 10499 @{ 10500 int i; 10501 int sum = 0; 10502 for (i = 0; i < n ; i ++) 10503 @{ 10504 sum += i * i; 10505 @} 10506 return sum; 10507 */ 10508 gccjit::type the_type = ctxt.get_int_type <int> (); 10509 gccjit::type return_type = the_type; 10510 10511 gccjit::param n = ctxt.new_param (the_type, "n"); 10512 std::vector<gccjit::param> params; 10513 params.push_back (n); 10514 gccjit::function func = 10515 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10516 return_type, 10517 "loop_test", 10518 params, 0); 10519 10520 /* Build locals: */ 10521 gccjit::lvalue i = func.new_local (the_type, "i"); 10522 gccjit::lvalue sum = func.new_local (the_type, "sum"); 10523 10524 gccjit::block b_initial = func.new_block ("initial"); 10525 gccjit::block b_loop_cond = func.new_block ("loop_cond"); 10526 gccjit::block b_loop_body = func.new_block ("loop_body"); 10527 gccjit::block b_after_loop = func.new_block ("after_loop"); 10528 10529 /* sum = 0; */ 10530 b_initial.add_assignment (sum, ctxt.zero (the_type)); 10531 10532 /* i = 0; */ 10533 b_initial.add_assignment (i, ctxt.zero (the_type)); 10534 10535 b_initial.end_with_jump (b_loop_cond); 10536 10537 /* if (i >= n) */ 10538 b_loop_cond.end_with_conditional ( 10539 i >= n, 10540 b_after_loop, 10541 b_loop_body); 10542 10543 /* sum += i * i */ 10544 b_loop_body.add_assignment_op (sum, 10545 GCC_JIT_BINARY_OP_PLUS, 10546 i * i); 10547 10548 /* i++ */ 10549 b_loop_body.add_assignment_op (i, 10550 GCC_JIT_BINARY_OP_PLUS, 10551 ctxt.one (the_type)); 10552 10553 b_loop_body.end_with_jump (b_loop_cond); 10554 10555 /* return sum */ 10556 b_after_loop.end_with_return (sum); 10557@} 10558 10559int 10560main (int argc, char **argv) 10561@{ 10562 gccjit::context ctxt; 10563 gcc_jit_result *result = NULL; 10564 10565 /* Get a "context" object for working with the library. */ 10566 ctxt = gccjit::context::acquire (); 10567 10568 /* Set some options on the context. 10569 Turn this on to see the code being generated, in assembler form. */ 10570 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 10571 0); 10572 10573 /* Populate the context. */ 10574 create_code (ctxt); 10575 10576 /* Compile the code. */ 10577 result = ctxt.compile (); 10578 10579 ctxt.release (); 10580 10581 if (!result) 10582 @{ 10583 fprintf (stderr, "NULL result"); 10584 return 1; 10585 @} 10586 10587 /* Extract the generated code from "result". */ 10588 typedef int (*loop_test_fn_type) (int); 10589 loop_test_fn_type loop_test = 10590 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 10591 if (!loop_test) 10592 @{ 10593 fprintf (stderr, "NULL loop_test"); 10594 gcc_jit_result_release (result); 10595 return 1; 10596 @} 10597 10598 /* Run the generated code. */ 10599 int val = loop_test (10); 10600 printf("loop_test returned: %d\n", val); 10601 10602 gcc_jit_result_release (result); 10603 return 0; 10604@} 10605 10606@end example 10607 10608@noindent 10609@end quotation 10610 10611Building and running it: 10612 10613@example 10614$ gcc \ 10615 tut03-sum-of-squares.cc \ 10616 -o tut03-sum-of-squares \ 10617 -lgccjit 10618 10619# Run the built program: 10620$ ./tut03-sum-of-squares 10621loop_test returned: 285 10622@end example 10623 10624@noindent 10625 10626@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 10627@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 10628@c 10629@c This is free software: you can redistribute it and/or modify it 10630@c under the terms of the GNU General Public License as published by 10631@c the Free Software Foundation, either version 3 of the License, or 10632@c (at your option) any later version. 10633@c 10634@c This program is distributed in the hope that it will be useful, but 10635@c WITHOUT ANY WARRANTY; without even the implied warranty of 10636@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10637@c General Public License for more details. 10638@c 10639@c You should have received a copy of the GNU General Public License 10640@c along with this program. If not, see 10641@c <http://www.gnu.org/licenses/>. 10642 10643@node Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,,Tutorial part 3 Loops and variables<2>,Tutorial<2> 10644@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{137}@anchor{cp/intro/tutorial04 doc}@anchor{138} 10645@subsection Tutorial part 4: Adding JIT-compilation to a toy interpreter 10646 10647 10648In this example we construct a "toy" interpreter, and add JIT-compilation 10649to it. 10650 10651@menu 10652* Our toy interpreter: Our toy interpreter<2>. 10653* Compiling to machine code: Compiling to machine code<2>. 10654* Setting things up: Setting things up<2>. 10655* Populating the function: Populating the function<2>. 10656* Verifying the control flow graph: Verifying the control flow graph<2>. 10657* Compiling the context: Compiling the context<2>. 10658* Single-stepping through the generated code: Single-stepping through the generated code<2>. 10659* Examining the generated code: Examining the generated code<2>. 10660* Putting it all together: Putting it all together<2>. 10661* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 10662 10663@end menu 10664 10665@node Our toy interpreter<2>,Compiling to machine code<2>,,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 10666@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{139} 10667@subsubsection Our toy interpreter 10668 10669 10670It's a stack-based interpreter, and is intended as a (very simple) example 10671of the kind of bytecode interpreter seen in dynamic languages such as 10672Python, Ruby etc. 10673 10674For the sake of simplicity, our toy virtual machine is very limited: 10675 10676@quotation 10677 10678 10679@itemize * 10680 10681@item 10682The only data type is @cite{int} 10683 10684@item 10685It can only work on one function at a time (so that the only 10686function call that can be made is to recurse). 10687 10688@item 10689Functions can only take one parameter. 10690 10691@item 10692Functions have a stack of @cite{int} values. 10693 10694@item 10695We'll implement function call within the interpreter by calling a 10696function in our implementation, rather than implementing our own 10697frame stack. 10698 10699@item 10700The parser is only good enough to get the examples to work. 10701@end itemize 10702@end quotation 10703 10704Naturally, a real interpreter would be much more complicated that this. 10705 10706The following operations are supported: 10707 10708 10709@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx} 10710@headitem 10711 10712Operation 10713 10714@tab 10715 10716Meaning 10717 10718@tab 10719 10720Old Stack 10721 10722@tab 10723 10724New Stack 10725 10726@item 10727 10728DUP 10729 10730@tab 10731 10732Duplicate top of stack. 10733 10734@tab 10735 10736@code{[..., x]} 10737 10738@tab 10739 10740@code{[..., x, x]} 10741 10742@item 10743 10744ROT 10745 10746@tab 10747 10748Swap top two elements 10749of stack. 10750 10751@tab 10752 10753@code{[..., x, y]} 10754 10755@tab 10756 10757@code{[..., y, x]} 10758 10759@item 10760 10761BINARY_ADD 10762 10763@tab 10764 10765Add the top two elements 10766on the stack. 10767 10768@tab 10769 10770@code{[..., x, y]} 10771 10772@tab 10773 10774@code{[..., (x+y)]} 10775 10776@item 10777 10778BINARY_SUBTRACT 10779 10780@tab 10781 10782Likewise, but subtract. 10783 10784@tab 10785 10786@code{[..., x, y]} 10787 10788@tab 10789 10790@code{[..., (x-y)]} 10791 10792@item 10793 10794BINARY_MULT 10795 10796@tab 10797 10798Likewise, but multiply. 10799 10800@tab 10801 10802@code{[..., x, y]} 10803 10804@tab 10805 10806@code{[..., (x*y)]} 10807 10808@item 10809 10810BINARY_COMPARE_LT 10811 10812@tab 10813 10814Compare the top two 10815elements on the stack 10816and push a nonzero/zero 10817if (x<y). 10818 10819@tab 10820 10821@code{[..., x, y]} 10822 10823@tab 10824 10825@code{[..., (x<y)]} 10826 10827@item 10828 10829RECURSE 10830 10831@tab 10832 10833Recurse, passing the top 10834of the stack, and 10835popping the result. 10836 10837@tab 10838 10839@code{[..., x]} 10840 10841@tab 10842 10843@code{[..., fn(x)]} 10844 10845@item 10846 10847RETURN 10848 10849@tab 10850 10851Return the top of the 10852stack. 10853 10854@tab 10855 10856@code{[x]} 10857 10858@tab 10859 10860@code{[]} 10861 10862@item 10863 10864PUSH_CONST @cite{arg} 10865 10866@tab 10867 10868Push an int const. 10869 10870@tab 10871 10872@code{[...]} 10873 10874@tab 10875 10876@code{[..., arg]} 10877 10878@item 10879 10880JUMP_ABS_IF_TRUE @cite{arg} 10881 10882@tab 10883 10884Pop; if top of stack was 10885nonzero, jump to 10886@code{arg}. 10887 10888@tab 10889 10890@code{[..., x]} 10891 10892@tab 10893 10894@code{[...]} 10895 10896@end multitable 10897 10898 10899Programs can be interpreted, disassembled, and compiled to machine code. 10900 10901The interpreter reads @code{.toy} scripts. Here's what a simple recursive 10902factorial program looks like, the script @code{factorial.toy}. 10903The parser ignores lines beginning with a @cite{#}. 10904 10905@quotation 10906 10907@example 10908# Simple recursive factorial implementation, roughly equivalent to: 10909# 10910# int factorial (int arg) 10911# @{ 10912# if (arg < 2) 10913# return arg 10914# return arg * factorial (arg - 1) 10915# @} 10916 10917# Initial state: 10918# stack: [arg] 10919 10920# 0: 10921DUP 10922# stack: [arg, arg] 10923 10924# 1: 10925PUSH_CONST 2 10926# stack: [arg, arg, 2] 10927 10928# 2: 10929BINARY_COMPARE_LT 10930# stack: [arg, (arg < 2)] 10931 10932# 3: 10933JUMP_ABS_IF_TRUE 9 10934# stack: [arg] 10935 10936# 4: 10937DUP 10938# stack: [arg, arg] 10939 10940# 5: 10941PUSH_CONST 1 10942# stack: [arg, arg, 1] 10943 10944# 6: 10945BINARY_SUBTRACT 10946# stack: [arg, (arg - 1) 10947 10948# 7: 10949RECURSE 10950# stack: [arg, factorial(arg - 1)] 10951 10952# 8: 10953BINARY_MULT 10954# stack: [arg * factorial(arg - 1)] 10955 10956# 9: 10957RETURN 10958 10959@end example 10960 10961@noindent 10962@end quotation 10963 10964The interpreter is a simple infinite loop with a big @code{switch} statement 10965based on what the next opcode is: 10966 10967@quotation 10968 10969@example 10970 10971int 10972toyvm_function::interpret (int arg, FILE *trace) 10973@{ 10974 toyvm_frame frame; 10975#define PUSH(ARG) (frame.push (ARG)) 10976#define POP(ARG) (frame.pop ()) 10977 10978 frame.frm_function = this; 10979 frame.frm_pc = 0; 10980 frame.frm_cur_depth = 0; 10981 10982 PUSH (arg); 10983 10984 while (1) 10985 @{ 10986 toyvm_op *op; 10987 int x, y; 10988 assert (frame.frm_pc < fn_num_ops); 10989 op = &fn_ops[frame.frm_pc++]; 10990 10991 if (trace) 10992 @{ 10993 frame.dump_stack (trace); 10994 disassemble_op (op, frame.frm_pc, trace); 10995 @} 10996 10997 switch (op->op_opcode) 10998 @{ 10999 /* Ops taking no operand. */ 11000 case DUP: 11001 x = POP (); 11002 PUSH (x); 11003 PUSH (x); 11004 break; 11005 11006 case ROT: 11007 y = POP (); 11008 x = POP (); 11009 PUSH (y); 11010 PUSH (x); 11011 break; 11012 11013 case BINARY_ADD: 11014 y = POP (); 11015 x = POP (); 11016 PUSH (x + y); 11017 break; 11018 11019 case BINARY_SUBTRACT: 11020 y = POP (); 11021 x = POP (); 11022 PUSH (x - y); 11023 break; 11024 11025 case BINARY_MULT: 11026 y = POP (); 11027 x = POP (); 11028 PUSH (x * y); 11029 break; 11030 11031 case BINARY_COMPARE_LT: 11032 y = POP (); 11033 x = POP (); 11034 PUSH (x < y); 11035 break; 11036 11037 case RECURSE: 11038 x = POP (); 11039 x = interpret (x, trace); 11040 PUSH (x); 11041 break; 11042 11043 case RETURN: 11044 return POP (); 11045 11046 /* Ops taking an operand. */ 11047 case PUSH_CONST: 11048 PUSH (op->op_operand); 11049 break; 11050 11051 case JUMP_ABS_IF_TRUE: 11052 x = POP (); 11053 if (x) 11054 frame.frm_pc = op->op_operand; 11055 break; 11056 11057 default: 11058 assert (0); /* unknown opcode */ 11059 11060 @} /* end of switch on opcode */ 11061 @} /* end of while loop */ 11062 11063#undef PUSH 11064#undef POP 11065@} 11066 11067 11068@end example 11069 11070@noindent 11071@end quotation 11072 11073@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> 11074@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{13a} 11075@subsubsection Compiling to machine code 11076 11077 11078We want to generate machine code that can be cast to this type and 11079then directly executed in-process: 11080 11081@quotation 11082 11083@example 11084typedef int (*toyvm_compiled_func) (int); 11085 11086 11087@end example 11088 11089@noindent 11090@end quotation 11091 11092Our compiler isn't very sophisticated; it takes the implementation of 11093each opcode above, and maps it directly to the operations supported by 11094the libgccjit API. 11095 11096How should we handle the stack? In theory we could calculate what the 11097stack depth will be at each opcode, and optimize away the stack 11098manipulation "by hand". We'll see below that libgccjit is able to do 11099this for us, so we'll implement stack manipulation 11100in a direct way, by creating a @code{stack} array and @code{stack_depth} 11101variables, local within the generated function, equivalent to this C code: 11102 11103@example 11104int stack_depth; 11105int stack[MAX_STACK_DEPTH]; 11106@end example 11107 11108@noindent 11109 11110We'll also have local variables @code{x} and @code{y} for use when implementing 11111the opcodes, equivalent to this: 11112 11113@example 11114int x; 11115int y; 11116@end example 11117 11118@noindent 11119 11120This means our compiler has the following state: 11121 11122@quotation 11123 11124@example 11125 11126 toyvm_function &toyvmfn; 11127 11128 gccjit::context ctxt; 11129 11130 gccjit::type int_type; 11131 gccjit::type bool_type; 11132 gccjit::type stack_type; /* int[MAX_STACK_DEPTH] */ 11133 11134 gccjit::rvalue const_one; 11135 11136 gccjit::function fn; 11137 gccjit::param param_arg; 11138 gccjit::lvalue stack; 11139 gccjit::lvalue stack_depth; 11140 gccjit::lvalue x; 11141 gccjit::lvalue y; 11142 11143 gccjit::location op_locs[MAX_OPS]; 11144 gccjit::block initial_block; 11145 gccjit::block op_blocks[MAX_OPS]; 11146 11147 11148@end example 11149 11150@noindent 11151@end quotation 11152 11153@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> 11154@anchor{cp/intro/tutorial04 setting-things-up}@anchor{13b} 11155@subsubsection Setting things up 11156 11157 11158First we create our types: 11159 11160@quotation 11161 11162@example 11163 11164void 11165compilation_state::create_types () 11166@{ 11167 /* Create types. */ 11168 int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 11169 bool_type = ctxt.get_type (GCC_JIT_TYPE_BOOL); 11170 stack_type = ctxt.new_array_type (int_type, MAX_STACK_DEPTH); 11171 11172 11173@end example 11174 11175@noindent 11176@end quotation 11177 11178along with extracting a useful @cite{int} constant: 11179 11180@quotation 11181 11182@example 11183 const_one = ctxt.one (int_type); 11184 11185@} 11186 11187 11188@end example 11189 11190@noindent 11191@end quotation 11192 11193We'll implement push and pop in terms of the @code{stack} array and 11194@code{stack_depth}. Here are helper functions for adding statements to 11195a block, implementing pushing and popping values: 11196 11197@quotation 11198 11199@example 11200 11201void 11202compilation_state::add_push (gccjit::block block, 11203 gccjit::rvalue rvalue, 11204 gccjit::location loc) 11205@{ 11206 /* stack[stack_depth] = RVALUE */ 11207 block.add_assignment ( 11208 /* stack[stack_depth] */ 11209 ctxt.new_array_access ( 11210 stack, 11211 stack_depth, 11212 loc), 11213 rvalue, 11214 loc); 11215 11216 /* "stack_depth++;". */ 11217 block.add_assignment_op ( 11218 stack_depth, 11219 GCC_JIT_BINARY_OP_PLUS, 11220 const_one, 11221 loc); 11222@} 11223 11224void 11225compilation_state::add_pop (gccjit::block block, 11226 gccjit::lvalue lvalue, 11227 gccjit::location loc) 11228@{ 11229 /* "--stack_depth;". */ 11230 block.add_assignment_op ( 11231 stack_depth, 11232 GCC_JIT_BINARY_OP_MINUS, 11233 const_one, 11234 loc); 11235 11236 /* "LVALUE = stack[stack_depth];". */ 11237 block.add_assignment ( 11238 lvalue, 11239 /* stack[stack_depth] */ 11240 ctxt.new_array_access (stack, 11241 stack_depth, 11242 loc), 11243 loc); 11244@} 11245 11246 11247@end example 11248 11249@noindent 11250@end quotation 11251 11252We will support single-stepping through the generated code in the 11253debugger, so we need to create @code{gccjit::location} instances, one 11254per operation in the source code. These will reference the lines of 11255e.g. @code{factorial.toy}. 11256 11257@quotation 11258 11259@example 11260 11261void 11262compilation_state::create_locations () 11263@{ 11264 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 11265 @{ 11266 toyvm_op *op = &toyvmfn.fn_ops[pc]; 11267 11268 op_locs[pc] = ctxt.new_location (toyvmfn.fn_filename, 11269 op->op_linenum, 11270 0); /* column */ 11271 @} 11272@} 11273 11274 11275@end example 11276 11277@noindent 11278@end quotation 11279 11280Let's create the function itself. As usual, we create its parameter 11281first, then use the parameter to create the function: 11282 11283@quotation 11284 11285@example 11286 11287void 11288compilation_state::create_function (const char *funcname) 11289@{ 11290 std::vector <gccjit::param> params; 11291 param_arg = ctxt.new_param (int_type, "arg", op_locs[0]); 11292 params.push_back (param_arg); 11293 fn = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 11294 int_type, 11295 funcname, 11296 params, 0, 11297 op_locs[0]); 11298 11299 11300@end example 11301 11302@noindent 11303@end quotation 11304 11305We create the locals within the function. 11306 11307@quotation 11308 11309@example 11310 stack = fn.new_local (stack_type, "stack"); 11311 stack_depth = fn.new_local (int_type, "stack_depth"); 11312 x = fn.new_local (int_type, "x"); 11313 y = fn.new_local (int_type, "y"); 11314 11315 11316@end example 11317 11318@noindent 11319@end quotation 11320 11321@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> 11322@anchor{cp/intro/tutorial04 populating-the-function}@anchor{13c} 11323@subsubsection Populating the function 11324 11325 11326There's some one-time initialization, and the API treats the first block 11327you create as the entrypoint of the function, so we need to create that 11328block first: 11329 11330@quotation 11331 11332@example 11333 initial_block = fn.new_block ("initial"); 11334 11335 11336@end example 11337 11338@noindent 11339@end quotation 11340 11341We can now create blocks for each of the operations. Most of these will 11342be consolidated into larger blocks when the optimizer runs. 11343 11344@quotation 11345 11346@example 11347 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 11348 @{ 11349 char buf[16]; 11350 sprintf (buf, "instr%i", pc); 11351 op_blocks[pc] = fn.new_block (buf); 11352 @} 11353 11354 11355@end example 11356 11357@noindent 11358@end quotation 11359 11360Now that we have a block it can jump to when it's done, we can populate 11361the initial block: 11362 11363@quotation 11364 11365@example 11366 11367 /* "stack_depth = 0;". */ 11368 initial_block.add_assignment (stack_depth, 11369 ctxt.zero (int_type), 11370 op_locs[0]); 11371 11372 /* "PUSH (arg);". */ 11373 add_push (initial_block, 11374 param_arg, 11375 op_locs[0]); 11376 11377 /* ...and jump to insn 0. */ 11378 initial_block.end_with_jump (op_blocks[0], 11379 op_locs[0]); 11380 11381 11382@end example 11383 11384@noindent 11385@end quotation 11386 11387We can now populate the blocks for the individual operations. We loop 11388through them, adding instructions to their blocks: 11389 11390@quotation 11391 11392@example 11393 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 11394 @{ 11395 gccjit::location loc = op_locs[pc]; 11396 11397 gccjit::block block = op_blocks[pc]; 11398 gccjit::block next_block = (pc < toyvmfn.fn_num_ops 11399 ? op_blocks[pc + 1] 11400 : NULL); 11401 11402 toyvm_op *op; 11403 op = &toyvmfn.fn_ops[pc]; 11404 11405 11406@end example 11407 11408@noindent 11409@end quotation 11410 11411We're going to have another big @code{switch} statement for implementing 11412the opcodes, this time for compiling them, rather than interpreting 11413them. It's helpful to have macros for implementing push and pop, so that 11414we can make the @code{switch} statement that's coming up look as much as 11415possible like the one above within the interpreter: 11416 11417@example 11418 11419#define X_EQUALS_POP()\ 11420 add_pop (block, x, loc) 11421#define Y_EQUALS_POP()\ 11422 add_pop (block, y, loc) 11423#define PUSH_RVALUE(RVALUE)\ 11424 add_push (block, (RVALUE), loc) 11425#define PUSH_X()\ 11426 PUSH_RVALUE (x) 11427#define PUSH_Y() \ 11428 PUSH_RVALUE (y) 11429 11430 11431@end example 11432 11433@noindent 11434 11435@cartouche 11436@quotation Note 11437A particularly clever implementation would have an @emph{identical} 11438@code{switch} statement shared by the interpreter and the compiler, with 11439some preprocessor "magic". We're not doing that here, for the sake 11440of simplicity. 11441@end quotation 11442@end cartouche 11443 11444When I first implemented this compiler, I accidentally missed an edit 11445when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the 11446stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y} 11447uninitialized. 11448 11449To track this kind of thing down, we can use 11450@pxref{13d,,gccjit;;block;;add_comment()} to add descriptive comments 11451to the internal representation. This is invaluable when looking through 11452the generated IR for, say @code{factorial}: 11453 11454@quotation 11455 11456@example 11457 11458 block.add_comment (opcode_names[op->op_opcode], loc); 11459 11460 11461@end example 11462 11463@noindent 11464@end quotation 11465 11466We can now write the big @code{switch} statement that implements the 11467individual opcodes, populating the relevant block with statements: 11468 11469@quotation 11470 11471@example 11472 11473 switch (op->op_opcode) 11474 @{ 11475 case DUP: 11476 X_EQUALS_POP (); 11477 PUSH_X (); 11478 PUSH_X (); 11479 break; 11480 11481 case ROT: 11482 Y_EQUALS_POP (); 11483 X_EQUALS_POP (); 11484 PUSH_Y (); 11485 PUSH_X (); 11486 break; 11487 11488 case BINARY_ADD: 11489 Y_EQUALS_POP (); 11490 X_EQUALS_POP (); 11491 PUSH_RVALUE ( 11492 ctxt.new_binary_op ( 11493 GCC_JIT_BINARY_OP_PLUS, 11494 int_type, 11495 x, y, 11496 loc)); 11497 break; 11498 11499 case BINARY_SUBTRACT: 11500 Y_EQUALS_POP (); 11501 X_EQUALS_POP (); 11502 PUSH_RVALUE ( 11503 ctxt.new_binary_op ( 11504 GCC_JIT_BINARY_OP_MINUS, 11505 int_type, 11506 x, y, 11507 loc)); 11508 break; 11509 11510 case BINARY_MULT: 11511 Y_EQUALS_POP (); 11512 X_EQUALS_POP (); 11513 PUSH_RVALUE ( 11514 ctxt.new_binary_op ( 11515 GCC_JIT_BINARY_OP_MULT, 11516 int_type, 11517 x, y, 11518 loc)); 11519 break; 11520 11521 case BINARY_COMPARE_LT: 11522 Y_EQUALS_POP (); 11523 X_EQUALS_POP (); 11524 PUSH_RVALUE ( 11525 /* cast of bool to int */ 11526 ctxt.new_cast ( 11527 /* (x < y) as a bool */ 11528 ctxt.new_comparison ( 11529 GCC_JIT_COMPARISON_LT, 11530 x, y, 11531 loc), 11532 int_type, 11533 loc)); 11534 break; 11535 11536 case RECURSE: 11537 @{ 11538 X_EQUALS_POP (); 11539 PUSH_RVALUE ( 11540 ctxt.new_call ( 11541 fn, 11542 x, 11543 loc)); 11544 break; 11545 @} 11546 11547 case RETURN: 11548 X_EQUALS_POP (); 11549 block.end_with_return (x, loc); 11550 break; 11551 11552 /* Ops taking an operand. */ 11553 case PUSH_CONST: 11554 PUSH_RVALUE ( 11555 ctxt.new_rvalue (int_type, op->op_operand)); 11556 break; 11557 11558 case JUMP_ABS_IF_TRUE: 11559 X_EQUALS_POP (); 11560 block.end_with_conditional ( 11561 /* "(bool)x". */ 11562 ctxt.new_cast (x, bool_type, loc), 11563 op_blocks[op->op_operand], /* on_true */ 11564 next_block, /* on_false */ 11565 loc); 11566 break; 11567 11568 default: 11569 assert(0); 11570 @} /* end of switch on opcode */ 11571 11572 11573@end example 11574 11575@noindent 11576@end quotation 11577 11578Every block must be terminated, via a call to one of the 11579@code{gccjit::block::end_with_} entrypoints. This has been done for two 11580of the opcodes, but we need to do it for the other ones, by jumping 11581to the next block. 11582 11583@quotation 11584 11585@example 11586 if (op->op_opcode != JUMP_ABS_IF_TRUE 11587 && op->op_opcode != RETURN) 11588 block.end_with_jump (next_block, loc); 11589 11590 11591@end example 11592 11593@noindent 11594@end quotation 11595 11596This is analogous to simply incrementing the program counter. 11597 11598@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> 11599@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{13e} 11600@subsubsection Verifying the control flow graph 11601 11602 11603Having finished looping over the blocks, the context is complete. 11604 11605As before, we can verify that the control flow and statements are sane by 11606using @pxref{135,,gccjit;;function;;dump_to_dot()}: 11607 11608@example 11609fn.dump_to_dot ("/tmp/factorial.dot"); 11610@end example 11611 11612@noindent 11613 11614and viewing the result. Note how the label names, comments, and 11615variable names show up in the dump, to make it easier to spot 11616errors in our compiler. 11617 11618@quotation 11619 11620 11621@float Figure 11622 11623@image{factorial,,,image of a control flow graph,png} 11624 11625@end float 11626 11627@end quotation 11628 11629@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> 11630@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{13f} 11631@subsubsection Compiling the context 11632 11633 11634Having finished looping over the blocks and populating them with 11635statements, the context is complete. 11636 11637We can now compile it, extract machine code from the result, and 11638run it: 11639 11640@quotation 11641 11642@example 11643 11644class compilation_result 11645@{ 11646public: 11647 compilation_result (gcc_jit_result *result) : 11648 m_result (result) 11649 @{ 11650 @} 11651 ~compilation_result () 11652 @{ 11653 gcc_jit_result_release (m_result); 11654 @} 11655 11656 void *get_code (const char *funcname) 11657 @{ 11658 return gcc_jit_result_get_code (m_result, funcname); 11659 @} 11660 11661private: 11662 gcc_jit_result *m_result; 11663@}; 11664 11665 11666@end example 11667 11668@noindent 11669 11670@example 11671 compilation_result compiler_result = fn->compile (); 11672 11673 const char *funcname = fn->get_function_name (); 11674 toyvm_compiled_func code 11675 = (toyvm_compiled_func)compiler_result.get_code (funcname); 11676 11677 printf ("compiler result: %d\n", 11678 code (atoi (argv[2]))); 11679 11680 11681@end example 11682 11683@noindent 11684@end quotation 11685 11686@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> 11687@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{140} 11688@subsubsection Single-stepping through the generated code 11689 11690 11691It's possible to debug the generated code. To do this we need to both: 11692 11693@quotation 11694 11695 11696@itemize * 11697 11698@item 11699Set up source code locations for our statements, so that we can 11700meaningfully step through the code. We did this above by 11701calling @pxref{141,,gccjit;;context;;new_location()} and using the 11702results. 11703 11704@item 11705Enable the generation of debugging information, by setting 11706@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 11707@code{gccjit::context} via 11708@pxref{126,,gccjit;;context;;set_bool_option()}: 11709 11710@example 11711ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1); 11712@end example 11713 11714@noindent 11715@end itemize 11716@end quotation 11717 11718Having done this, we can put a breakpoint on the generated function: 11719 11720@example 11721$ gdb --args ./toyvm factorial.toy 10 11722(gdb) break factorial 11723Function "factorial" not defined. 11724Make breakpoint pending on future shared library load? (y or [n]) y 11725Breakpoint 1 (factorial) pending. 11726(gdb) run 11727Breakpoint 1, factorial (arg=10) at factorial.toy:14 1172814 DUP 11729@end example 11730 11731@noindent 11732 11733We've set up location information, which references @code{factorial.toy}. 11734This allows us to use e.g. @code{list} to see where we are in the script: 11735 11736@example 11737(gdb) list 117389 1173910 # Initial state: 1174011 # stack: [arg] 1174112 1174213 # 0: 1174314 DUP 1174415 # stack: [arg, arg] 1174516 1174617 # 1: 1174718 PUSH_CONST 2 11748@end example 11749 11750@noindent 11751 11752and to step through the function, examining the data: 11753 11754@example 11755(gdb) n 1175618 PUSH_CONST 2 11757(gdb) n 1175822 BINARY_COMPARE_LT 11759(gdb) print stack 11760$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@} 11761(gdb) print stack_depth 11762$6 = 3 11763@end example 11764 11765@noindent 11766 11767You'll see that the parts of the @code{stack} array that haven't been 11768touched yet are uninitialized. 11769 11770@cartouche 11771@quotation Note 11772Turning on optimizations may lead to unpredictable results when 11773stepping through the generated code: the execution may appear to 11774"jump around" the source code. This is analogous to turning up the 11775optimization level in a regular compiler. 11776@end quotation 11777@end cartouche 11778 11779@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> 11780@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{142} 11781@subsubsection Examining the generated code 11782 11783 11784How good is the optimized code? 11785 11786We can turn up optimizations, by calling 11787@pxref{127,,gccjit;;context;;set_int_option()} with 11788@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 11789 11790@example 11791ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); 11792@end example 11793 11794@noindent 11795 11796One of GCC's internal representations is called "gimple". A dump of the 11797initial gimple representation of the code can be seen by setting: 11798 11799@example 11800ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); 11801@end example 11802 11803@noindent 11804 11805With optimization on and source locations displayed, this gives: 11806 11807@c We'll use "c" for gimple dumps 11808 11809@example 11810factorial (signed int arg) 11811@{ 11812 <unnamed type> D.80; 11813 signed int D.81; 11814 signed int D.82; 11815 signed int D.83; 11816 signed int D.84; 11817 signed int D.85; 11818 signed int y; 11819 signed int x; 11820 signed int stack_depth; 11821 signed int stack[8]; 11822 11823 try 11824 @{ 11825 initial: 11826 stack_depth = 0; 11827 stack[stack_depth] = arg; 11828 stack_depth = stack_depth + 1; 11829 goto instr0; 11830 instr0: 11831 /* DUP */: 11832 stack_depth = stack_depth + -1; 11833 x = stack[stack_depth]; 11834 stack[stack_depth] = x; 11835 stack_depth = stack_depth + 1; 11836 stack[stack_depth] = x; 11837 stack_depth = stack_depth + 1; 11838 goto instr1; 11839 instr1: 11840 /* PUSH_CONST */: 11841 stack[stack_depth] = 2; 11842 stack_depth = stack_depth + 1; 11843 goto instr2; 11844 11845 /* etc */ 11846@end example 11847 11848@noindent 11849 11850You can see the generated machine code in assembly form via: 11851 11852@example 11853ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); 11854result = ctxt.compile (); 11855@end example 11856 11857@noindent 11858 11859which shows that (on this x86_64 box) the compiler has unrolled the loop 11860and is using MMX instructions to perform several multiplications 11861simultaneously: 11862 11863@example 11864 .file "fake.c" 11865 .text 11866.Ltext0: 11867 .p2align 4,,15 11868 .globl factorial 11869 .type factorial, @@function 11870factorial: 11871.LFB0: 11872 .file 1 "factorial.toy" 11873 .loc 1 14 0 11874 .cfi_startproc 11875.LVL0: 11876.L2: 11877 .loc 1 26 0 11878 cmpl $1, %edi 11879 jle .L13 11880 leal -1(%rdi), %edx 11881 movl %edx, %ecx 11882 shrl $2, %ecx 11883 leal 0(,%rcx,4), %esi 11884 testl %esi, %esi 11885 je .L14 11886 cmpl $9, %edx 11887 jbe .L14 11888 leal -2(%rdi), %eax 11889 movl %eax, -16(%rsp) 11890 leal -3(%rdi), %eax 11891 movd -16(%rsp), %xmm0 11892 movl %edi, -16(%rsp) 11893 movl %eax, -12(%rsp) 11894 movd -16(%rsp), %xmm1 11895 xorl %eax, %eax 11896 movl %edx, -16(%rsp) 11897 movd -12(%rsp), %xmm4 11898 movd -16(%rsp), %xmm6 11899 punpckldq %xmm4, %xmm0 11900 movdqa .LC1(%rip), %xmm4 11901 punpckldq %xmm6, %xmm1 11902 punpcklqdq %xmm0, %xmm1 11903 movdqa .LC0(%rip), %xmm0 11904 jmp .L5 11905 # etc - edited for brevity 11906@end example 11907 11908@noindent 11909 11910This is clearly overkill for a function that will likely overflow the 11911@code{int} type before the vectorization is worthwhile - but then again, this 11912is a toy example. 11913 11914Turning down the optimization level to 2: 11915 11916@example 11917ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2); 11918@end example 11919 11920@noindent 11921 11922yields this code, which is simple enough to quote in its entirety: 11923 11924@example 11925 .file "fake.c" 11926 .text 11927 .p2align 4,,15 11928 .globl factorial 11929 .type factorial, @@function 11930factorial: 11931.LFB0: 11932 .cfi_startproc 11933.L2: 11934 cmpl $1, %edi 11935 jle .L8 11936 movl $1, %edx 11937 jmp .L4 11938 .p2align 4,,10 11939 .p2align 3 11940.L6: 11941 movl %eax, %edi 11942.L4: 11943.L5: 11944 leal -1(%rdi), %eax 11945 imull %edi, %edx 11946 cmpl $1, %eax 11947 jne .L6 11948.L3: 11949.L7: 11950 imull %edx, %eax 11951 ret 11952.L8: 11953 movl %edi, %eax 11954 movl $1, %edx 11955 jmp .L7 11956 .cfi_endproc 11957.LFE0: 11958 .size factorial, .-factorial 11959 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})" 11960 .section .note.GNU-stack,"",@@progbits 11961@end example 11962 11963@noindent 11964 11965Note that the stack pushing and popping have been eliminated, as has the 11966recursive call (in favor of an iteration). 11967 11968@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> 11969@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{143} 11970@subsubsection Putting it all together 11971 11972 11973The complete example can be seen in the source tree at 11974@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.cc} 11975 11976along with a Makefile and a couple of sample .toy scripts: 11977 11978@example 11979$ ls -al 11980drwxrwxr-x. 2 david david 4096 Sep 19 17:46 . 11981drwxrwxr-x. 3 david david 4096 Sep 19 15:26 .. 11982-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy 11983-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy 11984-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile 11985-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.cc 11986 11987$ make toyvm 11988g++ -Wall -g -o toyvm toyvm.cc -lgccjit 11989 11990$ ./toyvm factorial.toy 10 11991interpreter result: 3628800 11992compiler result: 3628800 11993 11994$ ./toyvm fibonacci.toy 10 11995interpreter result: 55 11996compiler result: 55 11997@end example 11998 11999@noindent 12000 12001@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> 12002@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{144} 12003@subsubsection Behind the curtain: How does our code get optimized? 12004 12005 12006Our example is done, but you may be wondering about exactly how the 12007compiler turned what we gave it into the machine code seen above. 12008 12009We can examine what the compiler is doing in detail by setting: 12010 12011@example 12012state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 1); 12013state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 1); 12014@end example 12015 12016@noindent 12017 12018This will dump detailed information about the compiler's state to a 12019directory under @code{/tmp}, and keep it from being cleaned up. 12020 12021The precise names and their formats of these files is subject to change. 12022Higher optimization levels lead to more files. 12023Here's what I saw (edited for brevity; there were almost 200 files): 12024 12025@example 12026intermediate files written to /tmp/libgccjit-KPQbGw 12027$ ls /tmp/libgccjit-KPQbGw/ 12028fake.c.000i.cgraph 12029fake.c.000i.type-inheritance 12030fake.c.004t.gimple 12031fake.c.007t.omplower 12032fake.c.008t.lower 12033fake.c.011t.eh 12034fake.c.012t.cfg 12035fake.c.014i.visibility 12036fake.c.015i.early_local_cleanups 12037fake.c.016t.ssa 12038# etc 12039@end example 12040 12041@noindent 12042 12043The gimple code is converted into Static Single Assignment form, 12044with annotations for use when generating the debuginfo: 12045 12046@example 12047$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa 12048@end example 12049 12050@noindent 12051 12052@example 12053;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12054 12055factorial (signed int arg) 12056@{ 12057 signed int stack[8]; 12058 signed int stack_depth; 12059 signed int x; 12060 signed int y; 12061 <unnamed type> _20; 12062 signed int _21; 12063 signed int _38; 12064 signed int _44; 12065 signed int _51; 12066 signed int _56; 12067 12068initial: 12069 stack_depth_3 = 0; 12070 # DEBUG stack_depth => stack_depth_3 12071 stack[stack_depth_3] = arg_5(D); 12072 stack_depth_7 = stack_depth_3 + 1; 12073 # DEBUG stack_depth => stack_depth_7 12074 # DEBUG instr0 => NULL 12075 # DEBUG /* DUP */ => NULL 12076 stack_depth_8 = stack_depth_7 + -1; 12077 # DEBUG stack_depth => stack_depth_8 12078 x_9 = stack[stack_depth_8]; 12079 # DEBUG x => x_9 12080 stack[stack_depth_8] = x_9; 12081 stack_depth_11 = stack_depth_8 + 1; 12082 # DEBUG stack_depth => stack_depth_11 12083 stack[stack_depth_11] = x_9; 12084 stack_depth_13 = stack_depth_11 + 1; 12085 # DEBUG stack_depth => stack_depth_13 12086 # DEBUG instr1 => NULL 12087 # DEBUG /* PUSH_CONST */ => NULL 12088 stack[stack_depth_13] = 2; 12089 12090 /* etc; edited for brevity */ 12091@end example 12092 12093@noindent 12094 12095We can perhaps better see the code by turning off 12096@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG} 12097statements, giving: 12098 12099@example 12100$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa 12101@end example 12102 12103@noindent 12104 12105@example 12106;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12107 12108factorial (signed int arg) 12109@{ 12110 signed int stack[8]; 12111 signed int stack_depth; 12112 signed int x; 12113 signed int y; 12114 <unnamed type> _20; 12115 signed int _21; 12116 signed int _38; 12117 signed int _44; 12118 signed int _51; 12119 signed int _56; 12120 12121initial: 12122 stack_depth_3 = 0; 12123 stack[stack_depth_3] = arg_5(D); 12124 stack_depth_7 = stack_depth_3 + 1; 12125 stack_depth_8 = stack_depth_7 + -1; 12126 x_9 = stack[stack_depth_8]; 12127 stack[stack_depth_8] = x_9; 12128 stack_depth_11 = stack_depth_8 + 1; 12129 stack[stack_depth_11] = x_9; 12130 stack_depth_13 = stack_depth_11 + 1; 12131 stack[stack_depth_13] = 2; 12132 stack_depth_15 = stack_depth_13 + 1; 12133 stack_depth_16 = stack_depth_15 + -1; 12134 y_17 = stack[stack_depth_16]; 12135 stack_depth_18 = stack_depth_16 + -1; 12136 x_19 = stack[stack_depth_18]; 12137 _20 = x_19 < y_17; 12138 _21 = (signed int) _20; 12139 stack[stack_depth_18] = _21; 12140 stack_depth_23 = stack_depth_18 + 1; 12141 stack_depth_24 = stack_depth_23 + -1; 12142 x_25 = stack[stack_depth_24]; 12143 if (x_25 != 0) 12144 goto <bb 4> (instr9); 12145 else 12146 goto <bb 3> (instr4); 12147 12148instr4: 12149/* DUP */: 12150 stack_depth_26 = stack_depth_24 + -1; 12151 x_27 = stack[stack_depth_26]; 12152 stack[stack_depth_26] = x_27; 12153 stack_depth_29 = stack_depth_26 + 1; 12154 stack[stack_depth_29] = x_27; 12155 stack_depth_31 = stack_depth_29 + 1; 12156 stack[stack_depth_31] = 1; 12157 stack_depth_33 = stack_depth_31 + 1; 12158 stack_depth_34 = stack_depth_33 + -1; 12159 y_35 = stack[stack_depth_34]; 12160 stack_depth_36 = stack_depth_34 + -1; 12161 x_37 = stack[stack_depth_36]; 12162 _38 = x_37 - y_35; 12163 stack[stack_depth_36] = _38; 12164 stack_depth_40 = stack_depth_36 + 1; 12165 stack_depth_41 = stack_depth_40 + -1; 12166 x_42 = stack[stack_depth_41]; 12167 _44 = factorial (x_42); 12168 stack[stack_depth_41] = _44; 12169 stack_depth_46 = stack_depth_41 + 1; 12170 stack_depth_47 = stack_depth_46 + -1; 12171 y_48 = stack[stack_depth_47]; 12172 stack_depth_49 = stack_depth_47 + -1; 12173 x_50 = stack[stack_depth_49]; 12174 _51 = x_50 * y_48; 12175 stack[stack_depth_49] = _51; 12176 stack_depth_53 = stack_depth_49 + 1; 12177 12178 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)> 12179instr9: 12180/* RETURN */: 12181 stack_depth_54 = stack_depth_1 + -1; 12182 x_55 = stack[stack_depth_54]; 12183 _56 = x_55; 12184 stack =@{v@} @{CLOBBER@}; 12185 return _56; 12186 12187@} 12188@end example 12189 12190@noindent 12191 12192Note in the above how all the @code{gccjit::block} instances we 12193created have been consolidated into just 3 blocks in GCC's internal 12194representation: @code{initial}, @code{instr4} and @code{instr9}. 12195 12196@menu 12197* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 12198* Elimination of tail recursion: Elimination of tail recursion<2>. 12199 12200@end menu 12201 12202@node Optimizing away stack manipulation<2>,Elimination of tail recursion<2>,,Behind the curtain How does our code get optimized?<2> 12203@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{145} 12204@subsubsection Optimizing away stack manipulation 12205 12206 12207Recall our simple implementation of stack operations. Let's examine 12208how the stack operations are optimized away. 12209 12210After a pass of constant-propagation, the depth of the stack at each 12211opcode can be determined at compile-time: 12212 12213@example 12214$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1 12215@end example 12216 12217@noindent 12218 12219@example 12220;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12221 12222factorial (signed int arg) 12223@{ 12224 signed int stack[8]; 12225 signed int stack_depth; 12226 signed int x; 12227 signed int y; 12228 <unnamed type> _20; 12229 signed int _21; 12230 signed int _38; 12231 signed int _44; 12232 signed int _51; 12233 12234initial: 12235 stack[0] = arg_5(D); 12236 x_9 = stack[0]; 12237 stack[0] = x_9; 12238 stack[1] = x_9; 12239 stack[2] = 2; 12240 y_17 = stack[2]; 12241 x_19 = stack[1]; 12242 _20 = x_19 < y_17; 12243 _21 = (signed int) _20; 12244 stack[1] = _21; 12245 x_25 = stack[1]; 12246 if (x_25 != 0) 12247 goto <bb 4> (instr9); 12248 else 12249 goto <bb 3> (instr4); 12250 12251instr4: 12252/* DUP */: 12253 x_27 = stack[0]; 12254 stack[0] = x_27; 12255 stack[1] = x_27; 12256 stack[2] = 1; 12257 y_35 = stack[2]; 12258 x_37 = stack[1]; 12259 _38 = x_37 - y_35; 12260 stack[1] = _38; 12261 x_42 = stack[1]; 12262 _44 = factorial (x_42); 12263 stack[1] = _44; 12264 y_48 = stack[1]; 12265 x_50 = stack[0]; 12266 _51 = x_50 * y_48; 12267 stack[0] = _51; 12268 12269instr9: 12270/* RETURN */: 12271 x_55 = stack[0]; 12272 x_56 = x_55; 12273 stack =@{v@} @{CLOBBER@}; 12274 return x_56; 12275 12276@} 12277@end example 12278 12279@noindent 12280 12281Note how, in the above, all those @code{stack_depth} values are now just 12282constants: we're accessing specific stack locations at each opcode. 12283 12284The "esra" pass ("Early Scalar Replacement of Aggregates") breaks 12285out our "stack" array into individual elements: 12286 12287@example 12288$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra 12289@end example 12290 12291@noindent 12292 12293@example 12294;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12295 12296Created a replacement for stack offset: 0, size: 32: stack$0 12297Created a replacement for stack offset: 32, size: 32: stack$1 12298Created a replacement for stack offset: 64, size: 32: stack$2 12299 12300Symbols to be put in SSA form 12301@{ D.89 D.90 D.91 @} 12302Incremental SSA update started at block: 0 12303Number of blocks in CFG: 5 12304Number of blocks to update: 4 ( 80%) 12305 12306 12307factorial (signed int arg) 12308@{ 12309 signed int stack$2; 12310 signed int stack$1; 12311 signed int stack$0; 12312 signed int stack[8]; 12313 signed int stack_depth; 12314 signed int x; 12315 signed int y; 12316 <unnamed type> _20; 12317 signed int _21; 12318 signed int _38; 12319 signed int _44; 12320 signed int _51; 12321 12322initial: 12323 stack$0_45 = arg_5(D); 12324 x_9 = stack$0_45; 12325 stack$0_39 = x_9; 12326 stack$1_32 = x_9; 12327 stack$2_30 = 2; 12328 y_17 = stack$2_30; 12329 x_19 = stack$1_32; 12330 _20 = x_19 < y_17; 12331 _21 = (signed int) _20; 12332 stack$1_28 = _21; 12333 x_25 = stack$1_28; 12334 if (x_25 != 0) 12335 goto <bb 4> (instr9); 12336 else 12337 goto <bb 3> (instr4); 12338 12339instr4: 12340/* DUP */: 12341 x_27 = stack$0_39; 12342 stack$0_22 = x_27; 12343 stack$1_14 = x_27; 12344 stack$2_12 = 1; 12345 y_35 = stack$2_12; 12346 x_37 = stack$1_14; 12347 _38 = x_37 - y_35; 12348 stack$1_10 = _38; 12349 x_42 = stack$1_10; 12350 _44 = factorial (x_42); 12351 stack$1_6 = _44; 12352 y_48 = stack$1_6; 12353 x_50 = stack$0_22; 12354 _51 = x_50 * y_48; 12355 stack$0_1 = _51; 12356 12357 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)> 12358instr9: 12359/* RETURN */: 12360 x_55 = stack$0_52; 12361 x_56 = x_55; 12362 stack =@{v@} @{CLOBBER@}; 12363 return x_56; 12364 12365@} 12366@end example 12367 12368@noindent 12369 12370Hence at this point, all those pushes and pops of the stack are now 12371simply assignments to specific temporary variables. 12372 12373After some copy propagation, the stack manipulation has been completely 12374optimized away: 12375 12376@example 12377$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1 12378@end example 12379 12380@noindent 12381 12382@example 12383;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12384 12385factorial (signed int arg) 12386@{ 12387 signed int stack$2; 12388 signed int stack$1; 12389 signed int stack$0; 12390 signed int stack[8]; 12391 signed int stack_depth; 12392 signed int x; 12393 signed int y; 12394 <unnamed type> _20; 12395 signed int _21; 12396 signed int _38; 12397 signed int _44; 12398 signed int _51; 12399 12400initial: 12401 stack$0_39 = arg_5(D); 12402 _20 = arg_5(D) <= 1; 12403 _21 = (signed int) _20; 12404 if (_21 != 0) 12405 goto <bb 4> (instr9); 12406 else 12407 goto <bb 3> (instr4); 12408 12409instr4: 12410/* DUP */: 12411 _38 = arg_5(D) + -1; 12412 _44 = factorial (_38); 12413 _51 = arg_5(D) * _44; 12414 stack$0_1 = _51; 12415 12416 # stack$0_52 = PHI <arg_5(D)(2), _51(3)> 12417instr9: 12418/* RETURN */: 12419 stack =@{v@} @{CLOBBER@}; 12420 return stack$0_52; 12421 12422@} 12423@end example 12424 12425@noindent 12426 12427Later on, another pass finally eliminated @code{stack_depth} local and the 12428unused parts of the @cite{stack`} array altogether: 12429 12430@example 12431$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa 12432@end example 12433 12434@noindent 12435 12436@example 12437;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12438 12439Released 44 names, 314.29%, removed 44 holes 12440factorial (signed int arg) 12441@{ 12442 signed int stack$0; 12443 signed int mult_acc_1; 12444 <unnamed type> _5; 12445 signed int _6; 12446 signed int _7; 12447 signed int mul_tmp_10; 12448 signed int mult_acc_11; 12449 signed int mult_acc_13; 12450 12451 # arg_9 = PHI <arg_8(D)(0)> 12452 # mult_acc_13 = PHI <1(0)> 12453initial: 12454 12455 <bb 5>: 12456 # arg_4 = PHI <arg_9(2), _7(3)> 12457 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)> 12458 _5 = arg_4 <= 1; 12459 _6 = (signed int) _5; 12460 if (_6 != 0) 12461 goto <bb 4> (instr9); 12462 else 12463 goto <bb 3> (instr4); 12464 12465instr4: 12466/* DUP */: 12467 _7 = arg_4 + -1; 12468 mult_acc_11 = mult_acc_1 * arg_4; 12469 goto <bb 5>; 12470 12471 # stack$0_12 = PHI <arg_4(5)> 12472instr9: 12473/* RETURN */: 12474 mul_tmp_10 = mult_acc_1 * stack$0_12; 12475 return mul_tmp_10; 12476 12477@} 12478@end example 12479 12480@noindent 12481 12482@node Elimination of tail recursion<2>,,Optimizing away stack manipulation<2>,Behind the curtain How does our code get optimized?<2> 12483@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{146} 12484@subsubsection Elimination of tail recursion 12485 12486 12487Another significant optimization is the detection that the call to 12488@code{factorial} is tail recursion, which can be eliminated in favor of 12489an iteration: 12490 12491@example 12492$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1 12493@end example 12494 12495@noindent 12496 12497@example 12498;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12499 12500 12501Symbols to be put in SSA form 12502@{ D.88 @} 12503Incremental SSA update started at block: 0 12504Number of blocks in CFG: 5 12505Number of blocks to update: 4 ( 80%) 12506 12507 12508factorial (signed int arg) 12509@{ 12510 signed int stack$2; 12511 signed int stack$1; 12512 signed int stack$0; 12513 signed int stack[8]; 12514 signed int stack_depth; 12515 signed int x; 12516 signed int y; 12517 signed int mult_acc_1; 12518 <unnamed type> _20; 12519 signed int _21; 12520 signed int _38; 12521 signed int mul_tmp_44; 12522 signed int mult_acc_51; 12523 12524 # arg_5 = PHI <arg_39(D)(0), _38(3)> 12525 # mult_acc_1 = PHI <1(0), mult_acc_51(3)> 12526initial: 12527 _20 = arg_5 <= 1; 12528 _21 = (signed int) _20; 12529 if (_21 != 0) 12530 goto <bb 4> (instr9); 12531 else 12532 goto <bb 3> (instr4); 12533 12534instr4: 12535/* DUP */: 12536 _38 = arg_5 + -1; 12537 mult_acc_51 = mult_acc_1 * arg_5; 12538 goto <bb 2> (initial); 12539 12540 # stack$0_52 = PHI <arg_5(2)> 12541instr9: 12542/* RETURN */: 12543 stack =@{v@} @{CLOBBER@}; 12544 mul_tmp_44 = mult_acc_1 * stack$0_52; 12545 return mul_tmp_44; 12546 12547@} 12548@end example 12549 12550@noindent 12551 12552@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 12553@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12554@c 12555@c This is free software: you can redistribute it and/or modify it 12556@c under the terms of the GNU General Public License as published by 12557@c the Free Software Foundation, either version 3 of the License, or 12558@c (at your option) any later version. 12559@c 12560@c This program is distributed in the hope that it will be useful, but 12561@c WITHOUT ANY WARRANTY; without even the implied warranty of 12562@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12563@c General Public License for more details. 12564@c 12565@c You should have received a copy of the GNU General Public License 12566@c along with this program. If not, see 12567@c <http://www.gnu.org/licenses/>. 12568 12569@node Topic Reference<2>,,Tutorial<2>,C++ bindings for libgccjit 12570@anchor{cp/topics/index doc}@anchor{147}@anchor{cp/topics/index topic-reference}@anchor{148} 12571@section Topic Reference 12572 12573 12574@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 12575@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12576@c 12577@c This is free software: you can redistribute it and/or modify it 12578@c under the terms of the GNU General Public License as published by 12579@c the Free Software Foundation, either version 3 of the License, or 12580@c (at your option) any later version. 12581@c 12582@c This program is distributed in the hope that it will be useful, but 12583@c WITHOUT ANY WARRANTY; without even the implied warranty of 12584@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12585@c General Public License for more details. 12586@c 12587@c You should have received a copy of the GNU General Public License 12588@c along with this program. If not, see 12589@c <http://www.gnu.org/licenses/>. 12590 12591@menu 12592* Compilation contexts: Compilation contexts<2>. 12593* Objects: Objects<2>. 12594* Types: Types<2>. 12595* Expressions: Expressions<2>. 12596* Creating and using functions: Creating and using functions<2>. 12597* Source Locations: Source Locations<2>. 12598* Compiling a context: Compiling a context<2>. 12599 12600Compilation contexts 12601 12602* Lifetime-management: Lifetime-management<2>. 12603* Thread-safety: Thread-safety<2>. 12604* Error-handling: Error-handling<3>. 12605* Debugging: Debugging<2>. 12606* Options: Options<4>. 12607 12608Options 12609 12610* String Options: String Options<2>. 12611* Boolean options: Boolean options<2>. 12612* Integer options: Integer options<2>. 12613* Additional command-line options: Additional command-line options<2>. 12614 12615Types 12616 12617* Standard types: Standard types<2>. 12618* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 12619* Vector types: Vector types<2>. 12620* Structures and unions: Structures and unions<2>. 12621 12622Expressions 12623 12624* Rvalues: Rvalues<2>. 12625* Lvalues: Lvalues<2>. 12626* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 12627 12628Rvalues 12629 12630* Simple expressions: Simple expressions<2>. 12631* Vector expressions: Vector expressions<2>. 12632* Unary Operations: Unary Operations<2>. 12633* Binary Operations: Binary Operations<2>. 12634* Comparisons: Comparisons<2>. 12635* Function calls: Function calls<2>. 12636* Function pointers: Function pointers<3>. 12637* Type-coercion: Type-coercion<2>. 12638 12639Lvalues 12640 12641* Global variables: Global variables<2>. 12642 12643Creating and using functions 12644 12645* Params: Params<2>. 12646* Functions: Functions<2>. 12647* Blocks: Blocks<2>. 12648* Statements: Statements<2>. 12649 12650Source Locations 12651 12652* Faking it: Faking it<2>. 12653 12654Compiling a context 12655 12656* In-memory compilation: In-memory compilation<2>. 12657* Ahead-of-time compilation: Ahead-of-time compilation<2>. 12658 12659@end menu 12660 12661 12662@node Compilation contexts<2>,Objects<2>,,Topic Reference<2> 12663@anchor{cp/topics/contexts compilation-contexts}@anchor{149}@anchor{cp/topics/contexts doc}@anchor{14a} 12664@subsection Compilation contexts 12665 12666 12667@geindex gccjit;;context (C++ class) 12668@anchor{cp/topics/contexts gccjit context}@anchor{14b} 12669@deffn {C++ Class} gccjit::context 12670@end deffn 12671 12672The top-level of the C++ API is the @pxref{14b,,gccjit;;context} type. 12673 12674A @pxref{14b,,gccjit;;context} instance encapsulates the state of a 12675compilation. 12676 12677You can set up options on it, and add types, functions and code. 12678Invoking @pxref{124,,gccjit;;context;;compile()} on it gives you a 12679@pxref{16,,gcc_jit_result *}. 12680 12681It is a thin wrapper around the C API's @pxref{8,,gcc_jit_context *}. 12682 12683@menu 12684* Lifetime-management: Lifetime-management<2>. 12685* Thread-safety: Thread-safety<2>. 12686* Error-handling: Error-handling<3>. 12687* Debugging: Debugging<2>. 12688* Options: Options<4>. 12689 12690@end menu 12691 12692@node Lifetime-management<2>,Thread-safety<2>,,Compilation contexts<2> 12693@anchor{cp/topics/contexts lifetime-management}@anchor{14c} 12694@subsubsection Lifetime-management 12695 12696 12697Contexts are the unit of lifetime-management within the API: objects 12698have their lifetime bounded by the context they are created within, and 12699cleanup of such objects is done for you when the context is released. 12700 12701@geindex gccjit;;context;;acquire (C++ function) 12702@anchor{cp/topics/contexts gccjit context acquire}@anchor{11e} 12703@deffn {C++ Function} gccjit::context gccjit::context::acquire () 12704 12705This function acquires a new @pxref{14b,,gccjit;;context} instance, 12706which is independent of any others that may be present within this 12707process. 12708@end deffn 12709 12710@geindex gccjit;;context;;release (C++ function) 12711@anchor{cp/topics/contexts gccjit context release}@anchor{120} 12712@deffn {C++ Function} void gccjit::context::release () 12713 12714This function releases all resources associated with the given context. 12715Both the context itself and all of its @code{gccjit::object *} 12716instances are cleaned up. It should be called exactly once on a given 12717context. 12718 12719It is invalid to use the context or any of its "contextual" objects 12720after calling this. 12721 12722@example 12723ctxt.release (); 12724@end example 12725 12726@noindent 12727@end deffn 12728 12729@geindex gccjit;;context;;new_child_context (C++ function) 12730@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{14d} 12731@deffn {C++ Function} gccjit::context gccjit::context::new_child_context () 12732 12733Given an existing JIT context, create a child context. 12734 12735The child inherits a copy of all option-settings from the parent. 12736 12737The child can reference objects created within the parent, but not 12738vice-versa. 12739 12740The lifetime of the child context must be bounded by that of the 12741parent: you should release a child context before releasing the parent 12742context. 12743 12744If you use a function from a parent context within a child context, 12745you have to compile the parent context before you can compile the 12746child context, and the gccjit::result of the parent context must 12747outlive the gccjit::result of the child context. 12748 12749This allows caching of shared initializations. For example, you could 12750create types and declarations of global functions in a parent context 12751once within a process, and then create child contexts whenever a 12752function or loop becomes hot. Each such child context can be used for 12753JIT-compiling just one function or loop, but can reference types 12754and helper functions created within the parent context. 12755 12756Contexts can be arbitrarily nested, provided the above rules are 12757followed, but it's probably not worth going above 2 or 3 levels, and 12758there will likely be a performance hit for such nesting. 12759@end deffn 12760 12761@node Thread-safety<2>,Error-handling<3>,Lifetime-management<2>,Compilation contexts<2> 12762@anchor{cp/topics/contexts thread-safety}@anchor{14e} 12763@subsubsection Thread-safety 12764 12765 12766Instances of @pxref{14b,,gccjit;;context} created via 12767@pxref{11e,,gccjit;;context;;acquire()} are independent from each other: 12768only one thread may use a given context at once, but multiple threads 12769could each have their own contexts without needing locks. 12770 12771Contexts created via @pxref{14d,,gccjit;;context;;new_child_context()} are 12772related to their parent context. They can be partitioned by their 12773ultimate ancestor into independent "family trees". Only one thread 12774within a process may use a given "family tree" of such contexts at once, 12775and if you're using multiple threads you should provide your own locking 12776around entire such context partitions. 12777 12778@node Error-handling<3>,Debugging<2>,Thread-safety<2>,Compilation contexts<2> 12779@anchor{cp/topics/contexts error-handling}@anchor{14f} 12780@subsubsection Error-handling 12781 12782 12783@c FIXME: How does error-handling work for C++ API? 12784 12785You can only compile and get code from a context if no errors occur. 12786 12787In general, if an error occurs when using an API entrypoint, it returns 12788NULL. You don't have to check everywhere for NULL results, since the 12789API gracefully handles a NULL being passed in for any argument. 12790 12791Errors are printed on stderr and can be queried using 12792@pxref{150,,gccjit;;context;;get_first_error()}. 12793 12794@geindex gccjit;;context;;get_first_error (C++ function) 12795@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{150} 12796@deffn {C++ Function} const char* gccjit::context::get_first_error (gccjit::context* ctxt) 12797 12798Returns the first error message that occurred on the context. 12799 12800The returned string is valid for the rest of the lifetime of the 12801context. 12802 12803If no errors occurred, this will be NULL. 12804@end deffn 12805 12806@node Debugging<2>,Options<4>,Error-handling<3>,Compilation contexts<2> 12807@anchor{cp/topics/contexts debugging}@anchor{151} 12808@subsubsection Debugging 12809 12810 12811@geindex gccjit;;context;;dump_to_file (C++ function) 12812@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{152} 12813@deffn {C++ Function} void gccjit::context::dump_to_file (const std::string& path, int update_locations) 12814 12815To help with debugging: dump a C-like representation to the given path, 12816describing what's been set up on the context. 12817 12818If "update_locations" is true, then also set up @pxref{153,,gccjit;;location} 12819information throughout the context, pointing at the dump file as if it 12820were a source file. This may be of use in conjunction with 12821@code{GCCJIT::BOOL_OPTION_DEBUGINFO} to allow stepping through the 12822code in a debugger. 12823@end deffn 12824 12825@geindex gccjit;;context;;dump_reproducer_to_file (C++ function) 12826@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{154} 12827@deffn {C++ Function} void gccjit::context::dump_reproducer_to_file (gcc_jit_context* ctxt, const char* path) 12828 12829This is a thin wrapper around the C API 12830@pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}, and hence works the 12831same way. 12832 12833Note that the generated source is C code, not C++; this might be of use 12834for seeing what the C++ bindings are doing at the C level. 12835@end deffn 12836 12837@node Options<4>,,Debugging<2>,Compilation contexts<2> 12838@anchor{cp/topics/contexts options}@anchor{155} 12839@subsubsection Options 12840 12841 12842@menu 12843* String Options: String Options<2>. 12844* Boolean options: Boolean options<2>. 12845* Integer options: Integer options<2>. 12846* Additional command-line options: Additional command-line options<2>. 12847 12848@end menu 12849 12850@node String Options<2>,Boolean options<2>,,Options<4> 12851@anchor{cp/topics/contexts string-options}@anchor{156} 12852@subsubsection String Options 12853 12854 12855@geindex gccjit;;context;;set_str_option (C++ function) 12856@anchor{cp/topics/contexts gccjit context set_str_option__enum cCP}@anchor{157} 12857@deffn {C++ Function} void gccjit::context::set_str_option (enum gcc_jit_str_option, const char* value) 12858 12859Set a string option of the context. 12860 12861This is a thin wrapper around the C API 12862@pxref{61,,gcc_jit_context_set_str_option()}; the options have the same 12863meaning. 12864@end deffn 12865 12866@node Boolean options<2>,Integer options<2>,String Options<2>,Options<4> 12867@anchor{cp/topics/contexts boolean-options}@anchor{158} 12868@subsubsection Boolean options 12869 12870 12871@geindex gccjit;;context;;set_bool_option (C++ function) 12872@anchor{cp/topics/contexts gccjit context set_bool_option__enum i}@anchor{126} 12873@deffn {C++ Function} void gccjit::context::set_bool_option (enum gcc_jit_bool_option, int value) 12874 12875Set a boolean option of the context. 12876 12877This is a thin wrapper around the C API 12878@pxref{1b,,gcc_jit_context_set_bool_option()}; the options have the same 12879meaning. 12880@end deffn 12881 12882@geindex gccjit;;context;;set_bool_allow_unreachable_blocks (C++ function) 12883@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{159} 12884@deffn {C++ Function} void gccjit::context::set_bool_allow_unreachable_blocks (int bool_value) 12885 12886By default, libgccjit will issue an error about unreachable blocks 12887within a function. 12888 12889This entrypoint can be used to disable that error; it is a thin wrapper 12890around the C API 12891@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}. 12892 12893This entrypoint was added in @pxref{6c,,LIBGCCJIT_ABI_2}; you can test for 12894its presence using 12895 12896@example 12897#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 12898@end example 12899 12900@noindent 12901@end deffn 12902 12903@geindex gccjit;;context;;set_bool_use_external_driver (C++ function) 12904@anchor{cp/topics/contexts gccjit context set_bool_use_external_driver__i}@anchor{15a} 12905@deffn {C++ Function} void gccjit::context::set_bool_use_external_driver (int bool_value) 12906 12907libgccjit internally generates assembler, and uses "driver" code 12908for converting it to other formats (e.g. shared libraries). 12909 12910By default, libgccjit will use an embedded copy of the driver 12911code. 12912 12913This option can be used to instead invoke an external driver executable 12914as a subprocess; it is a thin wrapper around the C API 12915@pxref{6d,,gcc_jit_context_set_bool_use_external_driver()}. 12916 12917This entrypoint was added in @pxref{6e,,LIBGCCJIT_ABI_5}; you can test for 12918its presence using 12919 12920@example 12921#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver 12922@end example 12923 12924@noindent 12925@end deffn 12926 12927@node Integer options<2>,Additional command-line options<2>,Boolean options<2>,Options<4> 12928@anchor{cp/topics/contexts integer-options}@anchor{15b} 12929@subsubsection Integer options 12930 12931 12932@geindex gccjit;;context;;set_int_option (C++ function) 12933@anchor{cp/topics/contexts gccjit context set_int_option__enum i}@anchor{127} 12934@deffn {C++ Function} void gccjit::context::set_int_option (enum gcc_jit_int_option, int value) 12935 12936Set an integer option of the context. 12937 12938This is a thin wrapper around the C API 12939@pxref{1e,,gcc_jit_context_set_int_option()}; the options have the same 12940meaning. 12941@end deffn 12942 12943@node Additional command-line options<2>,,Integer options<2>,Options<4> 12944@anchor{cp/topics/contexts additional-command-line-options}@anchor{15c} 12945@subsubsection Additional command-line options 12946 12947 12948@geindex gccjit;;context;;add_command_line_option (C++ function) 12949@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{15d} 12950@deffn {C++ Function} void gccjit::context::add_command_line_option (const char* optname) 12951 12952Add an arbitrary gcc command-line option to the context for use 12953when compiling. 12954 12955This is a thin wrapper around the C API 12956@pxref{72,,gcc_jit_context_add_command_line_option()}. 12957 12958This entrypoint was added in @pxref{73,,LIBGCCJIT_ABI_1}; you can test for 12959its presence using 12960 12961@example 12962#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 12963@end example 12964 12965@noindent 12966@end deffn 12967 12968@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 12969@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12970@c 12971@c This is free software: you can redistribute it and/or modify it 12972@c under the terms of the GNU General Public License as published by 12973@c the Free Software Foundation, either version 3 of the License, or 12974@c (at your option) any later version. 12975@c 12976@c This program is distributed in the hope that it will be useful, but 12977@c WITHOUT ANY WARRANTY; without even the implied warranty of 12978@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12979@c General Public License for more details. 12980@c 12981@c You should have received a copy of the GNU General Public License 12982@c along with this program. If not, see 12983@c <http://www.gnu.org/licenses/>. 12984 12985@node Objects<2>,Types<2>,Compilation contexts<2>,Topic Reference<2> 12986@anchor{cp/topics/objects objects}@anchor{15e}@anchor{cp/topics/objects doc}@anchor{15f} 12987@subsection Objects 12988 12989 12990@geindex gccjit;;object (C++ class) 12991@anchor{cp/topics/objects gccjit object}@anchor{160} 12992@deffn {C++ Class} gccjit::object 12993@end deffn 12994 12995Almost every entity in the API (with the exception of 12996@pxref{14b,,gccjit;;context} and @pxref{16,,gcc_jit_result *}) is a 12997"contextual" object, a @pxref{160,,gccjit;;object}. 12998 12999A JIT object: 13000 13001@quotation 13002 13003 13004@itemize * 13005 13006@item 13007is associated with a @pxref{14b,,gccjit;;context}. 13008 13009@item 13010is automatically cleaned up for you when its context is released so 13011you don't need to manually track and cleanup all objects, just the 13012contexts. 13013@end itemize 13014@end quotation 13015 13016The C++ class hierarchy within the @code{gccjit} namespace looks like this: 13017 13018@example 13019+- object 13020 +- location 13021 +- type 13022 +- struct 13023 +- field 13024 +- function 13025 +- block 13026 +- rvalue 13027 +- lvalue 13028 +- param 13029 +- case_ 13030@end example 13031 13032@noindent 13033 13034The @pxref{160,,gccjit;;object} base class has the following operations: 13035 13036@geindex gccjit;;object;;get_context (C++ function) 13037@anchor{cp/topics/objects gccjit object get_contextC}@anchor{161} 13038@deffn {C++ Function} gccjit::context gccjit::object::get_context () const 13039 13040Which context is the obj within? 13041@end deffn 13042 13043@geindex gccjit;;object;;get_debug_string (C++ function) 13044@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{121} 13045@deffn {C++ Function} std::string gccjit::object::get_debug_string () const 13046 13047Generate a human-readable description for the given object. 13048 13049For example, 13050 13051@example 13052printf ("obj: %s\n", obj.get_debug_string ().c_str ()); 13053@end example 13054 13055@noindent 13056 13057might give this text on stdout: 13058 13059@example 13060obj: 4.0 * (float)i 13061@end example 13062 13063@noindent 13064@end deffn 13065 13066@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 13067@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13068@c 13069@c This is free software: you can redistribute it and/or modify it 13070@c under the terms of the GNU General Public License as published by 13071@c the Free Software Foundation, either version 3 of the License, or 13072@c (at your option) any later version. 13073@c 13074@c This program is distributed in the hope that it will be useful, but 13075@c WITHOUT ANY WARRANTY; without even the implied warranty of 13076@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13077@c General Public License for more details. 13078@c 13079@c You should have received a copy of the GNU General Public License 13080@c along with this program. If not, see 13081@c <http://www.gnu.org/licenses/>. 13082 13083@node Types<2>,Expressions<2>,Objects<2>,Topic Reference<2> 13084@anchor{cp/topics/types doc}@anchor{162}@anchor{cp/topics/types types}@anchor{163} 13085@subsection Types 13086 13087 13088@geindex gccjit;;type (C++ class) 13089@anchor{cp/topics/types gccjit type}@anchor{164} 13090@deffn {C++ Class} gccjit::type 13091 13092gccjit::type represents a type within the library. It is a subclass 13093of @pxref{160,,gccjit;;object}. 13094@end deffn 13095 13096Types can be created in several ways: 13097 13098 13099@itemize * 13100 13101@item 13102fundamental types can be accessed using 13103@pxref{11f,,gccjit;;context;;get_type()}: 13104 13105@example 13106gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 13107@end example 13108 13109@noindent 13110 13111or using the @code{gccjit::context::get_int_type} template: 13112 13113@example 13114gccjit::type t = ctxt.get_int_type <unsigned short> (); 13115@end example 13116 13117@noindent 13118 13119See @pxref{b,,gcc_jit_context_get_type()} for the available types. 13120 13121@item 13122derived types can be accessed by using functions such as 13123@pxref{165,,gccjit;;type;;get_pointer()} and @pxref{166,,gccjit;;type;;get_const()}: 13124 13125@example 13126gccjit::type const_int_star = int_type.get_const ().get_pointer (); 13127gccjit::type int_const_star = int_type.get_pointer ().get_const (); 13128@end example 13129 13130@noindent 13131 13132@item 13133by creating structures (see below). 13134@end itemize 13135 13136@menu 13137* Standard types: Standard types<2>. 13138* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 13139* Vector types: Vector types<2>. 13140* Structures and unions: Structures and unions<2>. 13141 13142@end menu 13143 13144@node Standard types<2>,Pointers const and volatile<2>,,Types<2> 13145@anchor{cp/topics/types standard-types}@anchor{167} 13146@subsubsection Standard types 13147 13148 13149@geindex gccjit;;context;;get_type (C++ function) 13150@anchor{cp/topics/types gccjit context get_type__enum}@anchor{11f} 13151@deffn {C++ Function} gccjit::type gccjit::context::get_type (enum gcc_jit_types) 13152 13153Access a specific type. This is a thin wrapper around 13154@pxref{b,,gcc_jit_context_get_type()}; the parameter has the same meaning. 13155@end deffn 13156 13157@geindex gccjit;;context;;get_int_type (C++ function) 13158@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{168} 13159@deffn {C++ Function} gccjit::type gccjit::context::get_int_type (size_t num_bytes, int is_signed) 13160 13161Access the integer type of the given size. 13162@end deffn 13163 13164@geindex gccjit;;context;;get_int_type<T> (C++ function) 13165@anchor{cp/topics/types gccjit context get_int_type T}@anchor{169} 13166@deffn {C++ Function} gccjit::type gccjit::context::get_int_type<T> () 13167 13168Access the given integer type. For example, you could map the 13169@code{unsigned short} type into a gccjit::type via: 13170 13171@example 13172gccjit::type t = ctxt.get_int_type <unsigned short> (); 13173@end example 13174 13175@noindent 13176@end deffn 13177 13178@node Pointers const and volatile<2>,Vector types<2>,Standard types<2>,Types<2> 13179@anchor{cp/topics/types pointers-const-and-volatile}@anchor{16a} 13180@subsubsection Pointers, @cite{const}, and @cite{volatile} 13181 13182 13183@geindex gccjit;;type;;get_pointer (C++ function) 13184@anchor{cp/topics/types gccjit type get_pointer}@anchor{165} 13185@deffn {C++ Function} gccjit::type gccjit::type::get_pointer () 13186 13187Given type "T", get type "T*". 13188@end deffn 13189 13190@geindex gccjit;;type;;get_const (C++ function) 13191@anchor{cp/topics/types gccjit type get_const}@anchor{166} 13192@deffn {C++ Function} gccjit::type gccjit::type::get_const () 13193 13194Given type "T", get type "const T". 13195@end deffn 13196 13197@geindex gccjit;;type;;get_volatile (C++ function) 13198@anchor{cp/topics/types gccjit type get_volatile}@anchor{16b} 13199@deffn {C++ Function} gccjit::type gccjit::type::get_volatile () 13200 13201Given type "T", get type "volatile T". 13202@end deffn 13203 13204@geindex gccjit;;type;;get_aligned (C++ function) 13205@anchor{cp/topics/types gccjit type get_aligned__s}@anchor{16c} 13206@deffn {C++ Function} gccjit::type gccjit::type::get_aligned (size_t alignment_in_bytes) 13207 13208Given type "T", get type: 13209 13210@example 13211T __attribute__ ((aligned (ALIGNMENT_IN_BYTES))) 13212@end example 13213 13214@noindent 13215 13216The alignment must be a power of two. 13217@end deffn 13218 13219@geindex gccjit;;context;;new_array_type (C++ function) 13220@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{16d} 13221@deffn {C++ Function} gccjit::type gccjit::context::new_array_type (gccjit::type element_type, int num_elements, gccjit::location loc) 13222 13223Given type "T", get type "T[N]" (for a constant N). 13224Param "loc" is optional. 13225@end deffn 13226 13227@node Vector types<2>,Structures and unions<2>,Pointers const and volatile<2>,Types<2> 13228@anchor{cp/topics/types vector-types}@anchor{16e} 13229@subsubsection Vector types 13230 13231 13232@geindex gccjit;;type;;get_vector (C++ function) 13233@anchor{cp/topics/types gccjit type get_vector__s}@anchor{16f} 13234@deffn {C++ Function} gccjit::type gccjit::type::get_vector (size_t num_units) 13235 13236Given type "T", get type: 13237 13238@example 13239T __attribute__ ((vector_size (sizeof(T) * num_units)) 13240@end example 13241 13242@noindent 13243 13244T must be integral or floating point; num_units must be a power of two. 13245@end deffn 13246 13247@node Structures and unions<2>,,Vector types<2>,Types<2> 13248@anchor{cp/topics/types structures-and-unions}@anchor{170} 13249@subsubsection Structures and unions 13250 13251 13252@geindex gccjit;;struct_ (C++ class) 13253@anchor{cp/topics/types gccjit struct_}@anchor{171} 13254@deffn {C++ Class} gccjit::struct_ 13255@end deffn 13256 13257A compound type analagous to a C @cite{struct}. 13258 13259@pxref{171,,gccjit;;struct_} is a subclass of @pxref{164,,gccjit;;type} (and thus 13260of @pxref{160,,gccjit;;object} in turn). 13261 13262@geindex gccjit;;field (C++ class) 13263@anchor{cp/topics/types gccjit field}@anchor{172} 13264@deffn {C++ Class} gccjit::field 13265@end deffn 13266 13267A field within a @pxref{171,,gccjit;;struct_}. 13268 13269@pxref{172,,gccjit;;field} is a subclass of @pxref{160,,gccjit;;object}. 13270 13271You can model C @cite{struct} types by creating @pxref{171,,gccjit;;struct_} and 13272@pxref{172,,gccjit;;field} instances, in either order: 13273 13274 13275@itemize * 13276 13277@item 13278by creating the fields, then the structure. For example, to model: 13279 13280@example 13281struct coord @{double x; double y; @}; 13282@end example 13283 13284@noindent 13285 13286you could call: 13287 13288@example 13289gccjit::field field_x = ctxt.new_field (double_type, "x"); 13290gccjit::field field_y = ctxt.new_field (double_type, "y"); 13291std::vector fields; 13292fields.push_back (field_x); 13293fields.push_back (field_y); 13294gccjit::struct_ coord = ctxt.new_struct_type ("coord", fields); 13295@end example 13296 13297@noindent 13298 13299@item 13300by creating the structure, then populating it with fields, typically 13301to allow modelling self-referential structs such as: 13302 13303@example 13304struct node @{ int m_hash; struct node *m_next; @}; 13305@end example 13306 13307@noindent 13308 13309like this: 13310 13311@example 13312gccjit::struct_ node = ctxt.new_opaque_struct_type ("node"); 13313gccjit::type node_ptr = node.get_pointer (); 13314gccjit::field field_hash = ctxt.new_field (int_type, "m_hash"); 13315gccjit::field field_next = ctxt.new_field (node_ptr, "m_next"); 13316std::vector fields; 13317fields.push_back (field_hash); 13318fields.push_back (field_next); 13319node.set_fields (fields); 13320@end example 13321 13322@noindent 13323@end itemize 13324 13325@c FIXME: the above API doesn't seem to exist yet 13326 13327@geindex gccjit;;context;;new_field (C++ function) 13328@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{173} 13329@deffn {C++ Function} gccjit::field gccjit::context::new_field (gccjit::type type, const char* name, gccjit::location loc) 13330 13331Construct a new field, with the given type and name. 13332@end deffn 13333 13334@geindex gccjit;;context;;new_struct_type (C++ function) 13335@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{174} 13336@deffn {C++ Function} gccjit::struct_ gccjit::context::new_struct_type (const std::string& name, std::vector<field>& fields, gccjit::location loc) 13337 13338@quotation 13339 13340Construct a new struct type, with the given name and fields. 13341@end quotation 13342@end deffn 13343 13344@geindex gccjit;;context;;new_opaque_struct (C++ function) 13345@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{175} 13346@deffn {C++ Function} gccjit::struct_ gccjit::context::new_opaque_struct (const std::string& name, gccjit::location loc) 13347 13348Construct a new struct type, with the given name, but without 13349specifying the fields. The fields can be omitted (in which case the 13350size of the struct is not known), or later specified using 13351@pxref{8d,,gcc_jit_struct_set_fields()}. 13352@end deffn 13353 13354@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 13355@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13356@c 13357@c This is free software: you can redistribute it and/or modify it 13358@c under the terms of the GNU General Public License as published by 13359@c the Free Software Foundation, either version 3 of the License, or 13360@c (at your option) any later version. 13361@c 13362@c This program is distributed in the hope that it will be useful, but 13363@c WITHOUT ANY WARRANTY; without even the implied warranty of 13364@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13365@c General Public License for more details. 13366@c 13367@c You should have received a copy of the GNU General Public License 13368@c along with this program. If not, see 13369@c <http://www.gnu.org/licenses/>. 13370 13371@node Expressions<2>,Creating and using functions<2>,Types<2>,Topic Reference<2> 13372@anchor{cp/topics/expressions expressions}@anchor{176}@anchor{cp/topics/expressions doc}@anchor{177} 13373@subsection Expressions 13374 13375 13376@menu 13377* Rvalues: Rvalues<2>. 13378* Lvalues: Lvalues<2>. 13379* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 13380 13381Rvalues 13382 13383* Simple expressions: Simple expressions<2>. 13384* Vector expressions: Vector expressions<2>. 13385* Unary Operations: Unary Operations<2>. 13386* Binary Operations: Binary Operations<2>. 13387* Comparisons: Comparisons<2>. 13388* Function calls: Function calls<2>. 13389* Function pointers: Function pointers<3>. 13390* Type-coercion: Type-coercion<2>. 13391 13392Lvalues 13393 13394* Global variables: Global variables<2>. 13395 13396@end menu 13397 13398 13399@node Rvalues<2>,Lvalues<2>,,Expressions<2> 13400@anchor{cp/topics/expressions rvalues}@anchor{178} 13401@subsubsection Rvalues 13402 13403 13404@geindex gccjit;;rvalue (C++ class) 13405@anchor{cp/topics/expressions gccjit rvalue}@anchor{179} 13406@deffn {C++ Class} gccjit::rvalue 13407@end deffn 13408 13409A @pxref{179,,gccjit;;rvalue} is an expression that can be computed. It is a 13410subclass of @pxref{160,,gccjit;;object}, and is a thin wrapper around 13411@pxref{13,,gcc_jit_rvalue *} from the C API. 13412 13413It can be simple, e.g.: 13414 13415@quotation 13416 13417 13418@itemize * 13419 13420@item 13421an integer value e.g. @cite{0} or @cite{42} 13422 13423@item 13424a string literal e.g. @cite{"Hello world"} 13425 13426@item 13427a variable e.g. @cite{i}. These are also lvalues (see below). 13428@end itemize 13429@end quotation 13430 13431or compound e.g.: 13432 13433@quotation 13434 13435 13436@itemize * 13437 13438@item 13439a unary expression e.g. @cite{!cond} 13440 13441@item 13442a binary expression e.g. @cite{(a + b)} 13443 13444@item 13445a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} 13446 13447@item 13448etc. 13449@end itemize 13450@end quotation 13451 13452Every rvalue has an associated type, and the API will check to ensure 13453that types match up correctly (otherwise the context will emit an error). 13454 13455@geindex gccjit;;rvalue;;get_type (C++ function) 13456@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{17a} 13457@deffn {C++ Function} gccjit::type gccjit::rvalue::get_type () 13458 13459Get the type of this rvalue. 13460@end deffn 13461 13462@menu 13463* Simple expressions: Simple expressions<2>. 13464* Vector expressions: Vector expressions<2>. 13465* Unary Operations: Unary Operations<2>. 13466* Binary Operations: Binary Operations<2>. 13467* Comparisons: Comparisons<2>. 13468* Function calls: Function calls<2>. 13469* Function pointers: Function pointers<3>. 13470* Type-coercion: Type-coercion<2>. 13471 13472@end menu 13473 13474@node Simple expressions<2>,Vector expressions<2>,,Rvalues<2> 13475@anchor{cp/topics/expressions simple-expressions}@anchor{17b} 13476@subsubsection Simple expressions 13477 13478 13479@geindex gccjit;;context;;new_rvalue (C++ function) 13480@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{133} 13481@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, int value) const 13482 13483Given a numeric type (integer or floating point), build an rvalue for 13484the given constant @code{int} value. 13485@end deffn 13486 13487@geindex gccjit;;context;;new_rvalue (C++ function) 13488@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{17c} 13489@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, long value) const 13490 13491Given a numeric type (integer or floating point), build an rvalue for 13492the given constant @code{long} value. 13493@end deffn 13494 13495@geindex gccjit;;context;;zero (C++ function) 13496@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{12f} 13497@deffn {C++ Function} gccjit::rvalue gccjit::context::zero (gccjit::type numeric_type) const 13498 13499Given a numeric type (integer or floating point), get the rvalue for 13500zero. Essentially this is just a shortcut for: 13501 13502@example 13503ctxt.new_rvalue (numeric_type, 0) 13504@end example 13505 13506@noindent 13507@end deffn 13508 13509@geindex gccjit;;context;;one (C++ function) 13510@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{17d} 13511@deffn {C++ Function} gccjit::rvalue gccjit::context::one (gccjit::type numeric_type) const 13512 13513Given a numeric type (integer or floating point), get the rvalue for 13514one. Essentially this is just a shortcut for: 13515 13516@example 13517ctxt.new_rvalue (numeric_type, 1) 13518@end example 13519 13520@noindent 13521@end deffn 13522 13523@geindex gccjit;;context;;new_rvalue (C++ function) 13524@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{17e} 13525@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, double value) const 13526 13527Given a numeric type (integer or floating point), build an rvalue for 13528the given constant @code{double} value. 13529@end deffn 13530 13531@geindex gccjit;;context;;new_rvalue (C++ function) 13532@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{17f} 13533@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type pointer_type, void* value) const 13534 13535Given a pointer type, build an rvalue for the given address. 13536@end deffn 13537 13538@geindex gccjit;;context;;new_rvalue (C++ function) 13539@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{180} 13540@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (const std::string& value) const 13541 13542Generate an rvalue of type @code{GCC_JIT_TYPE_CONST_CHAR_PTR} for 13543the given string. This is akin to a string literal. 13544@end deffn 13545 13546@node Vector expressions<2>,Unary Operations<2>,Simple expressions<2>,Rvalues<2> 13547@anchor{cp/topics/expressions vector-expressions}@anchor{181} 13548@subsubsection Vector expressions 13549 13550 13551@geindex gccjit;;context;;new_rvalue (C++ function) 13552@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type std vector gccjit rvalue C}@anchor{182} 13553@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type vector_type, std::vector<gccjit::rvalue> elements) const 13554 13555Given a vector type, and a vector of scalar rvalue elements, generate a 13556vector rvalue. 13557 13558The number of elements needs to match that of the vector type. 13559@end deffn 13560 13561@node Unary Operations<2>,Binary Operations<2>,Vector expressions<2>,Rvalues<2> 13562@anchor{cp/topics/expressions unary-operations}@anchor{183} 13563@subsubsection Unary Operations 13564 13565 13566@geindex gccjit;;context;;new_unary_op (C++ function) 13567@anchor{cp/topics/expressions gccjit context new_unary_op__enum gccjit type gccjit rvalue gccjit location}@anchor{184} 13568@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) 13569 13570Build a unary operation out of an input rvalue. 13571 13572Parameter @code{loc} is optional. 13573 13574This is a thin wrapper around the C API's 13575@pxref{9e,,gcc_jit_context_new_unary_op()} and the available unary 13576operations are documented there. 13577@end deffn 13578 13579There are shorter ways to spell the various specific kinds of unary 13580operation: 13581 13582@geindex gccjit;;context;;new_minus (C++ function) 13583@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{185} 13584@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 13585 13586Negate an arithmetic value; for example: 13587 13588@example 13589gccjit::rvalue negpi = ctxt.new_minus (t_double, pi); 13590@end example 13591 13592@noindent 13593 13594builds the equivalent of this C expression: 13595 13596@example 13597-pi 13598@end example 13599 13600@noindent 13601@end deffn 13602 13603@geindex new_bitwise_negate (C++ function) 13604@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{186} 13605@deffn {C++ Function} gccjit::rvalue new_bitwise_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 13606 13607Bitwise negation of an integer value (one's complement); for example: 13608 13609@example 13610gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a); 13611@end example 13612 13613@noindent 13614 13615builds the equivalent of this C expression: 13616 13617@example 13618~a 13619@end example 13620 13621@noindent 13622@end deffn 13623 13624@geindex new_logical_negate (C++ function) 13625@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{187} 13626@deffn {C++ Function} gccjit::rvalue new_logical_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 13627 13628Logical negation of an arithmetic or pointer value; for example: 13629 13630@example 13631gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond); 13632@end example 13633 13634@noindent 13635 13636builds the equivalent of this C expression: 13637 13638@example 13639!cond 13640@end example 13641 13642@noindent 13643@end deffn 13644 13645The most concise way to spell them is with overloaded operators: 13646 13647@geindex operator- (C++ function) 13648@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{188} 13649@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a) 13650 13651@example 13652gccjit::rvalue negpi = -pi; 13653@end example 13654 13655@noindent 13656@end deffn 13657 13658@geindex operator~ (C++ function) 13659@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{189} 13660@deffn {C++ Function} gccjit::rvalue operator~ (gccjit::rvalue a) 13661 13662@example 13663gccjit::rvalue mask = ~a; 13664@end example 13665 13666@noindent 13667@end deffn 13668 13669@geindex operator! (C++ function) 13670@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{18a} 13671@deffn {C++ Function} gccjit::rvalue operator! (gccjit::rvalue a) 13672 13673@example 13674gccjit::rvalue guard = !cond; 13675@end example 13676 13677@noindent 13678@end deffn 13679 13680@node Binary Operations<2>,Comparisons<2>,Unary Operations<2>,Rvalues<2> 13681@anchor{cp/topics/expressions binary-operations}@anchor{18b} 13682@subsubsection Binary Operations 13683 13684 13685@geindex gccjit;;context;;new_binary_op (C++ function) 13686@anchor{cp/topics/expressions gccjit context new_binary_op__enum gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{123} 13687@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) 13688 13689Build a binary operation out of two constituent rvalues. 13690 13691Parameter @code{loc} is optional. 13692 13693This is a thin wrapper around the C API's 13694@pxref{12,,gcc_jit_context_new_binary_op()} and the available binary 13695operations are documented there. 13696@end deffn 13697 13698There are shorter ways to spell the various specific kinds of binary 13699operation: 13700 13701@geindex gccjit;;context;;new_plus (C++ function) 13702@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{18c} 13703@deffn {C++ Function} gccjit::rvalue gccjit::context::new_plus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13704@end deffn 13705 13706@geindex gccjit;;context;;new_minus (C++ function) 13707@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{18d} 13708@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13709@end deffn 13710 13711@geindex gccjit;;context;;new_mult (C++ function) 13712@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{18e} 13713@deffn {C++ Function} gccjit::rvalue gccjit::context::new_mult (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13714@end deffn 13715 13716@geindex gccjit;;context;;new_divide (C++ function) 13717@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{18f} 13718@deffn {C++ Function} gccjit::rvalue gccjit::context::new_divide (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13719@end deffn 13720 13721@geindex gccjit;;context;;new_modulo (C++ function) 13722@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{190} 13723@deffn {C++ Function} gccjit::rvalue gccjit::context::new_modulo (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13724@end deffn 13725 13726@geindex gccjit;;context;;new_bitwise_and (C++ function) 13727@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{191} 13728@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13729@end deffn 13730 13731@geindex gccjit;;context;;new_bitwise_xor (C++ function) 13732@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{192} 13733@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_xor (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13734@end deffn 13735 13736@geindex gccjit;;context;;new_bitwise_or (C++ function) 13737@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{193} 13738@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13739@end deffn 13740 13741@geindex gccjit;;context;;new_logical_and (C++ function) 13742@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{194} 13743@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13744@end deffn 13745 13746@geindex gccjit;;context;;new_logical_or (C++ function) 13747@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{195} 13748@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13749@end deffn 13750 13751The most concise way to spell them is with overloaded operators: 13752 13753@geindex operator+ (C++ function) 13754@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{196} 13755@deffn {C++ Function} gccjit::rvalue operator+ (gccjit::rvalue a, gccjit::rvalue b) 13756 13757@example 13758gccjit::rvalue sum = a + b; 13759@end example 13760 13761@noindent 13762@end deffn 13763 13764@geindex operator- (C++ function) 13765@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{197} 13766@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a, gccjit::rvalue b) 13767 13768@example 13769gccjit::rvalue diff = a - b; 13770@end example 13771 13772@noindent 13773@end deffn 13774 13775@geindex operator* (C++ function) 13776@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{198} 13777@deffn {C++ Function} gccjit::rvalue operator* (gccjit::rvalue a, gccjit::rvalue b) 13778 13779@example 13780gccjit::rvalue prod = a * b; 13781@end example 13782 13783@noindent 13784@end deffn 13785 13786@geindex operator/ (C++ function) 13787@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{199} 13788@deffn {C++ Function} gccjit::rvalue operator/ (gccjit::rvalue a, gccjit::rvalue b) 13789 13790@example 13791gccjit::rvalue result = a / b; 13792@end example 13793 13794@noindent 13795@end deffn 13796 13797@geindex operator% (C++ function) 13798@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{19a} 13799@deffn {C++ Function} gccjit::rvalue operator% (gccjit::rvalue a, gccjit::rvalue b) 13800 13801@example 13802gccjit::rvalue mod = a % b; 13803@end example 13804 13805@noindent 13806@end deffn 13807 13808@geindex operator& (C++ function) 13809@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{19b} 13810@deffn {C++ Function} gccjit::rvalue operator& (gccjit::rvalue a, gccjit::rvalue b) 13811 13812@example 13813gccjit::rvalue x = a & b; 13814@end example 13815 13816@noindent 13817@end deffn 13818 13819@geindex operator^ (C++ function) 13820@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{19c} 13821@deffn {C++ Function} gccjit::rvalue operator^ (gccjit::rvalue a, gccjit::rvalue b) 13822 13823@example 13824gccjit::rvalue x = a ^ b; 13825@end example 13826 13827@noindent 13828@end deffn 13829 13830@geindex operator| (C++ function) 13831@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{19d} 13832@deffn {C++ Function} gccjit::rvalue operator| (gccjit::rvalue a, gccjit::rvalue b) 13833 13834@example 13835gccjit::rvalue x = a | b; 13836@end example 13837 13838@noindent 13839@end deffn 13840 13841@geindex operator&& (C++ function) 13842@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{19e} 13843@deffn {C++ Function} gccjit::rvalue operator&& (gccjit::rvalue a, gccjit::rvalue b) 13844 13845@example 13846gccjit::rvalue cond = a && b; 13847@end example 13848 13849@noindent 13850@end deffn 13851 13852@geindex operator|| (C++ function) 13853@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{19f} 13854@deffn {C++ Function} gccjit::rvalue operator|| (gccjit::rvalue a, gccjit::rvalue b) 13855 13856@example 13857gccjit::rvalue cond = a || b; 13858@end example 13859 13860@noindent 13861@end deffn 13862 13863These can of course be combined, giving a terse way to build compound 13864expressions: 13865 13866@quotation 13867 13868@example 13869gccjit::rvalue discriminant = (b * b) - (four * a * c); 13870@end example 13871 13872@noindent 13873@end quotation 13874 13875@node Comparisons<2>,Function calls<2>,Binary Operations<2>,Rvalues<2> 13876@anchor{cp/topics/expressions comparisons}@anchor{1a0} 13877@subsubsection Comparisons 13878 13879 13880@geindex gccjit;;context;;new_comparison (C++ function) 13881@anchor{cp/topics/expressions gccjit context new_comparison__enum gccjit rvalue gccjit rvalue gccjit location}@anchor{130} 13882@deffn {C++ Function} gccjit::rvalue gccjit::context::new_comparison (enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13883 13884Build a boolean rvalue out of the comparison of two other rvalues. 13885 13886Parameter @code{loc} is optional. 13887 13888This is a thin wrapper around the C API's 13889@pxref{2c,,gcc_jit_context_new_comparison()} and the available kinds 13890of comparison are documented there. 13891@end deffn 13892 13893There are shorter ways to spell the various specific kinds of binary 13894operation: 13895 13896@geindex gccjit;;context;;new_eq (C++ function) 13897@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{1a1} 13898@deffn {C++ Function} gccjit::rvalue gccjit::context::new_eq (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13899@end deffn 13900 13901@geindex gccjit;;context;;new_ne (C++ function) 13902@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{1a2} 13903@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ne (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13904@end deffn 13905 13906@geindex gccjit;;context;;new_lt (C++ function) 13907@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{1a3} 13908@deffn {C++ Function} gccjit::rvalue gccjit::context::new_lt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13909@end deffn 13910 13911@geindex gccjit;;context;;new_le (C++ function) 13912@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{1a4} 13913@deffn {C++ Function} gccjit::rvalue gccjit::context::new_le (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13914@end deffn 13915 13916@geindex gccjit;;context;;new_gt (C++ function) 13917@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{1a5} 13918@deffn {C++ Function} gccjit::rvalue gccjit::context::new_gt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13919@end deffn 13920 13921@geindex gccjit;;context;;new_ge (C++ function) 13922@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{1a6} 13923@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ge (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13924@end deffn 13925 13926The most concise way to spell them is with overloaded operators: 13927 13928@geindex operator== (C++ function) 13929@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{1a7} 13930@deffn {C++ Function} gccjit::rvalue operator== (gccjit::rvalue a, gccjit::rvalue b) 13931 13932@example 13933gccjit::rvalue cond = (a == ctxt.zero (t_int)); 13934@end example 13935 13936@noindent 13937@end deffn 13938 13939@geindex operator!= (C++ function) 13940@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{1a8} 13941@deffn {C++ Function} gccjit::rvalue operator!= (gccjit::rvalue a, gccjit::rvalue b) 13942 13943@example 13944gccjit::rvalue cond = (i != j); 13945@end example 13946 13947@noindent 13948@end deffn 13949 13950@geindex operator< (C++ function) 13951@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{1a9} 13952@deffn {C++ Function} gccjit::rvalue operator< (gccjit::rvalue a, gccjit::rvalue b) 13953 13954@example 13955gccjit::rvalue cond = i < n; 13956@end example 13957 13958@noindent 13959@end deffn 13960 13961@geindex operator<= (C++ function) 13962@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{1aa} 13963@deffn {C++ Function} gccjit::rvalue operator<= (gccjit::rvalue a, gccjit::rvalue b) 13964 13965@example 13966gccjit::rvalue cond = i <= n; 13967@end example 13968 13969@noindent 13970@end deffn 13971 13972@geindex operator> (C++ function) 13973@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{1ab} 13974@deffn {C++ Function} gccjit::rvalue operator> (gccjit::rvalue a, gccjit::rvalue b) 13975 13976@example 13977gccjit::rvalue cond = (ch > limit); 13978@end example 13979 13980@noindent 13981@end deffn 13982 13983@geindex operator>= (C++ function) 13984@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{1ac} 13985@deffn {C++ Function} gccjit::rvalue operator>= (gccjit::rvalue a, gccjit::rvalue b) 13986 13987@example 13988gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100)); 13989@end example 13990 13991@noindent 13992@end deffn 13993 13994@c TODO: beyond this point 13995 13996@node Function calls<2>,Function pointers<3>,Comparisons<2>,Rvalues<2> 13997@anchor{cp/topics/expressions function-calls}@anchor{1ad} 13998@subsubsection Function calls 13999 14000 14001@geindex gcc_jit_context_new_call (C++ function) 14002@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{1ae} 14003@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) 14004 14005Given a function and the given table of argument rvalues, construct a 14006call to the function, with the result as an rvalue. 14007 14008@cartouche 14009@quotation Note 14010@code{gccjit::context::new_call()} merely builds a 14011@pxref{179,,gccjit;;rvalue} i.e. an expression that can be evaluated, 14012perhaps as part of a more complicated expression. 14013The call @emph{won't} happen unless you add a statement to a function 14014that evaluates the expression. 14015 14016For example, if you want to call a function and discard the result 14017(or to call a function with @code{void} return type), use 14018@pxref{1af,,gccjit;;block;;add_eval()}: 14019 14020@example 14021/* Add "(void)printf (arg0, arg1);". */ 14022block.add_eval (ctxt.new_call (printf_func, arg0, arg1)); 14023@end example 14024 14025@noindent 14026@end quotation 14027@end cartouche 14028@end deffn 14029 14030@node Function pointers<3>,Type-coercion<2>,Function calls<2>,Rvalues<2> 14031@anchor{cp/topics/expressions function-pointers}@anchor{1b0} 14032@subsubsection Function pointers 14033 14034 14035@geindex gccjit;;function;;get_address (C++ function) 14036@anchor{cp/topics/expressions gccjit function get_address__gccjit location}@anchor{1b1} 14037@deffn {C++ Function} gccjit::rvalue gccjit::function::get_address (gccjit::location loc) 14038 14039Get the address of a function as an rvalue, of function pointer 14040type. 14041@end deffn 14042 14043@node Type-coercion<2>,,Function pointers<3>,Rvalues<2> 14044@anchor{cp/topics/expressions type-coercion}@anchor{1b2} 14045@subsubsection Type-coercion 14046 14047 14048@geindex gccjit;;context;;new_cast (C++ function) 14049@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{1b3} 14050@deffn {C++ Function} gccjit::rvalue gccjit::context::new_cast (gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc) 14051 14052Given an rvalue of T, construct another rvalue of another type. 14053 14054Currently only a limited set of conversions are possible: 14055 14056@quotation 14057 14058 14059@itemize * 14060 14061@item 14062int <-> float 14063 14064@item 14065int <-> bool 14066 14067@item 14068P* <-> Q*, for pointer types P and Q 14069@end itemize 14070@end quotation 14071@end deffn 14072 14073@node Lvalues<2>,Working with pointers structs and unions<2>,Rvalues<2>,Expressions<2> 14074@anchor{cp/topics/expressions lvalues}@anchor{1b4} 14075@subsubsection Lvalues 14076 14077 14078@geindex gccjit;;lvalue (C++ class) 14079@anchor{cp/topics/expressions gccjit lvalue}@anchor{1b5} 14080@deffn {C++ Class} gccjit::lvalue 14081@end deffn 14082 14083An lvalue is something that can of the @emph{left}-hand side of an assignment: 14084a storage area (such as a variable). It is a subclass of 14085@pxref{179,,gccjit;;rvalue}, where the rvalue is computed by reading from the 14086storage area. 14087 14088It iss a thin wrapper around @pxref{24,,gcc_jit_lvalue *} from the C API. 14089 14090@geindex gccjit;;lvalue;;get_address (C++ function) 14091@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{1b6} 14092@deffn {C++ Function} gccjit::rvalue gccjit::lvalue::get_address (gccjit::location loc) 14093 14094Take the address of an lvalue; analogous to: 14095 14096@example 14097&(EXPR) 14098@end example 14099 14100@noindent 14101 14102in C. 14103 14104Parameter "loc" is optional. 14105@end deffn 14106 14107@menu 14108* Global variables: Global variables<2>. 14109 14110@end menu 14111 14112@node Global variables<2>,,,Lvalues<2> 14113@anchor{cp/topics/expressions global-variables}@anchor{1b7} 14114@subsubsection Global variables 14115 14116 14117@geindex gccjit;;context;;new_global (C++ function) 14118@anchor{cp/topics/expressions gccjit context new_global__enum gccjit type cCP gccjit location}@anchor{1b8} 14119@deffn {C++ Function} gccjit::lvalue gccjit::context::new_global (enum gcc_jit_global_kind, gccjit::type type, const char* name, gccjit::location loc) 14120 14121Add a new global variable of the given type and name to the context. 14122 14123This is a thin wrapper around @pxref{c4,,gcc_jit_context_new_global()} from 14124the C API; the "kind" parameter has the same meaning as there. 14125@end deffn 14126 14127@node Working with pointers structs and unions<2>,,Lvalues<2>,Expressions<2> 14128@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{1b9} 14129@subsubsection Working with pointers, structs and unions 14130 14131 14132@geindex gccjit;;rvalue;;dereference (C++ function) 14133@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{1ba} 14134@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference (gccjit::location loc) 14135 14136Given an rvalue of pointer type @code{T *}, dereferencing the pointer, 14137getting an lvalue of type @code{T}. Analogous to: 14138 14139@example 14140*(EXPR) 14141@end example 14142 14143@noindent 14144 14145in C. 14146 14147Parameter "loc" is optional. 14148@end deffn 14149 14150If you don't need to specify the location, this can also be expressed using 14151an overloaded operator: 14152 14153@geindex gccjit;;rvalue;;operator* (C++ function) 14154@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{1bb} 14155@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::operator* () 14156 14157@example 14158gccjit::lvalue content = *ptr; 14159@end example 14160 14161@noindent 14162@end deffn 14163 14164Field access is provided separately for both lvalues and rvalues: 14165 14166@geindex gccjit;;lvalue;;access_field (C++ function) 14167@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{1bc} 14168@deffn {C++ Function} gccjit::lvalue gccjit::lvalue::access_field (gccjit::field field, gccjit::location loc) 14169 14170Given an lvalue of struct or union type, access the given field, 14171getting an lvalue of the field's type. Analogous to: 14172 14173@example 14174(EXPR).field = ...; 14175@end example 14176 14177@noindent 14178 14179in C. 14180@end deffn 14181 14182@geindex gccjit;;rvalue;;access_field (C++ function) 14183@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{1bd} 14184@deffn {C++ Function} gccjit::rvalue gccjit::rvalue::access_field (gccjit::field field, gccjit::location loc) 14185 14186Given an rvalue of struct or union type, access the given field 14187as an rvalue. Analogous to: 14188 14189@example 14190(EXPR).field 14191@end example 14192 14193@noindent 14194 14195in C. 14196@end deffn 14197 14198@geindex gccjit;;rvalue;;dereference_field (C++ function) 14199@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{1be} 14200@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference_field (gccjit::field field, gccjit::location loc) 14201 14202Given an rvalue of pointer type @code{T *} where T is of struct or union 14203type, access the given field as an lvalue. Analogous to: 14204 14205@example 14206(EXPR)->field 14207@end example 14208 14209@noindent 14210 14211in C, itself equivalent to @code{(*EXPR).FIELD}. 14212@end deffn 14213 14214@geindex gccjit;;context;;new_array_access (C++ function) 14215@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{1bf} 14216@deffn {C++ Function} gccjit::lvalue gccjit::context::new_array_access (gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc) 14217 14218Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at 14219the given index, using standard C array indexing rules i.e. each 14220increment of @code{index} corresponds to @code{sizeof(T)} bytes. 14221Analogous to: 14222 14223@example 14224PTR[INDEX] 14225@end example 14226 14227@noindent 14228 14229in C (or, indeed, to @code{PTR + INDEX}). 14230 14231Parameter "loc" is optional. 14232@end deffn 14233 14234For array accesses where you don't need to specify a @pxref{153,,gccjit;;location}, 14235two overloaded operators are available: 14236 14237@quotation 14238 14239gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index) 14240 14241@example 14242gccjit::lvalue element = array[idx]; 14243@end example 14244 14245@noindent 14246 14247gccjit::lvalue gccjit::rvalue::operator[] (int index) 14248 14249@example 14250gccjit::lvalue element = array[0]; 14251@end example 14252 14253@noindent 14254@end quotation 14255 14256@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 14257@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14258@c 14259@c This is free software: you can redistribute it and/or modify it 14260@c under the terms of the GNU General Public License as published by 14261@c the Free Software Foundation, either version 3 of the License, or 14262@c (at your option) any later version. 14263@c 14264@c This program is distributed in the hope that it will be useful, but 14265@c WITHOUT ANY WARRANTY; without even the implied warranty of 14266@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14267@c General Public License for more details. 14268@c 14269@c You should have received a copy of the GNU General Public License 14270@c along with this program. If not, see 14271@c <http://www.gnu.org/licenses/>. 14272 14273@node Creating and using functions<2>,Source Locations<2>,Expressions<2>,Topic Reference<2> 14274@anchor{cp/topics/functions doc}@anchor{1c0}@anchor{cp/topics/functions creating-and-using-functions}@anchor{1c1} 14275@subsection Creating and using functions 14276 14277 14278@menu 14279* Params: Params<2>. 14280* Functions: Functions<2>. 14281* Blocks: Blocks<2>. 14282* Statements: Statements<2>. 14283 14284@end menu 14285 14286@node Params<2>,Functions<2>,,Creating and using functions<2> 14287@anchor{cp/topics/functions params}@anchor{1c2} 14288@subsubsection Params 14289 14290 14291@geindex gccjit;;param (C++ class) 14292@anchor{cp/topics/functions gccjit param}@anchor{1c3} 14293@deffn {C++ Class} gccjit::param 14294 14295A @cite{gccjit::param} represents a parameter to a function. 14296@end deffn 14297 14298@geindex gccjit;;context;;new_param (C++ function) 14299@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{122} 14300@deffn {C++ Function} gccjit::param gccjit::context::new_param (gccjit::type type, const char* name, gccjit::location loc) 14301 14302In preparation for creating a function, create a new parameter of the 14303given type and name. 14304@end deffn 14305 14306@pxref{1c3,,gccjit;;param} is a subclass of @pxref{1b5,,gccjit;;lvalue} (and thus 14307of @pxref{179,,gccjit;;rvalue} and @pxref{160,,gccjit;;object}). It is a thin 14308wrapper around the C API's @pxref{25,,gcc_jit_param *}. 14309 14310@node Functions<2>,Blocks<2>,Params<2>,Creating and using functions<2> 14311@anchor{cp/topics/functions functions}@anchor{1c4} 14312@subsubsection Functions 14313 14314 14315@geindex gccjit;;function (C++ class) 14316@anchor{cp/topics/functions gccjit function}@anchor{1c5} 14317@deffn {C++ Class} gccjit::function 14318 14319A @cite{gccjit::function} represents a function - either one that we're 14320creating ourselves, or one that we're referencing. 14321@end deffn 14322 14323@geindex gccjit;;context;;new_function (C++ function) 14324@anchor{cp/topics/functions gccjit context new_function__enum gccjit type cCP std vector param R i gccjit location}@anchor{1c6} 14325@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) 14326 14327Create a gcc_jit_function with the given name and parameters. 14328 14329Parameters "is_variadic" and "loc" are optional. 14330 14331This is a wrapper around the C API's @pxref{11,,gcc_jit_context_new_function()}. 14332@end deffn 14333 14334@geindex gccjit;;context;;get_builtin_function (C++ function) 14335@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{1c7} 14336@deffn {C++ Function} gccjit::function gccjit::context::get_builtin_function (const char* name) 14337 14338This is a wrapper around the C API's 14339@pxref{db,,gcc_jit_context_get_builtin_function()}. 14340@end deffn 14341 14342@geindex gccjit;;function;;get_param (C++ function) 14343@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{1c8} 14344@deffn {C++ Function} gccjit::param gccjit::function::get_param (int index) const 14345 14346Get the param of the given index (0-based). 14347@end deffn 14348 14349@geindex gccjit;;function;;dump_to_dot (C++ function) 14350@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{135} 14351@deffn {C++ Function} void gccjit::function::dump_to_dot (const char* path) 14352 14353Emit the function in graphviz format to the given path. 14354@end deffn 14355 14356@geindex gccjit;;function;;new_local (C++ function) 14357@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{12c} 14358@deffn {C++ Function} gccjit::lvalue gccjit::function::new_local (gccjit::type type, const char* name, gccjit::location loc) 14359 14360Create a new local variable within the function, of the given type and 14361name. 14362@end deffn 14363 14364@node Blocks<2>,Statements<2>,Functions<2>,Creating and using functions<2> 14365@anchor{cp/topics/functions blocks}@anchor{1c9} 14366@subsubsection Blocks 14367 14368 14369@geindex gccjit;;block (C++ class) 14370@anchor{cp/topics/functions gccjit block}@anchor{1ca} 14371@deffn {C++ Class} gccjit::block 14372 14373A @cite{gccjit::block} represents a basic block within a function i.e. a 14374sequence of statements with a single entry point and a single exit 14375point. 14376 14377@pxref{1ca,,gccjit;;block} is a subclass of @pxref{160,,gccjit;;object}. 14378 14379The first basic block that you create within a function will 14380be the entrypoint. 14381 14382Each basic block that you create within a function must be 14383terminated, either with a conditional, a jump, a return, or 14384a switch. 14385 14386It's legal to have multiple basic blocks that return within 14387one function. 14388@end deffn 14389 14390@geindex gccjit;;function;;new_block (C++ function) 14391@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{1cb} 14392@deffn {C++ Function} gccjit::block gccjit::function::new_block (const char* name) 14393 14394Create a basic block of the given name. The name may be NULL, but 14395providing meaningful names is often helpful when debugging: it may 14396show up in dumps of the internal representation, and in error 14397messages. 14398@end deffn 14399 14400@node Statements<2>,,Blocks<2>,Creating and using functions<2> 14401@anchor{cp/topics/functions statements}@anchor{1cc} 14402@subsubsection Statements 14403 14404 14405@geindex gccjit;;block;;add_eval (C++ function) 14406@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{1af} 14407@deffn {C++ Function} void gccjit::block::add_eval (gccjit::rvalue rvalue, gccjit::location loc) 14408 14409Add evaluation of an rvalue, discarding the result 14410(e.g. a function call that "returns" void). 14411 14412This is equivalent to this C code: 14413 14414@example 14415(void)expression; 14416@end example 14417 14418@noindent 14419@end deffn 14420 14421@geindex gccjit;;block;;add_assignment (C++ function) 14422@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{12e} 14423@deffn {C++ Function} void gccjit::block::add_assignment (gccjit::lvalue lvalue, gccjit::rvalue rvalue, gccjit::location loc) 14424 14425Add evaluation of an rvalue, assigning the result to the given 14426lvalue. 14427 14428This is roughly equivalent to this C code: 14429 14430@example 14431lvalue = rvalue; 14432@end example 14433 14434@noindent 14435@end deffn 14436 14437@geindex gccjit;;block;;add_assignment_op (C++ function) 14438@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue enum gccjit rvalue gccjit location}@anchor{132} 14439@deffn {C++ Function} void gccjit::block::add_assignment_op (gccjit::lvalue lvalue, enum gcc_jit_binary_op, gccjit::rvalue rvalue, gccjit::location loc) 14440 14441Add evaluation of an rvalue, using the result to modify an 14442lvalue. 14443 14444This is analogous to "+=" and friends: 14445 14446@example 14447lvalue += rvalue; 14448lvalue *= rvalue; 14449lvalue /= rvalue; 14450@end example 14451 14452@noindent 14453 14454etc. For example: 14455 14456@example 14457/* "i++" */ 14458loop_body.add_assignment_op ( 14459 i, 14460 GCC_JIT_BINARY_OP_PLUS, 14461 ctxt.one (int_type)); 14462@end example 14463 14464@noindent 14465@end deffn 14466 14467@geindex gccjit;;block;;add_comment (C++ function) 14468@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{13d} 14469@deffn {C++ Function} void gccjit::block::add_comment (const char* text, gccjit::location loc) 14470 14471Add a no-op textual comment to the internal representation of the 14472code. It will be optimized away, but will be visible in the dumps 14473seen via @pxref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} 14474and @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, 14475and thus may be of use when debugging how your project's internal 14476representation gets converted to the libgccjit IR. 14477 14478Parameter "loc" is optional. 14479@end deffn 14480 14481@geindex gccjit;;block;;end_with_conditional (C++ function) 14482@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{131} 14483@deffn {C++ Function} void gccjit::block::end_with_conditional (gccjit::rvalue boolval, gccjit::block on_true, gccjit::block on_false, gccjit::location loc) 14484 14485Terminate a block by adding evaluation of an rvalue, branching on the 14486result to the appropriate successor block. 14487 14488This is roughly equivalent to this C code: 14489 14490@example 14491if (boolval) 14492 goto on_true; 14493else 14494 goto on_false; 14495@end example 14496 14497@noindent 14498 14499block, boolval, on_true, and on_false must be non-NULL. 14500@end deffn 14501 14502@geindex gccjit;;block;;end_with_jump (C++ function) 14503@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{1cd} 14504@deffn {C++ Function} void gccjit::block::end_with_jump (gccjit::block target, gccjit::location loc) 14505 14506Terminate a block by adding a jump to the given target block. 14507 14508This is roughly equivalent to this C code: 14509 14510@example 14511goto target; 14512@end example 14513 14514@noindent 14515@end deffn 14516 14517@geindex gccjit;;block;;end_with_return (C++ function) 14518@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{1ce} 14519@deffn {C++ Function} void gccjit::block::end_with_return (gccjit::rvalue rvalue, gccjit::location loc) 14520 14521Terminate a block. 14522 14523Both params are optional. 14524 14525An rvalue must be provided for a function returning non-void, and 14526must not be provided by a function "returning" @cite{void}. 14527 14528If an rvalue is provided, the block is terminated by evaluating the 14529rvalue and returning the value. 14530 14531This is roughly equivalent to this C code: 14532 14533@example 14534return expression; 14535@end example 14536 14537@noindent 14538 14539If an rvalue is not provided, the block is terminated by adding a 14540valueless return, for use within a function with "void" return type. 14541 14542This is equivalent to this C code: 14543 14544@example 14545return; 14546@end example 14547 14548@noindent 14549@end deffn 14550 14551@geindex gccjit;;block;;end_with_switch (C++ function) 14552@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{1cf} 14553@deffn {C++ Function} void gccjit::block::end_with_switch (gccjit::rvalue expr, gccjit::block default_block, std::vector<gccjit::case_> cases, gccjit::location loc) 14554 14555Terminate a block by adding evalation of an rvalue, then performing 14556a multiway branch. 14557 14558This is roughly equivalent to this C code: 14559 14560@example 14561switch (expr) 14562 @{ 14563 default: 14564 goto default_block; 14565 14566 case C0.min_value ... C0.max_value: 14567 goto C0.dest_block; 14568 14569 case C1.min_value ... C1.max_value: 14570 goto C1.dest_block; 14571 14572 ...etc... 14573 14574 case C[N - 1].min_value ... C[N - 1].max_value: 14575 goto C[N - 1].dest_block; 14576@} 14577@end example 14578 14579@noindent 14580 14581@code{expr} must be of the same integer type as all of the @code{min_value} 14582and @code{max_value} within the cases. 14583 14584The ranges of the cases must not overlap (or have duplicate 14585values). 14586 14587The API entrypoints relating to switch statements and cases: 14588 14589@quotation 14590 14591 14592@itemize * 14593 14594@item 14595@pxref{1cf,,gccjit;;block;;end_with_switch()} 14596 14597@item 14598@pxref{1d0,,gccjit;;context;;new_case()} 14599@end itemize 14600@end quotation 14601 14602were added in @pxref{e9,,LIBGCCJIT_ABI_3}; you can test for their presence 14603using 14604 14605@example 14606#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 14607@end example 14608 14609@noindent 14610 14611@geindex gccjit;;block;;end_with_switch;;gccjit;;case_ (C++ class) 14612@anchor{cp/topics/functions gccjit block end_with_switch gccjit case_}@anchor{1d1} 14613@deffn {C++ Class} gccjit::case_ 14614@end deffn 14615 14616A @cite{gccjit::case_} represents a case within a switch statement, and 14617is created within a particular @pxref{14b,,gccjit;;context} using 14618@pxref{1d0,,gccjit;;context;;new_case()}. It is a subclass of 14619@pxref{160,,gccjit;;object}. 14620 14621Each case expresses a multivalued range of integer values. You 14622can express single-valued cases by passing in the same value for 14623both @cite{min_value} and @cite{max_value}. 14624 14625@geindex gccjit;;block;;end_with_switch;;gccjit;;context;;new_case (C++ function) 14626@anchor{cp/topics/functions gccjit block end_with_switch gccjit context new_case__gccjit rvalue gccjit rvalue gccjit block}@anchor{1d0} 14627@deffn {C++ Function} gccjit::case_* gccjit::context::new_case (gccjit::rvalue min_value, gccjit::rvalue max_value, gccjit::block dest_block) 14628 14629Create a new gccjit::case for use in a switch statement. 14630@cite{min_value} and @cite{max_value} must be constants of an integer type, 14631which must match that of the expression of the switch statement. 14632 14633@cite{dest_block} must be within the same function as the switch 14634statement. 14635@end deffn 14636 14637Here's an example of creating a switch statement: 14638 14639@quotation 14640 14641@example 14642 14643void 14644create_code (gcc_jit_context *c_ctxt, void *user_data) 14645@{ 14646 /* Let's try to inject the equivalent of: 14647 int 14648 test_switch (int x) 14649 @{ 14650 switch (x) 14651 @{ 14652 case 0 ... 5: 14653 return 3; 14654 14655 case 25 ... 27: 14656 return 4; 14657 14658 case -42 ... -17: 14659 return 83; 14660 14661 case 40: 14662 return 8; 14663 14664 default: 14665 return 10; 14666 @} 14667 @} 14668 */ 14669 gccjit::context ctxt (c_ctxt); 14670 gccjit::type t_int = ctxt.get_type (GCC_JIT_TYPE_INT); 14671 gccjit::type return_type = t_int; 14672 gccjit::param x = ctxt.new_param (t_int, "x"); 14673 std::vector <gccjit::param> params; 14674 params.push_back (x); 14675 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 14676 return_type, 14677 "test_switch", 14678 params, 0); 14679 14680 gccjit::block b_initial = func.new_block ("initial"); 14681 14682 gccjit::block b_default = func.new_block ("default"); 14683 gccjit::block b_case_0_5 = func.new_block ("case_0_5"); 14684 gccjit::block b_case_25_27 = func.new_block ("case_25_27"); 14685 gccjit::block b_case_m42_m17 = func.new_block ("case_m42_m17"); 14686 gccjit::block b_case_40 = func.new_block ("case_40"); 14687 14688 std::vector <gccjit::case_> cases; 14689 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 0), 14690 ctxt.new_rvalue (t_int, 5), 14691 b_case_0_5)); 14692 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 25), 14693 ctxt.new_rvalue (t_int, 27), 14694 b_case_25_27)); 14695 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, -42), 14696 ctxt.new_rvalue (t_int, -17), 14697 b_case_m42_m17)); 14698 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 40), 14699 ctxt.new_rvalue (t_int, 40), 14700 b_case_40)); 14701 b_initial.end_with_switch (x, 14702 b_default, 14703 cases); 14704 14705 b_case_0_5.end_with_return (ctxt.new_rvalue (t_int, 3)); 14706 b_case_25_27.end_with_return (ctxt.new_rvalue (t_int, 4)); 14707 b_case_m42_m17.end_with_return (ctxt.new_rvalue (t_int, 83)); 14708 b_case_40.end_with_return (ctxt.new_rvalue (t_int, 8)); 14709 b_default.end_with_return (ctxt.new_rvalue (t_int, 10)); 14710@} 14711 14712 14713@end example 14714 14715@noindent 14716@end quotation 14717@end deffn 14718 14719@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 14720@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14721@c 14722@c This is free software: you can redistribute it and/or modify it 14723@c under the terms of the GNU General Public License as published by 14724@c the Free Software Foundation, either version 3 of the License, or 14725@c (at your option) any later version. 14726@c 14727@c This program is distributed in the hope that it will be useful, but 14728@c WITHOUT ANY WARRANTY; without even the implied warranty of 14729@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14730@c General Public License for more details. 14731@c 14732@c You should have received a copy of the GNU General Public License 14733@c along with this program. If not, see 14734@c <http://www.gnu.org/licenses/>. 14735 14736@node Source Locations<2>,Compiling a context<2>,Creating and using functions<2>,Topic Reference<2> 14737@anchor{cp/topics/locations source-locations}@anchor{1d2}@anchor{cp/topics/locations doc}@anchor{1d3} 14738@subsection Source Locations 14739 14740 14741@geindex gccjit;;location (C++ class) 14742@anchor{cp/topics/locations gccjit location}@anchor{153} 14743@deffn {C++ Class} gccjit::location 14744 14745A @cite{gccjit::location} encapsulates a source code location, so that 14746you can (optionally) associate locations in your language with 14747statements in the JIT-compiled code, allowing the debugger to 14748single-step through your language. 14749 14750@cite{gccjit::location} instances are optional: you can always omit them 14751from any C++ API entrypoint accepting one. 14752 14753You can construct them using @pxref{141,,gccjit;;context;;new_location()}. 14754 14755You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 14756@pxref{14b,,gccjit;;context} for these locations to actually be usable by 14757the debugger: 14758 14759@example 14760ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1); 14761@end example 14762 14763@noindent 14764@end deffn 14765 14766@geindex gccjit;;context;;new_location (C++ function) 14767@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{141} 14768@deffn {C++ Function} gccjit::location gccjit::context::new_location (const char* filename, int line, int column) 14769 14770Create a @cite{gccjit::location} instance representing the given source 14771location. 14772@end deffn 14773 14774@menu 14775* Faking it: Faking it<2>. 14776 14777@end menu 14778 14779@node Faking it<2>,,,Source Locations<2> 14780@anchor{cp/topics/locations faking-it}@anchor{1d4} 14781@subsubsection Faking it 14782 14783 14784If you don't have source code for your internal representation, but need 14785to debug, you can generate a C-like representation of the functions in 14786your context using @pxref{152,,gccjit;;context;;dump_to_file()}: 14787 14788@example 14789ctxt.dump_to_file ("/tmp/something.c", 14790 1 /* update_locations */); 14791@end example 14792 14793@noindent 14794 14795This will dump C-like code to the given path. If the @cite{update_locations} 14796argument is true, this will also set up @cite{gccjit::location} information 14797throughout the context, pointing at the dump file as if it were a source 14798file, giving you @emph{something} you can step through in the debugger. 14799 14800@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 14801@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14802@c 14803@c This is free software: you can redistribute it and/or modify it 14804@c under the terms of the GNU General Public License as published by 14805@c the Free Software Foundation, either version 3 of the License, or 14806@c (at your option) any later version. 14807@c 14808@c This program is distributed in the hope that it will be useful, but 14809@c WITHOUT ANY WARRANTY; without even the implied warranty of 14810@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14811@c General Public License for more details. 14812@c 14813@c You should have received a copy of the GNU General Public License 14814@c along with this program. If not, see 14815@c <http://www.gnu.org/licenses/>. 14816 14817@node Compiling a context<2>,,Source Locations<2>,Topic Reference<2> 14818@anchor{cp/topics/compilation compiling-a-context}@anchor{1d5}@anchor{cp/topics/compilation doc}@anchor{1d6} 14819@subsection Compiling a context 14820 14821 14822Once populated, a @pxref{14b,,gccjit;;context} can be compiled to 14823machine code, either in-memory via @pxref{124,,gccjit;;context;;compile()} or 14824to disk via @pxref{1d7,,gccjit;;context;;compile_to_file()}. 14825 14826You can compile a context multiple times (using either form of 14827compilation), although any errors that occur on the context will 14828prevent any future compilation of that context. 14829 14830@menu 14831* In-memory compilation: In-memory compilation<2>. 14832* Ahead-of-time compilation: Ahead-of-time compilation<2>. 14833 14834@end menu 14835 14836@node In-memory compilation<2>,Ahead-of-time compilation<2>,,Compiling a context<2> 14837@anchor{cp/topics/compilation in-memory-compilation}@anchor{1d8} 14838@subsubsection In-memory compilation 14839 14840 14841@geindex gccjit;;context;;compile (C++ function) 14842@anchor{cp/topics/compilation gccjit context compile}@anchor{124} 14843@deffn {C++ Function} gcc_jit_result* gccjit::context::compile () 14844 14845This calls into GCC and builds the code, returning a 14846@cite{gcc_jit_result *}. 14847 14848This is a thin wrapper around the 14849@pxref{15,,gcc_jit_context_compile()} API entrypoint. 14850@end deffn 14851 14852@node Ahead-of-time compilation<2>,,In-memory compilation<2>,Compiling a context<2> 14853@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{1d9} 14854@subsubsection Ahead-of-time compilation 14855 14856 14857Although libgccjit is primarily aimed at just-in-time compilation, it 14858can also be used for implementing more traditional ahead-of-time 14859compilers, via the @pxref{1d7,,gccjit;;context;;compile_to_file()} method. 14860 14861@geindex gccjit;;context;;compile_to_file (C++ function) 14862@anchor{cp/topics/compilation gccjit context compile_to_file__enum cCP}@anchor{1d7} 14863@deffn {C++ Function} void gccjit::context::compile_to_file (enum gcc_jit_output_kind, const char* output_path) 14864 14865Compile the @pxref{14b,,gccjit;;context} to a file of the given 14866kind. 14867 14868This is a thin wrapper around the 14869@pxref{4a,,gcc_jit_context_compile_to_file()} API entrypoint. 14870@end deffn 14871 14872@c Copyright (C) 2014-2018 Free Software Foundation, Inc. 14873@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14874@c 14875@c This is free software: you can redistribute it and/or modify it 14876@c under the terms of the GNU General Public License as published by 14877@c the Free Software Foundation, either version 3 of the License, or 14878@c (at your option) any later version. 14879@c 14880@c This program is distributed in the hope that it will be useful, but 14881@c WITHOUT ANY WARRANTY; without even the implied warranty of 14882@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14883@c General Public License for more details. 14884@c 14885@c You should have received a copy of the GNU General Public License 14886@c along with this program. If not, see 14887@c <http://www.gnu.org/licenses/>. 14888 14889@node Internals,Indices and tables,C++ bindings for libgccjit,Top 14890@anchor{internals/index internals}@anchor{1da}@anchor{internals/index doc}@anchor{1db} 14891@chapter Internals 14892 14893 14894@menu 14895* Working on the JIT library:: 14896* Running the test suite:: 14897* Environment variables:: 14898* Packaging notes:: 14899* Overview of code structure:: 14900* Design notes:: 14901* Submitting patches:: 14902 14903@end menu 14904 14905@node Working on the JIT library,Running the test suite,,Internals 14906@anchor{internals/index working-on-the-jit-library}@anchor{1dc} 14907@section Working on the JIT library 14908 14909 14910Having checked out the source code (to "src"), you can configure and build 14911the JIT library like this: 14912 14913@example 14914mkdir build 14915mkdir install 14916PREFIX=$(pwd)/install 14917cd build 14918../src/configure \ 14919 --enable-host-shared \ 14920 --enable-languages=jit,c++ \ 14921 --disable-bootstrap \ 14922 --enable-checking=release \ 14923 --prefix=$PREFIX 14924nice make -j4 # altering the "4" to however many cores you have 14925@end example 14926 14927@noindent 14928 14929This should build a libgccjit.so within jit/build/gcc: 14930 14931@example 14932[build] $ file gcc/libgccjit.so* 14933gcc/libgccjit.so: symbolic link to `libgccjit.so.0' 14934gcc/libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' 14935gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped 14936@end example 14937 14938@noindent 14939 14940Here's what those configuration options mean: 14941 14942@geindex command line option; --enable-host-shared 14943@anchor{internals/index cmdoption--enable-host-shared}@anchor{1dd} 14944@deffn {Option} --enable-host-shared 14945 14946Configuring with this option means that the compiler is built as 14947position-independent code, which incurs a slight performance hit, 14948but it necessary for a shared library. 14949@end deffn 14950 14951@geindex command line option; --enable-languages=jit@comma{}c++ 14952@anchor{internals/index cmdoption--enable-languages}@anchor{1de} 14953@deffn {Option} --enable-languages=jit,c++ 14954 14955This specifies which frontends to build. The JIT library looks like 14956a frontend to the rest of the code. 14957 14958The C++ portion of the JIT test suite requires the C++ frontend to be 14959enabled at configure-time, or you may see errors like this when 14960running the test suite: 14961 14962@example 14963xgcc: error: /home/david/jit/src/gcc/testsuite/jit.dg/test-quadratic.cc: C++ compiler not installed on this system 14964c++: error trying to exec 'cc1plus': execvp: No such file or directory 14965@end example 14966 14967@noindent 14968@end deffn 14969 14970@geindex command line option; --disable-bootstrap 14971@anchor{internals/index cmdoption--disable-bootstrap}@anchor{1df} 14972@deffn {Option} --disable-bootstrap 14973 14974For hacking on the "jit" subdirectory, performing a full 14975bootstrap can be overkill, since it's unused by a bootstrap. However, 14976when submitting patches, you should remove this option, to ensure that 14977the compiler can still bootstrap itself. 14978@end deffn 14979 14980@geindex command line option; --enable-checking=release 14981@anchor{internals/index cmdoption--enable-checking}@anchor{1e0} 14982@deffn {Option} --enable-checking=release 14983 14984The compile can perform extensive self-checking as it runs, useful when 14985debugging, but slowing things down. 14986 14987For maximum speed, configure with @code{--enable-checking=release} to 14988disable this self-checking. 14989@end deffn 14990 14991@node Running the test suite,Environment variables,Working on the JIT library,Internals 14992@anchor{internals/index running-the-test-suite}@anchor{1e1} 14993@section Running the test suite 14994 14995 14996@example 14997[build] $ cd gcc 14998[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v" 14999@end example 15000 15001@noindent 15002 15003A summary of the tests can then be seen in: 15004 15005@example 15006jit/build/gcc/testsuite/jit/jit.sum 15007@end example 15008 15009@noindent 15010 15011and detailed logs in: 15012 15013@example 15014jit/build/gcc/testsuite/jit/jit.log 15015@end example 15016 15017@noindent 15018 15019The test executables are normally deleted after each test is run. For 15020debugging, they can be preserved by setting 15021@geindex PRESERVE_EXECUTABLES 15022@geindex environment variable; PRESERVE_EXECUTABLES 15023@code{PRESERVE_EXECUTABLES} 15024in the environment. If so, they can then be seen as: 15025 15026@example 15027jit/build/gcc/testsuite/jit/*.exe 15028@end example 15029 15030@noindent 15031 15032which can be run independently. 15033 15034You can compile and run individual tests by passing "jit.exp=TESTNAME" to RUNTESTFLAGS e.g.: 15035 15036@example 15037[gcc] $ PRESERVE_EXECUTABLES= \ 15038 make check-jit \ 15039 RUNTESTFLAGS="-v -v -v jit.exp=test-factorial.c" 15040@end example 15041 15042@noindent 15043 15044and once a test has been compiled, you can debug it directly: 15045 15046@example 15047[gcc] $ PATH=.:$PATH \ 15048 LD_LIBRARY_PATH=. \ 15049 LIBRARY_PATH=. \ 15050 gdb --args \ 15051 testsuite/jit/test-factorial.c.exe 15052@end example 15053 15054@noindent 15055 15056@menu 15057* Running under valgrind:: 15058 15059@end menu 15060 15061@node Running under valgrind,,,Running the test suite 15062@anchor{internals/index running-under-valgrind}@anchor{1e2} 15063@subsection Running under valgrind 15064 15065 15066The jit testsuite detects if 15067@geindex RUN_UNDER_VALGRIND 15068@geindex environment variable; RUN_UNDER_VALGRIND 15069@code{RUN_UNDER_VALGRIND} is present in the 15070environment (with any value). If it is present, it runs the test client 15071code under valgrind@footnote{http://valgrind.org}, 15072specifcally, the default 15073memcheck@footnote{http://valgrind.org/docs/manual/mc-manual.html} 15074tool with 15075--leak-check=full@footnote{http://valgrind.org/docs/manual/mc-manual.html#opt.leak-check}. 15076 15077It automatically parses the output from valgrind, injecting XFAIL results if 15078any issues are found, or PASS results if the output is clean. The output 15079is saved to @code{TESTNAME.exe.valgrind.txt}. 15080 15081For example, the following invocation verbosely runs the testcase 15082@code{test-sum-of-squares.c} under valgrind, showing an issue: 15083 15084@example 15085$ RUN_UNDER_VALGRIND= \ 15086 make check-jit \ 15087 RUNTESTFLAGS="-v -v -v jit.exp=test-sum-of-squares.c" 15088 15089(...verbose log contains detailed valgrind errors, if any...) 15090 15091 === jit Summary === 15092 15093# of expected passes 28 15094# of expected failures 2 15095 15096$ less testsuite/jit/jit.sum 15097(...other results...) 15098XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: definitely lost: 8 bytes in 1 blocks 15099XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: unsuppressed errors: 1 15100(...other results...) 15101 15102$ less testsuite/jit/test-sum-of-squares.c.exe.valgrind.txt 15103(...shows full valgrind report for this test case...) 15104@end example 15105 15106@noindent 15107 15108When running under valgrind, it's best to have configured gcc with 15109@code{--enable-valgrind-annotations}, which automatically suppresses 15110various known false positives. 15111 15112@node Environment variables,Packaging notes,Running the test suite,Internals 15113@anchor{internals/index environment-variables}@anchor{1e3} 15114@section Environment variables 15115 15116 15117When running client code against a locally-built libgccjit, three 15118environment variables need to be set up: 15119 15120@geindex environment variable; LD_LIBRARY_PATH 15121@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{1e4} 15122@deffn {Environment Variable} LD_LIBRARY_PATH 15123 15124@quotation 15125 15126@cite{libgccjit.so} is dynamically linked into client code, so if running 15127against a locally-built library, @code{LD_LIBRARY_PATH} needs to be set 15128up appropriately. The library can be found within the "gcc" 15129subdirectory of the build tree: 15130@end quotation 15131 15132@example 15133$ file libgccjit.so* 15134libgccjit.so: symbolic link to `libgccjit.so.0' 15135libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' 15136libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, not stripped 15137@end example 15138 15139@noindent 15140@end deffn 15141 15142@geindex environment variable; PATH 15143@anchor{internals/index envvar-PATH}@anchor{1e5} 15144@deffn {Environment Variable} PATH 15145 15146The library uses a driver executable for converting from .s assembler 15147files to .so shared libraries. Specifically, it looks for a name 15148expanded from 15149@code{$@{target_noncanonical@}-gcc-$@{gcc_BASEVER@}$@{exeext@}} 15150such as @code{x86_64-unknown-linux-gnu-gcc-5.0.0}. 15151 15152Hence @code{PATH} needs to include a directory where the library can 15153locate this executable. 15154 15155The executable is normally installed to the installation bindir 15156(e.g. /usr/bin), but a copy is also created within the "gcc" 15157subdirectory of the build tree for running the testsuite, and for ease 15158of development. 15159@end deffn 15160 15161@geindex environment variable; LIBRARY_PATH 15162@anchor{internals/index envvar-LIBRARY_PATH}@anchor{1e6} 15163@deffn {Environment Variable} LIBRARY_PATH 15164 15165The driver executable invokes the linker, and the latter needs to locate 15166support libraries needed by the generated code, or you will see errors 15167like: 15168 15169@example 15170ld: cannot find crtbeginS.o: No such file or directory 15171ld: cannot find -lgcc 15172ld: cannot find -lgcc_s 15173@end example 15174 15175@noindent 15176 15177Hence if running directly from a locally-built copy (without installing), 15178@code{LIBRARY_PATH} needs to contain the "gcc" subdirectory of the build 15179tree. 15180@end deffn 15181 15182For example, to run a binary that uses the library against a non-installed 15183build of the library in LIBGCCJIT_BUILD_DIR you need an invocation of the 15184client code like this, to preprend the dir to each of the environment 15185variables: 15186 15187@example 15188$ LD_LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LD_LIBRARY_PATH) \ 15189 PATH=$(LIBGCCJIT_BUILD_DIR):$(PATH) \ 15190 LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LIBRARY_PATH) \ 15191 ./jit-hello-world 15192hello world 15193@end example 15194 15195@noindent 15196 15197@node Packaging notes,Overview of code structure,Environment variables,Internals 15198@anchor{internals/index packaging-notes}@anchor{1e7} 15199@section Packaging notes 15200 15201 15202The configure-time option @pxref{1dd,,--enable-host-shared} is needed when 15203building the jit in order to get position-independent code. This will 15204slow down the regular compiler by a few percent. Hence when packaging gcc 15205with libgccjit, please configure and build twice: 15206 15207@quotation 15208 15209 15210@itemize * 15211 15212@item 15213once without @pxref{1dd,,--enable-host-shared} for most languages, and 15214 15215@item 15216once with @pxref{1dd,,--enable-host-shared} for the jit 15217@end itemize 15218@end quotation 15219 15220For example: 15221 15222@example 15223# Configure and build with --enable-host-shared 15224# for the jit: 15225mkdir configuration-for-jit 15226pushd configuration-for-jit 15227$(SRCDIR)/configure \ 15228 --enable-host-shared \ 15229 --enable-languages=jit \ 15230 --prefix=$(DESTDIR) 15231make 15232popd 15233 15234# Configure and build *without* --enable-host-shared 15235# for maximum speed: 15236mkdir standard-configuration 15237pushd standard-configuration 15238$(SRCDIR)/configure \ 15239 --enable-languages=all \ 15240 --prefix=$(DESTDIR) 15241make 15242popd 15243 15244# Both of the above are configured to install to $(DESTDIR) 15245# Install the configuration with --enable-host-shared first 15246# *then* the one without, so that the faster build 15247# of "cc1" et al overwrites the slower build. 15248pushd configuration-for-jit 15249make install 15250popd 15251 15252pushd standard-configuration 15253make install 15254popd 15255@end example 15256 15257@noindent 15258 15259@node Overview of code structure,Design notes,Packaging notes,Internals 15260@anchor{internals/index overview-of-code-structure}@anchor{1e8} 15261@section Overview of code structure 15262 15263 15264The library is implemented in C++. The source files have the @code{.c} 15265extension for legacy reasons. 15266 15267 15268@itemize * 15269 15270@item 15271@code{libgccjit.c} implements the API entrypoints. It performs error 15272checking, then calls into classes of the gcc::jit::recording namespace 15273within @code{jit-recording.c} and @code{jit-recording.h}. 15274 15275@item 15276The gcc::jit::recording classes (within @code{jit-recording.c} and 15277@code{jit-recording.h}) record the API calls that are made: 15278 15279@quotation 15280 15281@example 15282 15283 /* Indentation indicates inheritance: */ 15284 class context; 15285 class memento; 15286 class string; 15287 class location; 15288 class type; 15289 class function_type; 15290 class compound_type; 15291 class struct_; 15292 class union_; 15293 class vector_type; 15294 class field; 15295 class fields; 15296 class function; 15297 class block; 15298 class rvalue; 15299 class lvalue; 15300 class local; 15301 class global; 15302 class param; 15303 class base_call; 15304 class function_pointer; 15305 class statement; 15306 class case_; 15307 15308 15309@end example 15310 15311@noindent 15312@end quotation 15313 15314@item 15315When the context is compiled, the gcc::jit::playback classes (within 15316@code{jit-playback.c} and @code{jit-playback.h}) replay the API calls 15317within langhook:parse_file: 15318 15319@quotation 15320 15321@example 15322 15323 /* Indentation indicates inheritance: */ 15324 class context; 15325 class wrapper; 15326 class type; 15327 class compound_type; 15328 class field; 15329 class function; 15330 class block; 15331 class rvalue; 15332 class lvalue; 15333 class param; 15334 class source_file; 15335 class source_line; 15336 class location; 15337 class case_; 15338 15339 15340@end example 15341 15342@noindent 15343 15344@example 15345Client Code . Generated . libgccjit.so 15346 . code . 15347 . . JIT API . JIT "Frontend". (libbackend.a) 15348.................................................................................... 15349 ��� . . . . 15350 ������������������������������������������������������������������������������> . . 15351 . . ��� . . 15352 . . V . . 15353 . . ������> libgccjit.c . 15354 . . ��� (error-checking). 15355 . . ��� . 15356 . . ������> jit-recording.c 15357 . . (record API calls) 15358 . . <��������������������� . 15359 . . ��� . . 15360 <��������������������������������������������������������������������������������� . . 15361 ��� . . . . 15362 ��� . . . . 15363 V . . gcc_jit_context_compile . 15364 ������������������������������������������������������������������������������> . . 15365 . . ��� start of recording::context::compile () 15366 . . ��� . . 15367 . . ��� start of playback::context::compile () 15368 . . ��� (create tempdir) . 15369 . . ��� . . 15370 . . ��� ACQUIRE MUTEX . 15371 . . ��� . . 15372 . . V���������������������������������������������������������������������> toplev::main (for now) 15373 . . . . ��� 15374 . . . . (various code) 15375 . . . . ��� 15376 . . . . V 15377 . . . <��������������������������������������������������� langhook:parse_file 15378 . . . ��� . 15379 . . . ��� (jit_langhook_parse_file) 15380 . . . ��� . 15381..........................................���..................VVVVVVVVVVVVV... 15382 . . . ��� . No GC in here 15383 . . . ��� jit-playback.c 15384 . . . ��� (playback of API calls) 15385 . . . ���������������������������������������������> creation of functions, 15386 . . . . types, expression trees 15387 . . . <������������������������������������������������ etc 15388 . . . ���(handle_locations: add locations to 15389 . . . ��� linemap and associate them with trees) 15390 . . . ��� . 15391 . . . ��� . No GC in here 15392..........................................���..................AAAAAAAAAAAAA... 15393 . . . ��� for each function 15394 . . . ������> postprocess 15395 . . . ��� . 15396 . . . ������������������������������������> cgraph_finalize_function 15397 . . . <������������������������������������ 15398 . . . <������ . 15399 . . . ��� . 15400 . . . ������������������������������������������������������> (end of 15401 . . . . ��� langhook_parse_file) 15402 . . . . ��� 15403 . . . . (various code) 15404 . . . . ��� 15405 . . . . ��� 15406 . . . <��������������������������������������������������� langhook:write_globals 15407 . . . ��� . 15408 . . . ��� (jit_langhook_write_globals) 15409 . . . ��� . 15410 . . . ��� . 15411 . . . ������������������������������������������������������> finalize_compilation_unit 15412 . . . . ��� 15413 . . . . (the middle���end and backend) 15414 . . . . ��� 15415 . . <��������������������������������������������������������������������������������������� end of toplev::main 15416 . . ��� . . 15417 . . V���������������������������������������������������������������������> toplev::finalize 15418 . . . . ��� (purge internal state) 15419 . . <������������������������������������������������������������������������ end of toplev::finalize 15420 . . ��� . . 15421 . . V���> playback::context::postprocess: 15422 . . ��� . . 15423 . . ��� (assuming an in-memory compile): 15424 . . ��� . . 15425 . . --> Convert assembler to DSO, via embedded 15426 . . copy of driver: 15427 . . driver::main () 15428 . . invocation of "as" 15429 . . invocation of "ld" 15430 . . driver::finalize () 15431 . . <---- 15432 . . ��� . . 15433 . . ��� . Load DSO (dlopen "fake.so") 15434 . . ��� . . 15435 . . ��� . Bundle it up in a jit::result 15436 . . <������ . . 15437 . . ��� . . 15438 . . ��� RELEASE MUTEX . 15439 . . ��� . . 15440 . . ��� end of playback::context::compile () 15441 . . ��� . . 15442 . . ��� playback::context dtor 15443 . . ������> . . 15444 . . ��� Normally we cleanup the tempdir here: 15445 . . ��� ("fake.so" is unlinked from the 15446 . . ��� filesystem at this point) 15447 . . ��� If the client code requested debuginfo, the 15448 . . ��� cleanup happens later (in gcc_jit_result_release) 15449 . . ��� to make it easier on the debugger (see PR jit/64206) 15450 . . <������ . . 15451 . . ��� . . 15452 . . ��� end of recording::context::compile () 15453 <��������������������������������������������������������������������������������� . . 15454 ��� . . . . 15455 V . . gcc_jit_result_get_code . 15456 ������������������������������������������������������������������������������> . . 15457 . . ��� dlsym () within loaded DSO 15458 <��������������������������������������������������������������������������������� . . 15459 Get (void*). . . . 15460 ��� . . . . 15461 ��� Call it . . . . 15462 ���������������������������������������������> . . . 15463 . ��� . . . 15464 . ��� . . . 15465 <��������������������������������������������� . . . 15466 ��� . . . . 15467etc��� . . . . 15468 ��� . . . . 15469 V . . gcc_jit_result_release . 15470 ������������������������������������������������������������������������������> . . 15471 . . ��� dlclose () the loaded DSO 15472 . . ��� (code becomes uncallable) 15473 . . ��� . . 15474 . . ��� If the client code requested debuginfo, then 15475 . . ��� cleanup of the tempdir was delayed. 15476 . . ��� If that was the case, clean it up now. 15477 <��������������������������������������������������������������������������������� . . 15478 ��� . . . . 15479 15480@end example 15481 15482@noindent 15483@end quotation 15484@end itemize 15485 15486Here is a high-level summary from @code{jit-common.h}: 15487 15488@quotation 15489 15490In order to allow jit objects to be usable outside of a compile 15491whilst working with the existing structure of GCC's code the 15492C API is implemented in terms of a gcc::jit::recording::context, 15493which records the calls made to it. 15494 15495When a gcc_jit_context is compiled, the recording context creates a 15496playback context. The playback context invokes the bulk of the GCC 15497code, and within the "frontend" parsing hook, plays back the recorded 15498API calls, creating GCC tree objects. 15499 15500So there are two parallel families of classes: those relating to 15501recording, and those relating to playback: 15502 15503 15504@itemize * 15505 15506@item 15507Visibility: recording objects are exposed back to client code, 15508whereas playback objects are internal to the library. 15509 15510@item 15511Lifetime: recording objects have a lifetime equal to that of the 15512recording context that created them, whereas playback objects only 15513exist within the frontend hook. 15514 15515@item 15516Memory allocation: recording objects are allocated by the recording 15517context, and automatically freed by it when the context is released, 15518whereas playback objects are allocated within the GC heap, and 15519garbage-collected; they can own GC-references. 15520 15521@item 15522Integration with rest of GCC: recording objects are unrelated to the 15523rest of GCC, whereas playback objects are wrappers around "tree" 15524instances. Hence you can't ask a recording rvalue or lvalue what its 15525type is, whereas you can for a playback rvalue of lvalue (since it 15526can work with the underlying GCC tree nodes). 15527 15528@item 15529Instancing: There can be multiple recording contexts "alive" at once 15530(albeit it only one compiling at once), whereas there can only be one 15531playback context alive at one time (since it interacts with the GC). 15532@end itemize 15533 15534Ultimately if GCC could support multiple GC heaps and contexts, and 15535finer-grained initialization, then this recording vs playback 15536distinction could be eliminated. 15537 15538During a playback, we associate objects from the recording with 15539their counterparts during this playback. For simplicity, we store this 15540within the recording objects, as @code{void *m_playback_obj}, casting it to 15541the appropriate playback object subclass. For these casts to make 15542sense, the two class hierarchies need to have the same structure. 15543 15544Note that the playback objects that @code{m_playback_obj} points to are 15545GC-allocated, but the recording objects don't own references: 15546these associations only exist within a part of the code where 15547the GC doesn't collect, and are set back to NULL before the GC can 15548run. 15549@end quotation 15550@anchor{internals/index example-of-log-file}@anchor{5c} 15551Another way to understand the structure of the code is to enable logging, 15552via @pxref{5b,,gcc_jit_context_set_logfile()}. Here is an example of a log 15553generated via this call: 15554 15555@example 15556JIT: libgccjit (GCC) version 6.0.0 20150803 (experimental) (x86_64-pc-linux-gnu) 15557JIT: 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 15558JIT: entering: gcc_jit_context_set_str_option 15559JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe" 15560JIT: exiting: gcc_jit_context_set_str_option 15561JIT: entering: gcc_jit_context_set_int_option 15562JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3 15563JIT: exiting: gcc_jit_context_set_int_option 15564JIT: entering: gcc_jit_context_set_bool_option 15565JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true 15566JIT: exiting: gcc_jit_context_set_bool_option 15567JIT: entering: gcc_jit_context_set_bool_option 15568JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false 15569JIT: exiting: gcc_jit_context_set_bool_option 15570JIT: entering: gcc_jit_context_set_bool_option 15571JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false 15572JIT: exiting: gcc_jit_context_set_bool_option 15573JIT: entering: gcc_jit_context_set_bool_option 15574JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true 15575JIT: exiting: gcc_jit_context_set_bool_option 15576JIT: entering: gcc_jit_context_set_bool_option 15577JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false 15578JIT: exiting: gcc_jit_context_set_bool_option 15579JIT: entering: gcc_jit_context_get_type 15580JIT: exiting: gcc_jit_context_get_type 15581JIT: entering: gcc_jit_context_get_type 15582JIT: exiting: gcc_jit_context_get_type 15583JIT: entering: gcc_jit_context_new_param 15584JIT: exiting: gcc_jit_context_new_param 15585JIT: entering: gcc_jit_context_new_function 15586JIT: exiting: gcc_jit_context_new_function 15587JIT: entering: gcc_jit_context_new_param 15588JIT: exiting: gcc_jit_context_new_param 15589JIT: entering: gcc_jit_context_get_type 15590JIT: exiting: gcc_jit_context_get_type 15591JIT: entering: gcc_jit_context_new_function 15592JIT: exiting: gcc_jit_context_new_function 15593JIT: entering: gcc_jit_context_new_string_literal 15594JIT: exiting: gcc_jit_context_new_string_literal 15595JIT: entering: gcc_jit_function_new_block 15596JIT: exiting: gcc_jit_function_new_block 15597JIT: entering: gcc_jit_block_add_comment 15598JIT: exiting: gcc_jit_block_add_comment 15599JIT: entering: gcc_jit_context_new_call 15600JIT: exiting: gcc_jit_context_new_call 15601JIT: entering: gcc_jit_block_add_eval 15602JIT: exiting: gcc_jit_block_add_eval 15603JIT: entering: gcc_jit_block_end_with_void_return 15604JIT: exiting: gcc_jit_block_end_with_void_return 15605JIT: entering: gcc_jit_context_dump_reproducer_to_file 15606JIT: entering: void gcc::jit::recording::context::dump_reproducer_to_file(const char*) 15607JIT: exiting: void gcc::jit::recording::context::dump_reproducer_to_file(const char*) 15608JIT: exiting: gcc_jit_context_dump_reproducer_to_file 15609JIT: entering: gcc_jit_context_compile 15610JIT: in-memory compile of ctxt: 0x1283e20 15611JIT: entering: gcc::jit::result* gcc::jit::recording::context::compile() 15612JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe" 15613JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3 15614JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true 15615JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false 15616JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false 15617JIT: GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE: false 15618JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false 15619JIT: GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING: false 15620JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true 15621JIT: GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES: false 15622JIT: gcc_jit_context_set_bool_allow_unreachable_blocks: false 15623JIT: gcc_jit_context_set_bool_use_external_driver: false 15624JIT: entering: void gcc::jit::recording::context::validate() 15625JIT: exiting: void gcc::jit::recording::context::validate() 15626JIT: entering: gcc::jit::playback::context::context(gcc::jit::recording::context*) 15627JIT: exiting: gcc::jit::playback::context::context(gcc::jit::recording::context*) 15628JIT: entering: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*) 15629JIT: exiting: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*) 15630JIT: entering: void gcc::jit::playback::context::compile() 15631JIT: entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int) 15632JIT: exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int) 15633JIT: entering: bool gcc::jit::tempdir::create() 15634JIT: m_path_template: /tmp/libgccjit-XXXXXX 15635JIT: m_path_tempdir: /tmp/libgccjit-CKq1M9 15636JIT: exiting: bool gcc::jit::tempdir::create() 15637JIT: entering: void gcc::jit::playback::context::acquire_mutex() 15638JIT: exiting: void gcc::jit::playback::context::acquire_mutex() 15639JIT: entering: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*) 15640JIT: reusing cached configure-time options 15641JIT: configure_time_options[0]: -mtune=generic 15642JIT: configure_time_options[1]: -march=x86-64 15643JIT: exiting: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*) 15644JIT: entering: toplev::main 15645JIT: argv[0]: ./test-hello-world.c.exe 15646JIT: argv[1]: /tmp/libgccjit-CKq1M9/fake.c 15647JIT: argv[2]: -fPIC 15648JIT: argv[3]: -O3 15649JIT: argv[4]: -g 15650JIT: argv[5]: -quiet 15651JIT: argv[6]: --param 15652JIT: argv[7]: ggc-min-expand=0 15653JIT: argv[8]: --param 15654JIT: argv[9]: ggc-min-heapsize=0 15655JIT: argv[10]: -mtune=generic 15656JIT: argv[11]: -march=x86-64 15657JIT: entering: bool jit_langhook_init() 15658JIT: exiting: bool jit_langhook_init() 15659JIT: entering: void gcc::jit::playback::context::replay() 15660JIT: entering: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*) 15661JIT: exiting: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*) 15662JIT: entering: void gcc::jit::recording::context::disassociate_from_playback() 15663JIT: exiting: void gcc::jit::recording::context::disassociate_from_playback() 15664JIT: entering: void gcc::jit::playback::context::handle_locations() 15665JIT: exiting: void gcc::jit::playback::context::handle_locations() 15666JIT: entering: void gcc::jit::playback::function::build_stmt_list() 15667JIT: exiting: void gcc::jit::playback::function::build_stmt_list() 15668JIT: entering: void gcc::jit::playback::function::build_stmt_list() 15669JIT: exiting: void gcc::jit::playback::function::build_stmt_list() 15670JIT: entering: void gcc::jit::playback::function::postprocess() 15671JIT: exiting: void gcc::jit::playback::function::postprocess() 15672JIT: entering: void gcc::jit::playback::function::postprocess() 15673JIT: exiting: void gcc::jit::playback::function::postprocess() 15674JIT: exiting: void gcc::jit::playback::context::replay() 15675JIT: exiting: toplev::main 15676JIT: entering: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*) 15677JIT: exiting: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*) 15678JIT: entering: toplev::finalize 15679JIT: exiting: toplev::finalize 15680JIT: entering: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*) 15681JIT: entering: void gcc::jit::playback::context::convert_to_dso(const char*) 15682JIT: entering: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool) 15683JIT: entering: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*) 15684JIT: exiting: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*) 15685JIT: argv[0]: x86_64-unknown-linux-gnu-gcc-6.0.0 15686JIT: argv[1]: -m64 15687JIT: argv[2]: -shared 15688JIT: argv[3]: /tmp/libgccjit-CKq1M9/fake.s 15689JIT: argv[4]: -o 15690JIT: argv[5]: /tmp/libgccjit-CKq1M9/fake.so 15691JIT: argv[6]: -fno-use-linker-plugin 15692JIT: entering: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*) 15693JIT: exiting: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*) 15694JIT: exiting: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool) 15695JIT: exiting: void gcc::jit::playback::context::convert_to_dso(const char*) 15696JIT: entering: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso() 15697JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir to jit::result 15698JIT: entering: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*) 15699JIT: exiting: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*) 15700JIT: exiting: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso() 15701JIT: exiting: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*) 15702JIT: entering: void gcc::jit::playback::context::release_mutex() 15703JIT: exiting: void gcc::jit::playback::context::release_mutex() 15704JIT: exiting: void gcc::jit::playback::context::compile() 15705JIT: entering: gcc::jit::playback::context::~context() 15706JIT: exiting: gcc::jit::playback::context::~context() 15707JIT: exiting: gcc::jit::result* gcc::jit::recording::context::compile() 15708JIT: gcc_jit_context_compile: returning (gcc_jit_result *)0x12f75d0 15709JIT: exiting: gcc_jit_context_compile 15710JIT: entering: gcc_jit_result_get_code 15711JIT: locating fnname: hello_world 15712JIT: entering: void* gcc::jit::result::get_code(const char*) 15713JIT: exiting: void* gcc::jit::result::get_code(const char*) 15714JIT: gcc_jit_result_get_code: returning (void *)0x7ff6b8cd87f0 15715JIT: exiting: gcc_jit_result_get_code 15716JIT: entering: gcc_jit_context_release 15717JIT: deleting ctxt: 0x1283e20 15718JIT: entering: gcc::jit::recording::context::~context() 15719JIT: exiting: gcc::jit::recording::context::~context() 15720JIT: exiting: gcc_jit_context_release 15721JIT: entering: gcc_jit_result_release 15722JIT: deleting result: 0x12f75d0 15723JIT: entering: virtual gcc::jit::result::~result() 15724JIT: entering: gcc::jit::tempdir::~tempdir() 15725JIT: unlinking .s file: /tmp/libgccjit-CKq1M9/fake.s 15726JIT: unlinking .so file: /tmp/libgccjit-CKq1M9/fake.so 15727JIT: removing tempdir: /tmp/libgccjit-CKq1M9 15728JIT: exiting: gcc::jit::tempdir::~tempdir() 15729JIT: exiting: virtual gcc::jit::result::~result() 15730JIT: exiting: gcc_jit_result_release 15731JIT: gcc::jit::logger::~logger() 15732 15733@end example 15734 15735@noindent 15736 15737@node Design notes,Submitting patches,Overview of code structure,Internals 15738@anchor{internals/index design-notes}@anchor{1e9} 15739@section Design notes 15740 15741 15742It should not be possible for client code to cause an internal compiler 15743error. If this @emph{does} happen, the root cause should be isolated (perhaps 15744using @pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}) and the cause 15745should be rejected via additional checking. The checking ideally should 15746be within the libgccjit API entrypoints in libgccjit.c, since this is as 15747close as possible to the error; failing that, a good place is within 15748@code{recording::context::validate ()} in jit-recording.c. 15749 15750@node Submitting patches,,Design notes,Internals 15751@anchor{internals/index submitting-patches}@anchor{1ea} 15752@section Submitting patches 15753 15754 15755Please read the contribution guidelines for gcc at 15756@indicateurl{https://gcc.gnu.org/contribute.html}. 15757 15758Patches for the jit should be sent to both the 15759@email{gcc-patches@@gcc.gnu.org} and @email{jit@@gcc.gnu.org} mailing lists, 15760with "jit" and "PATCH" in the Subject line. 15761 15762You don't need to do a full bootstrap for code that just touches the 15763@code{jit} and @code{testsuite/jit.dg} subdirectories. However, please run 15764@code{make check-jit} before submitting the patch, and mention the results 15765in your email (along with the host triple that the tests were run on). 15766 15767A good patch should contain the information listed in the 15768gcc contribution guide linked to above; for a @code{jit} patch, the patch 15769shold contain: 15770 15771@quotation 15772 15773 15774@itemize * 15775 15776@item 15777the code itself (for example, a new API entrypoint will typically 15778touch @code{libgccjit.h} and @code{.c}, along with support code in 15779@code{jit-recording.[ch]} and @code{jit-playback.[ch]} as appropriate) 15780 15781@item 15782test coverage 15783 15784@item 15785documentation for the C API 15786 15787@item 15788documentation for the C++ API 15789@end itemize 15790@end quotation 15791 15792A patch that adds new API entrypoints should also contain: 15793 15794@quotation 15795 15796 15797@itemize * 15798 15799@item 15800a feature macro in @code{libgccjit.h} so that client code that doesn't 15801use a "configure" mechanism can still easily detect the presence of 15802the entrypoint. See e.g. @code{LIBGCCJIT_HAVE_SWITCH_STATEMENTS} (for 15803a category of entrypoints) and 15804@code{LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks} 15805(for an individual entrypoint). 15806 15807@item 15808a new ABI tag containing the new symbols (in @code{libgccjit.map}), so 15809that we can detect client code that uses them 15810 15811@item 15812Support for @pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}. Most 15813jit testcases attempt to dump their contexts to a .c file; @code{jit.exp} 15814then sanity-checks the generated c by compiling them (though 15815not running them). A new API entrypoint 15816needs to "know" how to write itself back out to C (by implementing 15817@code{gcc::jit::recording::memento::write_reproducer} for the appropriate 15818@code{memento} subclass). 15819 15820@item 15821C++ bindings for the new entrypoints (see @code{libgccjit++.h}); ideally 15822with test coverage, though the C++ API test coverage is admittedly 15823spotty at the moment 15824 15825@item 15826documentation for the new C entrypoints 15827 15828@item 15829documentation for the new C++ entrypoints 15830 15831@item 15832documentation for the new ABI tag (see @code{topics/compatibility.rst}). 15833@end itemize 15834@end quotation 15835 15836Depending on the patch you can either extend an existing test case, or 15837add a new test case. If you add an entirely new testcase: @code{jit.exp} 15838expects jit testcases to begin with @code{test-}, or @code{test-error-} (for a 15839testcase that generates an error on a @pxref{8,,gcc_jit_context}). 15840 15841Every new testcase that doesn't generate errors should also touch 15842@code{gcc/testsuite/jit.dg/all-non-failing-tests.h}: 15843 15844@quotation 15845 15846 15847@itemize * 15848 15849@item 15850Testcases that don't generate errors should ideally be added to the 15851@code{testcases} array in that file; this means that, in addition 15852to being run standalone, they also get run within 15853@code{test-combination.c} (which runs all successful tests inside one 15854big @pxref{8,,gcc_jit_context}), and @code{test-threads.c} (which runs all 15855successful tests in one process, each one running in a different 15856thread on a different @pxref{8,,gcc_jit_context}). 15857 15858@cartouche 15859@quotation Note 15860Given that exported functions within a @pxref{8,,gcc_jit_context} 15861must have unique names, and most testcases are run within 15862@code{test-combination.c}, this means that every jit-compiled test 15863function typically needs a name that's unique across the entire 15864test suite. 15865@end quotation 15866@end cartouche 15867 15868@item 15869Testcases that aren't to be added to the @code{testcases} array should 15870instead add a comment to the file clarifying why they're not in that 15871array. See the file for examples. 15872@end itemize 15873@end quotation 15874 15875Typically a patch that touches the .rst documentation will also need the 15876texinfo to be regenerated. You can do this with 15877Sphinx 1.0@footnote{http://sphinx-doc.org/} or later by 15878running @code{make texinfo} within @code{SRCDIR/gcc/jit/docs}. Don't do this 15879within the patch sent to the mailing list; it can often be relatively 15880large and inconsequential (e.g. anchor renumbering), rather like generated 15881"configure" changes from configure.ac. You can regenerate it when 15882committing to svn. 15883 15884@node Indices and tables,Index,Internals,Top 15885@anchor{index indices-and-tables}@anchor{1eb} 15886@unnumbered Indices and tables 15887 15888 15889 15890@itemize * 15891 15892@item 15893@emph{genindex} 15894 15895@item 15896@emph{modindex} 15897 15898@item 15899@emph{search} 15900@end itemize 15901 15902@c Some notes: 15903@c 15904@c The Sphinx C domain appears to lack explicit support for enum values, 15905@c so I've been using :c:macro: for them. 15906@c 15907@c See http://sphinx-doc.org/domains.html#the-c-domain 15908 15909@node Index,,Indices and tables,Top 15910@unnumbered Index 15911 15912 15913@printindex ge 15914 15915@c %**end of body 15916@bye 15917