1\input texinfo @c -*-texinfo-*- 2@c %**start of header 3@setfilename libgccjit.info 4@documentencoding UTF-8 5@ifinfo 6@*Generated by Sphinx 2.2.2.@* 7@end ifinfo 8@settitle libgccjit Documentation 9@defindex ge 10@paragraphindent 0 11@exampleindent 4 12@finalout 13@dircategory Miscellaneous 14@direntry 15* libgccjit: (libgccjit.info). GCC-based Just In Time compiler library. 16@end direntry 17 18@definfoenclose strong,`,' 19@definfoenclose emph,`,' 20@c %**end of header 21 22@copying 23@quotation 24libgccjit 12.0.1 (experimental 20220411), Apr 12, 2022 25 26David Malcolm 27 28Copyright @copyright{} 2014-2022 Free Software Foundation, Inc. 29@end quotation 30 31@end copying 32 33@titlepage 34@title libgccjit Documentation 35@insertcopying 36@end titlepage 37@contents 38 39@c %** start of user preamble 40 41@c %** end of user preamble 42 43@ifnottex 44@node Top 45@top libgccjit Documentation 46@insertcopying 47@end ifnottex 48 49@c %**start of body 50@anchor{index doc}@anchor{0} 51@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 52@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 53@c 54@c This is free software: you can redistribute it and/or modify it 55@c under the terms of the GNU General Public License as published by 56@c the Free Software Foundation, either version 3 of the License, or 57@c (at your option) any later version. 58@c 59@c This program is distributed in the hope that it will be useful, but 60@c WITHOUT ANY WARRANTY; without even the implied warranty of 61@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 62@c General Public License for more details. 63@c 64@c You should have received a copy of the GNU General Public License 65@c along with this program. If not, see 66@c <https://www.gnu.org/licenses/>. 67 68This document describes libgccjit@footnote{https://gcc.gnu.org/wiki/JIT}, an API 69for embedding GCC inside programs and libraries. 70 71There are actually two APIs for the library: 72 73 74@itemize * 75 76@item 77a pure C API: @code{libgccjit.h} 78 79@item 80a C++ wrapper API: @code{libgccjit++.h}. This is a collection of ���thin��� 81wrapper classes around the C API, to save typing. 82@end itemize 83 84Contents: 85 86@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 87@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 88@c 89@c This is free software: you can redistribute it and/or modify it 90@c under the terms of the GNU General Public License as published by 91@c the Free Software Foundation, either version 3 of the License, or 92@c (at your option) any later version. 93@c 94@c This program is distributed in the hope that it will be useful, but 95@c WITHOUT ANY WARRANTY; without even the implied warranty of 96@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 97@c General Public License for more details. 98@c 99@c You should have received a copy of the GNU General Public License 100@c along with this program. If not, see 101@c <https://www.gnu.org/licenses/>. 102 103@menu 104* Tutorial:: 105* Topic Reference:: 106* C++ bindings for libgccjit:: 107* Internals:: 108* Indices and tables:: 109* Index:: 110 111@detailmenu 112 --- The Detailed Node Listing --- 113 114Tutorial 115 116* Tutorial part 1; ���Hello world���: Tutorial part 1 ���Hello world���. 117* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function. 118* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables. 119* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter. 120* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler. 121 122Tutorial part 2: Creating a trivial machine code function 123 124* Error-handling:: 125* Options:: 126* Full example:: 127 128Tutorial part 3: Loops and variables 129 130* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. 131* Control flow:: 132* Visualizing the control flow graph:: 133* Full example: Full example<2>. 134 135Tutorial part 4: Adding JIT-compilation to a toy interpreter 136 137* Our toy interpreter:: 138* Compiling to machine code:: 139* Setting things up:: 140* Populating the function:: 141* Verifying the control flow graph:: 142* Compiling the context:: 143* Single-stepping through the generated code:: 144* Examining the generated code:: 145* Putting it all together:: 146* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?. 147 148Behind the curtain: How does our code get optimized? 149 150* Optimizing away stack manipulation:: 151* Elimination of tail recursion:: 152 153Tutorial part 5: Implementing an Ahead-of-Time compiler 154 155* The ���brainf��� language:: 156* Converting a brainf script to libgccjit IR:: 157* Compiling a context to a file:: 158* Other forms of ahead-of-time-compilation:: 159 160Topic Reference 161 162* Compilation contexts:: 163* Objects:: 164* Types:: 165* Expressions:: 166* Creating and using functions:: 167* Function pointers: Function pointers<2>. 168* Source Locations:: 169* Compiling a context:: 170* ABI and API compatibility:: 171* Performance:: 172* Using Assembly Language with libgccjit:: 173 174Compilation contexts 175 176* Lifetime-management:: 177* Thread-safety:: 178* Error-handling: Error-handling<2>. 179* Debugging:: 180* Options: Options<2>. 181 182Options 183 184* String Options:: 185* Boolean options:: 186* Integer options:: 187* Additional command-line options:: 188 189Types 190 191* Standard types:: 192* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 193* Vector types:: 194* Structures and unions:: 195* Function pointer types:: 196* Reflection API:: 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* Constructor expressions:: 208* Vector expressions:: 209* Unary Operations:: 210* Binary Operations:: 211* Comparisons:: 212* Function calls:: 213* Function pointers:: 214* Type-coercion:: 215 216Lvalues 217 218* Global variables:: 219 220Creating and using functions 221 222* Params:: 223* Functions:: 224* Blocks:: 225* Statements:: 226 227Source Locations 228 229* Faking it:: 230 231Compiling a context 232 233* In-memory compilation:: 234* Ahead-of-time compilation:: 235 236ABI and API compatibility 237 238* Programmatically checking version:: 239* ABI symbol tags:: 240 241ABI symbol tags 242 243* LIBGCCJIT_ABI_0:: 244* LIBGCCJIT_ABI_1:: 245* LIBGCCJIT_ABI_2:: 246* LIBGCCJIT_ABI_3:: 247* LIBGCCJIT_ABI_4:: 248* LIBGCCJIT_ABI_5:: 249* LIBGCCJIT_ABI_6:: 250* LIBGCCJIT_ABI_7:: 251* LIBGCCJIT_ABI_8:: 252* LIBGCCJIT_ABI_9:: 253* LIBGCCJIT_ABI_10:: 254* LIBGCCJIT_ABI_11:: 255* LIBGCCJIT_ABI_12:: 256* LIBGCCJIT_ABI_13:: 257* LIBGCCJIT_ABI_14:: 258* LIBGCCJIT_ABI_15:: 259* LIBGCCJIT_ABI_16:: 260* LIBGCCJIT_ABI_17:: 261* LIBGCCJIT_ABI_18:: 262* LIBGCCJIT_ABI_19:: 263* LIBGCCJIT_ABI_20:: 264* LIBGCCJIT_ABI_21:: 265* LIBGCCJIT_ABI_22:: 266* LIBGCCJIT_ABI_23:: 267* LIBGCCJIT_ABI_24:: 268 269Performance 270 271* The timing API:: 272 273Using Assembly Language with libgccjit 274 275* Adding assembler instructions within a function:: 276* Adding top-level assembler statements:: 277 278C++ bindings for libgccjit 279 280* Tutorial: Tutorial<2>. 281* Topic Reference: Topic Reference<2>. 282 283Tutorial 284 285* Tutorial part 1; ���Hello world���: Tutorial part 1 ���Hello world���<2>. 286* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 287* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 288* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 289 290Tutorial part 2: Creating a trivial machine code function 291 292* Options: Options<3>. 293* Full example: Full example<3>. 294 295Tutorial part 3: Loops and variables 296 297* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 298* Control flow: Control flow<2>. 299* Visualizing the control flow graph: Visualizing the control flow graph<2>. 300* Full example: Full example<4>. 301 302Tutorial part 4: Adding JIT-compilation to a toy interpreter 303 304* Our toy interpreter: Our toy interpreter<2>. 305* Compiling to machine code: Compiling to machine code<2>. 306* Setting things up: Setting things up<2>. 307* Populating the function: Populating the function<2>. 308* Verifying the control flow graph: Verifying the control flow graph<2>. 309* Compiling the context: Compiling the context<2>. 310* Single-stepping through the generated code: Single-stepping through the generated code<2>. 311* Examining the generated code: Examining the generated code<2>. 312* Putting it all together: Putting it all together<2>. 313* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 314 315Behind the curtain: How does our code get optimized? 316 317* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 318* Elimination of tail recursion: Elimination of tail recursion<2>. 319 320Topic Reference 321 322* Compilation contexts: Compilation contexts<2>. 323* Objects: Objects<2>. 324* Types: Types<2>. 325* Expressions: Expressions<2>. 326* Creating and using functions: Creating and using functions<2>. 327* Source Locations: Source Locations<2>. 328* Compiling a context: Compiling a context<2>. 329* Using Assembly Language with libgccjit++:: 330 331Compilation contexts 332 333* Lifetime-management: Lifetime-management<2>. 334* Thread-safety: Thread-safety<2>. 335* Error-handling: Error-handling<3>. 336* Debugging: Debugging<2>. 337* Options: Options<4>. 338 339Options 340 341* String Options: String Options<2>. 342* Boolean options: Boolean options<2>. 343* Integer options: Integer options<2>. 344* Additional command-line options: Additional command-line options<2>. 345 346Types 347 348* Standard types: Standard types<2>. 349* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 350* Vector types: Vector types<2>. 351* Structures and unions: Structures and unions<2>. 352 353Expressions 354 355* Rvalues: Rvalues<2>. 356* Lvalues: Lvalues<2>. 357* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 358 359Rvalues 360 361* Simple expressions: Simple expressions<2>. 362* Vector expressions: Vector expressions<2>. 363* Unary Operations: Unary Operations<2>. 364* Binary Operations: Binary Operations<2>. 365* Comparisons: Comparisons<2>. 366* Function calls: Function calls<2>. 367* Function pointers: Function pointers<3>. 368* Type-coercion: Type-coercion<2>. 369 370Lvalues 371 372* Global variables: Global variables<2>. 373 374Creating and using functions 375 376* Params: Params<2>. 377* Functions: Functions<2>. 378* Blocks: Blocks<2>. 379* Statements: Statements<2>. 380 381Source Locations 382 383* Faking it: Faking it<2>. 384 385Compiling a context 386 387* In-memory compilation: In-memory compilation<2>. 388* Ahead-of-time compilation: Ahead-of-time compilation<2>. 389 390Using Assembly Language with libgccjit++ 391 392* Adding assembler instructions within a function: Adding assembler instructions within a function<2>. 393* Adding top-level assembler statements: Adding top-level assembler statements<2>. 394 395Internals 396 397* Working on the JIT library:: 398* Running the test suite:: 399* Environment variables:: 400* Packaging notes:: 401* Overview of code structure:: 402* Design notes:: 403* Submitting patches:: 404 405Running the test suite 406 407* Running under valgrind:: 408 409@end detailmenu 410@end menu 411 412@node Tutorial,Topic Reference,Top,Top 413@anchor{intro/index doc}@anchor{1}@anchor{intro/index libgccjit}@anchor{2}@anchor{intro/index tutorial}@anchor{3} 414@chapter Tutorial 415 416 417@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 418@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 419@c 420@c This is free software: you can redistribute it and/or modify it 421@c under the terms of the GNU General Public License as published by 422@c the Free Software Foundation, either version 3 of the License, or 423@c (at your option) any later version. 424@c 425@c This program is distributed in the hope that it will be useful, but 426@c WITHOUT ANY WARRANTY; without even the implied warranty of 427@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 428@c General Public License for more details. 429@c 430@c You should have received a copy of the GNU General Public License 431@c along with this program. If not, see 432@c <https://www.gnu.org/licenses/>. 433 434@menu 435* Tutorial part 1; ���Hello world���: Tutorial part 1 ���Hello world���. 436* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function. 437* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables. 438* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter. 439* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler. 440 441@end menu 442 443@node Tutorial part 1 ���Hello world���,Tutorial part 2 Creating a trivial machine code function,,Tutorial 444@anchor{intro/tutorial01 doc}@anchor{4}@anchor{intro/tutorial01 tutorial-part-1-hello-world}@anchor{5} 445@section Tutorial part 1: ���Hello world��� 446 447 448Before we look at the details of the API, let���s look at building and 449running programs that use the library. 450 451Here���s a toy ���hello world��� program that uses the library to synthesize 452a call to @cite{printf} and uses it to write a message to stdout. 453 454Don���t worry about the content of the program for now; we���ll cover 455the details in later parts of this tutorial. 456 457@quotation 458 459@example 460/* Smoketest example for libgccjit.so 461 Copyright (C) 2014-2022 Free Software Foundation, Inc. 462 463This file is part of GCC. 464 465GCC is free software; you can redistribute it and/or modify it 466under the terms of the GNU General Public License as published by 467the Free Software Foundation; either version 3, or (at your option) 468any later version. 469 470GCC is distributed in the hope that it will be useful, but 471WITHOUT ANY WARRANTY; without even the implied warranty of 472MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 473General Public License for more details. 474 475You should have received a copy of the GNU General Public License 476along with GCC; see the file COPYING3. If not see 477<http://www.gnu.org/licenses/>. */ 478 479#include <libgccjit.h> 480 481#include <stdlib.h> 482#include <stdio.h> 483 484static void 485create_code (gcc_jit_context *ctxt) 486@{ 487 /* Let's try to inject the equivalent of: 488 void 489 greet (const char *name) 490 @{ 491 printf ("hello %s\n", name); 492 @} 493 */ 494 gcc_jit_type *void_type = 495 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); 496 gcc_jit_type *const_char_ptr_type = 497 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); 498 gcc_jit_param *param_name = 499 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); 500 gcc_jit_function *func = 501 gcc_jit_context_new_function (ctxt, NULL, 502 GCC_JIT_FUNCTION_EXPORTED, 503 void_type, 504 "greet", 505 1, ¶m_name, 506 0); 507 508 gcc_jit_param *param_format = 509 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); 510 gcc_jit_function *printf_func = 511 gcc_jit_context_new_function (ctxt, NULL, 512 GCC_JIT_FUNCTION_IMPORTED, 513 gcc_jit_context_get_type ( 514 ctxt, GCC_JIT_TYPE_INT), 515 "printf", 516 1, ¶m_format, 517 1); 518 gcc_jit_rvalue *args[2]; 519 args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); 520 args[1] = gcc_jit_param_as_rvalue (param_name); 521 522 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 523 524 gcc_jit_block_add_eval ( 525 block, NULL, 526 gcc_jit_context_new_call (ctxt, 527 NULL, 528 printf_func, 529 2, args)); 530 gcc_jit_block_end_with_void_return (block, NULL); 531@} 532 533int 534main (int argc, char **argv) 535@{ 536 gcc_jit_context *ctxt; 537 gcc_jit_result *result; 538 539 /* Get a "context" object for working with the library. */ 540 ctxt = gcc_jit_context_acquire (); 541 if (!ctxt) 542 @{ 543 fprintf (stderr, "NULL ctxt"); 544 exit (1); 545 @} 546 547 /* Set some options on the context. 548 Let's see the code being generated, in assembler form. */ 549 gcc_jit_context_set_bool_option ( 550 ctxt, 551 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 552 0); 553 554 /* Populate the context. */ 555 create_code (ctxt); 556 557 /* Compile the code. */ 558 result = gcc_jit_context_compile (ctxt); 559 if (!result) 560 @{ 561 fprintf (stderr, "NULL result"); 562 exit (1); 563 @} 564 565 /* Extract the generated code from "result". */ 566 typedef void (*fn_type) (const char *); 567 fn_type greet = 568 (fn_type)gcc_jit_result_get_code (result, "greet"); 569 if (!greet) 570 @{ 571 fprintf (stderr, "NULL greet"); 572 exit (1); 573 @} 574 575 /* Now call the generated function: */ 576 greet ("world"); 577 fflush (stdout); 578 579 gcc_jit_context_release (ctxt); 580 gcc_jit_result_release (result); 581 return 0; 582@} 583@end example 584@end quotation 585 586Copy the above to @cite{tut01-hello-world.c}. 587 588Assuming you have the jit library installed, build the test program 589using: 590 591@example 592$ gcc \ 593 tut01-hello-world.c \ 594 -o tut01-hello-world \ 595 -lgccjit 596@end example 597 598You should then be able to run the built program: 599 600@example 601$ ./tut01-hello-world 602hello world 603@end example 604 605@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 606@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 607@c 608@c This is free software: you can redistribute it and/or modify it 609@c under the terms of the GNU General Public License as published by 610@c the Free Software Foundation, either version 3 of the License, or 611@c (at your option) any later version. 612@c 613@c This program is distributed in the hope that it will be useful, but 614@c WITHOUT ANY WARRANTY; without even the implied warranty of 615@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 616@c General Public License for more details. 617@c 618@c You should have received a copy of the GNU General Public License 619@c along with this program. If not, see 620@c <https://www.gnu.org/licenses/>. 621 622@node Tutorial part 2 Creating a trivial machine code function,Tutorial part 3 Loops and variables,Tutorial part 1 ���Hello world���,Tutorial 623@anchor{intro/tutorial02 doc}@anchor{6}@anchor{intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{7} 624@section Tutorial part 2: Creating a trivial machine code function 625 626 627Consider this C function: 628 629@example 630int square (int i) 631@{ 632 return i * i; 633@} 634@end example 635 636How can we construct this at run-time using libgccjit? 637 638First we need to include the relevant header: 639 640@example 641#include <libgccjit.h> 642@end example 643 644All state associated with compilation is associated with a 645@ref{8,,gcc_jit_context *}. 646 647Create one using @ref{9,,gcc_jit_context_acquire()}: 648 649@example 650gcc_jit_context *ctxt; 651ctxt = gcc_jit_context_acquire (); 652@end example 653 654The JIT library has a system of types. It is statically-typed: every 655expression is of a specific type, fixed at compile-time. In our example, 656all of the expressions are of the C @cite{int} type, so let���s obtain this from 657the context, as a @ref{a,,gcc_jit_type *}, using 658@ref{b,,gcc_jit_context_get_type()}: 659 660@example 661gcc_jit_type *int_type = 662 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 663@end example 664 665@ref{a,,gcc_jit_type *} is an example of a ���contextual��� object: every 666entity in the API is associated with a @ref{8,,gcc_jit_context *}. 667 668Memory management is easy: all such ���contextual��� objects are automatically 669cleaned up for you when the context is released, using 670@ref{c,,gcc_jit_context_release()}: 671 672@example 673gcc_jit_context_release (ctxt); 674@end example 675 676so you don���t need to manually track and cleanup all objects, just the 677contexts. 678 679Although the API is C-based, there is a form of class hierarchy, which 680looks like this: 681 682@example 683+- gcc_jit_object 684 +- gcc_jit_location 685 +- gcc_jit_type 686 +- gcc_jit_struct 687 +- gcc_jit_field 688 +- gcc_jit_function 689 +- gcc_jit_block 690 +- gcc_jit_rvalue 691 +- gcc_jit_lvalue 692 +- gcc_jit_param 693@end example 694 695There are casting methods for upcasting from subclasses to parent classes. 696For example, @ref{d,,gcc_jit_type_as_object()}: 697 698@example 699gcc_jit_object *obj = gcc_jit_type_as_object (int_type); 700@end example 701 702One thing you can do with a @ref{e,,gcc_jit_object *} is 703to ask it for a human-readable description, using 704@ref{f,,gcc_jit_object_get_debug_string()}: 705 706@example 707printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); 708@end example 709 710giving this text on stdout: 711 712@example 713obj: int 714@end example 715 716This is invaluable when debugging. 717 718Let���s create the function. To do so, we first need to construct 719its single parameter, specifying its type and giving it a name, 720using @ref{10,,gcc_jit_context_new_param()}: 721 722@example 723gcc_jit_param *param_i = 724 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 725@end example 726 727Now we can create the function, using 728@ref{11,,gcc_jit_context_new_function()}: 729 730@example 731gcc_jit_function *func = 732 gcc_jit_context_new_function (ctxt, NULL, 733 GCC_JIT_FUNCTION_EXPORTED, 734 int_type, 735 "square", 736 1, ¶m_i, 737 0); 738@end example 739 740To define the code within the function, we must create basic blocks 741containing statements. 742 743Every basic block contains a list of statements, eventually terminated 744by a statement that either returns, or jumps to another basic block. 745 746Our function has no control-flow, so we just need one basic block: 747 748@example 749gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 750@end example 751 752Our basic block is relatively simple: it immediately terminates by 753returning the value of an expression. 754 755We can build the expression using @ref{12,,gcc_jit_context_new_binary_op()}: 756 757@example 758gcc_jit_rvalue *expr = 759 gcc_jit_context_new_binary_op ( 760 ctxt, NULL, 761 GCC_JIT_BINARY_OP_MULT, int_type, 762 gcc_jit_param_as_rvalue (param_i), 763 gcc_jit_param_as_rvalue (param_i)); 764@end example 765 766A @ref{13,,gcc_jit_rvalue *} is another example of a 767@ref{e,,gcc_jit_object *} subclass. We can upcast it using 768@ref{14,,gcc_jit_rvalue_as_object()} and as before print it with 769@ref{f,,gcc_jit_object_get_debug_string()}. 770 771@example 772printf ("expr: %s\n", 773 gcc_jit_object_get_debug_string ( 774 gcc_jit_rvalue_as_object (expr))); 775@end example 776 777giving this output: 778 779@example 780expr: i * i 781@end example 782 783Creating the expression in itself doesn���t do anything; we have to add 784this expression to a statement within the block. In this case, we use it 785to build a return statement, which terminates the basic block: 786 787@example 788gcc_jit_block_end_with_return (block, NULL, expr); 789@end example 790 791OK, we���ve populated the context. We can now compile it using 792@ref{15,,gcc_jit_context_compile()}: 793 794@example 795gcc_jit_result *result; 796result = gcc_jit_context_compile (ctxt); 797@end example 798 799and get a @ref{16,,gcc_jit_result *}. 800 801At this point we���re done with the context; we can release it: 802 803@example 804gcc_jit_context_release (ctxt); 805@end example 806 807We can now use @ref{17,,gcc_jit_result_get_code()} to look up a specific 808machine code routine within the result, in this case, the function we 809created above. 810 811@example 812void *fn_ptr = gcc_jit_result_get_code (result, "square"); 813if (!fn_ptr) 814 @{ 815 fprintf (stderr, "NULL fn_ptr"); 816 goto error; 817 @} 818@end example 819 820We can now cast the pointer to an appropriate function pointer type, and 821then call it: 822 823@example 824typedef int (*fn_type) (int); 825fn_type square = (fn_type)fn_ptr; 826printf ("result: %d", square (5)); 827@end example 828 829@example 830result: 25 831@end example 832 833Once we���re done with the code, we can release the result: 834 835@example 836gcc_jit_result_release (result); 837@end example 838 839We can���t call @code{square} anymore once we���ve released @code{result}. 840 841@menu 842* Error-handling:: 843* Options:: 844* Full example:: 845 846@end menu 847 848@node Error-handling,Options,,Tutorial part 2 Creating a trivial machine code function 849@anchor{intro/tutorial02 error-handling}@anchor{18} 850@subsection Error-handling 851 852 853Various kinds of errors are possible when using the API, such as 854mismatched types in an assignment. You can only compile and get code 855from a context if no errors occur. 856 857Errors are printed on stderr; they typically contain the name of the API 858entrypoint where the error occurred, and pertinent information on the 859problem: 860 861@example 862./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *) 863@end example 864 865The API is designed to cope with errors without crashing, so you can get 866away with having a single error-handling check in your code: 867 868@example 869void *fn_ptr = gcc_jit_result_get_code (result, "square"); 870if (!fn_ptr) 871 @{ 872 fprintf (stderr, "NULL fn_ptr"); 873 goto error; 874 @} 875@end example 876 877For more information, see the @ref{19,,error-handling guide} 878within the Topic eference. 879 880@node Options,Full example,Error-handling,Tutorial part 2 Creating a trivial machine code function 881@anchor{intro/tutorial02 options}@anchor{1a} 882@subsection Options 883 884 885To get more information on what���s going on, you can set debugging flags 886on the context using @ref{1b,,gcc_jit_context_set_bool_option()}. 887 888@c (I'm deliberately not mentioning 889@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think 890@c it's probably more of use to implementors than to users) 891 892Setting @ref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a 893C-like representation to stderr when you compile (GCC���s ���GIMPLE��� 894representation): 895 896@example 897gcc_jit_context_set_bool_option ( 898 ctxt, 899 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 900 1); 901result = gcc_jit_context_compile (ctxt); 902@end example 903 904@example 905square (signed int i) 906@{ 907 signed int D.260; 908 909 entry: 910 D.260 = i * i; 911 return D.260; 912@} 913@end example 914 915We can see the generated machine code in assembler form (on stderr) by 916setting @ref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context 917before compiling: 918 919@example 920gcc_jit_context_set_bool_option ( 921 ctxt, 922 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 923 1); 924result = gcc_jit_context_compile (ctxt); 925@end example 926 927@example 928 .file "fake.c" 929 .text 930 .globl square 931 .type square, @@function 932square: 933.LFB6: 934 .cfi_startproc 935 pushq %rbp 936 .cfi_def_cfa_offset 16 937 .cfi_offset 6, -16 938 movq %rsp, %rbp 939 .cfi_def_cfa_register 6 940 movl %edi, -4(%rbp) 941.L14: 942 movl -4(%rbp), %eax 943 imull -4(%rbp), %eax 944 popq %rbp 945 .cfi_def_cfa 7, 8 946 ret 947 .cfi_endproc 948.LFE6: 949 .size square, .-square 950 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 951 .section .note.GNU-stack,"",@@progbits 952@end example 953 954By default, no optimizations are performed, the equivalent of GCC���s 955@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling 956@ref{1e,,gcc_jit_context_set_int_option()} with 957@ref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 958 959@example 960gcc_jit_context_set_int_option ( 961 ctxt, 962 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 963 3); 964@end example 965 966@example 967 .file "fake.c" 968 .text 969 .p2align 4,,15 970 .globl square 971 .type square, @@function 972square: 973.LFB7: 974 .cfi_startproc 975.L16: 976 movl %edi, %eax 977 imull %edi, %eax 978 ret 979 .cfi_endproc 980.LFE7: 981 .size square, .-square 982 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 983 .section .note.GNU-stack,"",@@progbits 984@end example 985 986Naturally this has only a small effect on such a trivial function. 987 988@node Full example,,Options,Tutorial part 2 Creating a trivial machine code function 989@anchor{intro/tutorial02 full-example}@anchor{20} 990@subsection Full example 991 992 993Here���s what the above looks like as a complete program: 994 995@quotation 996 997@example 998/* Usage example for libgccjit.so 999 Copyright (C) 2014-2022 Free Software Foundation, Inc. 1000 1001This file is part of GCC. 1002 1003GCC is free software; you can redistribute it and/or modify it 1004under the terms of the GNU General Public License as published by 1005the Free Software Foundation; either version 3, or (at your option) 1006any later version. 1007 1008GCC is distributed in the hope that it will be useful, but 1009WITHOUT ANY WARRANTY; without even the implied warranty of 1010MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1011General Public License for more details. 1012 1013You should have received a copy of the GNU General Public License 1014along with GCC; see the file COPYING3. If not see 1015<http://www.gnu.org/licenses/>. */ 1016 1017#include <libgccjit.h> 1018 1019#include <stdlib.h> 1020#include <stdio.h> 1021 1022void 1023create_code (gcc_jit_context *ctxt) 1024@{ 1025 /* Let's try to inject the equivalent of: 1026 1027 int square (int i) 1028 @{ 1029 return i * i; 1030 @} 1031 */ 1032 gcc_jit_type *int_type = 1033 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1034 gcc_jit_param *param_i = 1035 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 1036 gcc_jit_function *func = 1037 gcc_jit_context_new_function (ctxt, NULL, 1038 GCC_JIT_FUNCTION_EXPORTED, 1039 int_type, 1040 "square", 1041 1, ¶m_i, 1042 0); 1043 1044 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 1045 1046 gcc_jit_rvalue *expr = 1047 gcc_jit_context_new_binary_op ( 1048 ctxt, NULL, 1049 GCC_JIT_BINARY_OP_MULT, int_type, 1050 gcc_jit_param_as_rvalue (param_i), 1051 gcc_jit_param_as_rvalue (param_i)); 1052 1053 gcc_jit_block_end_with_return (block, NULL, expr); 1054@} 1055 1056int 1057main (int argc, char **argv) 1058@{ 1059 gcc_jit_context *ctxt = NULL; 1060 gcc_jit_result *result = NULL; 1061 1062 /* Get a "context" object for working with the library. */ 1063 ctxt = gcc_jit_context_acquire (); 1064 if (!ctxt) 1065 @{ 1066 fprintf (stderr, "NULL ctxt"); 1067 goto error; 1068 @} 1069 1070 /* Set some options on the context. 1071 Let's see the code being generated, in assembler form. */ 1072 gcc_jit_context_set_bool_option ( 1073 ctxt, 1074 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1075 0); 1076 1077 /* Populate the context. */ 1078 create_code (ctxt); 1079 1080 /* Compile the code. */ 1081 result = gcc_jit_context_compile (ctxt); 1082 if (!result) 1083 @{ 1084 fprintf (stderr, "NULL result"); 1085 goto error; 1086 @} 1087 1088 /* We're done with the context; we can release it: */ 1089 gcc_jit_context_release (ctxt); 1090 ctxt = NULL; 1091 1092 /* Extract the generated code from "result". */ 1093 void *fn_ptr = gcc_jit_result_get_code (result, "square"); 1094 if (!fn_ptr) 1095 @{ 1096 fprintf (stderr, "NULL fn_ptr"); 1097 goto error; 1098 @} 1099 1100 typedef int (*fn_type) (int); 1101 fn_type square = (fn_type)fn_ptr; 1102 printf ("result: %d\n", square (5)); 1103 1104 error: 1105 if (ctxt) 1106 gcc_jit_context_release (ctxt); 1107 if (result) 1108 gcc_jit_result_release (result); 1109 return 0; 1110@} 1111@end example 1112@end quotation 1113 1114Building and running it: 1115 1116@example 1117$ gcc \ 1118 tut02-square.c \ 1119 -o tut02-square \ 1120 -lgccjit 1121 1122# Run the built program: 1123$ ./tut02-square 1124result: 25 1125@end example 1126 1127@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 1128@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 1129@c 1130@c This is free software: you can redistribute it and/or modify it 1131@c under the terms of the GNU General Public License as published by 1132@c the Free Software Foundation, either version 3 of the License, or 1133@c (at your option) any later version. 1134@c 1135@c This program is distributed in the hope that it will be useful, but 1136@c WITHOUT ANY WARRANTY; without even the implied warranty of 1137@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1138@c General Public License for more details. 1139@c 1140@c You should have received a copy of the GNU General Public License 1141@c along with this program. If not, see 1142@c <https://www.gnu.org/licenses/>. 1143 1144@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 1145@anchor{intro/tutorial03 doc}@anchor{21}@anchor{intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{22} 1146@section Tutorial part 3: Loops and variables 1147 1148 1149Consider this C function: 1150 1151@quotation 1152 1153@example 1154int loop_test (int n) 1155@{ 1156 int sum = 0; 1157 for (int i = 0; i < n; i++) 1158 sum += i * i; 1159 return sum; 1160@} 1161@end example 1162@end quotation 1163 1164This example demonstrates some more features of libgccjit, with local 1165variables and a loop. 1166 1167To break this down into libgccjit terms, it���s usually easier to reword 1168the @cite{for} loop as a @cite{while} loop, giving: 1169 1170@quotation 1171 1172@example 1173int loop_test (int n) 1174@{ 1175 int sum = 0; 1176 int i = 0; 1177 while (i < n) 1178 @{ 1179 sum += i * i; 1180 i++; 1181 @} 1182 return sum; 1183@} 1184@end example 1185@end quotation 1186 1187Here���s what the final control flow graph will look like: 1188 1189@quotation 1190 1191 1192@float Figure 1193 1194@image{libgccjit-figures/sum-of-squares1,,,image of a control flow graph,png} 1195 1196@end float 1197 1198@end quotation 1199 1200As before, we include the libgccjit header and make a 1201@ref{8,,gcc_jit_context *}. 1202 1203@example 1204#include <libgccjit.h> 1205 1206void test (void) 1207@{ 1208 gcc_jit_context *ctxt; 1209 ctxt = gcc_jit_context_acquire (); 1210@end example 1211 1212The function works with the C @cite{int} type: 1213 1214@example 1215gcc_jit_type *the_type = 1216 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1217gcc_jit_type *return_type = the_type; 1218@end example 1219 1220though we could equally well make it work on, say, @cite{double}: 1221 1222@example 1223gcc_jit_type *the_type = 1224 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE); 1225@end example 1226 1227Let���s build the function: 1228 1229@example 1230gcc_jit_param *n = 1231 gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); 1232gcc_jit_param *params[1] = @{n@}; 1233gcc_jit_function *func = 1234 gcc_jit_context_new_function (ctxt, NULL, 1235 GCC_JIT_FUNCTION_EXPORTED, 1236 return_type, 1237 "loop_test", 1238 1, params, 0); 1239@end example 1240 1241@menu 1242* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. 1243* Control flow:: 1244* Visualizing the control flow graph:: 1245* Full example: Full example<2>. 1246 1247@end menu 1248 1249@node Expressions lvalues and rvalues,Control flow,,Tutorial part 3 Loops and variables 1250@anchor{intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{23} 1251@subsection Expressions: lvalues and rvalues 1252 1253 1254The base class of expression is the @ref{13,,gcc_jit_rvalue *}, 1255representing an expression that can be on the @emph{right}-hand side of 1256an assignment: a value that can be computed somehow, and assigned 1257@emph{to} a storage area (such as a variable). It has a specific 1258@ref{a,,gcc_jit_type *}. 1259 1260Anothe important class is @ref{24,,gcc_jit_lvalue *}. 1261A @ref{24,,gcc_jit_lvalue *}. is something that can of the @emph{left}-hand 1262side of an assignment: a storage area (such as a variable). 1263 1264In other words, every assignment can be thought of as: 1265 1266@example 1267LVALUE = RVALUE; 1268@end example 1269 1270Note that @ref{24,,gcc_jit_lvalue *} is a subclass of 1271@ref{13,,gcc_jit_rvalue *}, where in an assignment of the form: 1272 1273@example 1274LVALUE_A = LVALUE_B; 1275@end example 1276 1277the @cite{LVALUE_B} implies reading the current value of that storage 1278area, assigning it into the @cite{LVALUE_A}. 1279 1280So far the only expressions we���ve seen are @cite{i * i}: 1281 1282@example 1283gcc_jit_rvalue *expr = 1284 gcc_jit_context_new_binary_op ( 1285 ctxt, NULL, 1286 GCC_JIT_BINARY_OP_MULT, int_type, 1287 gcc_jit_param_as_rvalue (param_i), 1288 gcc_jit_param_as_rvalue (param_i)); 1289@end example 1290 1291which is a @ref{13,,gcc_jit_rvalue *}, and the various function 1292parameters: @cite{param_i} and @cite{param_n}, instances of 1293@ref{25,,gcc_jit_param *}, which is a subclass of 1294@ref{24,,gcc_jit_lvalue *} (and, in turn, of @ref{13,,gcc_jit_rvalue *}): 1295we can both read from and write to function parameters within the 1296body of a function. 1297 1298Our new example has a couple of local variables. We create them by 1299calling @ref{26,,gcc_jit_function_new_local()}, supplying a type and a 1300name: 1301 1302@example 1303/* Build locals: */ 1304gcc_jit_lvalue *i = 1305 gcc_jit_function_new_local (func, NULL, the_type, "i"); 1306gcc_jit_lvalue *sum = 1307 gcc_jit_function_new_local (func, NULL, the_type, "sum"); 1308@end example 1309 1310These are instances of @ref{24,,gcc_jit_lvalue *} - they can be read from 1311and written to. 1312 1313Note that there is no precanned way to create @emph{and} initialize a variable 1314like in C: 1315 1316@example 1317int i = 0; 1318@end example 1319 1320Instead, having added the local to the function, we have to separately add 1321an assignment of @cite{0} to @cite{local_i} at the beginning of the function. 1322 1323@node Control flow,Visualizing the control flow graph,Expressions lvalues and rvalues,Tutorial part 3 Loops and variables 1324@anchor{intro/tutorial03 control-flow}@anchor{27} 1325@subsection Control flow 1326 1327 1328This function has a loop, so we need to build some basic blocks to 1329handle the control flow. In this case, we need 4 blocks: 1330 1331 1332@enumerate 1333 1334@item 1335before the loop (initializing the locals) 1336 1337@item 1338the conditional at the top of the loop (comparing @cite{i < n}) 1339 1340@item 1341the body of the loop 1342 1343@item 1344after the loop terminates (@cite{return sum}) 1345@end enumerate 1346 1347so we create these as @ref{28,,gcc_jit_block *} instances within the 1348@ref{29,,gcc_jit_function *}: 1349 1350@example 1351gcc_jit_block *b_initial = 1352 gcc_jit_function_new_block (func, "initial"); 1353gcc_jit_block *b_loop_cond = 1354 gcc_jit_function_new_block (func, "loop_cond"); 1355gcc_jit_block *b_loop_body = 1356 gcc_jit_function_new_block (func, "loop_body"); 1357gcc_jit_block *b_after_loop = 1358 gcc_jit_function_new_block (func, "after_loop"); 1359@end example 1360 1361We now populate each block with statements. 1362 1363The entry block @cite{b_initial} consists of initializations followed by a jump 1364to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using 1365@ref{2a,,gcc_jit_block_add_assignment()} to add 1366an assignment statement, and using @ref{2b,,gcc_jit_context_zero()} to get 1367the constant value @cite{0} for the relevant type for the right-hand side of 1368the assignment: 1369 1370@example 1371/* sum = 0; */ 1372gcc_jit_block_add_assignment ( 1373 b_initial, NULL, 1374 sum, 1375 gcc_jit_context_zero (ctxt, the_type)); 1376 1377/* i = 0; */ 1378gcc_jit_block_add_assignment ( 1379 b_initial, NULL, 1380 i, 1381 gcc_jit_context_zero (ctxt, the_type)); 1382@end example 1383 1384We can then terminate the entry block by jumping to the conditional: 1385 1386@example 1387gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); 1388@end example 1389 1390The conditional block is equivalent to the line @cite{while (i < n)} from our 1391C example. It contains a single statement: a conditional, which jumps to 1392one of two destination blocks depending on a boolean 1393@ref{13,,gcc_jit_rvalue *}, in this case the comparison of @cite{i} and @cite{n}. 1394We build the comparison using @ref{2c,,gcc_jit_context_new_comparison()}: 1395 1396@example 1397/* (i >= n) */ 1398 gcc_jit_rvalue *guard = 1399 gcc_jit_context_new_comparison ( 1400 ctxt, NULL, 1401 GCC_JIT_COMPARISON_GE, 1402 gcc_jit_lvalue_as_rvalue (i), 1403 gcc_jit_param_as_rvalue (n)); 1404@end example 1405 1406and can then use this to add @cite{b_loop_cond}���s sole statement, via 1407@ref{2d,,gcc_jit_block_end_with_conditional()}: 1408 1409@example 1410/* Equivalent to: 1411 if (guard) 1412 goto after_loop; 1413 else 1414 goto loop_body; */ 1415gcc_jit_block_end_with_conditional ( 1416 b_loop_cond, NULL, 1417 guard, 1418 b_after_loop, /* on_true */ 1419 b_loop_body); /* on_false */ 1420@end example 1421 1422Next, we populate the body of the loop. 1423 1424The C statement @cite{sum += i * i;} is an assignment operation, where an 1425lvalue is modified ���in-place���. We use 1426@ref{2e,,gcc_jit_block_add_assignment_op()} to handle these operations: 1427 1428@example 1429/* sum += i * i */ 1430gcc_jit_block_add_assignment_op ( 1431 b_loop_body, NULL, 1432 sum, 1433 GCC_JIT_BINARY_OP_PLUS, 1434 gcc_jit_context_new_binary_op ( 1435 ctxt, NULL, 1436 GCC_JIT_BINARY_OP_MULT, the_type, 1437 gcc_jit_lvalue_as_rvalue (i), 1438 gcc_jit_lvalue_as_rvalue (i))); 1439@end example 1440 1441The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in 1442a similar way. We use @ref{2f,,gcc_jit_context_one()} to get the constant 1443value @cite{1} (for the relevant type) for the right-hand side 1444of the assignment. 1445 1446@example 1447/* i++ */ 1448gcc_jit_block_add_assignment_op ( 1449 b_loop_body, NULL, 1450 i, 1451 GCC_JIT_BINARY_OP_PLUS, 1452 gcc_jit_context_one (ctxt, the_type)); 1453@end example 1454 1455@cartouche 1456@quotation Note 1457For numeric constants other than 0 or 1, we could use 1458@ref{30,,gcc_jit_context_new_rvalue_from_int()} and 1459@ref{31,,gcc_jit_context_new_rvalue_from_double()}. 1460@end quotation 1461@end cartouche 1462 1463The loop body completes by jumping back to the conditional: 1464 1465@example 1466gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); 1467@end example 1468 1469Finally, we populate the @cite{b_after_loop} block, reached when the loop 1470conditional is false. We want to generate the equivalent of: 1471 1472@example 1473return sum; 1474@end example 1475 1476so the block is just one statement: 1477 1478@example 1479/* return sum */ 1480gcc_jit_block_end_with_return ( 1481 b_after_loop, 1482 NULL, 1483 gcc_jit_lvalue_as_rvalue (sum)); 1484@end example 1485 1486@cartouche 1487@quotation Note 1488You can intermingle block creation with statement creation, 1489but given that the terminator statements generally include references 1490to other blocks, I find it���s clearer to create all the blocks, 1491@emph{then} all the statements. 1492@end quotation 1493@end cartouche 1494 1495We���ve finished populating the function. As before, we can now compile it 1496to machine code: 1497 1498@example 1499gcc_jit_result *result; 1500result = gcc_jit_context_compile (ctxt); 1501 1502typedef int (*loop_test_fn_type) (int); 1503loop_test_fn_type loop_test = 1504 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 1505if (!loop_test) 1506 goto error; 1507printf ("result: %d", loop_test (10)); 1508@end example 1509 1510@example 1511result: 285 1512@end example 1513 1514@node Visualizing the control flow graph,Full example<2>,Control flow,Tutorial part 3 Loops and variables 1515@anchor{intro/tutorial03 visualizing-the-control-flow-graph}@anchor{32} 1516@subsection Visualizing the control flow graph 1517 1518 1519You can see the control flow graph of a function using 1520@ref{33,,gcc_jit_function_dump_to_dot()}: 1521 1522@example 1523gcc_jit_function_dump_to_dot (func, "/tmp/sum-of-squares.dot"); 1524@end example 1525 1526giving a .dot file in GraphViz format. 1527 1528You can convert this to an image using @cite{dot}: 1529 1530@example 1531$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png 1532@end example 1533 1534or use a viewer (my preferred one is xdot.py; see 1535@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can 1536install it with @cite{yum install python-xdot}): 1537 1538@quotation 1539 1540 1541@float Figure 1542 1543@image{libgccjit-figures/sum-of-squares1,,,image of a control flow graph,png} 1544 1545@end float 1546 1547@end quotation 1548 1549@node Full example<2>,,Visualizing the control flow graph,Tutorial part 3 Loops and variables 1550@anchor{intro/tutorial03 full-example}@anchor{34} 1551@subsection Full example 1552 1553 1554@quotation 1555 1556@example 1557/* Usage example for libgccjit.so 1558 Copyright (C) 2014-2022 Free Software Foundation, Inc. 1559 1560This file is part of GCC. 1561 1562GCC is free software; you can redistribute it and/or modify it 1563under the terms of the GNU General Public License as published by 1564the Free Software Foundation; either version 3, or (at your option) 1565any later version. 1566 1567GCC is distributed in the hope that it will be useful, but 1568WITHOUT ANY WARRANTY; without even the implied warranty of 1569MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1570General Public License for more details. 1571 1572You should have received a copy of the GNU General Public License 1573along with GCC; see the file COPYING3. If not see 1574<http://www.gnu.org/licenses/>. */ 1575 1576#include <libgccjit.h> 1577 1578#include <stdlib.h> 1579#include <stdio.h> 1580 1581void 1582create_code (gcc_jit_context *ctxt) 1583@{ 1584 /* 1585 Simple sum-of-squares, to test conditionals and looping 1586 1587 int loop_test (int n) 1588 @{ 1589 int i; 1590 int sum = 0; 1591 for (i = 0; i < n ; i ++) 1592 @{ 1593 sum += i * i; 1594 @} 1595 return sum; 1596 */ 1597 gcc_jit_type *the_type = 1598 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1599 gcc_jit_type *return_type = the_type; 1600 1601 gcc_jit_param *n = 1602 gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); 1603 gcc_jit_param *params[1] = @{n@}; 1604 gcc_jit_function *func = 1605 gcc_jit_context_new_function (ctxt, NULL, 1606 GCC_JIT_FUNCTION_EXPORTED, 1607 return_type, 1608 "loop_test", 1609 1, params, 0); 1610 1611 /* Build locals: */ 1612 gcc_jit_lvalue *i = 1613 gcc_jit_function_new_local (func, NULL, the_type, "i"); 1614 gcc_jit_lvalue *sum = 1615 gcc_jit_function_new_local (func, NULL, the_type, "sum"); 1616 1617 gcc_jit_block *b_initial = 1618 gcc_jit_function_new_block (func, "initial"); 1619 gcc_jit_block *b_loop_cond = 1620 gcc_jit_function_new_block (func, "loop_cond"); 1621 gcc_jit_block *b_loop_body = 1622 gcc_jit_function_new_block (func, "loop_body"); 1623 gcc_jit_block *b_after_loop = 1624 gcc_jit_function_new_block (func, "after_loop"); 1625 1626 /* sum = 0; */ 1627 gcc_jit_block_add_assignment ( 1628 b_initial, NULL, 1629 sum, 1630 gcc_jit_context_zero (ctxt, the_type)); 1631 1632 /* i = 0; */ 1633 gcc_jit_block_add_assignment ( 1634 b_initial, NULL, 1635 i, 1636 gcc_jit_context_zero (ctxt, the_type)); 1637 1638 gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); 1639 1640 /* if (i >= n) */ 1641 gcc_jit_block_end_with_conditional ( 1642 b_loop_cond, NULL, 1643 gcc_jit_context_new_comparison ( 1644 ctxt, NULL, 1645 GCC_JIT_COMPARISON_GE, 1646 gcc_jit_lvalue_as_rvalue (i), 1647 gcc_jit_param_as_rvalue (n)), 1648 b_after_loop, 1649 b_loop_body); 1650 1651 /* sum += i * i */ 1652 gcc_jit_block_add_assignment_op ( 1653 b_loop_body, NULL, 1654 sum, 1655 GCC_JIT_BINARY_OP_PLUS, 1656 gcc_jit_context_new_binary_op ( 1657 ctxt, NULL, 1658 GCC_JIT_BINARY_OP_MULT, the_type, 1659 gcc_jit_lvalue_as_rvalue (i), 1660 gcc_jit_lvalue_as_rvalue (i))); 1661 1662 /* i++ */ 1663 gcc_jit_block_add_assignment_op ( 1664 b_loop_body, NULL, 1665 i, 1666 GCC_JIT_BINARY_OP_PLUS, 1667 gcc_jit_context_one (ctxt, the_type)); 1668 1669 gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); 1670 1671 /* return sum */ 1672 gcc_jit_block_end_with_return ( 1673 b_after_loop, 1674 NULL, 1675 gcc_jit_lvalue_as_rvalue (sum)); 1676@} 1677 1678int 1679main (int argc, char **argv) 1680@{ 1681 gcc_jit_context *ctxt = NULL; 1682 gcc_jit_result *result = NULL; 1683 1684 /* Get a "context" object for working with the library. */ 1685 ctxt = gcc_jit_context_acquire (); 1686 if (!ctxt) 1687 @{ 1688 fprintf (stderr, "NULL ctxt"); 1689 goto error; 1690 @} 1691 1692 /* Set some options on the context. 1693 Let's see the code being generated, in assembler form. */ 1694 gcc_jit_context_set_bool_option ( 1695 ctxt, 1696 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1697 0); 1698 1699 /* Populate the context. */ 1700 create_code (ctxt); 1701 1702 /* Compile the code. */ 1703 result = gcc_jit_context_compile (ctxt); 1704 if (!result) 1705 @{ 1706 fprintf (stderr, "NULL result"); 1707 goto error; 1708 @} 1709 1710 /* Extract the generated code from "result". */ 1711 typedef int (*loop_test_fn_type) (int); 1712 loop_test_fn_type loop_test = 1713 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 1714 if (!loop_test) 1715 @{ 1716 fprintf (stderr, "NULL loop_test"); 1717 goto error; 1718 @} 1719 1720 /* Run the generated code. */ 1721 int val = loop_test (10); 1722 printf("loop_test returned: %d\n", val); 1723 1724 error: 1725 gcc_jit_context_release (ctxt); 1726 gcc_jit_result_release (result); 1727 return 0; 1728@} 1729@end example 1730@end quotation 1731 1732Building and running it: 1733 1734@example 1735$ gcc \ 1736 tut03-sum-of-squares.c \ 1737 -o tut03-sum-of-squares \ 1738 -lgccjit 1739 1740# Run the built program: 1741$ ./tut03-sum-of-squares 1742loop_test returned: 285 1743@end example 1744 1745@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 1746@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 1747@c 1748@c This is free software: you can redistribute it and/or modify it 1749@c under the terms of the GNU General Public License as published by 1750@c the Free Software Foundation, either version 3 of the License, or 1751@c (at your option) any later version. 1752@c 1753@c This program is distributed in the hope that it will be useful, but 1754@c WITHOUT ANY WARRANTY; without even the implied warranty of 1755@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1756@c General Public License for more details. 1757@c 1758@c You should have received a copy of the GNU General Public License 1759@c along with this program. If not, see 1760@c <https://www.gnu.org/licenses/>. 1761 1762@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 1763@anchor{intro/tutorial04 doc}@anchor{35}@anchor{intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{36} 1764@section Tutorial part 4: Adding JIT-compilation to a toy interpreter 1765 1766 1767In this example we construct a ���toy��� interpreter, and add JIT-compilation 1768to it. 1769 1770@menu 1771* Our toy interpreter:: 1772* Compiling to machine code:: 1773* Setting things up:: 1774* Populating the function:: 1775* Verifying the control flow graph:: 1776* Compiling the context:: 1777* Single-stepping through the generated code:: 1778* Examining the generated code:: 1779* Putting it all together:: 1780* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?. 1781 1782@end menu 1783 1784@node Our toy interpreter,Compiling to machine code,,Tutorial part 4 Adding JIT-compilation to a toy interpreter 1785@anchor{intro/tutorial04 our-toy-interpreter}@anchor{37} 1786@subsection Our toy interpreter 1787 1788 1789It���s a stack-based interpreter, and is intended as a (very simple) example 1790of the kind of bytecode interpreter seen in dynamic languages such as 1791Python, Ruby etc. 1792 1793For the sake of simplicity, our toy virtual machine is very limited: 1794 1795@quotation 1796 1797 1798@itemize * 1799 1800@item 1801The only data type is @cite{int} 1802 1803@item 1804It can only work on one function at a time (so that the only 1805function call that can be made is to recurse). 1806 1807@item 1808Functions can only take one parameter. 1809 1810@item 1811Functions have a stack of @cite{int} values. 1812 1813@item 1814We���ll implement function call within the interpreter by calling a 1815function in our implementation, rather than implementing our own 1816frame stack. 1817 1818@item 1819The parser is only good enough to get the examples to work. 1820@end itemize 1821@end quotation 1822 1823Naturally, a real interpreter would be much more complicated that this. 1824 1825The following operations are supported: 1826 1827 1828@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx} 1829@headitem 1830 1831Operation 1832 1833@tab 1834 1835Meaning 1836 1837@tab 1838 1839Old Stack 1840 1841@tab 1842 1843New Stack 1844 1845@item 1846 1847DUP 1848 1849@tab 1850 1851Duplicate top of stack. 1852 1853@tab 1854 1855@code{[..., x]} 1856 1857@tab 1858 1859@code{[..., x, x]} 1860 1861@item 1862 1863ROT 1864 1865@tab 1866 1867Swap top two elements 1868of stack. 1869 1870@tab 1871 1872@code{[..., x, y]} 1873 1874@tab 1875 1876@code{[..., y, x]} 1877 1878@item 1879 1880BINARY_ADD 1881 1882@tab 1883 1884Add the top two elements 1885on the stack. 1886 1887@tab 1888 1889@code{[..., x, y]} 1890 1891@tab 1892 1893@code{[..., (x+y)]} 1894 1895@item 1896 1897BINARY_SUBTRACT 1898 1899@tab 1900 1901Likewise, but subtract. 1902 1903@tab 1904 1905@code{[..., x, y]} 1906 1907@tab 1908 1909@code{[..., (x-y)]} 1910 1911@item 1912 1913BINARY_MULT 1914 1915@tab 1916 1917Likewise, but multiply. 1918 1919@tab 1920 1921@code{[..., x, y]} 1922 1923@tab 1924 1925@code{[..., (x*y)]} 1926 1927@item 1928 1929BINARY_COMPARE_LT 1930 1931@tab 1932 1933Compare the top two 1934elements on the stack 1935and push a nonzero/zero 1936if (x<y). 1937 1938@tab 1939 1940@code{[..., x, y]} 1941 1942@tab 1943 1944@code{[..., (x<y)]} 1945 1946@item 1947 1948RECURSE 1949 1950@tab 1951 1952Recurse, passing the top 1953of the stack, and 1954popping the result. 1955 1956@tab 1957 1958@code{[..., x]} 1959 1960@tab 1961 1962@code{[..., fn(x)]} 1963 1964@item 1965 1966RETURN 1967 1968@tab 1969 1970Return the top of the 1971stack. 1972 1973@tab 1974 1975@code{[x]} 1976 1977@tab 1978 1979@code{[]} 1980 1981@item 1982 1983PUSH_CONST @cite{arg} 1984 1985@tab 1986 1987Push an int const. 1988 1989@tab 1990 1991@code{[...]} 1992 1993@tab 1994 1995@code{[..., arg]} 1996 1997@item 1998 1999JUMP_ABS_IF_TRUE @cite{arg} 2000 2001@tab 2002 2003Pop; if top of stack was 2004nonzero, jump to 2005@code{arg}. 2006 2007@tab 2008 2009@code{[..., x]} 2010 2011@tab 2012 2013@code{[...]} 2014 2015@end multitable 2016 2017 2018Programs can be interpreted, disassembled, and compiled to machine code. 2019 2020The interpreter reads @code{.toy} scripts. Here���s what a simple recursive 2021factorial program looks like, the script @code{factorial.toy}. 2022The parser ignores lines beginning with a @cite{#}. 2023 2024@quotation 2025 2026@example 2027# Simple recursive factorial implementation, roughly equivalent to: 2028# 2029# int factorial (int arg) 2030# @{ 2031# if (arg < 2) 2032# return arg 2033# return arg * factorial (arg - 1) 2034# @} 2035 2036# Initial state: 2037# stack: [arg] 2038 2039# 0: 2040DUP 2041# stack: [arg, arg] 2042 2043# 1: 2044PUSH_CONST 2 2045# stack: [arg, arg, 2] 2046 2047# 2: 2048BINARY_COMPARE_LT 2049# stack: [arg, (arg < 2)] 2050 2051# 3: 2052JUMP_ABS_IF_TRUE 9 2053# stack: [arg] 2054 2055# 4: 2056DUP 2057# stack: [arg, arg] 2058 2059# 5: 2060PUSH_CONST 1 2061# stack: [arg, arg, 1] 2062 2063# 6: 2064BINARY_SUBTRACT 2065# stack: [arg, (arg - 1) 2066 2067# 7: 2068RECURSE 2069# stack: [arg, factorial(arg - 1)] 2070 2071# 8: 2072BINARY_MULT 2073# stack: [arg * factorial(arg - 1)] 2074 2075# 9: 2076RETURN 2077@end example 2078@end quotation 2079 2080The interpreter is a simple infinite loop with a big @code{switch} statement 2081based on what the next opcode is: 2082 2083@quotation 2084 2085@example 2086 2087static int 2088toyvm_function_interpret (toyvm_function *fn, int arg, FILE *trace) 2089@{ 2090 toyvm_frame frame; 2091#define PUSH(ARG) (toyvm_frame_push (&frame, (ARG))) 2092#define POP(ARG) (toyvm_frame_pop (&frame)) 2093 2094 frame.frm_function = fn; 2095 frame.frm_pc = 0; 2096 frame.frm_cur_depth = 0; 2097 2098 PUSH (arg); 2099 2100 while (1) 2101 @{ 2102 toyvm_op *op; 2103 int x, y; 2104 assert (frame.frm_pc < fn->fn_num_ops); 2105 op = &fn->fn_ops[frame.frm_pc++]; 2106 2107 if (trace) 2108 @{ 2109 toyvm_frame_dump_stack (&frame, trace); 2110 toyvm_function_disassemble_op (fn, op, frame.frm_pc, trace); 2111 @} 2112 2113 switch (op->op_opcode) 2114 @{ 2115 /* Ops taking no operand. */ 2116 case DUP: 2117 x = POP (); 2118 PUSH (x); 2119 PUSH (x); 2120 break; 2121 2122 case ROT: 2123 y = POP (); 2124 x = POP (); 2125 PUSH (y); 2126 PUSH (x); 2127 break; 2128 2129 case BINARY_ADD: 2130 y = POP (); 2131 x = POP (); 2132 PUSH (x + y); 2133 break; 2134 2135 case BINARY_SUBTRACT: 2136 y = POP (); 2137 x = POP (); 2138 PUSH (x - y); 2139 break; 2140 2141 case BINARY_MULT: 2142 y = POP (); 2143 x = POP (); 2144 PUSH (x * y); 2145 break; 2146 2147 case BINARY_COMPARE_LT: 2148 y = POP (); 2149 x = POP (); 2150 PUSH (x < y); 2151 break; 2152 2153 case RECURSE: 2154 x = POP (); 2155 x = toyvm_function_interpret (fn, x, trace); 2156 PUSH (x); 2157 break; 2158 2159 case RETURN: 2160 return POP (); 2161 2162 /* Ops taking an operand. */ 2163 case PUSH_CONST: 2164 PUSH (op->op_operand); 2165 break; 2166 2167 case JUMP_ABS_IF_TRUE: 2168 x = POP (); 2169 if (x) 2170 frame.frm_pc = op->op_operand; 2171 break; 2172 2173 default: 2174 assert (0); /* unknown opcode */ 2175 2176 @} /* end of switch on opcode */ 2177 @} /* end of while loop */ 2178 2179#undef PUSH 2180#undef POP 2181@} 2182 2183@end example 2184@end quotation 2185 2186@node Compiling to machine code,Setting things up,Our toy interpreter,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2187@anchor{intro/tutorial04 compiling-to-machine-code}@anchor{38} 2188@subsection Compiling to machine code 2189 2190 2191We want to generate machine code that can be cast to this type and 2192then directly executed in-process: 2193 2194@quotation 2195 2196@example 2197typedef int (*toyvm_compiled_code) (int); 2198 2199@end example 2200@end quotation 2201 2202The lifetime of the code is tied to that of a @ref{16,,gcc_jit_result *}. 2203We���ll handle this by bundling them up in a structure, so that we can 2204clean them up together by calling @ref{39,,gcc_jit_result_release()}: 2205 2206@quotation 2207 2208@example 2209 2210struct toyvm_compiled_function 2211@{ 2212 gcc_jit_result *cf_jit_result; 2213 toyvm_compiled_code cf_code; 2214@}; 2215 2216@end example 2217@end quotation 2218 2219Our compiler isn���t very sophisticated; it takes the implementation of 2220each opcode above, and maps it directly to the operations supported by 2221the libgccjit API. 2222 2223How should we handle the stack? In theory we could calculate what the 2224stack depth will be at each opcode, and optimize away the stack 2225manipulation ���by hand���. We���ll see below that libgccjit is able to do 2226this for us, so we���ll implement stack manipulation 2227in a direct way, by creating a @code{stack} array and @code{stack_depth} 2228variables, local within the generated function, equivalent to this C code: 2229 2230@example 2231int stack_depth; 2232int stack[MAX_STACK_DEPTH]; 2233@end example 2234 2235We���ll also have local variables @code{x} and @code{y} for use when implementing 2236the opcodes, equivalent to this: 2237 2238@example 2239int x; 2240int y; 2241@end example 2242 2243This means our compiler has the following state: 2244 2245@quotation 2246 2247@example 2248 2249struct compilation_state 2250@{ 2251 gcc_jit_context *ctxt; 2252 2253 gcc_jit_type *int_type; 2254 gcc_jit_type *bool_type; 2255 gcc_jit_type *stack_type; /* int[MAX_STACK_DEPTH] */ 2256 2257 gcc_jit_rvalue *const_one; 2258 2259 gcc_jit_function *fn; 2260 gcc_jit_param *param_arg; 2261 gcc_jit_lvalue *stack; 2262 gcc_jit_lvalue *stack_depth; 2263 gcc_jit_lvalue *x; 2264 gcc_jit_lvalue *y; 2265 2266 gcc_jit_location *op_locs[MAX_OPS]; 2267 gcc_jit_block *initial_block; 2268 gcc_jit_block *op_blocks[MAX_OPS]; 2269 2270@}; 2271 2272@end example 2273@end quotation 2274 2275@node Setting things up,Populating the function,Compiling to machine code,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2276@anchor{intro/tutorial04 setting-things-up}@anchor{3a} 2277@subsection Setting things up 2278 2279 2280First we create our types: 2281 2282@quotation 2283 2284@example 2285 state.int_type = 2286 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_INT); 2287 state.bool_type = 2288 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_BOOL); 2289 state.stack_type = 2290 gcc_jit_context_new_array_type (state.ctxt, NULL, 2291 state.int_type, MAX_STACK_DEPTH); 2292 2293@end example 2294@end quotation 2295 2296along with extracting a useful @cite{int} constant: 2297 2298@quotation 2299 2300@example 2301 state.const_one = gcc_jit_context_one (state.ctxt, state.int_type); 2302 2303@end example 2304@end quotation 2305 2306We���ll implement push and pop in terms of the @code{stack} array and 2307@code{stack_depth}. Here are helper functions for adding statements to 2308a block, implementing pushing and popping values: 2309 2310@quotation 2311 2312@example 2313 2314static void 2315add_push (compilation_state *state, 2316 gcc_jit_block *block, 2317 gcc_jit_rvalue *rvalue, 2318 gcc_jit_location *loc) 2319@{ 2320 /* stack[stack_depth] = RVALUE */ 2321 gcc_jit_block_add_assignment ( 2322 block, 2323 loc, 2324 /* stack[stack_depth] */ 2325 gcc_jit_context_new_array_access ( 2326 state->ctxt, 2327 loc, 2328 gcc_jit_lvalue_as_rvalue (state->stack), 2329 gcc_jit_lvalue_as_rvalue (state->stack_depth)), 2330 rvalue); 2331 2332 /* "stack_depth++;". */ 2333 gcc_jit_block_add_assignment_op ( 2334 block, 2335 loc, 2336 state->stack_depth, 2337 GCC_JIT_BINARY_OP_PLUS, 2338 state->const_one); 2339@} 2340 2341static void 2342add_pop (compilation_state *state, 2343 gcc_jit_block *block, 2344 gcc_jit_lvalue *lvalue, 2345 gcc_jit_location *loc) 2346@{ 2347 /* "--stack_depth;". */ 2348 gcc_jit_block_add_assignment_op ( 2349 block, 2350 loc, 2351 state->stack_depth, 2352 GCC_JIT_BINARY_OP_MINUS, 2353 state->const_one); 2354 2355 /* "LVALUE = stack[stack_depth];". */ 2356 gcc_jit_block_add_assignment ( 2357 block, 2358 loc, 2359 lvalue, 2360 /* stack[stack_depth] */ 2361 gcc_jit_lvalue_as_rvalue ( 2362 gcc_jit_context_new_array_access ( 2363 state->ctxt, 2364 loc, 2365 gcc_jit_lvalue_as_rvalue (state->stack), 2366 gcc_jit_lvalue_as_rvalue (state->stack_depth)))); 2367@} 2368 2369@end example 2370@end quotation 2371 2372We will support single-stepping through the generated code in the 2373debugger, so we need to create @ref{3b,,gcc_jit_location} instances, one 2374per operation in the source code. These will reference the lines of 2375e.g. @code{factorial.toy}. 2376 2377@quotation 2378 2379@example 2380 for (pc = 0; pc < fn->fn_num_ops; pc++) 2381 @{ 2382 toyvm_op *op = &fn->fn_ops[pc]; 2383 2384 state.op_locs[pc] = gcc_jit_context_new_location (state.ctxt, 2385 fn->fn_filename, 2386 op->op_linenum, 2387 0); /* column */ 2388 @} 2389 2390@end example 2391@end quotation 2392 2393Let���s create the function itself. As usual, we create its parameter 2394first, then use the parameter to create the function: 2395 2396@quotation 2397 2398@example 2399 state.param_arg = 2400 gcc_jit_context_new_param (state.ctxt, state.op_locs[0], 2401 state.int_type, "arg"); 2402 state.fn = 2403 gcc_jit_context_new_function (state.ctxt, 2404 state.op_locs[0], 2405 GCC_JIT_FUNCTION_EXPORTED, 2406 state.int_type, 2407 funcname, 2408 1, &state.param_arg, 0); 2409 2410@end example 2411@end quotation 2412 2413We create the locals within the function. 2414 2415@quotation 2416 2417@example 2418 state.stack = 2419 gcc_jit_function_new_local (state.fn, NULL, 2420 state.stack_type, "stack"); 2421 state.stack_depth = 2422 gcc_jit_function_new_local (state.fn, NULL, 2423 state.int_type, "stack_depth"); 2424 state.x = 2425 gcc_jit_function_new_local (state.fn, NULL, 2426 state.int_type, "x"); 2427 state.y = 2428 gcc_jit_function_new_local (state.fn, NULL, 2429 state.int_type, "y"); 2430 2431@end example 2432@end quotation 2433 2434@node Populating the function,Verifying the control flow graph,Setting things up,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2435@anchor{intro/tutorial04 populating-the-function}@anchor{3c} 2436@subsection Populating the function 2437 2438 2439There���s some one-time initialization, and the API treats the first block 2440you create as the entrypoint of the function, so we need to create that 2441block first: 2442 2443@quotation 2444 2445@example 2446 state.initial_block = gcc_jit_function_new_block (state.fn, "initial"); 2447 2448@end example 2449@end quotation 2450 2451We can now create blocks for each of the operations. Most of these will 2452be consolidated into larger blocks when the optimizer runs. 2453 2454@quotation 2455 2456@example 2457 for (pc = 0; pc < fn->fn_num_ops; pc++) 2458 @{ 2459 char buf[100]; 2460 sprintf (buf, "instr%i", pc); 2461 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); 2462 @} 2463 2464@end example 2465@end quotation 2466 2467Now that we have a block it can jump to when it���s done, we can populate 2468the initial block: 2469 2470@quotation 2471 2472@example 2473 2474 /* "stack_depth = 0;". */ 2475 gcc_jit_block_add_assignment ( 2476 state.initial_block, 2477 state.op_locs[0], 2478 state.stack_depth, 2479 gcc_jit_context_zero (state.ctxt, state.int_type)); 2480 2481 /* "PUSH (arg);". */ 2482 add_push (&state, 2483 state.initial_block, 2484 gcc_jit_param_as_rvalue (state.param_arg), 2485 state.op_locs[0]); 2486 2487 /* ...and jump to insn 0. */ 2488 gcc_jit_block_end_with_jump (state.initial_block, 2489 state.op_locs[0], 2490 state.op_blocks[0]); 2491 2492@end example 2493@end quotation 2494 2495We can now populate the blocks for the individual operations. We loop 2496through them, adding instructions to their blocks: 2497 2498@quotation 2499 2500@example 2501 for (pc = 0; pc < fn->fn_num_ops; pc++) 2502 @{ 2503 gcc_jit_location *loc = state.op_locs[pc]; 2504 2505 gcc_jit_block *block = state.op_blocks[pc]; 2506 gcc_jit_block *next_block = (pc < fn->fn_num_ops 2507 ? state.op_blocks[pc + 1] 2508 : NULL); 2509 2510 toyvm_op *op; 2511 op = &fn->fn_ops[pc]; 2512 2513@end example 2514@end quotation 2515 2516We���re going to have another big @code{switch} statement for implementing 2517the opcodes, this time for compiling them, rather than interpreting 2518them. It���s helpful to have macros for implementing push and pop, so that 2519we can make the @code{switch} statement that���s coming up look as much as 2520possible like the one above within the interpreter: 2521 2522@example 2523 2524#define X_EQUALS_POP()\ 2525 add_pop (&state, block, state.x, loc) 2526#define Y_EQUALS_POP()\ 2527 add_pop (&state, block, state.y, loc) 2528#define PUSH_RVALUE(RVALUE)\ 2529 add_push (&state, block, (RVALUE), loc) 2530#define PUSH_X()\ 2531 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.x)) 2532#define PUSH_Y() \ 2533 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.y)) 2534 2535@end example 2536 2537@cartouche 2538@quotation Note 2539A particularly clever implementation would have an @emph{identical} 2540@code{switch} statement shared by the interpreter and the compiler, with 2541some preprocessor ���magic���. We���re not doing that here, for the sake 2542of simplicity. 2543@end quotation 2544@end cartouche 2545 2546When I first implemented this compiler, I accidentally missed an edit 2547when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the 2548stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y} 2549uninitialized. 2550 2551To track this kind of thing down, we can use 2552@ref{3d,,gcc_jit_block_add_comment()} to add descriptive comments 2553to the internal representation. This is invaluable when looking through 2554the generated IR for, say @code{factorial}: 2555 2556@quotation 2557 2558@example 2559 2560 gcc_jit_block_add_comment (block, loc, opcode_names[op->op_opcode]); 2561 2562@end example 2563@end quotation 2564 2565We can now write the big @code{switch} statement that implements the 2566individual opcodes, populating the relevant block with statements: 2567 2568@quotation 2569 2570@example 2571 2572 switch (op->op_opcode) 2573 @{ 2574 case DUP: 2575 X_EQUALS_POP (); 2576 PUSH_X (); 2577 PUSH_X (); 2578 break; 2579 2580 case ROT: 2581 Y_EQUALS_POP (); 2582 X_EQUALS_POP (); 2583 PUSH_Y (); 2584 PUSH_X (); 2585 break; 2586 2587 case BINARY_ADD: 2588 Y_EQUALS_POP (); 2589 X_EQUALS_POP (); 2590 PUSH_RVALUE ( 2591 gcc_jit_context_new_binary_op ( 2592 state.ctxt, 2593 loc, 2594 GCC_JIT_BINARY_OP_PLUS, 2595 state.int_type, 2596 gcc_jit_lvalue_as_rvalue (state.x), 2597 gcc_jit_lvalue_as_rvalue (state.y))); 2598 break; 2599 2600 case BINARY_SUBTRACT: 2601 Y_EQUALS_POP (); 2602 X_EQUALS_POP (); 2603 PUSH_RVALUE ( 2604 gcc_jit_context_new_binary_op ( 2605 state.ctxt, 2606 loc, 2607 GCC_JIT_BINARY_OP_MINUS, 2608 state.int_type, 2609 gcc_jit_lvalue_as_rvalue (state.x), 2610 gcc_jit_lvalue_as_rvalue (state.y))); 2611 break; 2612 2613 case BINARY_MULT: 2614 Y_EQUALS_POP (); 2615 X_EQUALS_POP (); 2616 PUSH_RVALUE ( 2617 gcc_jit_context_new_binary_op ( 2618 state.ctxt, 2619 loc, 2620 GCC_JIT_BINARY_OP_MULT, 2621 state.int_type, 2622 gcc_jit_lvalue_as_rvalue (state.x), 2623 gcc_jit_lvalue_as_rvalue (state.y))); 2624 break; 2625 2626 case BINARY_COMPARE_LT: 2627 Y_EQUALS_POP (); 2628 X_EQUALS_POP (); 2629 PUSH_RVALUE ( 2630 /* cast of bool to int */ 2631 gcc_jit_context_new_cast ( 2632 state.ctxt, 2633 loc, 2634 /* (x < y) as a bool */ 2635 gcc_jit_context_new_comparison ( 2636 state.ctxt, 2637 loc, 2638 GCC_JIT_COMPARISON_LT, 2639 gcc_jit_lvalue_as_rvalue (state.x), 2640 gcc_jit_lvalue_as_rvalue (state.y)), 2641 state.int_type)); 2642 break; 2643 2644 case RECURSE: 2645 @{ 2646 X_EQUALS_POP (); 2647 gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (state.x); 2648 PUSH_RVALUE ( 2649 gcc_jit_context_new_call ( 2650 state.ctxt, 2651 loc, 2652 state.fn, 2653 1, &arg)); 2654 break; 2655 @} 2656 2657 case RETURN: 2658 X_EQUALS_POP (); 2659 gcc_jit_block_end_with_return ( 2660 block, 2661 loc, 2662 gcc_jit_lvalue_as_rvalue (state.x)); 2663 break; 2664 2665 /* Ops taking an operand. */ 2666 case PUSH_CONST: 2667 PUSH_RVALUE ( 2668 gcc_jit_context_new_rvalue_from_int ( 2669 state.ctxt, 2670 state.int_type, 2671 op->op_operand)); 2672 break; 2673 2674 case JUMP_ABS_IF_TRUE: 2675 X_EQUALS_POP (); 2676 gcc_jit_block_end_with_conditional ( 2677 block, 2678 loc, 2679 /* "(bool)x". */ 2680 gcc_jit_context_new_cast ( 2681 state.ctxt, 2682 loc, 2683 gcc_jit_lvalue_as_rvalue (state.x), 2684 state.bool_type), 2685 state.op_blocks[op->op_operand], /* on_true */ 2686 next_block); /* on_false */ 2687 break; 2688 2689 default: 2690 assert(0); 2691 @} /* end of switch on opcode */ 2692 2693@end example 2694@end quotation 2695 2696Every block must be terminated, via a call to one of the 2697@code{gcc_jit_block_end_with_} entrypoints. This has been done for two 2698of the opcodes, but we need to do it for the other ones, by jumping 2699to the next block. 2700 2701@quotation 2702 2703@example 2704 if (op->op_opcode != JUMP_ABS_IF_TRUE 2705 && op->op_opcode != RETURN) 2706 gcc_jit_block_end_with_jump ( 2707 block, 2708 loc, 2709 next_block); 2710 2711@end example 2712@end quotation 2713 2714This is analogous to simply incrementing the program counter. 2715 2716@node Verifying the control flow graph,Compiling the context,Populating the function,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2717@anchor{intro/tutorial04 verifying-the-control-flow-graph}@anchor{3e} 2718@subsection Verifying the control flow graph 2719 2720 2721Having finished looping over the blocks, the context is complete. 2722 2723As before, we can verify that the control flow and statements are sane by 2724using @ref{33,,gcc_jit_function_dump_to_dot()}: 2725 2726@example 2727gcc_jit_function_dump_to_dot (state.fn, "/tmp/factorial.dot"); 2728@end example 2729 2730and viewing the result. Note how the label names, comments, and 2731variable names show up in the dump, to make it easier to spot 2732errors in our compiler. 2733 2734@quotation 2735 2736 2737@float Figure 2738 2739@image{libgccjit-figures/factorial1,,,image of a control flow graph,png} 2740 2741@end float 2742 2743@end quotation 2744 2745@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 2746@anchor{intro/tutorial04 compiling-the-context}@anchor{3f} 2747@subsection Compiling the context 2748 2749 2750Having finished looping over the blocks and populating them with 2751statements, the context is complete. 2752 2753We can now compile it, and extract machine code from the result: 2754 2755@quotation 2756@end quotation 2757 2758We can now run the result: 2759 2760@quotation 2761 2762@example 2763 toyvm_compiled_function *compiled_fn 2764 = toyvm_function_compile (fn); 2765 2766 toyvm_compiled_code code = compiled_fn->cf_code; 2767 printf ("compiler result: %d\n", 2768 code (atoi (argv[2]))); 2769 2770 gcc_jit_result_release (compiled_fn->cf_jit_result); 2771 free (compiled_fn); 2772 2773@end example 2774@end quotation 2775 2776@node Single-stepping through the generated code,Examining the generated code,Compiling the context,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2777@anchor{intro/tutorial04 single-stepping-through-the-generated-code}@anchor{40} 2778@subsection Single-stepping through the generated code 2779 2780 2781It���s possible to debug the generated code. To do this we need to both: 2782 2783@quotation 2784 2785 2786@itemize * 2787 2788@item 2789Set up source code locations for our statements, so that we can 2790meaningfully step through the code. We did this above by 2791calling @ref{41,,gcc_jit_context_new_location()} and using the 2792results. 2793 2794@item 2795Enable the generation of debugging information, by setting 2796@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 2797@ref{8,,gcc_jit_context} via 2798@ref{1b,,gcc_jit_context_set_bool_option()}: 2799 2800@example 2801gcc_jit_context_set_bool_option ( 2802 ctxt, 2803 GCC_JIT_BOOL_OPTION_DEBUGINFO, 2804 1); 2805@end example 2806@end itemize 2807@end quotation 2808 2809Having done this, we can put a breakpoint on the generated function: 2810 2811@example 2812$ gdb --args ./toyvm factorial.toy 10 2813(gdb) break factorial 2814Function "factorial" not defined. 2815Make breakpoint pending on future shared library load? (y or [n]) y 2816Breakpoint 1 (factorial) pending. 2817(gdb) run 2818Breakpoint 1, factorial (arg=10) at factorial.toy:14 281914 DUP 2820@end example 2821 2822We���ve set up location information, which references @code{factorial.toy}. 2823This allows us to use e.g. @code{list} to see where we are in the script: 2824 2825@example 2826(gdb) list 28279 282810 # Initial state: 282911 # stack: [arg] 283012 283113 # 0: 283214 DUP 283315 # stack: [arg, arg] 283416 283517 # 1: 283618 PUSH_CONST 2 2837@end example 2838 2839and to step through the function, examining the data: 2840 2841@example 2842(gdb) n 284318 PUSH_CONST 2 2844(gdb) n 284522 BINARY_COMPARE_LT 2846(gdb) print stack 2847$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@} 2848(gdb) print stack_depth 2849$6 = 3 2850@end example 2851 2852You���ll see that the parts of the @code{stack} array that haven���t been 2853touched yet are uninitialized. 2854 2855@cartouche 2856@quotation Note 2857Turning on optimizations may lead to unpredictable results when 2858stepping through the generated code: the execution may appear to 2859���jump around��� the source code. This is analogous to turning up the 2860optimization level in a regular compiler. 2861@end quotation 2862@end cartouche 2863 2864@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 2865@anchor{intro/tutorial04 examining-the-generated-code}@anchor{43} 2866@subsection Examining the generated code 2867 2868 2869How good is the optimized code? 2870 2871We can turn up optimizations, by calling 2872@ref{1e,,gcc_jit_context_set_int_option()} with 2873@ref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 2874 2875@example 2876gcc_jit_context_set_int_option ( 2877 ctxt, 2878 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2879 3); 2880@end example 2881 2882One of GCC���s internal representations is called ���gimple���. A dump of the 2883initial gimple representation of the code can be seen by setting: 2884 2885@example 2886gcc_jit_context_set_bool_option (ctxt, 2887 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 2888 1); 2889@end example 2890 2891With optimization on and source locations displayed, this gives: 2892 2893@c We'll use "c" for gimple dumps 2894 2895@example 2896factorial (signed int arg) 2897@{ 2898 <unnamed type> D.80; 2899 signed int D.81; 2900 signed int D.82; 2901 signed int D.83; 2902 signed int D.84; 2903 signed int D.85; 2904 signed int y; 2905 signed int x; 2906 signed int stack_depth; 2907 signed int stack[8]; 2908 2909 try 2910 @{ 2911 initial: 2912 stack_depth = 0; 2913 stack[stack_depth] = arg; 2914 stack_depth = stack_depth + 1; 2915 goto instr0; 2916 instr0: 2917 /* DUP */: 2918 stack_depth = stack_depth + -1; 2919 x = stack[stack_depth]; 2920 stack[stack_depth] = x; 2921 stack_depth = stack_depth + 1; 2922 stack[stack_depth] = x; 2923 stack_depth = stack_depth + 1; 2924 goto instr1; 2925 instr1: 2926 /* PUSH_CONST */: 2927 stack[stack_depth] = 2; 2928 stack_depth = stack_depth + 1; 2929 goto instr2; 2930 2931 /* etc */ 2932@end example 2933 2934You can see the generated machine code in assembly form via: 2935 2936@example 2937gcc_jit_context_set_bool_option ( 2938 ctxt, 2939 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 2940 1); 2941result = gcc_jit_context_compile (ctxt); 2942@end example 2943 2944which shows that (on this x86_64 box) the compiler has unrolled the loop 2945and is using MMX instructions to perform several multiplications 2946simultaneously: 2947 2948@example 2949 .file "fake.c" 2950 .text 2951.Ltext0: 2952 .p2align 4,,15 2953 .globl factorial 2954 .type factorial, @@function 2955factorial: 2956.LFB0: 2957 .file 1 "factorial.toy" 2958 .loc 1 14 0 2959 .cfi_startproc 2960.LVL0: 2961.L2: 2962 .loc 1 26 0 2963 cmpl $1, %edi 2964 jle .L13 2965 leal -1(%rdi), %edx 2966 movl %edx, %ecx 2967 shrl $2, %ecx 2968 leal 0(,%rcx,4), %esi 2969 testl %esi, %esi 2970 je .L14 2971 cmpl $9, %edx 2972 jbe .L14 2973 leal -2(%rdi), %eax 2974 movl %eax, -16(%rsp) 2975 leal -3(%rdi), %eax 2976 movd -16(%rsp), %xmm0 2977 movl %edi, -16(%rsp) 2978 movl %eax, -12(%rsp) 2979 movd -16(%rsp), %xmm1 2980 xorl %eax, %eax 2981 movl %edx, -16(%rsp) 2982 movd -12(%rsp), %xmm4 2983 movd -16(%rsp), %xmm6 2984 punpckldq %xmm4, %xmm0 2985 movdqa .LC1(%rip), %xmm4 2986 punpckldq %xmm6, %xmm1 2987 punpcklqdq %xmm0, %xmm1 2988 movdqa .LC0(%rip), %xmm0 2989 jmp .L5 2990 # etc - edited for brevity 2991@end example 2992 2993This is clearly overkill for a function that will likely overflow the 2994@code{int} type before the vectorization is worthwhile - but then again, this 2995is a toy example. 2996 2997Turning down the optimization level to 2: 2998 2999@example 3000gcc_jit_context_set_int_option ( 3001 ctxt, 3002 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3003 3); 3004@end example 3005 3006yields this code, which is simple enough to quote in its entirety: 3007 3008@example 3009 .file "fake.c" 3010 .text 3011 .p2align 4,,15 3012 .globl factorial 3013 .type factorial, @@function 3014factorial: 3015.LFB0: 3016 .cfi_startproc 3017.L2: 3018 cmpl $1, %edi 3019 jle .L8 3020 movl $1, %edx 3021 jmp .L4 3022 .p2align 4,,10 3023 .p2align 3 3024.L6: 3025 movl %eax, %edi 3026.L4: 3027.L5: 3028 leal -1(%rdi), %eax 3029 imull %edi, %edx 3030 cmpl $1, %eax 3031 jne .L6 3032.L3: 3033.L7: 3034 imull %edx, %eax 3035 ret 3036.L8: 3037 movl %edi, %eax 3038 movl $1, %edx 3039 jmp .L7 3040 .cfi_endproc 3041.LFE0: 3042 .size factorial, .-factorial 3043 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})" 3044 .section .note.GNU-stack,"",@@progbits 3045@end example 3046 3047Note that the stack pushing and popping have been eliminated, as has the 3048recursive call (in favor of an iteration). 3049 3050@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 3051@anchor{intro/tutorial04 putting-it-all-together}@anchor{44} 3052@subsection Putting it all together 3053 3054 3055The complete example can be seen in the source tree at 3056@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.c} 3057 3058along with a Makefile and a couple of sample .toy scripts: 3059 3060@example 3061$ ls -al 3062drwxrwxr-x. 2 david david 4096 Sep 19 17:46 . 3063drwxrwxr-x. 3 david david 4096 Sep 19 15:26 .. 3064-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy 3065-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy 3066-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile 3067-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.c 3068 3069$ make toyvm 3070g++ -Wall -g -o toyvm toyvm.c -lgccjit 3071 3072$ ./toyvm factorial.toy 10 3073interpreter result: 3628800 3074compiler result: 3628800 3075 3076$ ./toyvm fibonacci.toy 10 3077interpreter result: 55 3078compiler result: 55 3079@end example 3080 3081@node Behind the curtain How does our code get optimized?,,Putting it all together,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3082@anchor{intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{45} 3083@subsection Behind the curtain: How does our code get optimized? 3084 3085 3086Our example is done, but you may be wondering about exactly how the 3087compiler turned what we gave it into the machine code seen above. 3088 3089We can examine what the compiler is doing in detail by setting: 3090 3091@example 3092gcc_jit_context_set_bool_option (state.ctxt, 3093 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 3094 1); 3095gcc_jit_context_set_bool_option (state.ctxt, 3096 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 3097 1); 3098@end example 3099 3100This will dump detailed information about the compiler���s state to a 3101directory under @code{/tmp}, and keep it from being cleaned up. 3102 3103The precise names and their formats of these files is subject to change. 3104Higher optimization levels lead to more files. 3105Here���s what I saw (edited for brevity; there were almost 200 files): 3106 3107@example 3108intermediate files written to /tmp/libgccjit-KPQbGw 3109$ ls /tmp/libgccjit-KPQbGw/ 3110fake.c.000i.cgraph 3111fake.c.000i.type-inheritance 3112fake.c.004t.gimple 3113fake.c.007t.omplower 3114fake.c.008t.lower 3115fake.c.011t.eh 3116fake.c.012t.cfg 3117fake.c.014i.visibility 3118fake.c.015i.early_local_cleanups 3119fake.c.016t.ssa 3120# etc 3121@end example 3122 3123The gimple code is converted into Static Single Assignment form, 3124with annotations for use when generating the debuginfo: 3125 3126@example 3127$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa 3128@end example 3129 3130@example 3131;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3132 3133factorial (signed int arg) 3134@{ 3135 signed int stack[8]; 3136 signed int stack_depth; 3137 signed int x; 3138 signed int y; 3139 <unnamed type> _20; 3140 signed int _21; 3141 signed int _38; 3142 signed int _44; 3143 signed int _51; 3144 signed int _56; 3145 3146initial: 3147 stack_depth_3 = 0; 3148 # DEBUG stack_depth => stack_depth_3 3149 stack[stack_depth_3] = arg_5(D); 3150 stack_depth_7 = stack_depth_3 + 1; 3151 # DEBUG stack_depth => stack_depth_7 3152 # DEBUG instr0 => NULL 3153 # DEBUG /* DUP */ => NULL 3154 stack_depth_8 = stack_depth_7 + -1; 3155 # DEBUG stack_depth => stack_depth_8 3156 x_9 = stack[stack_depth_8]; 3157 # DEBUG x => x_9 3158 stack[stack_depth_8] = x_9; 3159 stack_depth_11 = stack_depth_8 + 1; 3160 # DEBUG stack_depth => stack_depth_11 3161 stack[stack_depth_11] = x_9; 3162 stack_depth_13 = stack_depth_11 + 1; 3163 # DEBUG stack_depth => stack_depth_13 3164 # DEBUG instr1 => NULL 3165 # DEBUG /* PUSH_CONST */ => NULL 3166 stack[stack_depth_13] = 2; 3167 3168 /* etc; edited for brevity */ 3169@end example 3170 3171We can perhaps better see the code by turning off 3172@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG} 3173statements, giving: 3174 3175@example 3176$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa 3177@end example 3178 3179@example 3180;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3181 3182factorial (signed int arg) 3183@{ 3184 signed int stack[8]; 3185 signed int stack_depth; 3186 signed int x; 3187 signed int y; 3188 <unnamed type> _20; 3189 signed int _21; 3190 signed int _38; 3191 signed int _44; 3192 signed int _51; 3193 signed int _56; 3194 3195initial: 3196 stack_depth_3 = 0; 3197 stack[stack_depth_3] = arg_5(D); 3198 stack_depth_7 = stack_depth_3 + 1; 3199 stack_depth_8 = stack_depth_7 + -1; 3200 x_9 = stack[stack_depth_8]; 3201 stack[stack_depth_8] = x_9; 3202 stack_depth_11 = stack_depth_8 + 1; 3203 stack[stack_depth_11] = x_9; 3204 stack_depth_13 = stack_depth_11 + 1; 3205 stack[stack_depth_13] = 2; 3206 stack_depth_15 = stack_depth_13 + 1; 3207 stack_depth_16 = stack_depth_15 + -1; 3208 y_17 = stack[stack_depth_16]; 3209 stack_depth_18 = stack_depth_16 + -1; 3210 x_19 = stack[stack_depth_18]; 3211 _20 = x_19 < y_17; 3212 _21 = (signed int) _20; 3213 stack[stack_depth_18] = _21; 3214 stack_depth_23 = stack_depth_18 + 1; 3215 stack_depth_24 = stack_depth_23 + -1; 3216 x_25 = stack[stack_depth_24]; 3217 if (x_25 != 0) 3218 goto <bb 4> (instr9); 3219 else 3220 goto <bb 3> (instr4); 3221 3222instr4: 3223/* DUP */: 3224 stack_depth_26 = stack_depth_24 + -1; 3225 x_27 = stack[stack_depth_26]; 3226 stack[stack_depth_26] = x_27; 3227 stack_depth_29 = stack_depth_26 + 1; 3228 stack[stack_depth_29] = x_27; 3229 stack_depth_31 = stack_depth_29 + 1; 3230 stack[stack_depth_31] = 1; 3231 stack_depth_33 = stack_depth_31 + 1; 3232 stack_depth_34 = stack_depth_33 + -1; 3233 y_35 = stack[stack_depth_34]; 3234 stack_depth_36 = stack_depth_34 + -1; 3235 x_37 = stack[stack_depth_36]; 3236 _38 = x_37 - y_35; 3237 stack[stack_depth_36] = _38; 3238 stack_depth_40 = stack_depth_36 + 1; 3239 stack_depth_41 = stack_depth_40 + -1; 3240 x_42 = stack[stack_depth_41]; 3241 _44 = factorial (x_42); 3242 stack[stack_depth_41] = _44; 3243 stack_depth_46 = stack_depth_41 + 1; 3244 stack_depth_47 = stack_depth_46 + -1; 3245 y_48 = stack[stack_depth_47]; 3246 stack_depth_49 = stack_depth_47 + -1; 3247 x_50 = stack[stack_depth_49]; 3248 _51 = x_50 * y_48; 3249 stack[stack_depth_49] = _51; 3250 stack_depth_53 = stack_depth_49 + 1; 3251 3252 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)> 3253instr9: 3254/* RETURN */: 3255 stack_depth_54 = stack_depth_1 + -1; 3256 x_55 = stack[stack_depth_54]; 3257 _56 = x_55; 3258 stack =@{v@} @{CLOBBER@}; 3259 return _56; 3260 3261@} 3262@end example 3263 3264Note in the above how all the @ref{28,,gcc_jit_block} instances we 3265created have been consolidated into just 3 blocks in GCC���s internal 3266representation: @code{initial}, @code{instr4} and @code{instr9}. 3267 3268@menu 3269* Optimizing away stack manipulation:: 3270* Elimination of tail recursion:: 3271 3272@end menu 3273 3274@node Optimizing away stack manipulation,Elimination of tail recursion,,Behind the curtain How does our code get optimized? 3275@anchor{intro/tutorial04 optimizing-away-stack-manipulation}@anchor{46} 3276@subsubsection Optimizing away stack manipulation 3277 3278 3279Recall our simple implementation of stack operations. Let���s examine 3280how the stack operations are optimized away. 3281 3282After a pass of constant-propagation, the depth of the stack at each 3283opcode can be determined at compile-time: 3284 3285@example 3286$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1 3287@end example 3288 3289@example 3290;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3291 3292factorial (signed int arg) 3293@{ 3294 signed int stack[8]; 3295 signed int stack_depth; 3296 signed int x; 3297 signed int y; 3298 <unnamed type> _20; 3299 signed int _21; 3300 signed int _38; 3301 signed int _44; 3302 signed int _51; 3303 3304initial: 3305 stack[0] = arg_5(D); 3306 x_9 = stack[0]; 3307 stack[0] = x_9; 3308 stack[1] = x_9; 3309 stack[2] = 2; 3310 y_17 = stack[2]; 3311 x_19 = stack[1]; 3312 _20 = x_19 < y_17; 3313 _21 = (signed int) _20; 3314 stack[1] = _21; 3315 x_25 = stack[1]; 3316 if (x_25 != 0) 3317 goto <bb 4> (instr9); 3318 else 3319 goto <bb 3> (instr4); 3320 3321instr4: 3322/* DUP */: 3323 x_27 = stack[0]; 3324 stack[0] = x_27; 3325 stack[1] = x_27; 3326 stack[2] = 1; 3327 y_35 = stack[2]; 3328 x_37 = stack[1]; 3329 _38 = x_37 - y_35; 3330 stack[1] = _38; 3331 x_42 = stack[1]; 3332 _44 = factorial (x_42); 3333 stack[1] = _44; 3334 y_48 = stack[1]; 3335 x_50 = stack[0]; 3336 _51 = x_50 * y_48; 3337 stack[0] = _51; 3338 3339instr9: 3340/* RETURN */: 3341 x_55 = stack[0]; 3342 x_56 = x_55; 3343 stack =@{v@} @{CLOBBER@}; 3344 return x_56; 3345 3346@} 3347@end example 3348 3349Note how, in the above, all those @code{stack_depth} values are now just 3350constants: we���re accessing specific stack locations at each opcode. 3351 3352The ���esra��� pass (���Early Scalar Replacement of Aggregates���) breaks 3353out our ���stack��� array into individual elements: 3354 3355@example 3356$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra 3357@end example 3358 3359@example 3360;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3361 3362Created a replacement for stack offset: 0, size: 32: stack$0 3363Created a replacement for stack offset: 32, size: 32: stack$1 3364Created a replacement for stack offset: 64, size: 32: stack$2 3365 3366Symbols to be put in SSA form 3367@{ D.89 D.90 D.91 @} 3368Incremental SSA update started at block: 0 3369Number of blocks in CFG: 5 3370Number of blocks to update: 4 ( 80%) 3371 3372 3373factorial (signed int arg) 3374@{ 3375 signed int stack$2; 3376 signed int stack$1; 3377 signed int stack$0; 3378 signed int stack[8]; 3379 signed int stack_depth; 3380 signed int x; 3381 signed int y; 3382 <unnamed type> _20; 3383 signed int _21; 3384 signed int _38; 3385 signed int _44; 3386 signed int _51; 3387 3388initial: 3389 stack$0_45 = arg_5(D); 3390 x_9 = stack$0_45; 3391 stack$0_39 = x_9; 3392 stack$1_32 = x_9; 3393 stack$2_30 = 2; 3394 y_17 = stack$2_30; 3395 x_19 = stack$1_32; 3396 _20 = x_19 < y_17; 3397 _21 = (signed int) _20; 3398 stack$1_28 = _21; 3399 x_25 = stack$1_28; 3400 if (x_25 != 0) 3401 goto <bb 4> (instr9); 3402 else 3403 goto <bb 3> (instr4); 3404 3405instr4: 3406/* DUP */: 3407 x_27 = stack$0_39; 3408 stack$0_22 = x_27; 3409 stack$1_14 = x_27; 3410 stack$2_12 = 1; 3411 y_35 = stack$2_12; 3412 x_37 = stack$1_14; 3413 _38 = x_37 - y_35; 3414 stack$1_10 = _38; 3415 x_42 = stack$1_10; 3416 _44 = factorial (x_42); 3417 stack$1_6 = _44; 3418 y_48 = stack$1_6; 3419 x_50 = stack$0_22; 3420 _51 = x_50 * y_48; 3421 stack$0_1 = _51; 3422 3423 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)> 3424instr9: 3425/* RETURN */: 3426 x_55 = stack$0_52; 3427 x_56 = x_55; 3428 stack =@{v@} @{CLOBBER@}; 3429 return x_56; 3430 3431@} 3432@end example 3433 3434Hence at this point, all those pushes and pops of the stack are now 3435simply assignments to specific temporary variables. 3436 3437After some copy propagation, the stack manipulation has been completely 3438optimized away: 3439 3440@example 3441$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1 3442@end example 3443 3444@example 3445;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3446 3447factorial (signed int arg) 3448@{ 3449 signed int stack$2; 3450 signed int stack$1; 3451 signed int stack$0; 3452 signed int stack[8]; 3453 signed int stack_depth; 3454 signed int x; 3455 signed int y; 3456 <unnamed type> _20; 3457 signed int _21; 3458 signed int _38; 3459 signed int _44; 3460 signed int _51; 3461 3462initial: 3463 stack$0_39 = arg_5(D); 3464 _20 = arg_5(D) <= 1; 3465 _21 = (signed int) _20; 3466 if (_21 != 0) 3467 goto <bb 4> (instr9); 3468 else 3469 goto <bb 3> (instr4); 3470 3471instr4: 3472/* DUP */: 3473 _38 = arg_5(D) + -1; 3474 _44 = factorial (_38); 3475 _51 = arg_5(D) * _44; 3476 stack$0_1 = _51; 3477 3478 # stack$0_52 = PHI <arg_5(D)(2), _51(3)> 3479instr9: 3480/* RETURN */: 3481 stack =@{v@} @{CLOBBER@}; 3482 return stack$0_52; 3483 3484@} 3485@end example 3486 3487Later on, another pass finally eliminated @code{stack_depth} local and the 3488unused parts of the @cite{stack`} array altogether: 3489 3490@example 3491$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa 3492@end example 3493 3494@example 3495;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3496 3497Released 44 names, 314.29%, removed 44 holes 3498factorial (signed int arg) 3499@{ 3500 signed int stack$0; 3501 signed int mult_acc_1; 3502 <unnamed type> _5; 3503 signed int _6; 3504 signed int _7; 3505 signed int mul_tmp_10; 3506 signed int mult_acc_11; 3507 signed int mult_acc_13; 3508 3509 # arg_9 = PHI <arg_8(D)(0)> 3510 # mult_acc_13 = PHI <1(0)> 3511initial: 3512 3513 <bb 5>: 3514 # arg_4 = PHI <arg_9(2), _7(3)> 3515 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)> 3516 _5 = arg_4 <= 1; 3517 _6 = (signed int) _5; 3518 if (_6 != 0) 3519 goto <bb 4> (instr9); 3520 else 3521 goto <bb 3> (instr4); 3522 3523instr4: 3524/* DUP */: 3525 _7 = arg_4 + -1; 3526 mult_acc_11 = mult_acc_1 * arg_4; 3527 goto <bb 5>; 3528 3529 # stack$0_12 = PHI <arg_4(5)> 3530instr9: 3531/* RETURN */: 3532 mul_tmp_10 = mult_acc_1 * stack$0_12; 3533 return mul_tmp_10; 3534 3535@} 3536@end example 3537 3538@node Elimination of tail recursion,,Optimizing away stack manipulation,Behind the curtain How does our code get optimized? 3539@anchor{intro/tutorial04 elimination-of-tail-recursion}@anchor{47} 3540@subsubsection Elimination of tail recursion 3541 3542 3543Another significant optimization is the detection that the call to 3544@code{factorial} is tail recursion, which can be eliminated in favor of 3545an iteration: 3546 3547@example 3548$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1 3549@end example 3550 3551@example 3552;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3553 3554 3555Symbols to be put in SSA form 3556@{ D.88 @} 3557Incremental SSA update started at block: 0 3558Number of blocks in CFG: 5 3559Number of blocks to update: 4 ( 80%) 3560 3561 3562factorial (signed int arg) 3563@{ 3564 signed int stack$2; 3565 signed int stack$1; 3566 signed int stack$0; 3567 signed int stack[8]; 3568 signed int stack_depth; 3569 signed int x; 3570 signed int y; 3571 signed int mult_acc_1; 3572 <unnamed type> _20; 3573 signed int _21; 3574 signed int _38; 3575 signed int mul_tmp_44; 3576 signed int mult_acc_51; 3577 3578 # arg_5 = PHI <arg_39(D)(0), _38(3)> 3579 # mult_acc_1 = PHI <1(0), mult_acc_51(3)> 3580initial: 3581 _20 = arg_5 <= 1; 3582 _21 = (signed int) _20; 3583 if (_21 != 0) 3584 goto <bb 4> (instr9); 3585 else 3586 goto <bb 3> (instr4); 3587 3588instr4: 3589/* DUP */: 3590 _38 = arg_5 + -1; 3591 mult_acc_51 = mult_acc_1 * arg_5; 3592 goto <bb 2> (initial); 3593 3594 # stack$0_52 = PHI <arg_5(2)> 3595instr9: 3596/* RETURN */: 3597 stack =@{v@} @{CLOBBER@}; 3598 mul_tmp_44 = mult_acc_1 * stack$0_52; 3599 return mul_tmp_44; 3600 3601@} 3602@end example 3603 3604@c Copyright (C) 2015-2022 Free Software Foundation, Inc. 3605@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 3606@c 3607@c This is free software: you can redistribute it and/or modify it 3608@c under the terms of the GNU General Public License as published by 3609@c the Free Software Foundation, either version 3 of the License, or 3610@c (at your option) any later version. 3611@c 3612@c This program is distributed in the hope that it will be useful, but 3613@c WITHOUT ANY WARRANTY; without even the implied warranty of 3614@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 3615@c General Public License for more details. 3616@c 3617@c You should have received a copy of the GNU General Public License 3618@c along with this program. If not, see 3619@c <https://www.gnu.org/licenses/>. 3620 3621@node Tutorial part 5 Implementing an Ahead-of-Time compiler,,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial 3622@anchor{intro/tutorial05 doc}@anchor{48}@anchor{intro/tutorial05 tutorial-part-5-implementing-an-ahead-of-time-compiler}@anchor{49} 3623@section Tutorial part 5: Implementing an Ahead-of-Time compiler 3624 3625 3626If you have a pre-existing language frontend that���s compatible with 3627libgccjit���s license, it���s possible to hook it up to libgccjit as a 3628backend. In the previous example we showed 3629how to do that for in-memory JIT-compilation, but libgccjit can also 3630compile code directly to a file, allowing you to implement a more 3631traditional ahead-of-time compiler (���JIT��� is something of a misnomer 3632for this use-case). 3633 3634The essential difference is to compile the context using 3635@ref{4a,,gcc_jit_context_compile_to_file()} rather than 3636@ref{15,,gcc_jit_context_compile()}. 3637 3638@menu 3639* The ���brainf��� language:: 3640* Converting a brainf script to libgccjit IR:: 3641* Compiling a context to a file:: 3642* Other forms of ahead-of-time-compilation:: 3643 3644@end menu 3645 3646@node The ���brainf��� language,Converting a brainf script to libgccjit IR,,Tutorial part 5 Implementing an Ahead-of-Time compiler 3647@anchor{intro/tutorial05 the-brainf-language}@anchor{4b} 3648@subsection The ���brainf��� language 3649 3650 3651In this example we use libgccjit to construct an ahead-of-time compiler 3652for an esoteric programming language that we shall refer to as ���brainf���. 3653 3654brainf scripts operate on an array of bytes, with a notional data pointer 3655within the array. 3656 3657brainf is hard for humans to read, but it���s trivial to write a parser for 3658it, as there is no lexing; just a stream of bytes. The operations are: 3659 3660 3661@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 3662@headitem 3663 3664Character 3665 3666@tab 3667 3668Meaning 3669 3670@item 3671 3672@code{>} 3673 3674@tab 3675 3676@code{idx += 1} 3677 3678@item 3679 3680@code{<} 3681 3682@tab 3683 3684@code{idx -= 1} 3685 3686@item 3687 3688@code{+} 3689 3690@tab 3691 3692@code{data[idx] += 1} 3693 3694@item 3695 3696@code{-} 3697 3698@tab 3699 3700@code{data[idx] -= 1} 3701 3702@item 3703 3704@code{.} 3705 3706@tab 3707 3708@code{output (data[idx])} 3709 3710@item 3711 3712@code{,} 3713 3714@tab 3715 3716@code{data[idx] = input ()} 3717 3718@item 3719 3720@code{[} 3721 3722@tab 3723 3724loop until @code{data[idx] == 0} 3725 3726@item 3727 3728@code{]} 3729 3730@tab 3731 3732end of loop 3733 3734@item 3735 3736Anything else 3737 3738@tab 3739 3740ignored 3741 3742@end multitable 3743 3744 3745Unlike the previous example, we���ll implement an ahead-of-time compiler, 3746which reads @code{.bf} scripts and outputs executables (though it would 3747be trivial to have it run them JIT-compiled in-process). 3748 3749Here���s what a simple @code{.bf} script looks like: 3750 3751@quotation 3752 3753@example 3754[ 3755 Emit the uppercase alphabet 3756] 3757 3758cell 0 = 26 3759++++++++++++++++++++++++++ 3760 3761cell 1 = 65 3762>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 3763 3764while cell#0 != 0 3765[ 3766 > 3767 . emit cell#1 3768 + increment cell@@1 3769 <- decrement cell@@0 3770] 3771@end example 3772@end quotation 3773 3774@cartouche 3775@quotation Note 3776This example makes use of whitespace and comments for legibility, but 3777could have been written as: 3778 3779@example 3780++++++++++++++++++++++++++ 3781>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 3782[>.+<-] 3783@end example 3784 3785It���s not a particularly useful language, except for providing 3786compiler-writers with a test case that���s easy to parse. The point 3787is that you can use @ref{4a,,gcc_jit_context_compile_to_file()} 3788to use libgccjit as a backend for a pre-existing language frontend 3789(provided that the pre-existing frontend is compatible with libgccjit���s 3790license). 3791@end quotation 3792@end cartouche 3793 3794@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 3795@anchor{intro/tutorial05 converting-a-brainf-script-to-libgccjit-ir}@anchor{4c} 3796@subsection Converting a brainf script to libgccjit IR 3797 3798 3799As before we write simple code to populate a @ref{8,,gcc_jit_context *}. 3800 3801@quotation 3802 3803@example 3804 3805typedef struct bf_compiler 3806@{ 3807 const char *filename; 3808 int line; 3809 int column; 3810 3811 gcc_jit_context *ctxt; 3812 3813 gcc_jit_type *void_type; 3814 gcc_jit_type *int_type; 3815 gcc_jit_type *byte_type; 3816 gcc_jit_type *array_type; 3817 3818 gcc_jit_function *func_getchar; 3819 gcc_jit_function *func_putchar; 3820 3821 gcc_jit_function *func; 3822 gcc_jit_block *curblock; 3823 3824 gcc_jit_rvalue *int_zero; 3825 gcc_jit_rvalue *int_one; 3826 gcc_jit_rvalue *byte_zero; 3827 gcc_jit_rvalue *byte_one; 3828 gcc_jit_lvalue *data_cells; 3829 gcc_jit_lvalue *idx; 3830 3831 int num_open_parens; 3832 gcc_jit_block *paren_test[MAX_OPEN_PARENS]; 3833 gcc_jit_block *paren_body[MAX_OPEN_PARENS]; 3834 gcc_jit_block *paren_after[MAX_OPEN_PARENS]; 3835 3836@} bf_compiler; 3837 3838/* Bail out, with a message on stderr. */ 3839 3840static void 3841fatal_error (bf_compiler *bfc, const char *msg) 3842@{ 3843 fprintf (stderr, 3844 "%s:%i:%i: %s", 3845 bfc->filename, bfc->line, bfc->column, msg); 3846 abort (); 3847@} 3848 3849/* Get "data_cells[idx]" as an lvalue. */ 3850 3851static gcc_jit_lvalue * 3852bf_get_current_data (bf_compiler *bfc, gcc_jit_location *loc) 3853@{ 3854 return gcc_jit_context_new_array_access ( 3855 bfc->ctxt, 3856 loc, 3857 gcc_jit_lvalue_as_rvalue (bfc->data_cells), 3858 gcc_jit_lvalue_as_rvalue (bfc->idx)); 3859@} 3860 3861/* Get "data_cells[idx] == 0" as a boolean rvalue. */ 3862 3863static gcc_jit_rvalue * 3864bf_current_data_is_zero (bf_compiler *bfc, gcc_jit_location *loc) 3865@{ 3866 return gcc_jit_context_new_comparison ( 3867 bfc->ctxt, 3868 loc, 3869 GCC_JIT_COMPARISON_EQ, 3870 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)), 3871 bfc->byte_zero); 3872@} 3873 3874/* Compile one bf character. */ 3875 3876static void 3877bf_compile_char (bf_compiler *bfc, 3878 unsigned char ch) 3879@{ 3880 gcc_jit_location *loc = 3881 gcc_jit_context_new_location (bfc->ctxt, 3882 bfc->filename, 3883 bfc->line, 3884 bfc->column); 3885 3886 /* Turn this on to trace execution, by injecting putchar () 3887 of each source char. */ 3888 if (0) 3889 @{ 3890 gcc_jit_rvalue *arg = 3891 gcc_jit_context_new_rvalue_from_int ( 3892 bfc->ctxt, 3893 bfc->int_type, 3894 ch); 3895 gcc_jit_rvalue *call = 3896 gcc_jit_context_new_call (bfc->ctxt, 3897 loc, 3898 bfc->func_putchar, 3899 1, &arg); 3900 gcc_jit_block_add_eval (bfc->curblock, 3901 loc, 3902 call); 3903 @} 3904 3905 switch (ch) 3906 @{ 3907 case '>': 3908 gcc_jit_block_add_comment (bfc->curblock, 3909 loc, 3910 "'>': idx += 1;"); 3911 gcc_jit_block_add_assignment_op (bfc->curblock, 3912 loc, 3913 bfc->idx, 3914 GCC_JIT_BINARY_OP_PLUS, 3915 bfc->int_one); 3916 break; 3917 3918 case '<': 3919 gcc_jit_block_add_comment (bfc->curblock, 3920 loc, 3921 "'<': idx -= 1;"); 3922 gcc_jit_block_add_assignment_op (bfc->curblock, 3923 loc, 3924 bfc->idx, 3925 GCC_JIT_BINARY_OP_MINUS, 3926 bfc->int_one); 3927 break; 3928 3929 case '+': 3930 gcc_jit_block_add_comment (bfc->curblock, 3931 loc, 3932 "'+': data[idx] += 1;"); 3933 gcc_jit_block_add_assignment_op (bfc->curblock, 3934 loc, 3935 bf_get_current_data (bfc, loc), 3936 GCC_JIT_BINARY_OP_PLUS, 3937 bfc->byte_one); 3938 break; 3939 3940 case '-': 3941 gcc_jit_block_add_comment (bfc->curblock, 3942 loc, 3943 "'-': data[idx] -= 1;"); 3944 gcc_jit_block_add_assignment_op (bfc->curblock, 3945 loc, 3946 bf_get_current_data (bfc, loc), 3947 GCC_JIT_BINARY_OP_MINUS, 3948 bfc->byte_one); 3949 break; 3950 3951 case '.': 3952 @{ 3953 gcc_jit_rvalue *arg = 3954 gcc_jit_context_new_cast ( 3955 bfc->ctxt, 3956 loc, 3957 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)), 3958 bfc->int_type); 3959 gcc_jit_rvalue *call = 3960 gcc_jit_context_new_call (bfc->ctxt, 3961 loc, 3962 bfc->func_putchar, 3963 1, &arg); 3964 gcc_jit_block_add_comment (bfc->curblock, 3965 loc, 3966 "'.': putchar ((int)data[idx]);"); 3967 gcc_jit_block_add_eval (bfc->curblock, 3968 loc, 3969 call); 3970 @} 3971 break; 3972 3973 case ',': 3974 @{ 3975 gcc_jit_rvalue *call = 3976 gcc_jit_context_new_call (bfc->ctxt, 3977 loc, 3978 bfc->func_getchar, 3979 0, NULL); 3980 gcc_jit_block_add_comment ( 3981 bfc->curblock, 3982 loc, 3983 "',': data[idx] = (unsigned char)getchar ();"); 3984 gcc_jit_block_add_assignment (bfc->curblock, 3985 loc, 3986 bf_get_current_data (bfc, loc), 3987 gcc_jit_context_new_cast ( 3988 bfc->ctxt, 3989 loc, 3990 call, 3991 bfc->byte_type)); 3992 @} 3993 break; 3994 3995 case '[': 3996 @{ 3997 gcc_jit_block *loop_test = 3998 gcc_jit_function_new_block (bfc->func, NULL); 3999 gcc_jit_block *on_zero = 4000 gcc_jit_function_new_block (bfc->func, NULL); 4001 gcc_jit_block *on_non_zero = 4002 gcc_jit_function_new_block (bfc->func, NULL); 4003 4004 if (bfc->num_open_parens == MAX_OPEN_PARENS) 4005 fatal_error (bfc, "too many open parens"); 4006 4007 gcc_jit_block_end_with_jump ( 4008 bfc->curblock, 4009 loc, 4010 loop_test); 4011 4012 gcc_jit_block_add_comment ( 4013 loop_test, 4014 loc, 4015 "'['"); 4016 gcc_jit_block_end_with_conditional ( 4017 loop_test, 4018 loc, 4019 bf_current_data_is_zero (bfc, loc), 4020 on_zero, 4021 on_non_zero); 4022 bfc->paren_test[bfc->num_open_parens] = loop_test; 4023 bfc->paren_body[bfc->num_open_parens] = on_non_zero; 4024 bfc->paren_after[bfc->num_open_parens] = on_zero; 4025 bfc->num_open_parens += 1; 4026 bfc->curblock = on_non_zero; 4027 @} 4028 break; 4029 4030 case ']': 4031 @{ 4032 gcc_jit_block_add_comment ( 4033 bfc->curblock, 4034 loc, 4035 "']'"); 4036 4037 if (bfc->num_open_parens == 0) 4038 fatal_error (bfc, "mismatching parens"); 4039 bfc->num_open_parens -= 1; 4040 gcc_jit_block_end_with_jump ( 4041 bfc->curblock, 4042 loc, 4043 bfc->paren_test[bfc->num_open_parens]); 4044 bfc->curblock = bfc->paren_after[bfc->num_open_parens]; 4045 @} 4046 break; 4047 4048 case '\n': 4049 bfc->line +=1; 4050 bfc->column = 0; 4051 break; 4052 @} 4053 4054 if (ch != '\n') 4055 bfc->column += 1; 4056@} 4057 4058/* Compile the given .bf file into a gcc_jit_context, containing a 4059 single "main" function suitable for compiling into an executable. */ 4060 4061gcc_jit_context * 4062bf_compile (const char *filename) 4063@{ 4064 bf_compiler bfc; 4065 FILE *f_in; 4066 int ch; 4067 4068 memset (&bfc, 0, sizeof (bfc)); 4069 4070 bfc.filename = filename; 4071 f_in = fopen (filename, "r"); 4072 if (!f_in) 4073 fatal_error (&bfc, "unable to open file"); 4074 bfc.line = 1; 4075 4076 bfc.ctxt = gcc_jit_context_acquire (); 4077 4078 gcc_jit_context_set_int_option ( 4079 bfc.ctxt, 4080 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 4081 3); 4082 gcc_jit_context_set_bool_option ( 4083 bfc.ctxt, 4084 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 4085 0); 4086 gcc_jit_context_set_bool_option ( 4087 bfc.ctxt, 4088 GCC_JIT_BOOL_OPTION_DEBUGINFO, 4089 1); 4090 gcc_jit_context_set_bool_option ( 4091 bfc.ctxt, 4092 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 4093 0); 4094 gcc_jit_context_set_bool_option ( 4095 bfc.ctxt, 4096 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 4097 0); 4098 4099 bfc.void_type = 4100 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_VOID); 4101 bfc.int_type = 4102 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_INT); 4103 bfc.byte_type = 4104 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR); 4105 bfc.array_type = 4106 gcc_jit_context_new_array_type (bfc.ctxt, 4107 NULL, 4108 bfc.byte_type, 4109 30000); 4110 4111 bfc.func_getchar = 4112 gcc_jit_context_new_function (bfc.ctxt, NULL, 4113 GCC_JIT_FUNCTION_IMPORTED, 4114 bfc.int_type, 4115 "getchar", 4116 0, NULL, 4117 0); 4118 4119 gcc_jit_param *param_c = 4120 gcc_jit_context_new_param (bfc.ctxt, NULL, bfc.int_type, "c"); 4121 bfc.func_putchar = 4122 gcc_jit_context_new_function (bfc.ctxt, NULL, 4123 GCC_JIT_FUNCTION_IMPORTED, 4124 bfc.void_type, 4125 "putchar", 4126 1, ¶m_c, 4127 0); 4128 4129 bfc.func = make_main (bfc.ctxt); 4130 bfc.curblock = 4131 gcc_jit_function_new_block (bfc.func, "initial"); 4132 bfc.int_zero = gcc_jit_context_zero (bfc.ctxt, bfc.int_type); 4133 bfc.int_one = gcc_jit_context_one (bfc.ctxt, bfc.int_type); 4134 bfc.byte_zero = gcc_jit_context_zero (bfc.ctxt, bfc.byte_type); 4135 bfc.byte_one = gcc_jit_context_one (bfc.ctxt, bfc.byte_type); 4136 4137 bfc.data_cells = 4138 gcc_jit_context_new_global (bfc.ctxt, NULL, 4139 GCC_JIT_GLOBAL_INTERNAL, 4140 bfc.array_type, 4141 "data_cells"); 4142 bfc.idx = 4143 gcc_jit_function_new_local (bfc.func, NULL, 4144 bfc.int_type, 4145 "idx"); 4146 4147 gcc_jit_block_add_comment (bfc.curblock, 4148 NULL, 4149 "idx = 0;"); 4150 gcc_jit_block_add_assignment (bfc.curblock, 4151 NULL, 4152 bfc.idx, 4153 bfc.int_zero); 4154 4155 bfc.num_open_parens = 0; 4156 4157 while ( EOF != (ch = fgetc (f_in))) 4158 bf_compile_char (&bfc, (unsigned char)ch); 4159 4160 gcc_jit_block_end_with_return (bfc.curblock, NULL, bfc.int_zero); 4161 4162 fclose (f_in); 4163 4164 return bfc.ctxt; 4165@} 4166 4167@end example 4168@end quotation 4169 4170@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 4171@anchor{intro/tutorial05 compiling-a-context-to-a-file}@anchor{4d} 4172@subsection Compiling a context to a file 4173 4174 4175Unlike the previous tutorial, this time we���ll compile the context 4176directly to an executable, using @ref{4a,,gcc_jit_context_compile_to_file()}: 4177 4178@example 4179gcc_jit_context_compile_to_file (ctxt, 4180 GCC_JIT_OUTPUT_KIND_EXECUTABLE, 4181 output_file); 4182@end example 4183 4184Here���s the top-level of the compiler, which is what actually calls into 4185@ref{4a,,gcc_jit_context_compile_to_file()}: 4186 4187@quotation 4188 4189@example 4190 4191int 4192main (int argc, char **argv) 4193@{ 4194 const char *input_file; 4195 const char *output_file; 4196 gcc_jit_context *ctxt; 4197 const char *err; 4198 4199 if (argc != 3) 4200 @{ 4201 fprintf (stderr, "%s: INPUT_FILE OUTPUT_FILE\n", argv[0]); 4202 return 1; 4203 @} 4204 4205 input_file = argv[1]; 4206 output_file = argv[2]; 4207 ctxt = bf_compile (input_file); 4208 4209 gcc_jit_context_compile_to_file (ctxt, 4210 GCC_JIT_OUTPUT_KIND_EXECUTABLE, 4211 output_file); 4212 4213 err = gcc_jit_context_get_first_error (ctxt); 4214 4215 if (err) 4216 @{ 4217 gcc_jit_context_release (ctxt); 4218 return 1; 4219 @} 4220 4221 gcc_jit_context_release (ctxt); 4222 return 0; 4223@} 4224 4225@end example 4226@end quotation 4227 4228Note how once the context is populated you could trivially instead compile 4229it to memory using @ref{15,,gcc_jit_context_compile()} and run it in-process 4230as in the previous tutorial. 4231 4232To create an executable, we need to export a @code{main} function. Here���s 4233how to create one from the JIT API: 4234 4235@quotation 4236 4237@example 4238 4239/* Make "main" function: 4240 int 4241 main (int argc, char **argv) 4242 @{ 4243 ... 4244 @} 4245*/ 4246static gcc_jit_function * 4247make_main (gcc_jit_context *ctxt) 4248@{ 4249 gcc_jit_type *int_type = 4250 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 4251 gcc_jit_param *param_argc = 4252 gcc_jit_context_new_param (ctxt, NULL, int_type, "argc"); 4253 gcc_jit_type *char_ptr_ptr_type = 4254 gcc_jit_type_get_pointer ( 4255 gcc_jit_type_get_pointer ( 4256 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR))); 4257 gcc_jit_param *param_argv = 4258 gcc_jit_context_new_param (ctxt, NULL, char_ptr_ptr_type, "argv"); 4259 gcc_jit_param *params[2] = @{param_argc, param_argv@}; 4260 gcc_jit_function *func_main = 4261 gcc_jit_context_new_function (ctxt, NULL, 4262 GCC_JIT_FUNCTION_EXPORTED, 4263 int_type, 4264 "main", 4265 2, params, 4266 0); 4267 return func_main; 4268@} 4269 4270@end example 4271@end quotation 4272 4273@cartouche 4274@quotation Note 4275The above implementation ignores @code{argc} and @code{argv}, but you could 4276make use of them by exposing @code{param_argc} and @code{param_argv} to the 4277caller. 4278@end quotation 4279@end cartouche 4280 4281Upon compiling this C code, we obtain a bf-to-machine-code compiler; 4282let���s call it @code{bfc}: 4283 4284@example 4285$ gcc \ 4286 tut05-bf.c \ 4287 -o bfc \ 4288 -lgccjit 4289@end example 4290 4291We can now use @code{bfc} to compile .bf files into machine code executables: 4292 4293@example 4294$ ./bfc \ 4295 emit-alphabet.bf \ 4296 a.out 4297@end example 4298 4299which we can run directly: 4300 4301@example 4302$ ./a.out 4303ABCDEFGHIJKLMNOPQRSTUVWXYZ 4304@end example 4305 4306Success! 4307 4308We can also inspect the generated executable using standard tools: 4309 4310@example 4311$ objdump -d a.out |less 4312@end example 4313 4314which shows that libgccjit has managed to optimize the function 4315somewhat (for example, the runs of 26 and 65 increment operations 4316have become integer constants 0x1a and 0x41): 4317 4318@example 43190000000000400620 <main>: 4320 400620: 80 3d 39 0a 20 00 00 cmpb $0x0,0x200a39(%rip) # 601060 <data 4321 400627: 74 07 je 400630 <main 4322 400629: eb fe jmp 400629 <main+0x9> 4323 40062b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 4324 400630: 48 83 ec 08 sub $0x8,%rsp 4325 400634: 0f b6 05 26 0a 20 00 movzbl 0x200a26(%rip),%eax # 601061 <data_cells+0x1> 4326 40063b: c6 05 1e 0a 20 00 1a movb $0x1a,0x200a1e(%rip) # 601060 <data_cells> 4327 400642: 8d 78 41 lea 0x41(%rax),%edi 4328 400645: 40 88 3d 15 0a 20 00 mov %dil,0x200a15(%rip) # 601061 <data_cells+0x1> 4329 40064c: 0f 1f 40 00 nopl 0x0(%rax) 4330 400650: 40 0f b6 ff movzbl %dil,%edi 4331 400654: e8 87 fe ff ff callq 4004e0 <putchar@@plt> 4332 400659: 0f b6 05 01 0a 20 00 movzbl 0x200a01(%rip),%eax # 601061 <data_cells+0x1> 4333 400660: 80 2d f9 09 20 00 01 subb $0x1,0x2009f9(%rip) # 601060 <data_cells> 4334 400667: 8d 78 01 lea 0x1(%rax),%edi 4335 40066a: 40 88 3d f0 09 20 00 mov %dil,0x2009f0(%rip) # 601061 <data_cells+0x1> 4336 400671: 75 dd jne 400650 <main+0x30> 4337 400673: 31 c0 xor %eax,%eax 4338 400675: 48 83 c4 08 add $0x8,%rsp 4339 400679: c3 retq 4340 40067a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 4341@end example 4342 4343We also set up debugging information (via 4344@ref{41,,gcc_jit_context_new_location()} and 4345@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO}), so it���s possible to use @code{gdb} 4346to singlestep through the generated binary and inspect the internal 4347state @code{idx} and @code{data_cells}: 4348 4349@example 4350(gdb) break main 4351Breakpoint 1 at 0x400790 4352(gdb) run 4353Starting program: a.out 4354 4355Breakpoint 1, 0x0000000000400790 in main (argc=1, argv=0x7fffffffe448) 4356(gdb) stepi 43570x0000000000400797 in main (argc=1, argv=0x7fffffffe448) 4358(gdb) stepi 43590x00000000004007a0 in main (argc=1, argv=0x7fffffffe448) 4360(gdb) stepi 43619 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4362(gdb) list 43634 43645 cell 0 = 26 43656 ++++++++++++++++++++++++++ 43667 43678 cell 1 = 65 43689 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 436910 437011 while cell#0 != 0 437112 [ 437213 > 4373(gdb) n 43746 ++++++++++++++++++++++++++ 4375(gdb) n 43769 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4377(gdb) p idx 4378$1 = 1 4379(gdb) p data_cells 4380$2 = "\032", '\000' <repeats 29998 times> 4381(gdb) p data_cells[0] 4382$3 = 26 '\032' 4383(gdb) p data_cells[1] 4384$4 = 0 '\000' 4385(gdb) list 43864 43875 cell 0 = 26 43886 ++++++++++++++++++++++++++ 43897 43908 cell 1 = 65 43919 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 439210 439311 while cell#0 != 0 439412 [ 439513 > 4396@end example 4397 4398@node Other forms of ahead-of-time-compilation,,Compiling a context to a file,Tutorial part 5 Implementing an Ahead-of-Time compiler 4399@anchor{intro/tutorial05 other-forms-of-ahead-of-time-compilation}@anchor{4e} 4400@subsection Other forms of ahead-of-time-compilation 4401 4402 4403The above demonstrates compiling a @ref{8,,gcc_jit_context *} directly 4404to an executable. It���s also possible to compile it to an object file, 4405and to a dynamic library. See the documentation of 4406@ref{4a,,gcc_jit_context_compile_to_file()} for more information. 4407 4408@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 4409@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 4410@c 4411@c This is free software: you can redistribute it and/or modify it 4412@c under the terms of the GNU General Public License as published by 4413@c the Free Software Foundation, either version 3 of the License, or 4414@c (at your option) any later version. 4415@c 4416@c This program is distributed in the hope that it will be useful, but 4417@c WITHOUT ANY WARRANTY; without even the implied warranty of 4418@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4419@c General Public License for more details. 4420@c 4421@c You should have received a copy of the GNU General Public License 4422@c along with this program. If not, see 4423@c <https://www.gnu.org/licenses/>. 4424 4425@node Topic Reference,C++ bindings for libgccjit,Tutorial,Top 4426@anchor{topics/index doc}@anchor{4f}@anchor{topics/index topic-reference}@anchor{50} 4427@chapter Topic Reference 4428 4429 4430@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 4431@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 4432@c 4433@c This is free software: you can redistribute it and/or modify it 4434@c under the terms of the GNU General Public License as published by 4435@c the Free Software Foundation, either version 3 of the License, or 4436@c (at your option) any later version. 4437@c 4438@c This program is distributed in the hope that it will be useful, but 4439@c WITHOUT ANY WARRANTY; without even the implied warranty of 4440@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4441@c General Public License for more details. 4442@c 4443@c You should have received a copy of the GNU General Public License 4444@c along with this program. If not, see 4445@c <https://www.gnu.org/licenses/>. 4446 4447@menu 4448* Compilation contexts:: 4449* Objects:: 4450* Types:: 4451* Expressions:: 4452* Creating and using functions:: 4453* Function pointers: Function pointers<2>. 4454* Source Locations:: 4455* Compiling a context:: 4456* ABI and API compatibility:: 4457* Performance:: 4458* Using Assembly Language with libgccjit:: 4459 4460@end menu 4461 4462@node Compilation contexts,Objects,,Topic Reference 4463@anchor{topics/contexts doc}@anchor{51}@anchor{topics/contexts compilation-contexts}@anchor{52} 4464@section Compilation contexts 4465 4466 4467@geindex gcc_jit_context (C type) 4468@anchor{topics/contexts c gcc_jit_context}@anchor{8} 4469@deffn {C Type} gcc_jit_context 4470@end deffn 4471 4472The top-level of the API is the @ref{8,,gcc_jit_context} type. 4473 4474A @ref{8,,gcc_jit_context} instance encapsulates the state of a 4475compilation. 4476 4477You can set up options on it, and add types, functions and code. 4478Invoking @ref{15,,gcc_jit_context_compile()} on it gives you a 4479@ref{16,,gcc_jit_result}. 4480 4481@menu 4482* Lifetime-management:: 4483* Thread-safety:: 4484* Error-handling: Error-handling<2>. 4485* Debugging:: 4486* Options: Options<2>. 4487 4488@end menu 4489 4490@node Lifetime-management,Thread-safety,,Compilation contexts 4491@anchor{topics/contexts lifetime-management}@anchor{53} 4492@subsection Lifetime-management 4493 4494 4495Contexts are the unit of lifetime-management within the API: objects 4496have their lifetime bounded by the context they are created within, and 4497cleanup of such objects is done for you when the context is released. 4498 4499@geindex gcc_jit_context_acquire (C function) 4500@anchor{topics/contexts c gcc_jit_context_acquire}@anchor{9} 4501@deffn {C Function} gcc_jit_context *gcc_jit_context_acquire (void) 4502 4503This function acquires a new @ref{8,,gcc_jit_context *} instance, 4504which is independent of any others that may be present within this 4505process. 4506@end deffn 4507 4508@geindex gcc_jit_context_release (C function) 4509@anchor{topics/contexts c gcc_jit_context_release}@anchor{c} 4510@deffn {C Function} void gcc_jit_context_release (gcc_jit_context@w{ }*ctxt) 4511 4512This function releases all resources associated with the given context. 4513Both the context itself and all of its @ref{e,,gcc_jit_object *} 4514instances are cleaned up. It should be called exactly once on a given 4515context. 4516 4517It is invalid to use the context or any of its ���contextual��� objects 4518after calling this. 4519 4520@example 4521gcc_jit_context_release (ctxt); 4522@end example 4523@end deffn 4524 4525@geindex gcc_jit_context_new_child_context (C function) 4526@anchor{topics/contexts c gcc_jit_context_new_child_context}@anchor{54} 4527@deffn {C Function} gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context@w{ }*parent_ctxt) 4528 4529Given an existing JIT context, create a child context. 4530 4531The child inherits a copy of all option-settings from the parent. 4532 4533The child can reference objects created within the parent, but not 4534vice-versa. 4535 4536The lifetime of the child context must be bounded by that of the 4537parent: you should release a child context before releasing the parent 4538context. 4539 4540If you use a function from a parent context within a child context, 4541you have to compile the parent context before you can compile the 4542child context, and the gcc_jit_result of the parent context must 4543outlive the gcc_jit_result of the child context. 4544 4545This allows caching of shared initializations. For example, you could 4546create types and declarations of global functions in a parent context 4547once within a process, and then create child contexts whenever a 4548function or loop becomes hot. Each such child context can be used for 4549JIT-compiling just one function or loop, but can reference types 4550and helper functions created within the parent context. 4551 4552Contexts can be arbitrarily nested, provided the above rules are 4553followed, but it���s probably not worth going above 2 or 3 levels, and 4554there will likely be a performance hit for such nesting. 4555@end deffn 4556 4557@node Thread-safety,Error-handling<2>,Lifetime-management,Compilation contexts 4558@anchor{topics/contexts thread-safety}@anchor{55} 4559@subsection Thread-safety 4560 4561 4562Instances of @ref{8,,gcc_jit_context *} created via 4563@ref{9,,gcc_jit_context_acquire()} are independent from each other: 4564only one thread may use a given context at once, but multiple threads 4565could each have their own contexts without needing locks. 4566 4567Contexts created via @ref{54,,gcc_jit_context_new_child_context()} are 4568related to their parent context. They can be partitioned by their 4569ultimate ancestor into independent ���family trees���. Only one thread 4570within a process may use a given ���family tree��� of such contexts at once, 4571and if you���re using multiple threads you should provide your own locking 4572around entire such context partitions. 4573 4574@node Error-handling<2>,Debugging,Thread-safety,Compilation contexts 4575@anchor{topics/contexts error-handling}@anchor{19}@anchor{topics/contexts id1}@anchor{56} 4576@subsection Error-handling 4577 4578 4579Various kinds of errors are possible when using the API, such as 4580mismatched types in an assignment. You can only compile and get code from 4581a context if no errors occur. 4582 4583Errors are printed on stderr and can be queried using 4584@ref{57,,gcc_jit_context_get_first_error()}. 4585 4586They typically contain the name of the API entrypoint where the error 4587occurred, and pertinent information on the problem: 4588 4589@example 4590./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *) 4591@end example 4592 4593In general, if an error occurs when using an API entrypoint, the 4594entrypoint returns NULL. You don���t have to check everywhere for NULL 4595results, since the API handles a NULL being passed in for any 4596argument by issuing another error. This typically leads to a cascade of 4597followup error messages, but is safe (albeit verbose). The first error 4598message is usually the one to pay attention to, since it is likely to 4599be responsible for all of the rest: 4600 4601@geindex gcc_jit_context_get_first_error (C function) 4602@anchor{topics/contexts c gcc_jit_context_get_first_error}@anchor{57} 4603@deffn {C Function} const char * gcc_jit_context_get_first_error (gcc_jit_context@w{ }*ctxt) 4604 4605Returns the first error message that occurred on the context. 4606 4607The returned string is valid for the rest of the lifetime of the 4608context. 4609 4610If no errors occurred, this will be NULL. 4611@end deffn 4612 4613If you are wrapping the C API for a higher-level language that supports 4614exception-handling, you may instead be interested in the last error that 4615occurred on the context, so that you can embed this in an exception: 4616 4617@geindex gcc_jit_context_get_last_error (C function) 4618@anchor{topics/contexts c gcc_jit_context_get_last_error}@anchor{58} 4619@deffn {C Function} const char * gcc_jit_context_get_last_error (gcc_jit_context@w{ }*ctxt) 4620 4621Returns the last error message that occurred on the context. 4622 4623If no errors occurred, this will be NULL. 4624 4625If non-NULL, the returned string is only guaranteed to be valid until 4626the next call to libgccjit relating to this context. 4627@end deffn 4628 4629@node Debugging,Options<2>,Error-handling<2>,Compilation contexts 4630@anchor{topics/contexts debugging}@anchor{59} 4631@subsection Debugging 4632 4633 4634@geindex gcc_jit_context_dump_to_file (C function) 4635@anchor{topics/contexts c gcc_jit_context_dump_to_file}@anchor{5a} 4636@deffn {C Function} void gcc_jit_context_dump_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path, int@w{ }update_locations) 4637 4638To help with debugging: dump a C-like representation to the given path, 4639describing what���s been set up on the context. 4640 4641If ���update_locations��� is true, then also set up @ref{3b,,gcc_jit_location} 4642information throughout the context, pointing at the dump file as if it 4643were a source file. This may be of use in conjunction with 4644@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to allow stepping through the 4645code in a debugger. 4646@end deffn 4647 4648@geindex gcc_jit_context_set_logfile (C function) 4649@anchor{topics/contexts c gcc_jit_context_set_logfile}@anchor{5b} 4650@deffn {C Function} void gcc_jit_context_set_logfile (gcc_jit_context@w{ }*ctxt, FILE@w{ }*logfile, int@w{ }flags, int@w{ }verbosity) 4651 4652To help with debugging; enable ongoing logging of the context���s 4653activity to the given file. 4654 4655For example, the following will enable logging to stderr. 4656 4657@example 4658gcc_jit_context_set_logfile (ctxt, stderr, 0, 0); 4659@end example 4660 4661Examples of information logged include: 4662 4663 4664@itemize * 4665 4666@item 4667API calls 4668 4669@item 4670the various steps involved within compilation 4671 4672@item 4673activity on any @ref{16,,gcc_jit_result} instances created by 4674the context 4675 4676@item 4677activity within any child contexts 4678@end itemize 4679 4680An example of a log can be seen @ref{5c,,here}, 4681though the precise format and kinds of information logged is subject 4682to change. 4683 4684The caller remains responsible for closing @cite{logfile}, and it must not 4685be closed until all users are released. In particular, note that 4686child contexts and @ref{16,,gcc_jit_result} instances created by 4687the context will use the logfile. 4688 4689There may a performance cost for logging. 4690 4691You can turn off logging on @cite{ctxt} by passing @cite{NULL} for @cite{logfile}. 4692Doing so only affects the context; it does not affect child contexts 4693or @ref{16,,gcc_jit_result} instances already created by 4694the context. 4695 4696The parameters ���flags��� and ���verbosity��� are reserved for future 4697expansion, and must be zero for now. 4698@end deffn 4699 4700To contrast the above: @ref{5a,,gcc_jit_context_dump_to_file()} dumps the 4701current state of a context to the given path, whereas 4702@ref{5b,,gcc_jit_context_set_logfile()} enables on-going logging of 4703future activies on a context to the given @cite{FILE *}. 4704 4705@geindex gcc_jit_context_dump_reproducer_to_file (C function) 4706@anchor{topics/contexts c gcc_jit_context_dump_reproducer_to_file}@anchor{5d} 4707@deffn {C Function} void gcc_jit_context_dump_reproducer_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path) 4708 4709Write C source code into @cite{path} that can be compiled into a 4710self-contained executable (i.e. with libgccjit as the only dependency). 4711The generated code will attempt to replay the API calls that have been 4712made into the given context. 4713 4714This may be useful when debugging the library or client code, for 4715reducing a complicated recipe for reproducing a bug into a simpler 4716form. For example, consider client code that parses some source file 4717into some internal representation, and then walks this IR, calling into 4718libgccjit. If this encounters a bug, a call to 4719@cite{gcc_jit_context_dump_reproducer_to_file} will write out C code for 4720a much simpler executable that performs the equivalent calls into 4721libgccjit, without needing the client code and its data. 4722 4723Typically you need to supply @code{-Wno-unused-variable} when 4724compiling the generated file (since the result of each API call is 4725assigned to a unique variable within the generated C source, and not 4726all are necessarily then used). 4727@end deffn 4728 4729@geindex gcc_jit_context_enable_dump (C function) 4730@anchor{topics/contexts c gcc_jit_context_enable_dump}@anchor{5e} 4731@deffn {C Function} void gcc_jit_context_enable_dump (gcc_jit_context@w{ }*ctxt, const char@w{ }*dumpname, char@w{ }**out_ptr) 4732 4733Enable the dumping of a specific set of internal state from the 4734compilation, capturing the result in-memory as a buffer. 4735 4736Parameter ���dumpname��� corresponds to the equivalent gcc command-line 4737option, without the ���-fdump-��� prefix. 4738For example, to get the equivalent of @code{-fdump-tree-vrp1}, 4739supply @code{"tree-vrp1"}: 4740 4741@example 4742static char *dump_vrp1; 4743 4744void 4745create_code (gcc_jit_context *ctxt) 4746@{ 4747 gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1); 4748 /* (other API calls omitted for brevity) */ 4749@} 4750@end example 4751 4752The context directly stores the dumpname as a @code{(const char *)}, so 4753the passed string must outlive the context. 4754 4755@ref{15,,gcc_jit_context_compile()} will capture the dump as a 4756dynamically-allocated buffer, writing it to @code{*out_ptr}. 4757 4758The caller becomes responsible for calling: 4759 4760@example 4761free (*out_ptr) 4762@end example 4763 4764each time that @ref{15,,gcc_jit_context_compile()} is called. 4765@code{*out_ptr} will be written to, either with the address of a buffer, 4766or with @code{NULL} if an error occurred. 4767 4768@cartouche 4769@quotation Warning 4770This API entrypoint is likely to be less stable than the others. 4771In particular, both the precise dumpnames, and the format and content 4772of the dumps are subject to change. 4773 4774It exists primarily for writing the library���s own test suite. 4775@end quotation 4776@end cartouche 4777@end deffn 4778 4779@node Options<2>,,Debugging,Compilation contexts 4780@anchor{topics/contexts options}@anchor{5f} 4781@subsection Options 4782 4783 4784Options present in the initial release of libgccjit were handled using 4785enums, whereas those added subsequently have their own per-option API 4786entrypoints. 4787 4788Adding entrypoints for each new option means that client code that use 4789the new options can be identified directly from binary metadata, which 4790would not be possible if we instead extended the various 4791@code{enum gcc_jit_*_option}. 4792 4793@menu 4794* String Options:: 4795* Boolean options:: 4796* Integer options:: 4797* Additional command-line options:: 4798 4799@end menu 4800 4801@node String Options,Boolean options,,Options<2> 4802@anchor{topics/contexts string-options}@anchor{60} 4803@subsubsection String Options 4804 4805 4806@geindex gcc_jit_context_set_str_option (C function) 4807@anchor{topics/contexts c gcc_jit_context_set_str_option}@anchor{61} 4808@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) 4809 4810Set a string option of the context. 4811 4812@geindex gcc_jit_str_option (C type) 4813@anchor{topics/contexts c gcc_jit_str_option}@anchor{62} 4814@deffn {C Type} enum gcc_jit_str_option 4815@end deffn 4816 4817The parameter @code{value} can be NULL. If non-NULL, the call takes a 4818copy of the underlying string, so it is valid to pass in a pointer to 4819an on-stack buffer. 4820 4821There is just one string option specified this way: 4822 4823@geindex GCC_JIT_STR_OPTION_PROGNAME (C macro) 4824@anchor{topics/contexts c GCC_JIT_STR_OPTION_PROGNAME}@anchor{63} 4825@deffn {C Macro} GCC_JIT_STR_OPTION_PROGNAME 4826 4827The name of the program, for use as a prefix when printing error 4828messages to stderr. If @cite{NULL}, or default, ���libgccjit.so��� is used. 4829@end deffn 4830@end deffn 4831 4832@node Boolean options,Integer options,String Options,Options<2> 4833@anchor{topics/contexts boolean-options}@anchor{64} 4834@subsubsection Boolean options 4835 4836 4837@geindex gcc_jit_context_set_bool_option (C function) 4838@anchor{topics/contexts c gcc_jit_context_set_bool_option}@anchor{1b} 4839@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) 4840 4841Set a boolean option of the context. 4842Zero is ���false��� (the default), non-zero is ���true���. 4843 4844@geindex gcc_jit_bool_option (C type) 4845@anchor{topics/contexts c gcc_jit_bool_option}@anchor{65} 4846@deffn {C Type} enum gcc_jit_bool_option 4847@end deffn 4848 4849@geindex GCC_JIT_BOOL_OPTION_DEBUGINFO (C macro) 4850@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DEBUGINFO}@anchor{42} 4851@deffn {C Macro} GCC_JIT_BOOL_OPTION_DEBUGINFO 4852 4853If true, @ref{15,,gcc_jit_context_compile()} will attempt to do the right 4854thing so that if you attach a debugger to the process, it will 4855be able to inspect variables and step through your code. 4856 4857Note that you can���t step through code unless you set up source 4858location information for the code (by creating and passing in 4859@ref{3b,,gcc_jit_location} instances). 4860@end deffn 4861 4862@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE (C macro) 4863@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}@anchor{66} 4864@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE 4865 4866If true, @ref{15,,gcc_jit_context_compile()} will dump its initial 4867���tree��� representation of your code to stderr (before any 4868optimizations). 4869 4870Here���s some sample output (from the @cite{square} example): 4871 4872@example 4873<statement_list 0x7f4875a62cc0 4874 type <void_type 0x7f4875a64bd0 VOID 4875 align 8 symtab 0 alias set -1 canonical type 0x7f4875a64bd0 4876 pointer_to_this <pointer_type 0x7f4875a64c78>> 4877 side-effects head 0x7f4875a761e0 tail 0x7f4875a761f8 stmts 0x7f4875a62d20 0x7f4875a62d00 4878 4879 stmt <label_expr 0x7f4875a62d20 type <void_type 0x7f4875a64bd0> 4880 side-effects 4881 arg 0 <label_decl 0x7f4875a79080 entry type <void_type 0x7f4875a64bd0> 4882 VOID file (null) line 0 col 0 4883 align 1 context <function_decl 0x7f4875a77500 square>>> 4884 stmt <return_expr 0x7f4875a62d00 4885 type <integer_type 0x7f4875a645e8 public SI 4886 size <integer_cst 0x7f4875a623a0 constant 32> 4887 unit size <integer_cst 0x7f4875a623c0 constant 4> 4888 align 32 symtab 0 alias set -1 canonical type 0x7f4875a645e8 precision 32 min <integer_cst 0x7f4875a62340 -2147483648> max <integer_cst 0x7f4875a62360 2147483647> 4889 pointer_to_this <pointer_type 0x7f4875a6b348>> 4890 side-effects 4891 arg 0 <modify_expr 0x7f4875a72a78 type <integer_type 0x7f4875a645e8> 4892 side-effects arg 0 <result_decl 0x7f4875a7a000 D.54> 4893 arg 1 <mult_expr 0x7f4875a72a50 type <integer_type 0x7f4875a645e8> 4894 arg 0 <parm_decl 0x7f4875a79000 i> arg 1 <parm_decl 0x7f4875a79000 i>>>>> 4895@end example 4896@end deffn 4897 4898@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE (C macro) 4899@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}@anchor{1c} 4900@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE 4901 4902If true, @ref{15,,gcc_jit_context_compile()} will dump the ���gimple��� 4903representation of your code to stderr, before any optimizations 4904are performed. The dump resembles C code: 4905 4906@example 4907square (signed int i) 4908@{ 4909 signed int D.56; 4910 4911 entry: 4912 D.56 = i * i; 4913 return D.56; 4914@} 4915@end example 4916@end deffn 4917 4918@geindex GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE (C macro) 4919@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE}@anchor{1d} 4920@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE 4921 4922If true, @ref{15,,gcc_jit_context_compile()} will dump the final 4923generated code to stderr, in the form of assembly language: 4924 4925@example 4926 .file "fake.c" 4927 .text 4928 .globl square 4929 .type square, @@function 4930square: 4931.LFB0: 4932 .cfi_startproc 4933 pushq %rbp 4934 .cfi_def_cfa_offset 16 4935 .cfi_offset 6, -16 4936 movq %rsp, %rbp 4937 .cfi_def_cfa_register 6 4938 movl %edi, -4(%rbp) 4939.L2: 4940 movl -4(%rbp), %eax 4941 imull -4(%rbp), %eax 4942 popq %rbp 4943 .cfi_def_cfa 7, 8 4944 ret 4945 .cfi_endproc 4946.LFE0: 4947 .size square, .-square 4948 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.1-%@{gcc_release@})" 4949 .section .note.GNU-stack,"",@@progbits 4950@end example 4951@end deffn 4952 4953@geindex GCC_JIT_BOOL_OPTION_DUMP_SUMMARY (C macro) 4954@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DUMP_SUMMARY}@anchor{67} 4955@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_SUMMARY 4956 4957If true, @ref{15,,gcc_jit_context_compile()} will print information to stderr 4958on the actions it is performing. 4959@end deffn 4960 4961@geindex GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING (C macro) 4962@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING}@anchor{68} 4963@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING 4964 4965If true, @ref{15,,gcc_jit_context_compile()} will dump copious 4966amount of information on what it���s doing to various 4967files within a temporary directory. Use 4968@ref{69,,GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES} (see below) to 4969see the results. The files are intended to be human-readable, 4970but the exact files and their formats are subject to change. 4971@end deffn 4972 4973@geindex GCC_JIT_BOOL_OPTION_SELFCHECK_GC (C macro) 4974@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_SELFCHECK_GC}@anchor{6a} 4975@deffn {C Macro} GCC_JIT_BOOL_OPTION_SELFCHECK_GC 4976 4977If true, libgccjit will aggressively run its garbage collector, to 4978shake out bugs (greatly slowing down the compile). This is likely 4979to only be of interest to developers @emph{of} the library. It is 4980used when running the selftest suite. 4981@end deffn 4982 4983@geindex GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES (C macro) 4984@anchor{topics/contexts c GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES}@anchor{69} 4985@deffn {C Macro} GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES 4986 4987If true, the @ref{8,,gcc_jit_context} will not clean up intermediate files 4988written to the filesystem, and will display their location on stderr. 4989@end deffn 4990@end deffn 4991 4992@geindex gcc_jit_context_set_bool_allow_unreachable_blocks (C function) 4993@anchor{topics/contexts c gcc_jit_context_set_bool_allow_unreachable_blocks}@anchor{6b} 4994@deffn {C Function} void gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value) 4995 4996By default, libgccjit will issue an error about unreachable blocks 4997within a function. 4998 4999This entrypoint can be used to disable that error. 5000 5001This entrypoint was added in @ref{6c,,LIBGCCJIT_ABI_2}; you can test for 5002its presence using 5003 5004@example 5005#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 5006@end example 5007@end deffn 5008 5009@geindex gcc_jit_context_set_bool_use_external_driver (C function) 5010@anchor{topics/contexts c gcc_jit_context_set_bool_use_external_driver}@anchor{6d} 5011@deffn {C Function} void gcc_jit_context_set_bool_use_external_driver (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value) 5012 5013libgccjit internally generates assembler, and uses ���driver��� code 5014for converting it to other formats (e.g. shared libraries). 5015 5016By default, libgccjit will use an embedded copy of the driver 5017code. 5018 5019This option can be used to instead invoke an external driver executable 5020as a subprocess. 5021 5022This entrypoint was added in @ref{6e,,LIBGCCJIT_ABI_5}; you can test for 5023its presence using 5024 5025@example 5026#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver 5027@end example 5028@end deffn 5029 5030@geindex gcc_jit_context_set_bool_print_errors_to_stderr (C function) 5031@anchor{topics/contexts c gcc_jit_context_set_bool_print_errors_to_stderr}@anchor{6f} 5032@deffn {C Function} void gcc_jit_context_set_bool_print_errors_to_stderr (gcc_jit_context@w{ }*ctxt, int@w{ }enabled) 5033 5034By default, libgccjit will print errors to stderr. 5035 5036This entrypoint can be used to disable the printing. 5037 5038This entrypoint was added in @ref{70,,LIBGCCJIT_ABI_23}; you can test for 5039its presence using 5040 5041@example 5042#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_print_errors_to_stderr 5043@end example 5044@end deffn 5045 5046@node Integer options,Additional command-line options,Boolean options,Options<2> 5047@anchor{topics/contexts integer-options}@anchor{71} 5048@subsubsection Integer options 5049 5050 5051@geindex gcc_jit_context_set_int_option (C function) 5052@anchor{topics/contexts c gcc_jit_context_set_int_option}@anchor{1e} 5053@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) 5054 5055Set an integer option of the context. 5056 5057@geindex gcc_jit_int_option (C type) 5058@anchor{topics/contexts c gcc_jit_int_option}@anchor{72} 5059@deffn {C Type} enum gcc_jit_int_option 5060@end deffn 5061 5062There is just one integer option specified this way: 5063 5064@geindex GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL (C macro) 5065@anchor{topics/contexts c GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}@anchor{1f} 5066@deffn {C Macro} GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL 5067 5068How much to optimize the code. 5069 5070Valid values are 0-3, corresponding to GCC���s command-line options 5071-O0 through -O3. 5072 5073The default value is 0 (unoptimized). 5074@end deffn 5075@end deffn 5076 5077@node Additional command-line options,,Integer options,Options<2> 5078@anchor{topics/contexts additional-command-line-options}@anchor{73} 5079@subsubsection Additional command-line options 5080 5081 5082@geindex gcc_jit_context_add_command_line_option (C function) 5083@anchor{topics/contexts c gcc_jit_context_add_command_line_option}@anchor{74} 5084@deffn {C Function} void gcc_jit_context_add_command_line_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname) 5085 5086Add an arbitrary gcc command-line option to the context, for use 5087by @ref{15,,gcc_jit_context_compile()} and 5088@ref{4a,,gcc_jit_context_compile_to_file()}. 5089 5090The parameter @code{optname} must be non-NULL. The underlying buffer is 5091copied, so that it does not need to outlive the call. 5092 5093Extra options added by @cite{gcc_jit_context_add_command_line_option} are 5094applied @emph{after} the regular options above, potentially overriding them. 5095Options from parent contexts are inherited by child contexts; options 5096from the parent are applied @emph{before} those from the child. 5097 5098For example: 5099 5100@example 5101gcc_jit_context_add_command_line_option (ctxt, "-ffast-math"); 5102gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm"); 5103@end example 5104 5105Note that only some options are likely to be meaningful; there is no 5106���frontend��� within libgccjit, so typically only those affecting 5107optimization and code-generation are likely to be useful. 5108 5109This entrypoint was added in @ref{75,,LIBGCCJIT_ABI_1}; you can test for 5110its presence using 5111 5112@example 5113#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 5114@end example 5115@end deffn 5116 5117@geindex gcc_jit_context_add_driver_option (C function) 5118@anchor{topics/contexts c gcc_jit_context_add_driver_option}@anchor{76} 5119@deffn {C Function} void gcc_jit_context_add_driver_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname) 5120 5121Add an arbitrary gcc driver option to the context, for use by 5122@ref{15,,gcc_jit_context_compile()} and 5123@ref{4a,,gcc_jit_context_compile_to_file()}. 5124 5125The parameter @code{optname} must be non-NULL. The underlying buffer is 5126copied, so that it does not need to outlive the call. 5127 5128Extra options added by @cite{gcc_jit_context_add_driver_option} are 5129applied @emph{after} all other options potentially overriding them. 5130Options from parent contexts are inherited by child contexts; options 5131from the parent are applied @emph{before} those from the child. 5132 5133For example: 5134 5135@example 5136gcc_jit_context_add_driver_option (ctxt, "-lm"); 5137gcc_jit_context_add_driver_option (ctxt, "-fuse-linker-plugin"); 5138 5139gcc_jit_context_add_driver_option (ctxt, "obj.o"); 5140 5141gcc_jit_context_add_driver_option (ctxt, "-L."); 5142gcc_jit_context_add_driver_option (ctxt, "-lwhatever"); 5143@end example 5144 5145Note that only some options are likely to be meaningful; there is no 5146���frontend��� within libgccjit, so typically only those affecting 5147assembler and linker are likely to be useful. 5148 5149This entrypoint was added in @ref{77,,LIBGCCJIT_ABI_11}; you can test for 5150its presence using 5151 5152@example 5153#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option 5154@end example 5155@end deffn 5156 5157@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 5158@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 5159@c 5160@c This is free software: you can redistribute it and/or modify it 5161@c under the terms of the GNU General Public License as published by 5162@c the Free Software Foundation, either version 3 of the License, or 5163@c (at your option) any later version. 5164@c 5165@c This program is distributed in the hope that it will be useful, but 5166@c WITHOUT ANY WARRANTY; without even the implied warranty of 5167@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5168@c General Public License for more details. 5169@c 5170@c You should have received a copy of the GNU General Public License 5171@c along with this program. If not, see 5172@c <https://www.gnu.org/licenses/>. 5173 5174@node Objects,Types,Compilation contexts,Topic Reference 5175@anchor{topics/objects doc}@anchor{78}@anchor{topics/objects objects}@anchor{79} 5176@section Objects 5177 5178 5179@geindex gcc_jit_object (C type) 5180@anchor{topics/objects c gcc_jit_object}@anchor{e} 5181@deffn {C Type} gcc_jit_object 5182@end deffn 5183 5184Almost every entity in the API (with the exception of 5185@ref{8,,gcc_jit_context *} and @ref{16,,gcc_jit_result *}) is a 5186���contextual��� object, a @ref{e,,gcc_jit_object *} 5187 5188A JIT object: 5189 5190@quotation 5191 5192 5193@itemize * 5194 5195@item 5196is associated with a @ref{8,,gcc_jit_context *}. 5197 5198@item 5199is automatically cleaned up for you when its context is released so 5200you don���t need to manually track and cleanup all objects, just the 5201contexts. 5202@end itemize 5203@end quotation 5204 5205Although the API is C-based, there is a form of class hierarchy, which 5206looks like this: 5207 5208@example 5209+- gcc_jit_object 5210 +- gcc_jit_location 5211 +- gcc_jit_type 5212 +- gcc_jit_struct 5213 +- gcc_jit_field 5214 +- gcc_jit_function 5215 +- gcc_jit_block 5216 +- gcc_jit_rvalue 5217 +- gcc_jit_lvalue 5218 +- gcc_jit_param 5219 +- gcc_jit_case 5220 +- gcc_jit_extended_asm 5221@end example 5222 5223There are casting methods for upcasting from subclasses to parent classes. 5224For example, @ref{d,,gcc_jit_type_as_object()}: 5225 5226@example 5227gcc_jit_object *obj = gcc_jit_type_as_object (int_type); 5228@end example 5229 5230The object ���base class��� has the following operations: 5231 5232@geindex gcc_jit_object_get_context (C function) 5233@anchor{topics/objects c gcc_jit_object_get_context}@anchor{7a} 5234@deffn {C Function} gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object@w{ }*obj) 5235 5236Which context is ���obj��� within? 5237@end deffn 5238 5239@geindex gcc_jit_object_get_debug_string (C function) 5240@anchor{topics/objects c gcc_jit_object_get_debug_string}@anchor{f} 5241@deffn {C Function} const char *gcc_jit_object_get_debug_string (gcc_jit_object@w{ }*obj) 5242 5243Generate a human-readable description for the given object. 5244 5245For example, 5246 5247@example 5248printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); 5249@end example 5250 5251might give this text on stdout: 5252 5253@example 5254obj: 4.0 * (float)i 5255@end example 5256 5257@cartouche 5258@quotation Note 5259If you call this on an object, the @cite{const char *} buffer is allocated 5260and generated on the first call for that object, and the buffer will 5261have the same lifetime as the object i.e. it will exist until the 5262object���s context is released. 5263@end quotation 5264@end cartouche 5265@end deffn 5266 5267@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 5268@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 5269@c 5270@c This is free software: you can redistribute it and/or modify it 5271@c under the terms of the GNU General Public License as published by 5272@c the Free Software Foundation, either version 3 of the License, or 5273@c (at your option) any later version. 5274@c 5275@c This program is distributed in the hope that it will be useful, but 5276@c WITHOUT ANY WARRANTY; without even the implied warranty of 5277@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5278@c General Public License for more details. 5279@c 5280@c You should have received a copy of the GNU General Public License 5281@c along with this program. If not, see 5282@c <https://www.gnu.org/licenses/>. 5283 5284@node Types,Expressions,Objects,Topic Reference 5285@anchor{topics/types doc}@anchor{7b}@anchor{topics/types types}@anchor{7c} 5286@section Types 5287 5288 5289@geindex gcc_jit_type (C type) 5290@anchor{topics/types c gcc_jit_type}@anchor{a} 5291@deffn {C Type} gcc_jit_type 5292 5293gcc_jit_type represents a type within the library. 5294@end deffn 5295 5296@geindex gcc_jit_type_as_object (C function) 5297@anchor{topics/types c gcc_jit_type_as_object}@anchor{d} 5298@deffn {C Function} gcc_jit_object *gcc_jit_type_as_object (gcc_jit_type@w{ }*type) 5299 5300Upcast a type to an object. 5301@end deffn 5302 5303Types can be created in several ways: 5304 5305 5306@itemize * 5307 5308@item 5309fundamental types can be accessed using 5310@ref{b,,gcc_jit_context_get_type()}: 5311 5312@example 5313gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 5314@end example 5315 5316See @ref{b,,gcc_jit_context_get_type()} for the available types. 5317 5318@item 5319derived types can be accessed by using functions such as 5320@ref{7d,,gcc_jit_type_get_pointer()} and @ref{7e,,gcc_jit_type_get_const()}: 5321 5322@example 5323gcc_jit_type *const_int_star = gcc_jit_type_get_pointer (gcc_jit_type_get_const (int_type)); 5324gcc_jit_type *int_const_star = gcc_jit_type_get_const (gcc_jit_type_get_pointer (int_type)); 5325@end example 5326 5327@item 5328by creating structures (see below). 5329@end itemize 5330 5331@menu 5332* Standard types:: 5333* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 5334* Vector types:: 5335* Structures and unions:: 5336* Function pointer types:: 5337* Reflection API:: 5338 5339@end menu 5340 5341@node Standard types,Pointers const and volatile,,Types 5342@anchor{topics/types standard-types}@anchor{7f} 5343@subsection Standard types 5344 5345 5346@geindex gcc_jit_context_get_type (C function) 5347@anchor{topics/types c gcc_jit_context_get_type}@anchor{b} 5348@deffn {C Function} gcc_jit_type *gcc_jit_context_get_type (gcc_jit_context@w{ }*ctxt, enum gcc_jit_types@w{ }type_) 5349 5350Access a specific type. The available types are: 5351 5352 5353@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 5354@headitem 5355 5356@cite{enum gcc_jit_types} value 5357 5358@tab 5359 5360Meaning 5361 5362@item 5363 5364@code{GCC_JIT_TYPE_VOID} 5365 5366@tab 5367 5368C���s @code{void} type. 5369 5370@item 5371 5372@code{GCC_JIT_TYPE_VOID_PTR} 5373 5374@tab 5375 5376C���s @code{void *}. 5377 5378@item 5379 5380@code{GCC_JIT_TYPE_BOOL} 5381 5382@tab 5383 5384C++���s @code{bool} type; also C99���s 5385@code{_Bool} type, aka @code{bool} if 5386using stdbool.h. 5387 5388@item 5389 5390@code{GCC_JIT_TYPE_CHAR} 5391 5392@tab 5393 5394C���s @code{char} (of some signedness) 5395 5396@item 5397 5398@code{GCC_JIT_TYPE_SIGNED_CHAR} 5399 5400@tab 5401 5402C���s @code{signed char} 5403 5404@item 5405 5406@code{GCC_JIT_TYPE_UNSIGNED_CHAR} 5407 5408@tab 5409 5410C���s @code{unsigned char} 5411 5412@item 5413 5414@code{GCC_JIT_TYPE_SHORT} 5415 5416@tab 5417 5418C���s @code{short} (signed) 5419 5420@item 5421 5422@code{GCC_JIT_TYPE_UNSIGNED_SHORT} 5423 5424@tab 5425 5426C���s @code{unsigned short} 5427 5428@item 5429 5430@code{GCC_JIT_TYPE_INT} 5431 5432@tab 5433 5434C���s @code{int} (signed) 5435 5436@item 5437 5438@code{GCC_JIT_TYPE_UNSIGNED_INT} 5439 5440@tab 5441 5442C���s @code{unsigned int} 5443 5444@item 5445 5446@code{GCC_JIT_TYPE_LONG} 5447 5448@tab 5449 5450C���s @code{long} (signed) 5451 5452@item 5453 5454@code{GCC_JIT_TYPE_UNSIGNED_LONG} 5455 5456@tab 5457 5458C���s @code{unsigned long} 5459 5460@item 5461 5462@code{GCC_JIT_TYPE_LONG_LONG} 5463 5464@tab 5465 5466C99���s @code{long long} (signed) 5467 5468@item 5469 5470@code{GCC_JIT_TYPE_UNSIGNED_LONG_LONG} 5471 5472@tab 5473 5474C99���s @code{unsigned long long} 5475 5476@item 5477 5478@code{GCC_JIT_TYPE_UINT8_T} 5479 5480@tab 5481 5482C99���s @code{uint8_t} 5483 5484@item 5485 5486@code{GCC_JIT_TYPE_UINT16_T} 5487 5488@tab 5489 5490C99���s @code{uint16_t} 5491 5492@item 5493 5494@code{GCC_JIT_TYPE_UINT32_T} 5495 5496@tab 5497 5498C99���s @code{uint32_t} 5499 5500@item 5501 5502@code{GCC_JIT_TYPE_UINT64_T} 5503 5504@tab 5505 5506C99���s @code{uint64_t} 5507 5508@item 5509 5510@code{GCC_JIT_TYPE_UINT128_T} 5511 5512@tab 5513 5514C99���s @code{__uint128_t} 5515 5516@item 5517 5518@code{GCC_JIT_TYPE_INT8_T} 5519 5520@tab 5521 5522C99���s @code{int8_t} 5523 5524@item 5525 5526@code{GCC_JIT_TYPE_INT16_T} 5527 5528@tab 5529 5530C99���s @code{int16_t} 5531 5532@item 5533 5534@code{GCC_JIT_TYPE_INT32_T} 5535 5536@tab 5537 5538C99���s @code{int32_t} 5539 5540@item 5541 5542@code{GCC_JIT_TYPE_INT64_T} 5543 5544@tab 5545 5546C99���s @code{int64_t} 5547 5548@item 5549 5550@code{GCC_JIT_TYPE_INT128_T} 5551 5552@tab 5553 5554C99���s @code{__int128_t} 5555 5556@item 5557 5558@code{GCC_JIT_TYPE_FLOAT} 5559 5560@tab 5561 5562@item 5563 5564@code{GCC_JIT_TYPE_DOUBLE} 5565 5566@tab 5567 5568@item 5569 5570@code{GCC_JIT_TYPE_LONG_DOUBLE} 5571 5572@tab 5573 5574@item 5575 5576@code{GCC_JIT_TYPE_CONST_CHAR_PTR} 5577 5578@tab 5579 5580C type: @code{(const char *)} 5581 5582@item 5583 5584@code{GCC_JIT_TYPE_SIZE_T} 5585 5586@tab 5587 5588C���s @code{size_t} type 5589 5590@item 5591 5592@code{GCC_JIT_TYPE_FILE_PTR} 5593 5594@tab 5595 5596C type: @code{(FILE *)} 5597 5598@item 5599 5600@code{GCC_JIT_TYPE_COMPLEX_FLOAT} 5601 5602@tab 5603 5604C99���s @code{_Complex float} 5605 5606@item 5607 5608@code{GCC_JIT_TYPE_COMPLEX_DOUBLE} 5609 5610@tab 5611 5612C99���s @code{_Complex double} 5613 5614@item 5615 5616@code{GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE} 5617 5618@tab 5619 5620C99���s @code{_Complex long double} 5621 5622@end multitable 5623 5624@end deffn 5625 5626@geindex gcc_jit_context_get_int_type (C function) 5627@anchor{topics/types c gcc_jit_context_get_int_type}@anchor{80} 5628@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) 5629 5630Access the integer type of the given size. 5631@end deffn 5632 5633@node Pointers const and volatile,Vector types,Standard types,Types 5634@anchor{topics/types pointers-const-and-volatile}@anchor{81} 5635@subsection Pointers, @cite{const}, and @cite{volatile} 5636 5637 5638@geindex gcc_jit_type_get_pointer (C function) 5639@anchor{topics/types c gcc_jit_type_get_pointer}@anchor{7d} 5640@deffn {C Function} gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type@w{ }*type) 5641 5642Given type ���T���, get type ���T*���. 5643@end deffn 5644 5645@geindex gcc_jit_type_get_const (C function) 5646@anchor{topics/types c gcc_jit_type_get_const}@anchor{7e} 5647@deffn {C Function} gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type@w{ }*type) 5648 5649Given type ���T���, get type ���const T���. 5650@end deffn 5651 5652@geindex gcc_jit_type_get_volatile (C function) 5653@anchor{topics/types c gcc_jit_type_get_volatile}@anchor{82} 5654@deffn {C Function} gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type@w{ }*type) 5655 5656Given type ���T���, get type ���volatile T���. 5657@end deffn 5658 5659@geindex gcc_jit_context_new_array_type (C function) 5660@anchor{topics/types c gcc_jit_context_new_array_type}@anchor{83} 5661@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) 5662 5663Given non-@cite{void} type ���T���, get type ���T[N]��� (for a constant N). 5664@end deffn 5665 5666@geindex gcc_jit_type_get_aligned (C function) 5667@anchor{topics/types c gcc_jit_type_get_aligned}@anchor{84} 5668@deffn {C Function} gcc_jit_type * gcc_jit_type_get_aligned (gcc_jit_type@w{ }*type, size_t@w{ }alignment_in_bytes) 5669 5670Given non-@cite{void} type ���T���, get type: 5671 5672@example 5673T __attribute__ ((aligned (ALIGNMENT_IN_BYTES))) 5674@end example 5675 5676The alignment must be a power of two. 5677 5678This entrypoint was added in @ref{85,,LIBGCCJIT_ABI_7}; you can test for 5679its presence using 5680 5681@example 5682#ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_aligned 5683@end example 5684@end deffn 5685 5686@node Vector types,Structures and unions,Pointers const and volatile,Types 5687@anchor{topics/types vector-types}@anchor{86} 5688@subsection Vector types 5689 5690 5691@geindex gcc_jit_type_get_vector (C function) 5692@anchor{topics/types c gcc_jit_type_get_vector}@anchor{87} 5693@deffn {C Function} gcc_jit_type * gcc_jit_type_get_vector (gcc_jit_type@w{ }*type, size_t@w{ }num_units) 5694 5695Given type ���T���, get type: 5696 5697@example 5698T __attribute__ ((vector_size (sizeof(T) * num_units)) 5699@end example 5700 5701T must be integral or floating point; num_units must be a power of two. 5702 5703This can be used to construct a vector type in which operations 5704are applied element-wise. The compiler will automatically 5705use SIMD instructions where possible. See: 5706@indicateurl{https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html} 5707 5708For example, assuming 4-byte @code{ints}, then: 5709 5710@example 5711typedef int v4si __attribute__ ((vector_size (16))); 5712@end example 5713 5714can be obtained using: 5715 5716@example 5717gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, 5718 GCC_JIT_TYPE_INT); 5719gcc_jit_type *v4si_type = gcc_jit_type_get_vector (int_type, 4); 5720@end example 5721 5722This API entrypoint was added in @ref{88,,LIBGCCJIT_ABI_8}; you can test 5723for its presence using 5724 5725@example 5726#ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_vector 5727@end example 5728 5729Vector rvalues can be generated using 5730@ref{89,,gcc_jit_context_new_rvalue_from_vector()}. 5731@end deffn 5732 5733@node Structures and unions,Function pointer types,Vector types,Types 5734@anchor{topics/types structures-and-unions}@anchor{8a} 5735@subsection Structures and unions 5736 5737 5738@geindex gcc_jit_struct (C type) 5739@anchor{topics/types c gcc_jit_struct}@anchor{8b} 5740@deffn {C Type} gcc_jit_struct 5741@end deffn 5742 5743A compound type analagous to a C @cite{struct}. 5744 5745@geindex gcc_jit_field (C type) 5746@anchor{topics/types c gcc_jit_field}@anchor{8c} 5747@deffn {C Type} gcc_jit_field 5748@end deffn 5749 5750A field within a @ref{8b,,gcc_jit_struct}. 5751 5752You can model C @cite{struct} types by creating @ref{8b,,gcc_jit_struct} and 5753@ref{8c,,gcc_jit_field} instances, in either order: 5754 5755 5756@itemize * 5757 5758@item 5759by creating the fields, then the structure. For example, to model: 5760 5761@example 5762struct coord @{double x; double y; @}; 5763@end example 5764 5765you could call: 5766 5767@example 5768gcc_jit_field *field_x = 5769 gcc_jit_context_new_field (ctxt, NULL, double_type, "x"); 5770gcc_jit_field *field_y = 5771 gcc_jit_context_new_field (ctxt, NULL, double_type, "y"); 5772gcc_jit_field *fields[2] = @{field_x, field_y@}; 5773gcc_jit_struct *coord = 5774 gcc_jit_context_new_struct_type (ctxt, NULL, "coord", 2, fields); 5775@end example 5776 5777@item 5778by creating the structure, then populating it with fields, typically 5779to allow modelling self-referential structs such as: 5780 5781@example 5782struct node @{ int m_hash; struct node *m_next; @}; 5783@end example 5784 5785like this: 5786 5787@example 5788gcc_jit_type *node = 5789 gcc_jit_context_new_opaque_struct (ctxt, NULL, "node"); 5790gcc_jit_type *node_ptr = 5791 gcc_jit_type_get_pointer (node); 5792gcc_jit_field *field_hash = 5793 gcc_jit_context_new_field (ctxt, NULL, int_type, "m_hash"); 5794gcc_jit_field *field_next = 5795 gcc_jit_context_new_field (ctxt, NULL, node_ptr, "m_next"); 5796gcc_jit_field *fields[2] = @{field_hash, field_next@}; 5797gcc_jit_struct_set_fields (node, NULL, 2, fields); 5798@end example 5799@end itemize 5800 5801@geindex gcc_jit_context_new_field (C function) 5802@anchor{topics/types c gcc_jit_context_new_field}@anchor{8d} 5803@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) 5804 5805Construct a new field, with the given type and name. 5806 5807The parameter @code{type} must be non-@cite{void}. 5808 5809The parameter @code{name} must be non-NULL. The call takes a copy of the 5810underlying string, so it is valid to pass in a pointer to an on-stack 5811buffer. 5812@end deffn 5813 5814@geindex gcc_jit_context_new_bitfield (C function) 5815@anchor{topics/types c gcc_jit_context_new_bitfield}@anchor{8e} 5816@deffn {C Function} gcc_jit_field * gcc_jit_context_new_bitfield (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, int@w{ }width, const char@w{ }*name) 5817 5818Construct a new bit field, with the given type width and name. 5819 5820The parameter @code{name} must be non-NULL. The call takes a copy of the 5821underlying string, so it is valid to pass in a pointer to an on-stack 5822buffer. 5823 5824The parameter @code{type} must be an integer type. 5825 5826The parameter @code{width} must be a positive integer that does not exceed the 5827size of @code{type}. 5828 5829This API entrypoint was added in @ref{8f,,LIBGCCJIT_ABI_12}; you can test 5830for its presence using 5831 5832@example 5833#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield 5834@end example 5835@end deffn 5836 5837@geindex gcc_jit_field_as_object (C function) 5838@anchor{topics/types c gcc_jit_field_as_object}@anchor{90} 5839@deffn {C Function} gcc_jit_object * gcc_jit_field_as_object (gcc_jit_field@w{ }*field) 5840 5841Upcast from field to object. 5842@end deffn 5843 5844@geindex gcc_jit_context_new_struct_type (C function) 5845@anchor{topics/types c gcc_jit_context_new_struct_type}@anchor{91} 5846@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) 5847 5848@quotation 5849 5850Construct a new struct type, with the given name and fields. 5851 5852The parameter @code{name} must be non-NULL. The call takes a copy of 5853the underlying string, so it is valid to pass in a pointer to an 5854on-stack buffer. 5855@end quotation 5856@end deffn 5857 5858@geindex gcc_jit_context_new_opaque_struct (C function) 5859@anchor{topics/types c gcc_jit_context_new_opaque_struct}@anchor{92} 5860@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) 5861 5862Construct a new struct type, with the given name, but without 5863specifying the fields. The fields can be omitted (in which case the 5864size of the struct is not known), or later specified using 5865@ref{93,,gcc_jit_struct_set_fields()}. 5866 5867The parameter @code{name} must be non-NULL. The call takes a copy of 5868the underlying string, so it is valid to pass in a pointer to an 5869on-stack buffer. 5870@end deffn 5871 5872@geindex gcc_jit_struct_as_type (C function) 5873@anchor{topics/types c gcc_jit_struct_as_type}@anchor{94} 5874@deffn {C Function} gcc_jit_type * gcc_jit_struct_as_type (gcc_jit_struct@w{ }*struct_type) 5875 5876Upcast from struct to type. 5877@end deffn 5878 5879@geindex gcc_jit_struct_set_fields (C function) 5880@anchor{topics/types c gcc_jit_struct_set_fields}@anchor{93} 5881@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) 5882 5883Populate the fields of a formerly-opaque struct type. 5884 5885This can only be called once on a given struct type. 5886@end deffn 5887 5888@geindex gcc_jit_context_new_union_type (C function) 5889@anchor{topics/types c gcc_jit_context_new_union_type}@anchor{95} 5890@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) 5891 5892Construct a new union type, with the given name and fields. 5893 5894The parameter @code{name} must be non-NULL. It is copied, so the input 5895buffer does not need to outlive the call. 5896 5897Example of use: 5898 5899@example 5900 5901union int_or_float 5902@{ 5903 int as_int; 5904 float as_float; 5905@}; 5906 5907void 5908create_code (gcc_jit_context *ctxt, void *user_data) 5909@{ 5910 /* Let's try to inject the equivalent of: 5911 float 5912 test_union (int i) 5913 @{ 5914 union int_or_float u; 5915 u.as_int = i; 5916 return u.as_float; 5917 @} 5918 */ 5919 gcc_jit_type *int_type = 5920 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 5921 gcc_jit_type *float_type = 5922 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); 5923 gcc_jit_field *as_int = 5924 gcc_jit_context_new_field (ctxt, 5925 NULL, 5926 int_type, 5927 "as_int"); 5928 gcc_jit_field *as_float = 5929 gcc_jit_context_new_field (ctxt, 5930 NULL, 5931 float_type, 5932 "as_float"); 5933 gcc_jit_field *fields[] = @{as_int, as_float@}; 5934 gcc_jit_type *union_type = 5935 gcc_jit_context_new_union_type (ctxt, NULL, 5936 "int_or_float", 2, fields); 5937 5938 /* Build the test function. */ 5939 gcc_jit_param *param_i = 5940 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 5941 gcc_jit_function *test_fn = 5942 gcc_jit_context_new_function (ctxt, NULL, 5943 GCC_JIT_FUNCTION_EXPORTED, 5944 float_type, 5945 "test_union", 5946 1, ¶m_i, 5947 0); 5948 5949 gcc_jit_lvalue *u = 5950 gcc_jit_function_new_local (test_fn, NULL, 5951 union_type, "u"); 5952 5953 gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); 5954 5955 /* u.as_int = i; */ 5956 gcc_jit_block_add_assignment ( 5957 block, 5958 NULL, 5959 /* "u.as_int = ..." */ 5960 gcc_jit_lvalue_access_field (u, 5961 NULL, 5962 as_int), 5963 gcc_jit_param_as_rvalue (param_i)); 5964 5965 /* return u.as_float; */ 5966 gcc_jit_block_end_with_return ( 5967 block, NULL, 5968 gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (u), 5969 NULL, 5970 as_float)); 5971@} 5972 5973@end example 5974@end deffn 5975 5976@node Function pointer types,Reflection API,Structures and unions,Types 5977@anchor{topics/types function-pointer-types}@anchor{96} 5978@subsection Function pointer types 5979 5980 5981Function pointer types can be created using 5982@ref{97,,gcc_jit_context_new_function_ptr_type()}. 5983 5984@node Reflection API,,Function pointer types,Types 5985@anchor{topics/types reflection-api}@anchor{98} 5986@subsection Reflection API 5987 5988 5989@geindex gcc_jit_type_dyncast_array (C function) 5990@anchor{topics/types c gcc_jit_type_dyncast_array}@anchor{99} 5991@deffn {C Function} gcc_jit_type * gcc_jit_type_dyncast_array (gcc_jit_type@w{ }*type) 5992 5993Get the element type of an array type or NULL if it���s not an array. 5994@end deffn 5995 5996@geindex gcc_jit_type_is_bool (C function) 5997@anchor{topics/types c gcc_jit_type_is_bool}@anchor{9a} 5998@deffn {C Function} int gcc_jit_type_is_bool (gcc_jit_type@w{ }*type) 5999 6000Return non-zero if the type is a bool. 6001@end deffn 6002 6003@geindex gcc_jit_type_dyncast_function_ptr_type (C function) 6004@anchor{topics/types c gcc_jit_type_dyncast_function_ptr_type}@anchor{9b} 6005@deffn {C Function} gcc_jit_function_type * gcc_jit_type_dyncast_function_ptr_type (gcc_jit_type@w{ }*type) 6006 6007Return the function type if it is one or NULL. 6008@end deffn 6009 6010@geindex gcc_jit_function_type_get_return_type (C function) 6011@anchor{topics/types c gcc_jit_function_type_get_return_type}@anchor{9c} 6012@deffn {C Function} gcc_jit_type * gcc_jit_function_type_get_return_type (gcc_jit_function_type@w{ }*function_type) 6013 6014Given a function type, return its return type. 6015@end deffn 6016 6017@geindex gcc_jit_function_type_get_param_count (C function) 6018@anchor{topics/types c gcc_jit_function_type_get_param_count}@anchor{9d} 6019@deffn {C Function} size_t gcc_jit_function_type_get_param_count (gcc_jit_function_type@w{ }*function_type) 6020 6021Given a function type, return its number of parameters. 6022@end deffn 6023 6024@geindex gcc_jit_function_type_get_param_type (C function) 6025@anchor{topics/types c gcc_jit_function_type_get_param_type}@anchor{9e} 6026@deffn {C Function} gcc_jit_type * gcc_jit_function_type_get_param_type (gcc_jit_function_type@w{ }*function_type, size_t@w{ }index) 6027 6028Given a function type, return the type of the specified parameter. 6029@end deffn 6030 6031@geindex gcc_jit_type_is_integral (C function) 6032@anchor{topics/types c gcc_jit_type_is_integral}@anchor{9f} 6033@deffn {C Function} int gcc_jit_type_is_integral (gcc_jit_type@w{ }*type) 6034 6035Return non-zero if the type is an integral. 6036@end deffn 6037 6038@geindex gcc_jit_type_is_pointer (C function) 6039@anchor{topics/types c gcc_jit_type_is_pointer}@anchor{a0} 6040@deffn {C Function} gcc_jit_type * gcc_jit_type_is_pointer (gcc_jit_type@w{ }*type) 6041 6042Return the type pointed by the pointer type or NULL if it���s not a pointer. 6043@end deffn 6044 6045@geindex gcc_jit_type_dyncast_vector (C function) 6046@anchor{topics/types c gcc_jit_type_dyncast_vector}@anchor{a1} 6047@deffn {C Function} gcc_jit_vector_type * gcc_jit_type_dyncast_vector (gcc_jit_type@w{ }*type) 6048 6049Given a type, return a dynamic cast to a vector type or NULL. 6050@end deffn 6051 6052@geindex gcc_jit_type_is_struct (C function) 6053@anchor{topics/types c gcc_jit_type_is_struct}@anchor{a2} 6054@deffn {C Function} gcc_jit_struct * gcc_jit_type_is_struct (gcc_jit_type@w{ }*type) 6055 6056Given a type, return a dynamic cast to a struct type or NULL. 6057@end deffn 6058 6059@geindex gcc_jit_vector_type_get_num_units (C function) 6060@anchor{topics/types c gcc_jit_vector_type_get_num_units}@anchor{a3} 6061@deffn {C Function} size_t gcc_jit_vector_type_get_num_units (gcc_jit_vector_type@w{ }*vector_type) 6062 6063Given a vector type, return the number of units it contains. 6064@end deffn 6065 6066@geindex gcc_jit_vector_type_get_element_type (C function) 6067@anchor{topics/types c gcc_jit_vector_type_get_element_type}@anchor{a4} 6068@deffn {C Function} gcc_jit_type * gcc_jit_vector_type_get_element_type (gcc_jit_vector_type *@w{ }vector_type) 6069 6070Given a vector type, return the type of its elements. 6071@end deffn 6072 6073@geindex gcc_jit_type_unqualified (C function) 6074@anchor{topics/types c gcc_jit_type_unqualified}@anchor{a5} 6075@deffn {C Function} gcc_jit_type * gcc_jit_type_unqualified (gcc_jit_type@w{ }*type) 6076 6077Given a type, return the unqualified type, removing ���const���, ���volatile��� and 6078alignment qualifiers. 6079@end deffn 6080 6081@geindex gcc_jit_struct_get_field (C function) 6082@anchor{topics/types c gcc_jit_struct_get_field}@anchor{a6} 6083@deffn {C Function} gcc_jit_field * gcc_jit_struct_get_field (gcc_jit_struct@w{ }*struct_type, size_t@w{ }index) 6084 6085Get a struct field by index. 6086@end deffn 6087 6088@geindex gcc_jit_struct_get_field_count (C function) 6089@anchor{topics/types c gcc_jit_struct_get_field_count}@anchor{a7} 6090@deffn {C Function} size_t gcc_jit_struct_get_field_count (gcc_jit_struct@w{ }*struct_type) 6091 6092@quotation 6093 6094Get the number of fields in the struct. 6095@end quotation 6096 6097The API entrypoints related to the reflection API: 6098 6099@quotation 6100 6101 6102@itemize * 6103 6104@item 6105@ref{9c,,gcc_jit_function_type_get_return_type()} 6106 6107@item 6108@ref{9d,,gcc_jit_function_type_get_param_count()} 6109 6110@item 6111@ref{9e,,gcc_jit_function_type_get_param_type()} 6112 6113@item 6114@ref{a5,,gcc_jit_type_unqualified()} 6115 6116@item 6117@ref{99,,gcc_jit_type_dyncast_array()} 6118 6119@item 6120@ref{9a,,gcc_jit_type_is_bool()} 6121 6122@item 6123@ref{9b,,gcc_jit_type_dyncast_function_ptr_type()} 6124 6125@item 6126@ref{9f,,gcc_jit_type_is_integral()} 6127 6128@item 6129@ref{a0,,gcc_jit_type_is_pointer()} 6130 6131@item 6132@ref{a1,,gcc_jit_type_dyncast_vector()} 6133 6134@item 6135@ref{a4,,gcc_jit_vector_type_get_element_type()} 6136 6137@item 6138@ref{a3,,gcc_jit_vector_type_get_num_units()} 6139 6140@item 6141@ref{a6,,gcc_jit_struct_get_field()} 6142 6143@item 6144@ref{a2,,gcc_jit_type_is_struct()} 6145 6146@item 6147@ref{a7,,gcc_jit_struct_get_field_count()} 6148@end itemize 6149@end quotation 6150 6151were added in @ref{a8,,LIBGCCJIT_ABI_16}; you can test for their presence 6152using 6153 6154@example 6155#ifdef LIBGCCJIT_HAVE_REFLECTION 6156@end example 6157 6158@geindex gcc_jit_case (C type) 6159@anchor{topics/types c gcc_jit_case}@anchor{a9} 6160@deffn {C Type} gcc_jit_case 6161@end deffn 6162@end deffn 6163 6164@geindex gcc_jit_compatible_types (C function) 6165@anchor{topics/types c gcc_jit_compatible_types}@anchor{aa} 6166@deffn {C Function} int gcc_jit_compatible_types (gcc_jit_type@w{ }*ltype, gcc_jit_type@w{ }*rtype) 6167 6168@quotation 6169 6170Return non-zero if the two types are compatible. For instance, 6171if @code{GCC_JIT_TYPE_UINT64_T} and @code{GCC_JIT_TYPE_UNSIGNED_LONG} 6172are the same size on the target, this will return non-zero. 6173The parameters @code{ltype} and @code{rtype} must be non-NULL. 6174Return 0 on errors. 6175@end quotation 6176 6177This entrypoint was added in @ref{ab,,LIBGCCJIT_ABI_20}; you can test for 6178its presence using 6179 6180@example 6181#ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS 6182@end example 6183@end deffn 6184 6185@geindex gcc_jit_type_get_size (C function) 6186@anchor{topics/types c gcc_jit_type_get_size}@anchor{ac} 6187@deffn {C Function} ssize_t gcc_jit_type_get_size (gcc_jit_type@w{ }*type) 6188 6189@quotation 6190 6191Return the size of a type, in bytes. It only works on integer types for now. 6192The parameter @code{type} must be non-NULL. 6193Return -1 on errors. 6194@end quotation 6195 6196This entrypoint was added in @ref{ab,,LIBGCCJIT_ABI_20}; you can test for 6197its presence using 6198 6199@example 6200#ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS 6201@end example 6202@end deffn 6203 6204@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 6205@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 6206@c 6207@c This is free software: you can redistribute it and/or modify it 6208@c under the terms of the GNU General Public License as published by 6209@c the Free Software Foundation, either version 3 of the License, or 6210@c (at your option) any later version. 6211@c 6212@c This program is distributed in the hope that it will be useful, but 6213@c WITHOUT ANY WARRANTY; without even the implied warranty of 6214@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 6215@c General Public License for more details. 6216@c 6217@c You should have received a copy of the GNU General Public License 6218@c along with this program. If not, see 6219@c <https://www.gnu.org/licenses/>. 6220 6221@node Expressions,Creating and using functions,Types,Topic Reference 6222@anchor{topics/expressions doc}@anchor{ad}@anchor{topics/expressions expressions}@anchor{ae} 6223@section Expressions 6224 6225 6226@menu 6227* Rvalues:: 6228* Lvalues:: 6229* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 6230 6231@end menu 6232 6233@node Rvalues,Lvalues,,Expressions 6234@anchor{topics/expressions rvalues}@anchor{af} 6235@subsection Rvalues 6236 6237 6238@geindex gcc_jit_rvalue (C type) 6239@anchor{topics/expressions c gcc_jit_rvalue}@anchor{13} 6240@deffn {C Type} gcc_jit_rvalue 6241@end deffn 6242 6243A @ref{13,,gcc_jit_rvalue} is an expression that can be computed. 6244 6245It can be simple, e.g.: 6246 6247@quotation 6248 6249 6250@itemize * 6251 6252@item 6253an integer value e.g. @cite{0} or @cite{42} 6254 6255@item 6256a string literal e.g. @cite{���Hello world���} 6257 6258@item 6259a variable e.g. @cite{i}. These are also lvalues (see below). 6260@end itemize 6261@end quotation 6262 6263or compound e.g.: 6264 6265@quotation 6266 6267 6268@itemize * 6269 6270@item 6271a unary expression e.g. @cite{!cond} 6272 6273@item 6274a binary expression e.g. @cite{(a + b)} 6275 6276@item 6277a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} 6278 6279@item 6280etc. 6281@end itemize 6282@end quotation 6283 6284Every rvalue has an associated type, and the API will check to ensure 6285that types match up correctly (otherwise the context will emit an error). 6286 6287@geindex gcc_jit_rvalue_get_type (C function) 6288@anchor{topics/expressions c gcc_jit_rvalue_get_type}@anchor{b0} 6289@deffn {C Function} gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue@w{ }*rvalue) 6290 6291Get the type of this rvalue. 6292@end deffn 6293 6294@geindex gcc_jit_rvalue_as_object (C function) 6295@anchor{topics/expressions c gcc_jit_rvalue_as_object}@anchor{14} 6296@deffn {C Function} gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue@w{ }*rvalue) 6297 6298Upcast the given rvalue to be an object. 6299@end deffn 6300 6301@menu 6302* Simple expressions:: 6303* Constructor expressions:: 6304* Vector expressions:: 6305* Unary Operations:: 6306* Binary Operations:: 6307* Comparisons:: 6308* Function calls:: 6309* Function pointers:: 6310* Type-coercion:: 6311 6312@end menu 6313 6314@node Simple expressions,Constructor expressions,,Rvalues 6315@anchor{topics/expressions simple-expressions}@anchor{b1} 6316@subsubsection Simple expressions 6317 6318 6319@geindex gcc_jit_context_new_rvalue_from_int (C function) 6320@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_int}@anchor{30} 6321@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) 6322 6323Given a numeric type (integer or floating point), build an rvalue for 6324the given constant @code{int} value. 6325@end deffn 6326 6327@geindex gcc_jit_context_new_rvalue_from_long (C function) 6328@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_long}@anchor{b2} 6329@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) 6330 6331Given a numeric type (integer or floating point), build an rvalue for 6332the given constant @code{long} value. 6333@end deffn 6334 6335@geindex gcc_jit_context_zero (C function) 6336@anchor{topics/expressions c gcc_jit_context_zero}@anchor{2b} 6337@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) 6338 6339Given a numeric type (integer or floating point), get the rvalue for 6340zero. Essentially this is just a shortcut for: 6341 6342@example 6343gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0) 6344@end example 6345@end deffn 6346 6347@geindex gcc_jit_context_one (C function) 6348@anchor{topics/expressions c gcc_jit_context_one}@anchor{2f} 6349@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_one (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) 6350 6351Given a numeric type (integer or floating point), get the rvalue for 6352one. Essentially this is just a shortcut for: 6353 6354@example 6355gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1) 6356@end example 6357@end deffn 6358 6359@geindex gcc_jit_context_new_rvalue_from_double (C function) 6360@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_double}@anchor{31} 6361@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) 6362 6363Given a numeric type (integer or floating point), build an rvalue for 6364the given constant @code{double} value. 6365@end deffn 6366 6367@geindex gcc_jit_context_new_rvalue_from_ptr (C function) 6368@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_ptr}@anchor{b3} 6369@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) 6370 6371Given a pointer type, build an rvalue for the given address. 6372@end deffn 6373 6374@geindex gcc_jit_context_null (C function) 6375@anchor{topics/expressions c gcc_jit_context_null}@anchor{b4} 6376@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type) 6377 6378Given a pointer type, build an rvalue for @code{NULL}. Essentially this 6379is just a shortcut for: 6380 6381@example 6382gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL) 6383@end example 6384@end deffn 6385 6386@geindex gcc_jit_context_new_string_literal (C function) 6387@anchor{topics/expressions c gcc_jit_context_new_string_literal}@anchor{b5} 6388@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_string_literal (gcc_jit_context@w{ }*ctxt, const char@w{ }*value) 6389 6390Generate an rvalue for the given NIL-terminated string, of type 6391@code{GCC_JIT_TYPE_CONST_CHAR_PTR}. 6392 6393The parameter @code{value} must be non-NULL. The call takes a copy of the 6394underlying string, so it is valid to pass in a pointer to an on-stack 6395buffer. 6396@end deffn 6397 6398@node Constructor expressions,Vector expressions,Simple expressions,Rvalues 6399@anchor{topics/expressions constructor-expressions}@anchor{b6} 6400@subsubsection Constructor expressions 6401 6402 6403@quotation 6404 6405The following functions make constructors for array, struct and union 6406types. 6407 6408The constructor rvalue can be used for assignment to locals. 6409It can be used to initialize global variables with 6410@ref{b7,,gcc_jit_global_set_initializer_rvalue()}. It can also be used as a 6411temporary value for function calls and return values, but its address 6412can���t be taken. 6413 6414Note that arrays in libgccjit do not collapse to pointers like in 6415C. I.e. if an array constructor is used as e.g. a return value, the whole 6416array would be returned by value - array constructors can be assigned to 6417array variables. 6418 6419The constructor can contain nested constructors. 6420 6421Note that a string literal rvalue can���t be used to construct a char array; 6422the latter needs one rvalue for each char. 6423 6424These entrypoints were added in @ref{b8,,LIBGCCJIT_ABI_19}; you can test for 6425their presence using: 6426 6427@example 6428#ifdef LIBGCCJIT_HAVE_CTORS 6429@end example 6430@end quotation 6431 6432@geindex gcc_jit_context_new_array_constructor (C function) 6433@anchor{topics/expressions c gcc_jit_context_new_array_constructor}@anchor{b9} 6434@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_array_constructor (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, size_t@w{ }num_values, gcc_jit_rvalue@w{ }**values) 6435 6436Create a constructor for an array as an rvalue. 6437 6438Returns NULL on error. @code{values} are copied and 6439do not have to outlive the context. 6440 6441@code{type} specifies what the constructor will build and has to be 6442an array. 6443 6444@code{num_values} specifies the number of elements in @code{values} and 6445it can���t have more elements than the array type. 6446 6447Each value in @code{values} sets the corresponding value in the array. 6448If the array type itself has more elements than @code{values}, the 6449left-over elements will be zeroed. 6450 6451Each value in @code{values} need to be the same unqualified type as the 6452array type���s element type. 6453 6454If @code{num_values} is 0, the @code{values} parameter will be 6455ignored and zero initialization will be used. 6456 6457This entrypoint was added in @ref{b8,,LIBGCCJIT_ABI_19}; you can test for its 6458presence using: 6459 6460@example 6461#ifdef LIBGCCJIT_HAVE_CTORS 6462@end example 6463@end deffn 6464 6465@geindex gcc_jit_context_new_struct_constructor (C function) 6466@anchor{topics/expressions c gcc_jit_context_new_struct_constructor}@anchor{ba} 6467@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_struct_constructor (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, size_t@w{ }num_values, gcc_jit_field@w{ }**fields, gcc_jit_rvalue@w{ }**values) 6468 6469Create a constructor for a struct as an rvalue. 6470 6471Returns NULL on error. The two parameter arrays are copied and 6472do not have to outlive the context. 6473 6474@code{type} specifies what the constructor will build and has to be 6475a struct. 6476 6477@code{num_values} specifies the number of elements in @code{values}. 6478 6479@code{fields} need to have the same length as @code{values}, or be NULL. 6480 6481If @code{fields} is null, the values are applied in definition order. 6482 6483Otherwise, each field in @code{fields} specifies which field in the struct to 6484set to the corresponding value in @code{values}. @code{fields} and @code{values} 6485are paired by index. 6486 6487The fields in @code{fields} have to be in definition order, but there 6488can be gaps. Any field in the struct that is not specified in 6489@code{fields} will be zeroed. 6490 6491The fields in @code{fields} need to be the same objects that were used 6492to create the struct. 6493 6494Each value has to have have the same unqualified type as the field 6495it is applied to. 6496 6497A NULL value element in @code{values} is a shorthand for zero initialization 6498of the corresponding field. 6499 6500If @code{num_values} is 0, the array parameters will be 6501ignored and zero initialization will be used. 6502 6503This entrypoint was added in @ref{b8,,LIBGCCJIT_ABI_19}; you can test for its 6504presence using: 6505 6506@example 6507#ifdef LIBGCCJIT_HAVE_CTORS 6508@end example 6509@end deffn 6510 6511@geindex gcc_jit_context_new_union_constructor (C function) 6512@anchor{topics/expressions c gcc_jit_context_new_union_constructor}@anchor{bb} 6513@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_union_constructor (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, gcc_jit_field@w{ }*field, gcc_jit_rvalue@w{ }*value) 6514 6515Create a constructor for a union as an rvalue. 6516 6517Returns NULL on error. 6518 6519@code{type} specifies what the constructor will build and has to be 6520an union. 6521 6522@code{field} specifies which field to set. If it is NULL, the first 6523field in the union will be set.`@w{`}field`@w{`} need to be the same object 6524that were used to create the union. 6525 6526@code{value} specifies what value to set the corresponding field to. 6527If @code{value} is NULL, zero initialization will be used. 6528 6529Each value has to have have the same unqualified type as the field 6530it is applied to. 6531 6532This entrypoint was added in @ref{b8,,LIBGCCJIT_ABI_19}; you can test for its 6533presence using: 6534 6535@example 6536#ifdef LIBGCCJIT_HAVE_CTORS 6537@end example 6538@end deffn 6539 6540@node Vector expressions,Unary Operations,Constructor expressions,Rvalues 6541@anchor{topics/expressions vector-expressions}@anchor{bc} 6542@subsubsection Vector expressions 6543 6544 6545@geindex gcc_jit_context_new_rvalue_from_vector (C function) 6546@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_vector}@anchor{89} 6547@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) 6548 6549Build a vector rvalue from an array of elements. 6550 6551���vec_type��� should be a vector type, created using 6552@ref{87,,gcc_jit_type_get_vector()}. 6553 6554���num_elements��� should match that of the vector type. 6555 6556This entrypoint was added in @ref{bd,,LIBGCCJIT_ABI_10}; you can test for 6557its presence using 6558 6559@example 6560#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector 6561@end example 6562@end deffn 6563 6564@node Unary Operations,Binary Operations,Vector expressions,Rvalues 6565@anchor{topics/expressions unary-operations}@anchor{be} 6566@subsubsection Unary Operations 6567 6568 6569@geindex gcc_jit_context_new_unary_op (C function) 6570@anchor{topics/expressions c gcc_jit_context_new_unary_op}@anchor{bf} 6571@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) 6572 6573Build a unary operation out of an input rvalue. 6574 6575The parameter @code{result_type} must be a numeric type. 6576@end deffn 6577 6578@geindex gcc_jit_unary_op (C type) 6579@anchor{topics/expressions c gcc_jit_unary_op}@anchor{c0} 6580@deffn {C Type} enum gcc_jit_unary_op 6581@end deffn 6582 6583The available unary operations are: 6584 6585 6586@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6587@headitem 6588 6589Unary Operation 6590 6591@tab 6592 6593C equivalent 6594 6595@item 6596 6597@ref{c1,,GCC_JIT_UNARY_OP_MINUS} 6598 6599@tab 6600 6601@cite{-(EXPR)} 6602 6603@item 6604 6605@ref{c2,,GCC_JIT_UNARY_OP_BITWISE_NEGATE} 6606 6607@tab 6608 6609@cite{~(EXPR)} 6610 6611@item 6612 6613@ref{c3,,GCC_JIT_UNARY_OP_LOGICAL_NEGATE} 6614 6615@tab 6616 6617@cite{!(EXPR)} 6618 6619@item 6620 6621@ref{c4,,GCC_JIT_UNARY_OP_ABS} 6622 6623@tab 6624 6625@cite{abs (EXPR)} 6626 6627@end multitable 6628 6629 6630@geindex GCC_JIT_UNARY_OP_MINUS (C macro) 6631@anchor{topics/expressions c GCC_JIT_UNARY_OP_MINUS}@anchor{c1} 6632@deffn {C Macro} GCC_JIT_UNARY_OP_MINUS 6633 6634Negate an arithmetic value; analogous to: 6635 6636@example 6637-(EXPR) 6638@end example 6639 6640in C. 6641@end deffn 6642 6643@geindex GCC_JIT_UNARY_OP_BITWISE_NEGATE (C macro) 6644@anchor{topics/expressions c GCC_JIT_UNARY_OP_BITWISE_NEGATE}@anchor{c2} 6645@deffn {C Macro} GCC_JIT_UNARY_OP_BITWISE_NEGATE 6646 6647Bitwise negation of an integer value (one���s complement); analogous 6648to: 6649 6650@example 6651~(EXPR) 6652@end example 6653 6654in C. 6655@end deffn 6656 6657@geindex GCC_JIT_UNARY_OP_LOGICAL_NEGATE (C macro) 6658@anchor{topics/expressions c GCC_JIT_UNARY_OP_LOGICAL_NEGATE}@anchor{c3} 6659@deffn {C Macro} GCC_JIT_UNARY_OP_LOGICAL_NEGATE 6660 6661Logical negation of an arithmetic or pointer value; analogous to: 6662 6663@example 6664!(EXPR) 6665@end example 6666 6667in C. 6668@end deffn 6669 6670@geindex GCC_JIT_UNARY_OP_ABS (C macro) 6671@anchor{topics/expressions c GCC_JIT_UNARY_OP_ABS}@anchor{c4} 6672@deffn {C Macro} GCC_JIT_UNARY_OP_ABS 6673 6674Absolute value of an arithmetic expression; analogous to: 6675 6676@example 6677abs (EXPR) 6678@end example 6679 6680in C. 6681@end deffn 6682 6683@node Binary Operations,Comparisons,Unary Operations,Rvalues 6684@anchor{topics/expressions binary-operations}@anchor{c5} 6685@subsubsection Binary Operations 6686 6687 6688@geindex gcc_jit_context_new_binary_op (C function) 6689@anchor{topics/expressions c gcc_jit_context_new_binary_op}@anchor{12} 6690@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) 6691 6692Build a binary operation out of two constituent rvalues. 6693 6694The parameter @code{result_type} must be a numeric type. 6695@end deffn 6696 6697@geindex gcc_jit_binary_op (C type) 6698@anchor{topics/expressions c gcc_jit_binary_op}@anchor{c6} 6699@deffn {C Type} enum gcc_jit_binary_op 6700@end deffn 6701 6702The available binary operations are: 6703 6704 6705@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6706@headitem 6707 6708Binary Operation 6709 6710@tab 6711 6712C equivalent 6713 6714@item 6715 6716@ref{c7,,GCC_JIT_BINARY_OP_PLUS} 6717 6718@tab 6719 6720@cite{x + y} 6721 6722@item 6723 6724@ref{c8,,GCC_JIT_BINARY_OP_MINUS} 6725 6726@tab 6727 6728@cite{x - y} 6729 6730@item 6731 6732@ref{c9,,GCC_JIT_BINARY_OP_MULT} 6733 6734@tab 6735 6736@cite{x * y} 6737 6738@item 6739 6740@ref{ca,,GCC_JIT_BINARY_OP_DIVIDE} 6741 6742@tab 6743 6744@cite{x / y} 6745 6746@item 6747 6748@ref{cb,,GCC_JIT_BINARY_OP_MODULO} 6749 6750@tab 6751 6752@cite{x % y} 6753 6754@item 6755 6756@ref{cc,,GCC_JIT_BINARY_OP_BITWISE_AND} 6757 6758@tab 6759 6760@cite{x & y} 6761 6762@item 6763 6764@ref{cd,,GCC_JIT_BINARY_OP_BITWISE_XOR} 6765 6766@tab 6767 6768@cite{x ^ y} 6769 6770@item 6771 6772@ref{ce,,GCC_JIT_BINARY_OP_BITWISE_OR} 6773 6774@tab 6775 6776@cite{x | y} 6777 6778@item 6779 6780@ref{cf,,GCC_JIT_BINARY_OP_LOGICAL_AND} 6781 6782@tab 6783 6784@cite{x && y} 6785 6786@item 6787 6788@ref{d0,,GCC_JIT_BINARY_OP_LOGICAL_OR} 6789 6790@tab 6791 6792@cite{x || y} 6793 6794@item 6795 6796@ref{d1,,GCC_JIT_BINARY_OP_LSHIFT} 6797 6798@tab 6799 6800@cite{x << y} 6801 6802@item 6803 6804@ref{d2,,GCC_JIT_BINARY_OP_RSHIFT} 6805 6806@tab 6807 6808@cite{x >> y} 6809 6810@end multitable 6811 6812 6813@geindex GCC_JIT_BINARY_OP_PLUS (C macro) 6814@anchor{topics/expressions c GCC_JIT_BINARY_OP_PLUS}@anchor{c7} 6815@deffn {C Macro} GCC_JIT_BINARY_OP_PLUS 6816 6817Addition of arithmetic values; analogous to: 6818 6819@example 6820(EXPR_A) + (EXPR_B) 6821@end example 6822 6823in C. 6824 6825For pointer addition, use @ref{d3,,gcc_jit_context_new_array_access()}. 6826@end deffn 6827 6828@geindex GCC_JIT_BINARY_OP_MINUS (C macro) 6829@anchor{topics/expressions c GCC_JIT_BINARY_OP_MINUS}@anchor{c8} 6830@deffn {C Macro} GCC_JIT_BINARY_OP_MINUS 6831 6832Subtraction of arithmetic values; analogous to: 6833 6834@example 6835(EXPR_A) - (EXPR_B) 6836@end example 6837 6838in C. 6839@end deffn 6840 6841@geindex GCC_JIT_BINARY_OP_MULT (C macro) 6842@anchor{topics/expressions c GCC_JIT_BINARY_OP_MULT}@anchor{c9} 6843@deffn {C Macro} GCC_JIT_BINARY_OP_MULT 6844 6845Multiplication of a pair of arithmetic values; analogous to: 6846 6847@example 6848(EXPR_A) * (EXPR_B) 6849@end example 6850 6851in C. 6852@end deffn 6853 6854@geindex GCC_JIT_BINARY_OP_DIVIDE (C macro) 6855@anchor{topics/expressions c GCC_JIT_BINARY_OP_DIVIDE}@anchor{ca} 6856@deffn {C Macro} GCC_JIT_BINARY_OP_DIVIDE 6857 6858Quotient of division of arithmetic values; analogous to: 6859 6860@example 6861(EXPR_A) / (EXPR_B) 6862@end example 6863 6864in C. 6865 6866The result type affects the kind of division: if the result type is 6867integer-based, then the result is truncated towards zero, whereas 6868a floating-point result type indicates floating-point division. 6869@end deffn 6870 6871@geindex GCC_JIT_BINARY_OP_MODULO (C macro) 6872@anchor{topics/expressions c GCC_JIT_BINARY_OP_MODULO}@anchor{cb} 6873@deffn {C Macro} GCC_JIT_BINARY_OP_MODULO 6874 6875Remainder of division of arithmetic values; analogous to: 6876 6877@example 6878(EXPR_A) % (EXPR_B) 6879@end example 6880 6881in C. 6882@end deffn 6883 6884@geindex GCC_JIT_BINARY_OP_BITWISE_AND (C macro) 6885@anchor{topics/expressions c GCC_JIT_BINARY_OP_BITWISE_AND}@anchor{cc} 6886@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_AND 6887 6888Bitwise AND; analogous to: 6889 6890@example 6891(EXPR_A) & (EXPR_B) 6892@end example 6893 6894in C. 6895@end deffn 6896 6897@geindex GCC_JIT_BINARY_OP_BITWISE_XOR (C macro) 6898@anchor{topics/expressions c GCC_JIT_BINARY_OP_BITWISE_XOR}@anchor{cd} 6899@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_XOR 6900 6901Bitwise exclusive OR; analogous to: 6902 6903@example 6904(EXPR_A) ^ (EXPR_B) 6905@end example 6906 6907in C. 6908@end deffn 6909 6910@geindex GCC_JIT_BINARY_OP_BITWISE_OR (C macro) 6911@anchor{topics/expressions c GCC_JIT_BINARY_OP_BITWISE_OR}@anchor{ce} 6912@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_OR 6913 6914Bitwise inclusive OR; analogous to: 6915 6916@example 6917(EXPR_A) | (EXPR_B) 6918@end example 6919 6920in C. 6921@end deffn 6922 6923@geindex GCC_JIT_BINARY_OP_LOGICAL_AND (C macro) 6924@anchor{topics/expressions c GCC_JIT_BINARY_OP_LOGICAL_AND}@anchor{cf} 6925@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_AND 6926 6927Logical AND; analogous to: 6928 6929@example 6930(EXPR_A) && (EXPR_B) 6931@end example 6932 6933in C. 6934@end deffn 6935 6936@geindex GCC_JIT_BINARY_OP_LOGICAL_OR (C macro) 6937@anchor{topics/expressions c GCC_JIT_BINARY_OP_LOGICAL_OR}@anchor{d0} 6938@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_OR 6939 6940Logical OR; analogous to: 6941 6942@example 6943(EXPR_A) || (EXPR_B) 6944@end example 6945 6946in C. 6947@end deffn 6948 6949@geindex GCC_JIT_BINARY_OP_LSHIFT (C macro) 6950@anchor{topics/expressions c GCC_JIT_BINARY_OP_LSHIFT}@anchor{d1} 6951@deffn {C Macro} GCC_JIT_BINARY_OP_LSHIFT 6952 6953Left shift; analogous to: 6954 6955@example 6956(EXPR_A) << (EXPR_B) 6957@end example 6958 6959in C. 6960@end deffn 6961 6962@geindex GCC_JIT_BINARY_OP_RSHIFT (C macro) 6963@anchor{topics/expressions c GCC_JIT_BINARY_OP_RSHIFT}@anchor{d2} 6964@deffn {C Macro} GCC_JIT_BINARY_OP_RSHIFT 6965 6966Right shift; analogous to: 6967 6968@example 6969(EXPR_A) >> (EXPR_B) 6970@end example 6971 6972in C. 6973@end deffn 6974 6975@node Comparisons,Function calls,Binary Operations,Rvalues 6976@anchor{topics/expressions comparisons}@anchor{d4} 6977@subsubsection Comparisons 6978 6979 6980@geindex gcc_jit_context_new_comparison (C function) 6981@anchor{topics/expressions c gcc_jit_context_new_comparison}@anchor{2c} 6982@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) 6983 6984Build a boolean rvalue out of the comparison of two other rvalues. 6985@end deffn 6986 6987@geindex gcc_jit_comparison (C type) 6988@anchor{topics/expressions c gcc_jit_comparison}@anchor{d5} 6989@deffn {C Type} enum gcc_jit_comparison 6990@end deffn 6991 6992 6993@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6994@headitem 6995 6996Comparison 6997 6998@tab 6999 7000C equivalent 7001 7002@item 7003 7004@code{GCC_JIT_COMPARISON_EQ} 7005 7006@tab 7007 7008@cite{x == y} 7009 7010@item 7011 7012@code{GCC_JIT_COMPARISON_NE} 7013 7014@tab 7015 7016@cite{x != y} 7017 7018@item 7019 7020@code{GCC_JIT_COMPARISON_LT} 7021 7022@tab 7023 7024@cite{x < y} 7025 7026@item 7027 7028@code{GCC_JIT_COMPARISON_LE} 7029 7030@tab 7031 7032@cite{x <= y} 7033 7034@item 7035 7036@code{GCC_JIT_COMPARISON_GT} 7037 7038@tab 7039 7040@cite{x > y} 7041 7042@item 7043 7044@code{GCC_JIT_COMPARISON_GE} 7045 7046@tab 7047 7048@cite{x >= y} 7049 7050@end multitable 7051 7052 7053@node Function calls,Function pointers,Comparisons,Rvalues 7054@anchor{topics/expressions function-calls}@anchor{d6} 7055@subsubsection Function calls 7056 7057 7058@geindex gcc_jit_context_new_call (C function) 7059@anchor{topics/expressions c gcc_jit_context_new_call}@anchor{d7} 7060@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) 7061 7062Given a function and the given table of argument rvalues, construct a 7063call to the function, with the result as an rvalue. 7064 7065@cartouche 7066@quotation Note 7067@ref{d7,,gcc_jit_context_new_call()} merely builds a 7068@ref{13,,gcc_jit_rvalue} i.e. an expression that can be evaluated, 7069perhaps as part of a more complicated expression. 7070The call @emph{won���t} happen unless you add a statement to a function 7071that evaluates the expression. 7072 7073For example, if you want to call a function and discard the result 7074(or to call a function with @code{void} return type), use 7075@ref{d8,,gcc_jit_block_add_eval()}: 7076 7077@example 7078/* Add "(void)printf (arg0, arg1);". */ 7079gcc_jit_block_add_eval ( 7080 block, NULL, 7081 gcc_jit_context_new_call ( 7082 ctxt, 7083 NULL, 7084 printf_func, 7085 2, args)); 7086@end example 7087@end quotation 7088@end cartouche 7089@end deffn 7090 7091@geindex gcc_jit_context_new_call_through_ptr (C function) 7092@anchor{topics/expressions c gcc_jit_context_new_call_through_ptr}@anchor{d9} 7093@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) 7094 7095Given an rvalue of function pointer type (e.g. from 7096@ref{97,,gcc_jit_context_new_function_ptr_type()}), and the given table of 7097argument rvalues, construct a call to the function pointer, with the 7098result as an rvalue. 7099 7100@cartouche 7101@quotation Note 7102The same caveat as for @ref{d7,,gcc_jit_context_new_call()} applies. 7103@end quotation 7104@end cartouche 7105@end deffn 7106 7107@geindex gcc_jit_rvalue_set_bool_require_tail_call (C function) 7108@anchor{topics/expressions c gcc_jit_rvalue_set_bool_require_tail_call}@anchor{da} 7109@deffn {C Function} void gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue@w{ }*call, int@w{ }require_tail_call) 7110 7111Given an @ref{13,,gcc_jit_rvalue} for a call created through 7112@ref{d7,,gcc_jit_context_new_call()} or 7113@ref{d9,,gcc_jit_context_new_call_through_ptr()}, mark/clear the 7114call as needing tail-call optimization. The optimizer will 7115attempt to optimize the call into a jump instruction; if it is 7116unable to do do, an error will be emitted. 7117 7118This may be useful when implementing functions that use the 7119continuation-passing style (e.g. for functional programming 7120languages), in which every function ���returns��� by calling a 7121���continuation��� function pointer. This call must be 7122guaranteed to be implemented as a jump, otherwise the program 7123could consume an arbitrary amount of stack space as it executed. 7124 7125This entrypoint was added in @ref{db,,LIBGCCJIT_ABI_6}; you can test for 7126its presence using 7127 7128@example 7129#ifdef LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call 7130@end example 7131@end deffn 7132 7133@node Function pointers,Type-coercion,Function calls,Rvalues 7134@anchor{topics/expressions function-pointers}@anchor{dc} 7135@subsubsection Function pointers 7136 7137 7138Function pointers can be obtained: 7139 7140@quotation 7141 7142 7143@itemize * 7144 7145@item 7146from a @ref{29,,gcc_jit_function} using 7147@ref{dd,,gcc_jit_function_get_address()}, or 7148 7149@item 7150from an existing function using 7151@ref{b3,,gcc_jit_context_new_rvalue_from_ptr()}, 7152using a function pointer type obtained using 7153@ref{97,,gcc_jit_context_new_function_ptr_type()}. 7154@end itemize 7155@end quotation 7156 7157@node Type-coercion,,Function pointers,Rvalues 7158@anchor{topics/expressions type-coercion}@anchor{de} 7159@subsubsection Type-coercion 7160 7161 7162@geindex gcc_jit_context_new_cast (C function) 7163@anchor{topics/expressions c gcc_jit_context_new_cast}@anchor{df} 7164@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) 7165 7166Given an rvalue of T, construct another rvalue of another type. 7167 7168Currently only a limited set of conversions are possible: 7169 7170@quotation 7171 7172 7173@itemize * 7174 7175@item 7176int <-> float 7177 7178@item 7179int <-> bool 7180 7181@item 7182P* <-> Q*, for pointer types P and Q 7183@end itemize 7184@end quotation 7185@end deffn 7186 7187@geindex gcc_jit_context_new_bitcast (C function) 7188@anchor{topics/expressions c gcc_jit_context_new_bitcast}@anchor{e0} 7189@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_bitcast (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue, gcc_jit_type@w{ }*type) 7190 7191Given an rvalue of T, bitcast it to another type, meaning that this will 7192generate a new rvalue by interpreting the bits of @code{rvalue} to the layout 7193of @code{type}. 7194 7195The type of rvalue must be the same size as the size of @code{type}. 7196 7197This entrypoint was added in @ref{e1,,LIBGCCJIT_ABI_21}; you can test for 7198its presence using 7199 7200@example 7201#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast 7202@end example 7203@end deffn 7204 7205@node Lvalues,Working with pointers structs and unions,Rvalues,Expressions 7206@anchor{topics/expressions lvalues}@anchor{e2} 7207@subsection Lvalues 7208 7209 7210@geindex gcc_jit_lvalue (C type) 7211@anchor{topics/expressions c gcc_jit_lvalue}@anchor{24} 7212@deffn {C Type} gcc_jit_lvalue 7213@end deffn 7214 7215An lvalue is something that can of the @emph{left}-hand side of an assignment: 7216a storage area (such as a variable). It is also usable as an rvalue, 7217where the rvalue is computed by reading from the storage area. 7218 7219@geindex gcc_jit_lvalue_as_object (C function) 7220@anchor{topics/expressions c gcc_jit_lvalue_as_object}@anchor{e3} 7221@deffn {C Function} gcc_jit_object * gcc_jit_lvalue_as_object (gcc_jit_lvalue@w{ }*lvalue) 7222 7223Upcast an lvalue to be an object. 7224@end deffn 7225 7226@geindex gcc_jit_lvalue_as_rvalue (C function) 7227@anchor{topics/expressions c gcc_jit_lvalue_as_rvalue}@anchor{e4} 7228@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue@w{ }*lvalue) 7229 7230Upcast an lvalue to be an rvalue. 7231@end deffn 7232 7233@geindex gcc_jit_lvalue_get_address (C function) 7234@anchor{topics/expressions c gcc_jit_lvalue_get_address}@anchor{e5} 7235@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_get_address (gcc_jit_lvalue@w{ }*lvalue, gcc_jit_location@w{ }*loc) 7236 7237Take the address of an lvalue; analogous to: 7238 7239@example 7240&(EXPR) 7241@end example 7242 7243in C. 7244@end deffn 7245 7246@geindex gcc_jit_lvalue_set_tls_model (C function) 7247@anchor{topics/expressions c gcc_jit_lvalue_set_tls_model}@anchor{e6} 7248@deffn {C Function} void gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue@w{ }*lvalue, enum gcc_jit_tls_model@w{ }model) 7249 7250Make a variable a thread-local variable. 7251 7252The ���model��� parameter determines the thread-local storage model of the ���lvalue���: 7253 7254@geindex gcc_jit_tls_model (C type) 7255@anchor{topics/expressions c gcc_jit_tls_model}@anchor{e7} 7256@deffn {C Type} enum gcc_jit_tls_model 7257@end deffn 7258 7259@geindex GCC_JIT_TLS_MODEL_NONE (C macro) 7260@anchor{topics/expressions c GCC_JIT_TLS_MODEL_NONE}@anchor{e8} 7261@deffn {C Macro} GCC_JIT_TLS_MODEL_NONE 7262 7263Don���t set the TLS model. 7264@end deffn 7265 7266@geindex GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC (C macro) 7267@anchor{topics/expressions c GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC}@anchor{e9} 7268@deffn {C Macro} GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC 7269@end deffn 7270 7271@geindex GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC (C macro) 7272@anchor{topics/expressions c GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC}@anchor{ea} 7273@deffn {C Macro} GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC 7274@end deffn 7275 7276@geindex GCC_JIT_TLS_MODEL_INITIAL_EXEC (C macro) 7277@anchor{topics/expressions c GCC_JIT_TLS_MODEL_INITIAL_EXEC}@anchor{eb} 7278@deffn {C Macro} GCC_JIT_TLS_MODEL_INITIAL_EXEC 7279@end deffn 7280 7281@geindex GCC_JIT_TLS_MODEL_LOCAL_EXEC (C macro) 7282@anchor{topics/expressions c GCC_JIT_TLS_MODEL_LOCAL_EXEC}@anchor{ec} 7283@deffn {C Macro} GCC_JIT_TLS_MODEL_LOCAL_EXEC 7284@end deffn 7285 7286This is analogous to: 7287 7288@example 7289_Thread_local int foo __attribute__ ((tls_model("MODEL"))); 7290@end example 7291 7292in C. 7293 7294This entrypoint was added in @ref{ed,,LIBGCCJIT_ABI_17}; you can test for 7295its presence using 7296 7297@example 7298#ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_tls_model 7299@end example 7300@end deffn 7301 7302@geindex gcc_jit_lvalue_set_link_section (C function) 7303@anchor{topics/expressions c gcc_jit_lvalue_set_link_section}@anchor{ee} 7304@deffn {C Function} void gcc_jit_lvalue_set_link_section (gcc_jit_lvalue@w{ }*lvalue, const char@w{ }*section_name) 7305 7306Set the link section of a variable. 7307The parameter @code{section_name} must be non-NULL and must contain the 7308leading dot. Analogous to: 7309 7310@example 7311int variable __attribute__((section(".section"))); 7312@end example 7313 7314in C. 7315 7316This entrypoint was added in @ref{ef,,LIBGCCJIT_ABI_18}; you can test for 7317its presence using 7318 7319@example 7320#ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section 7321@end example 7322@end deffn 7323 7324 7325@deffn {C Function} void gcc_jit_lvalue_set_register_name (gcc_jit_lvalue *lvalue, const char *reg_name); 7326 7327Set the register name of a variable. 7328The parameter @code{reg_name} must be non-NULL. Analogous to: 7329 7330@example 7331register int variable asm ("r12"); 7332@end example 7333 7334in C. 7335 7336This entrypoint was added in @ref{f0,,LIBGCCJIT_ABI_22}; you can test for 7337its presence using 7338 7339@example 7340#ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_register_name 7341@end example 7342@end deffn 7343 7344@geindex gcc_jit_lvalue_set_alignment (C function) 7345@anchor{topics/expressions c gcc_jit_lvalue_set_alignment}@anchor{f1} 7346@deffn {C Function} void gcc_jit_lvalue_set_alignment (gcc_jit_lvalue@w{ }*lvalue, unsigned@w{ }bytes) 7347 7348Set the alignment of a variable, in bytes. 7349Analogous to: 7350 7351@example 7352int variable __attribute__((aligned (16))); 7353@end example 7354 7355in C. 7356 7357This entrypoint was added in @ref{f2,,LIBGCCJIT_ABI_24}; you can test for 7358its presence using 7359 7360@example 7361#ifdef LIBGCCJIT_HAVE_ALIGNMENT 7362@end example 7363@end deffn 7364 7365@geindex gcc_jit_lvalue_get_alignment (C function) 7366@anchor{topics/expressions c gcc_jit_lvalue_get_alignment}@anchor{f3} 7367@deffn {C Function} unsigned gcc_jit_lvalue_get_alignment (gcc_jit_lvalue@w{ }*lvalue) 7368 7369Return the alignment of a variable set by @code{gcc_jit_lvalue_set_alignment}. 7370Return 0 if the alignment was not set. Analogous to: 7371 7372@example 7373_Alignof (variable) 7374@end example 7375 7376in C. 7377 7378This entrypoint was added in @ref{f2,,LIBGCCJIT_ABI_24}; you can test for 7379its presence using 7380 7381@example 7382#ifdef LIBGCCJIT_HAVE_ALIGNMENT 7383@end example 7384@end deffn 7385 7386@menu 7387* Global variables:: 7388 7389@end menu 7390 7391@node Global variables,,,Lvalues 7392@anchor{topics/expressions global-variables}@anchor{f4} 7393@subsubsection Global variables 7394 7395 7396@geindex gcc_jit_context_new_global (C function) 7397@anchor{topics/expressions c gcc_jit_context_new_global}@anchor{f5} 7398@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) 7399 7400Add a new global variable of the given type and name to the context. 7401 7402The parameter @code{type} must be non-@cite{void}. 7403 7404The parameter @code{name} must be non-NULL. The call takes a copy of the 7405underlying string, so it is valid to pass in a pointer to an on-stack 7406buffer. 7407 7408The ���kind��� parameter determines the visibility of the ���global��� outside 7409of the @ref{16,,gcc_jit_result}: 7410 7411@geindex gcc_jit_global_kind (C type) 7412@anchor{topics/expressions c gcc_jit_global_kind}@anchor{f6} 7413@deffn {C Type} enum gcc_jit_global_kind 7414@end deffn 7415 7416@geindex GCC_JIT_GLOBAL_EXPORTED (C macro) 7417@anchor{topics/expressions c GCC_JIT_GLOBAL_EXPORTED}@anchor{f7} 7418@deffn {C Macro} GCC_JIT_GLOBAL_EXPORTED 7419 7420Global is defined by the client code and is visible 7421by name outside of this JIT context via 7422@ref{f8,,gcc_jit_result_get_global()} (and this value is required for 7423the global to be accessible via that entrypoint). 7424@end deffn 7425 7426@geindex GCC_JIT_GLOBAL_INTERNAL (C macro) 7427@anchor{topics/expressions c GCC_JIT_GLOBAL_INTERNAL}@anchor{f9} 7428@deffn {C Macro} GCC_JIT_GLOBAL_INTERNAL 7429 7430Global is defined by the client code, but is invisible 7431outside of it. Analogous to a ���static��� global within a .c file. 7432Specifically, the variable will only be visible within this 7433context and within child contexts. 7434@end deffn 7435 7436@geindex GCC_JIT_GLOBAL_IMPORTED (C macro) 7437@anchor{topics/expressions c GCC_JIT_GLOBAL_IMPORTED}@anchor{fa} 7438@deffn {C Macro} GCC_JIT_GLOBAL_IMPORTED 7439 7440Global is not defined by the client code; we���re merely 7441referring to it. Analogous to using an ���extern��� global from a 7442header file. 7443@end deffn 7444@end deffn 7445 7446@geindex gcc_jit_global_set_initializer (C function) 7447@anchor{topics/expressions c gcc_jit_global_set_initializer}@anchor{fb} 7448@deffn {C Function} gcc_jit_lvalue * gcc_jit_global_set_initializer (gcc_jit_lvalue@w{ }*global, const void@w{ }*blob, size_t@w{ }num_bytes) 7449 7450Set an initializer for @code{global} using the memory content pointed 7451by @code{blob} for @code{num_bytes}. @code{global} must be an array of an 7452integral type. Return the global itself. 7453 7454The parameter @code{blob} must be non-NULL. The call copies the memory 7455pointed by @code{blob} for @code{num_bytes} bytes, so it is valid to pass 7456in a pointer to an on-stack buffer. The content will be stored in 7457the compilation unit and used as initialization value of the array. 7458 7459This entrypoint was added in @ref{fc,,LIBGCCJIT_ABI_14}; you can test for 7460its presence using 7461 7462@example 7463#ifdef LIBGCCJIT_HAVE_gcc_jit_global_set_initializer 7464@end example 7465@end deffn 7466 7467@geindex gcc_jit_global_set_initializer_rvalue (C function) 7468@anchor{topics/expressions c gcc_jit_global_set_initializer_rvalue}@anchor{b7} 7469@deffn {C Function} gcc_jit_lvalue * gcc_jit_global_set_initializer_rvalue (gcc_jit_lvalue@w{ }*global, gcc_jit_rvalue@w{ }*init_value) 7470 7471Set the initial value of a global with an rvalue. 7472 7473The rvalue needs to be a constant expression, e.g. no function calls. 7474 7475The global can���t have the @code{kind} @ref{fa,,GCC_JIT_GLOBAL_IMPORTED}. 7476 7477As a non-comprehensive example it is OK to do the equivalent of: 7478 7479@example 7480int foo = 3 * 2; /* rvalue from gcc_jit_context_new_binary_op. */ 7481int arr[] = @{1,2,3,4@}; /* rvalue from gcc_jit_context_new_constructor. */ 7482int *bar = &arr[2] + 1; /* rvalue from nested "get address" of "array access". */ 7483const int baz = 3; /* rvalue from gcc_jit_context_rvalue_from_int. */ 7484int boz = baz; /* rvalue from gcc_jit_lvalue_as_rvalue. */ 7485@end example 7486 7487Use together with @ref{ba,,gcc_jit_context_new_struct_constructor()}, 7488@ref{bb,,gcc_jit_context_new_union_constructor()}, @ref{b9,,gcc_jit_context_new_array_constructor()} 7489to initialize structs, unions and arrays. 7490 7491On success, returns the @code{global} parameter unchanged. Otherwise, @code{NULL}. 7492 7493This entrypoint was added in @ref{b8,,LIBGCCJIT_ABI_19}; you can test for its 7494presence using: 7495 7496@example 7497#ifdef LIBGCCJIT_HAVE_CTORS 7498@end example 7499@end deffn 7500 7501@node Working with pointers structs and unions,,Lvalues,Expressions 7502@anchor{topics/expressions working-with-pointers-structs-and-unions}@anchor{fd} 7503@subsection Working with pointers, structs and unions 7504 7505 7506@geindex gcc_jit_rvalue_dereference (C function) 7507@anchor{topics/expressions c gcc_jit_rvalue_dereference}@anchor{fe} 7508@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference (gcc_jit_rvalue@w{ }*rvalue, gcc_jit_location@w{ }*loc) 7509 7510Given an rvalue of pointer type @code{T *}, dereferencing the pointer, 7511getting an lvalue of type @code{T}. Analogous to: 7512 7513@example 7514*(EXPR) 7515@end example 7516 7517in C. 7518@end deffn 7519 7520Field access is provided separately for both lvalues and rvalues. 7521 7522@geindex gcc_jit_lvalue_access_field (C function) 7523@anchor{topics/expressions c gcc_jit_lvalue_access_field}@anchor{ff} 7524@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) 7525 7526Given an lvalue of struct or union type, access the given field, 7527getting an lvalue of the field���s type. Analogous to: 7528 7529@example 7530(EXPR).field = ...; 7531@end example 7532 7533in C. 7534@end deffn 7535 7536@geindex gcc_jit_rvalue_access_field (C function) 7537@anchor{topics/expressions c gcc_jit_rvalue_access_field}@anchor{100} 7538@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) 7539 7540Given an rvalue of struct or union type, access the given field 7541as an rvalue. Analogous to: 7542 7543@example 7544(EXPR).field 7545@end example 7546 7547in C. 7548@end deffn 7549 7550@geindex gcc_jit_rvalue_dereference_field (C function) 7551@anchor{topics/expressions c gcc_jit_rvalue_dereference_field}@anchor{101} 7552@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) 7553 7554Given an rvalue of pointer type @code{T *} where T is of struct or union 7555type, access the given field as an lvalue. Analogous to: 7556 7557@example 7558(EXPR)->field 7559@end example 7560 7561in C, itself equivalent to @code{(*EXPR).FIELD}. 7562@end deffn 7563 7564@geindex gcc_jit_context_new_array_access (C function) 7565@anchor{topics/expressions c gcc_jit_context_new_array_access}@anchor{d3} 7566@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) 7567 7568Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at 7569the given index, using standard C array indexing rules i.e. each 7570increment of @code{index} corresponds to @code{sizeof(T)} bytes. 7571Analogous to: 7572 7573@example 7574PTR[INDEX] 7575@end example 7576 7577in C (or, indeed, to @code{PTR + INDEX}). 7578@end deffn 7579 7580@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 7581@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7582@c 7583@c This is free software: you can redistribute it and/or modify it 7584@c under the terms of the GNU General Public License as published by 7585@c the Free Software Foundation, either version 3 of the License, or 7586@c (at your option) any later version. 7587@c 7588@c This program is distributed in the hope that it will be useful, but 7589@c WITHOUT ANY WARRANTY; without even the implied warranty of 7590@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7591@c General Public License for more details. 7592@c 7593@c You should have received a copy of the GNU General Public License 7594@c along with this program. If not, see 7595@c <https://www.gnu.org/licenses/>. 7596 7597@node Creating and using functions,Function pointers<2>,Expressions,Topic Reference 7598@anchor{topics/functions doc}@anchor{102}@anchor{topics/functions creating-and-using-functions}@anchor{103} 7599@section Creating and using functions 7600 7601 7602@menu 7603* Params:: 7604* Functions:: 7605* Blocks:: 7606* Statements:: 7607 7608@end menu 7609 7610@node Params,Functions,,Creating and using functions 7611@anchor{topics/functions params}@anchor{104} 7612@subsection Params 7613 7614 7615@geindex gcc_jit_param (C type) 7616@anchor{topics/functions c gcc_jit_param}@anchor{25} 7617@deffn {C Type} gcc_jit_param 7618 7619A @cite{gcc_jit_param} represents a parameter to a function. 7620@end deffn 7621 7622@geindex gcc_jit_context_new_param (C function) 7623@anchor{topics/functions c gcc_jit_context_new_param}@anchor{10} 7624@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) 7625 7626In preparation for creating a function, create a new parameter of the 7627given type and name. 7628 7629The parameter @code{type} must be non-@cite{void}. 7630 7631The parameter @code{name} must be non-NULL. The call takes a copy of the 7632underlying string, so it is valid to pass in a pointer to an on-stack 7633buffer. 7634@end deffn 7635 7636Parameters are lvalues, and thus are also rvalues (and objects), so the 7637following upcasts are available: 7638 7639@geindex gcc_jit_param_as_lvalue (C function) 7640@anchor{topics/functions c gcc_jit_param_as_lvalue}@anchor{105} 7641@deffn {C Function} gcc_jit_lvalue * gcc_jit_param_as_lvalue (gcc_jit_param@w{ }*param) 7642 7643Upcasting from param to lvalue. 7644@end deffn 7645 7646@geindex gcc_jit_param_as_rvalue (C function) 7647@anchor{topics/functions c gcc_jit_param_as_rvalue}@anchor{106} 7648@deffn {C Function} gcc_jit_rvalue * gcc_jit_param_as_rvalue (gcc_jit_param@w{ }*param) 7649 7650Upcasting from param to rvalue. 7651@end deffn 7652 7653@geindex gcc_jit_param_as_object (C function) 7654@anchor{topics/functions c gcc_jit_param_as_object}@anchor{107} 7655@deffn {C Function} gcc_jit_object * gcc_jit_param_as_object (gcc_jit_param@w{ }*param) 7656 7657Upcasting from param to object. 7658@end deffn 7659 7660@node Functions,Blocks,Params,Creating and using functions 7661@anchor{topics/functions functions}@anchor{108} 7662@subsection Functions 7663 7664 7665@geindex gcc_jit_function (C type) 7666@anchor{topics/functions c gcc_jit_function}@anchor{29} 7667@deffn {C Type} gcc_jit_function 7668 7669A @cite{gcc_jit_function} represents a function - either one that we���re 7670creating ourselves, or one that we���re referencing. 7671@end deffn 7672 7673@geindex gcc_jit_context_new_function (C function) 7674@anchor{topics/functions c gcc_jit_context_new_function}@anchor{11} 7675@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) 7676 7677Create a gcc_jit_function with the given name and parameters. 7678 7679@geindex gcc_jit_function_kind (C type) 7680@anchor{topics/functions c gcc_jit_function_kind}@anchor{109} 7681@deffn {C Type} enum gcc_jit_function_kind 7682@end deffn 7683 7684This enum controls the kind of function created, and has the following 7685values: 7686 7687@quotation 7688 7689@geindex GCC_JIT_FUNCTION_EXPORTED (C macro) 7690@anchor{topics/functions c GCC_JIT_FUNCTION_EXPORTED}@anchor{10a} 7691@deffn {C Macro} GCC_JIT_FUNCTION_EXPORTED 7692 7693Function is defined by the client code and visible 7694by name outside of the JIT. 7695 7696This value is required if you want to extract machine code 7697for this function from a @ref{16,,gcc_jit_result} via 7698@ref{17,,gcc_jit_result_get_code()}. 7699@end deffn 7700 7701@geindex GCC_JIT_FUNCTION_INTERNAL (C macro) 7702@anchor{topics/functions c GCC_JIT_FUNCTION_INTERNAL}@anchor{10b} 7703@deffn {C Macro} GCC_JIT_FUNCTION_INTERNAL 7704 7705Function is defined by the client code, but is invisible 7706outside of the JIT. Analogous to a ���static��� function. 7707@end deffn 7708 7709@geindex GCC_JIT_FUNCTION_IMPORTED (C macro) 7710@anchor{topics/functions c GCC_JIT_FUNCTION_IMPORTED}@anchor{10c} 7711@deffn {C Macro} GCC_JIT_FUNCTION_IMPORTED 7712 7713Function is not defined by the client code; we���re merely 7714referring to it. Analogous to using an ���extern��� function from a 7715header file. 7716@end deffn 7717 7718@geindex GCC_JIT_FUNCTION_ALWAYS_INLINE (C macro) 7719@anchor{topics/functions c GCC_JIT_FUNCTION_ALWAYS_INLINE}@anchor{10d} 7720@deffn {C Macro} GCC_JIT_FUNCTION_ALWAYS_INLINE 7721 7722Function is only ever inlined into other functions, and is 7723invisible outside of the JIT. 7724 7725Analogous to prefixing with @code{inline} and adding 7726@code{__attribute__((always_inline))} 7727 7728Inlining will only occur when the optimization level is 7729above 0; when optimization is off, this is essentially the 7730same as GCC_JIT_FUNCTION_INTERNAL. 7731@end deffn 7732@end quotation 7733 7734The parameter @code{name} must be non-NULL. The call takes a copy of the 7735underlying string, so it is valid to pass in a pointer to an on-stack 7736buffer. 7737@end deffn 7738 7739@geindex gcc_jit_context_get_builtin_function (C function) 7740@anchor{topics/functions c gcc_jit_context_get_builtin_function}@anchor{10e} 7741@deffn {C Function} gcc_jit_function * gcc_jit_context_get_builtin_function (gcc_jit_context@w{ }*ctxt, const char@w{ }*name) 7742 7743Get the @ref{29,,gcc_jit_function} for the built-in function with the 7744given name. For example: 7745 7746@example 7747gcc_jit_function *fn 7748 = gcc_jit_context_get_builtin_function (ctxt, "__builtin_memcpy"); 7749@end example 7750 7751@cartouche 7752@quotation Note 7753Due to technical limitations with how libgccjit interacts with 7754the insides of GCC, not all built-in functions are supported. More 7755precisely, not all types are supported for parameters of built-in 7756functions from libgccjit. Attempts to get a built-in function that 7757uses such a parameter will lead to an error being emitted within 7758the context. 7759@end quotation 7760@end cartouche 7761@end deffn 7762 7763@geindex gcc_jit_function_as_object (C function) 7764@anchor{topics/functions c gcc_jit_function_as_object}@anchor{10f} 7765@deffn {C Function} gcc_jit_object * gcc_jit_function_as_object (gcc_jit_function@w{ }*func) 7766 7767Upcasting from function to object. 7768@end deffn 7769 7770@geindex gcc_jit_function_get_param (C function) 7771@anchor{topics/functions c gcc_jit_function_get_param}@anchor{110} 7772@deffn {C Function} gcc_jit_param * gcc_jit_function_get_param (gcc_jit_function@w{ }*func, int@w{ }index) 7773 7774Get the param of the given index (0-based). 7775@end deffn 7776 7777@geindex gcc_jit_function_dump_to_dot (C function) 7778@anchor{topics/functions c gcc_jit_function_dump_to_dot}@anchor{33} 7779@deffn {C Function} void gcc_jit_function_dump_to_dot (gcc_jit_function@w{ }*func, const char@w{ }*path) 7780 7781Emit the function in graphviz format to the given path. 7782@end deffn 7783 7784@geindex gcc_jit_function_new_local (C function) 7785@anchor{topics/functions c gcc_jit_function_new_local}@anchor{26} 7786@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) 7787 7788Create a new local variable within the function, of the given type and 7789name. 7790 7791The parameter @code{type} must be non-@cite{void}. 7792 7793The parameter @code{name} must be non-NULL. The call takes a copy of the 7794underlying string, so it is valid to pass in a pointer to an on-stack 7795buffer. 7796@end deffn 7797 7798@geindex gcc_jit_function_get_param_count (C function) 7799@anchor{topics/functions c gcc_jit_function_get_param_count}@anchor{111} 7800@deffn {C Function} size_t gcc_jit_function_get_param_count (gcc_jit_function@w{ }*func) 7801 7802Get the number of parameters of the function. 7803@end deffn 7804 7805@geindex gcc_jit_function_get_return_type (C function) 7806@anchor{topics/functions c gcc_jit_function_get_return_type}@anchor{112} 7807@deffn {C Function} gcc_jit_type * gcc_jit_function_get_return_type (gcc_jit_function@w{ }*func) 7808 7809Get the return type of the function. 7810 7811The API entrypoints relating to getting info about parameters and return 7812types: 7813 7814@quotation 7815 7816 7817@itemize * 7818 7819@item 7820@ref{112,,gcc_jit_function_get_return_type()} 7821 7822@item 7823@ref{111,,gcc_jit_function_get_param_count()} 7824@end itemize 7825@end quotation 7826 7827were added in @ref{a8,,LIBGCCJIT_ABI_16}; you can test for their presence 7828using 7829 7830@example 7831#ifdef LIBGCCJIT_HAVE_REFLECTION 7832@end example 7833 7834@geindex gcc_jit_case (C type) 7835@anchor{topics/functions c gcc_jit_case}@anchor{113} 7836@deffn {C Type} gcc_jit_case 7837@end deffn 7838@end deffn 7839 7840@node Blocks,Statements,Functions,Creating and using functions 7841@anchor{topics/functions blocks}@anchor{114} 7842@subsection Blocks 7843 7844 7845@geindex gcc_jit_block (C type) 7846@anchor{topics/functions c gcc_jit_block}@anchor{28} 7847@deffn {C Type} gcc_jit_block 7848 7849A @cite{gcc_jit_block} represents a basic block within a function i.e. a 7850sequence of statements with a single entry point and a single exit 7851point. 7852 7853The first basic block that you create within a function will 7854be the entrypoint. 7855 7856Each basic block that you create within a function must be 7857terminated, either with a conditional, a jump, a return, or a 7858switch. 7859 7860It���s legal to have multiple basic blocks that return within 7861one function. 7862@end deffn 7863 7864@geindex gcc_jit_function_new_block (C function) 7865@anchor{topics/functions c gcc_jit_function_new_block}@anchor{115} 7866@deffn {C Function} gcc_jit_block * gcc_jit_function_new_block (gcc_jit_function@w{ }*func, const char@w{ }*name) 7867 7868Create a basic block of the given name. The name may be NULL, but 7869providing meaningful names is often helpful when debugging: it may 7870show up in dumps of the internal representation, and in error 7871messages. It is copied, so the input buffer does not need to outlive 7872the call; you can pass in a pointer to an on-stack buffer, e.g.: 7873 7874@example 7875for (pc = 0; pc < fn->fn_num_ops; pc++) 7876 @{ 7877 char buf[16]; 7878 sprintf (buf, "instr%i", pc); 7879 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); 7880 @} 7881@end example 7882@end deffn 7883 7884@geindex gcc_jit_block_as_object (C function) 7885@anchor{topics/functions c gcc_jit_block_as_object}@anchor{116} 7886@deffn {C Function} gcc_jit_object * gcc_jit_block_as_object (gcc_jit_block@w{ }*block) 7887 7888Upcast from block to object. 7889@end deffn 7890 7891@geindex gcc_jit_block_get_function (C function) 7892@anchor{topics/functions c gcc_jit_block_get_function}@anchor{117} 7893@deffn {C Function} gcc_jit_function * gcc_jit_block_get_function (gcc_jit_block@w{ }*block) 7894 7895Which function is this block within? 7896@end deffn 7897 7898@node Statements,,Blocks,Creating and using functions 7899@anchor{topics/functions statements}@anchor{118} 7900@subsection Statements 7901 7902 7903@geindex gcc_jit_block_add_eval (C function) 7904@anchor{topics/functions c gcc_jit_block_add_eval}@anchor{d8} 7905@deffn {C Function} void gcc_jit_block_add_eval (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue) 7906 7907Add evaluation of an rvalue, discarding the result 7908(e.g. a function call that ���returns��� void). 7909 7910This is equivalent to this C code: 7911 7912@example 7913(void)expression; 7914@end example 7915@end deffn 7916 7917@geindex gcc_jit_block_add_assignment (C function) 7918@anchor{topics/functions c gcc_jit_block_add_assignment}@anchor{2a} 7919@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) 7920 7921Add evaluation of an rvalue, assigning the result to the given 7922lvalue. 7923 7924This is roughly equivalent to this C code: 7925 7926@example 7927lvalue = rvalue; 7928@end example 7929@end deffn 7930 7931@geindex gcc_jit_block_add_assignment_op (C function) 7932@anchor{topics/functions c gcc_jit_block_add_assignment_op}@anchor{2e} 7933@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) 7934 7935Add evaluation of an rvalue, using the result to modify an 7936lvalue. 7937 7938This is analogous to ���+=��� and friends: 7939 7940@example 7941lvalue += rvalue; 7942lvalue *= rvalue; 7943lvalue /= rvalue; 7944@end example 7945 7946etc. For example: 7947 7948@example 7949/* "i++" */ 7950gcc_jit_block_add_assignment_op ( 7951 loop_body, NULL, 7952 i, 7953 GCC_JIT_BINARY_OP_PLUS, 7954 gcc_jit_context_one (ctxt, int_type)); 7955@end example 7956@end deffn 7957 7958@geindex gcc_jit_block_add_comment (C function) 7959@anchor{topics/functions c gcc_jit_block_add_comment}@anchor{3d} 7960@deffn {C Function} void gcc_jit_block_add_comment (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*text) 7961 7962Add a no-op textual comment to the internal representation of the 7963code. It will be optimized away, but will be visible in the dumps 7964seen via @ref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} 7965and @ref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, 7966and thus may be of use when debugging how your project���s internal 7967representation gets converted to the libgccjit IR. 7968 7969The parameter @code{text} must be non-NULL. It is copied, so the input 7970buffer does not need to outlive the call. For example: 7971 7972@example 7973char buf[100]; 7974snprintf (buf, sizeof (buf), 7975 "op%i: %s", 7976 pc, opcode_names[op->op_opcode]); 7977gcc_jit_block_add_comment (block, loc, buf); 7978@end example 7979@end deffn 7980 7981@geindex gcc_jit_block_end_with_conditional (C function) 7982@anchor{topics/functions c gcc_jit_block_end_with_conditional}@anchor{2d} 7983@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) 7984 7985Terminate a block by adding evaluation of an rvalue, branching on the 7986result to the appropriate successor block. 7987 7988This is roughly equivalent to this C code: 7989 7990@example 7991if (boolval) 7992 goto on_true; 7993else 7994 goto on_false; 7995@end example 7996 7997block, boolval, on_true, and on_false must be non-NULL. 7998@end deffn 7999 8000@geindex gcc_jit_block_end_with_jump (C function) 8001@anchor{topics/functions c gcc_jit_block_end_with_jump}@anchor{119} 8002@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) 8003 8004Terminate a block by adding a jump to the given target block. 8005 8006This is roughly equivalent to this C code: 8007 8008@example 8009goto target; 8010@end example 8011@end deffn 8012 8013@geindex gcc_jit_block_end_with_return (C function) 8014@anchor{topics/functions c gcc_jit_block_end_with_return}@anchor{11a} 8015@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) 8016 8017Terminate a block by adding evaluation of an rvalue, returning the value. 8018 8019This is roughly equivalent to this C code: 8020 8021@example 8022return expression; 8023@end example 8024@end deffn 8025 8026@geindex gcc_jit_block_end_with_void_return (C function) 8027@anchor{topics/functions c gcc_jit_block_end_with_void_return}@anchor{11b} 8028@deffn {C Function} void gcc_jit_block_end_with_void_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc) 8029 8030Terminate a block by adding a valueless return, for use within a function 8031with ���void��� return type. 8032 8033This is equivalent to this C code: 8034 8035@example 8036return; 8037@end example 8038@end deffn 8039 8040@geindex gcc_jit_block_end_with_switch (C function) 8041@anchor{topics/functions c gcc_jit_block_end_with_switch}@anchor{11c} 8042@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) 8043 8044Terminate a block by adding evalation of an rvalue, then performing 8045a multiway branch. 8046 8047This is roughly equivalent to this C code: 8048 8049@example 8050switch (expr) 8051 @{ 8052 default: 8053 goto default_block; 8054 8055 case C0.min_value ... C0.max_value: 8056 goto C0.dest_block; 8057 8058 case C1.min_value ... C1.max_value: 8059 goto C1.dest_block; 8060 8061 ...etc... 8062 8063 case C[N - 1].min_value ... C[N - 1].max_value: 8064 goto C[N - 1].dest_block; 8065@} 8066@end example 8067 8068@code{block}, @code{expr}, @code{default_block} and @code{cases} must all be 8069non-NULL. 8070 8071@code{expr} must be of the same integer type as all of the @code{min_value} 8072and @code{max_value} within the cases. 8073 8074@code{num_cases} must be >= 0. 8075 8076The ranges of the cases must not overlap (or have duplicate 8077values). 8078 8079The API entrypoints relating to switch statements and cases: 8080 8081@quotation 8082 8083 8084@itemize * 8085 8086@item 8087@ref{11c,,gcc_jit_block_end_with_switch()} 8088 8089@item 8090@ref{11d,,gcc_jit_case_as_object()} 8091 8092@item 8093@ref{11e,,gcc_jit_context_new_case()} 8094@end itemize 8095@end quotation 8096 8097were added in @ref{11f,,LIBGCCJIT_ABI_3}; you can test for their presence 8098using 8099 8100@example 8101#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 8102@end example 8103 8104@geindex gcc_jit_case (C type) 8105 8106@deffn {C Type} gcc_jit_case 8107@end deffn 8108 8109A @cite{gcc_jit_case} represents a case within a switch statement, and 8110is created within a particular @ref{8,,gcc_jit_context} using 8111@ref{11e,,gcc_jit_context_new_case()}. 8112 8113Each case expresses a multivalued range of integer values. You 8114can express single-valued cases by passing in the same value for 8115both @cite{min_value} and @cite{max_value}. 8116 8117@geindex gcc_jit_context_new_case (C function) 8118@anchor{topics/functions c gcc_jit_context_new_case}@anchor{11e} 8119@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) 8120 8121Create a new gcc_jit_case instance for use in a switch statement. 8122@cite{min_value} and @cite{max_value} must be constants of an integer type, 8123which must match that of the expression of the switch statement. 8124 8125@cite{dest_block} must be within the same function as the switch 8126statement. 8127@end deffn 8128 8129@geindex gcc_jit_case_as_object (C function) 8130@anchor{topics/functions c gcc_jit_case_as_object}@anchor{11d} 8131@deffn {C Function} gcc_jit_object * gcc_jit_case_as_object (gcc_jit_case@w{ }*case_) 8132 8133Upcast from a case to an object. 8134@end deffn 8135 8136Here���s an example of creating a switch statement: 8137 8138@quotation 8139 8140@example 8141 8142void 8143create_code (gcc_jit_context *ctxt, void *user_data) 8144@{ 8145 /* Let's try to inject the equivalent of: 8146 int 8147 test_switch (int x) 8148 @{ 8149 switch (x) 8150 @{ 8151 case 0 ... 5: 8152 return 3; 8153 8154 case 25 ... 27: 8155 return 4; 8156 8157 case -42 ... -17: 8158 return 83; 8159 8160 case 40: 8161 return 8; 8162 8163 default: 8164 return 10; 8165 @} 8166 @} 8167 */ 8168 gcc_jit_type *t_int = 8169 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 8170 gcc_jit_type *return_type = t_int; 8171 gcc_jit_param *x = 8172 gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); 8173 gcc_jit_param *params[1] = @{x@}; 8174 gcc_jit_function *func = 8175 gcc_jit_context_new_function (ctxt, NULL, 8176 GCC_JIT_FUNCTION_EXPORTED, 8177 return_type, 8178 "test_switch", 8179 1, params, 0); 8180 8181 gcc_jit_block *b_initial = 8182 gcc_jit_function_new_block (func, "initial"); 8183 8184 gcc_jit_block *b_default = 8185 gcc_jit_function_new_block (func, "default"); 8186 gcc_jit_block *b_case_0_5 = 8187 gcc_jit_function_new_block (func, "case_0_5"); 8188 gcc_jit_block *b_case_25_27 = 8189 gcc_jit_function_new_block (func, "case_25_27"); 8190 gcc_jit_block *b_case_m42_m17 = 8191 gcc_jit_function_new_block (func, "case_m42_m17"); 8192 gcc_jit_block *b_case_40 = 8193 gcc_jit_function_new_block (func, "case_40"); 8194 8195 gcc_jit_case *cases[4] = @{ 8196 gcc_jit_context_new_case ( 8197 ctxt, 8198 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0), 8199 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5), 8200 b_case_0_5), 8201 gcc_jit_context_new_case ( 8202 ctxt, 8203 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 25), 8204 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 27), 8205 b_case_25_27), 8206 gcc_jit_context_new_case ( 8207 ctxt, 8208 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -42), 8209 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -17), 8210 b_case_m42_m17), 8211 gcc_jit_context_new_case ( 8212 ctxt, 8213 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), 8214 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), 8215 b_case_40) 8216 @}; 8217 gcc_jit_block_end_with_switch ( 8218 b_initial, NULL, 8219 gcc_jit_param_as_rvalue (x), 8220 b_default, 8221 4, cases); 8222 8223 gcc_jit_block_end_with_return ( 8224 b_case_0_5, NULL, 8225 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); 8226 gcc_jit_block_end_with_return ( 8227 b_case_25_27, NULL, 8228 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4)); 8229 gcc_jit_block_end_with_return ( 8230 b_case_m42_m17, NULL, 8231 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 83)); 8232 gcc_jit_block_end_with_return ( 8233 b_case_40, NULL, 8234 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 8)); 8235 gcc_jit_block_end_with_return ( 8236 b_default, NULL, 8237 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); 8238@} 8239 8240@end example 8241@end quotation 8242@end deffn 8243 8244See also @ref{120,,gcc_jit_extended_asm} for entrypoints for adding inline 8245assembler statements to a function. 8246 8247@c Copyright (C) 2017-2022 Free Software Foundation, Inc. 8248@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8249@c 8250@c This is free software: you can redistribute it and/or modify it 8251@c under the terms of the GNU General Public License as published by 8252@c the Free Software Foundation, either version 3 of the License, or 8253@c (at your option) any later version. 8254@c 8255@c This program is distributed in the hope that it will be useful, but 8256@c WITHOUT ANY WARRANTY; without even the implied warranty of 8257@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8258@c General Public License for more details. 8259@c 8260@c You should have received a copy of the GNU General Public License 8261@c along with this program. If not, see 8262@c <https://www.gnu.org/licenses/>. 8263 8264@node Function pointers<2>,Source Locations,Creating and using functions,Topic Reference 8265@anchor{topics/function-pointers doc}@anchor{121}@anchor{topics/function-pointers function-pointers}@anchor{122} 8266@section Function pointers 8267 8268 8269You can generate calls that use a function pointer via 8270@ref{d9,,gcc_jit_context_new_call_through_ptr()}. 8271 8272To do requires a @ref{13,,gcc_jit_rvalue} of the correct function pointer type. 8273 8274Function pointers for a @ref{29,,gcc_jit_function} can be obtained 8275via @ref{dd,,gcc_jit_function_get_address()}. 8276 8277@geindex gcc_jit_function_get_address (C function) 8278@anchor{topics/function-pointers c gcc_jit_function_get_address}@anchor{dd} 8279@deffn {C Function} gcc_jit_rvalue * gcc_jit_function_get_address (gcc_jit_function@w{ }*fn, gcc_jit_location@w{ }*loc) 8280 8281Get the address of a function as an rvalue, of function pointer 8282type. 8283 8284This entrypoint was added in @ref{123,,LIBGCCJIT_ABI_9}; you can test 8285for its presence using 8286 8287@example 8288#ifdef LIBGCCJIT_HAVE_gcc_jit_function_get_address 8289@end example 8290@end deffn 8291 8292Alternatively, given an existing function, you can obtain a pointer 8293to it in @ref{13,,gcc_jit_rvalue} form using 8294@ref{b3,,gcc_jit_context_new_rvalue_from_ptr()}, using a function pointer 8295type obtained using @ref{97,,gcc_jit_context_new_function_ptr_type()}. 8296 8297Here���s an example of creating a function pointer type corresponding to C���s 8298@code{void (*) (int, int, int)}: 8299 8300@example 8301gcc_jit_type *void_type = 8302 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); 8303gcc_jit_type *int_type = 8304 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 8305 8306/* Build the function ptr type. */ 8307gcc_jit_type *param_types[3]; 8308param_types[0] = int_type; 8309param_types[1] = int_type; 8310param_types[2] = int_type; 8311 8312gcc_jit_type *fn_ptr_type = 8313 gcc_jit_context_new_function_ptr_type (ctxt, NULL, 8314 void_type, 8315 3, param_types, 0); 8316@end example 8317 8318@geindex gcc_jit_context_new_function_ptr_type (C function) 8319@anchor{topics/function-pointers c gcc_jit_context_new_function_ptr_type}@anchor{97} 8320@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) 8321 8322Generate a @ref{a,,gcc_jit_type} for a function pointer with the 8323given return type and parameters. 8324 8325Each of @cite{param_types} must be non-@cite{void}; @cite{return_type} may be @cite{void}. 8326@end deffn 8327 8328@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 8329@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8330@c 8331@c This is free software: you can redistribute it and/or modify it 8332@c under the terms of the GNU General Public License as published by 8333@c the Free Software Foundation, either version 3 of the License, or 8334@c (at your option) any later version. 8335@c 8336@c This program is distributed in the hope that it will be useful, but 8337@c WITHOUT ANY WARRANTY; without even the implied warranty of 8338@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8339@c General Public License for more details. 8340@c 8341@c You should have received a copy of the GNU General Public License 8342@c along with this program. If not, see 8343@c <https://www.gnu.org/licenses/>. 8344 8345@node Source Locations,Compiling a context,Function pointers<2>,Topic Reference 8346@anchor{topics/locations doc}@anchor{124}@anchor{topics/locations source-locations}@anchor{125} 8347@section Source Locations 8348 8349 8350@geindex gcc_jit_location (C type) 8351@anchor{topics/locations c gcc_jit_location}@anchor{3b} 8352@deffn {C Type} gcc_jit_location 8353 8354A @cite{gcc_jit_location} encapsulates a source code location, so that 8355you can (optionally) associate locations in your language with 8356statements in the JIT-compiled code, allowing the debugger to 8357single-step through your language. 8358 8359@cite{gcc_jit_location} instances are optional: you can always pass NULL to 8360any API entrypoint accepting one. 8361 8362You can construct them using @ref{41,,gcc_jit_context_new_location()}. 8363 8364You need to enable @ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 8365@ref{8,,gcc_jit_context} for these locations to actually be usable by 8366the debugger: 8367 8368@example 8369gcc_jit_context_set_bool_option ( 8370 ctxt, 8371 GCC_JIT_BOOL_OPTION_DEBUGINFO, 8372 1); 8373@end example 8374@end deffn 8375 8376@geindex gcc_jit_context_new_location (C function) 8377@anchor{topics/locations c gcc_jit_context_new_location}@anchor{41} 8378@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) 8379 8380Create a @cite{gcc_jit_location} instance representing the given source 8381location. 8382 8383The parameter @code{filename} must be non-NULL. The call takes a copy of 8384the underlying string, so it is valid to pass in a pointer to an 8385on-stack buffer. 8386@end deffn 8387 8388@menu 8389* Faking it:: 8390 8391@end menu 8392 8393@node Faking it,,,Source Locations 8394@anchor{topics/locations faking-it}@anchor{126} 8395@subsection Faking it 8396 8397 8398If you don���t have source code for your internal representation, but need 8399to debug, you can generate a C-like representation of the functions in 8400your context using @ref{5a,,gcc_jit_context_dump_to_file()}: 8401 8402@example 8403gcc_jit_context_dump_to_file (ctxt, "/tmp/something.c", 8404 1 /* update_locations */); 8405@end example 8406 8407This will dump C-like code to the given path. If the @cite{update_locations} 8408argument is true, this will also set up @cite{gcc_jit_location} information 8409throughout the context, pointing at the dump file as if it were a source 8410file, giving you @emph{something} you can step through in the debugger. 8411 8412@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 8413@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8414@c 8415@c This is free software: you can redistribute it and/or modify it 8416@c under the terms of the GNU General Public License as published by 8417@c the Free Software Foundation, either version 3 of the License, or 8418@c (at your option) any later version. 8419@c 8420@c This program is distributed in the hope that it will be useful, but 8421@c WITHOUT ANY WARRANTY; without even the implied warranty of 8422@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8423@c General Public License for more details. 8424@c 8425@c You should have received a copy of the GNU General Public License 8426@c along with this program. If not, see 8427@c <https://www.gnu.org/licenses/>. 8428 8429@node Compiling a context,ABI and API compatibility,Source Locations,Topic Reference 8430@anchor{topics/compilation doc}@anchor{127}@anchor{topics/compilation compiling-a-context}@anchor{128} 8431@section Compiling a context 8432 8433 8434Once populated, a @ref{8,,gcc_jit_context *} can be compiled to 8435machine code, either in-memory via @ref{15,,gcc_jit_context_compile()} or 8436to disk via @ref{4a,,gcc_jit_context_compile_to_file()}. 8437 8438You can compile a context multiple times (using either form of 8439compilation), although any errors that occur on the context will 8440prevent any future compilation of that context. 8441 8442@menu 8443* In-memory compilation:: 8444* Ahead-of-time compilation:: 8445 8446@end menu 8447 8448@node In-memory compilation,Ahead-of-time compilation,,Compiling a context 8449@anchor{topics/compilation in-memory-compilation}@anchor{129} 8450@subsection In-memory compilation 8451 8452 8453@geindex gcc_jit_context_compile (C function) 8454@anchor{topics/compilation c gcc_jit_context_compile}@anchor{15} 8455@deffn {C Function} gcc_jit_result * gcc_jit_context_compile (gcc_jit_context@w{ }*ctxt) 8456 8457This calls into GCC and builds the code, returning a 8458@cite{gcc_jit_result *}. 8459 8460If the result is non-NULL, the caller becomes responsible for 8461calling @ref{39,,gcc_jit_result_release()} on it once they���re done 8462with it. 8463@end deffn 8464 8465@geindex gcc_jit_result (C type) 8466@anchor{topics/compilation c gcc_jit_result}@anchor{16} 8467@deffn {C Type} gcc_jit_result 8468 8469A @cite{gcc_jit_result} encapsulates the result of compiling a context 8470in-memory, and the lifetimes of any machine code functions or globals 8471that are within the result. 8472@end deffn 8473 8474@geindex gcc_jit_result_get_code (C function) 8475@anchor{topics/compilation c gcc_jit_result_get_code}@anchor{17} 8476@deffn {C Function} void * gcc_jit_result_get_code (gcc_jit_result@w{ }*result, const char@w{ }*funcname) 8477 8478Locate a given function within the built machine code. 8479 8480Functions are looked up by name. For this to succeed, a function 8481with a name matching @cite{funcname} must have been created on 8482@cite{result}���s context (or a parent context) via a call to 8483@ref{11,,gcc_jit_context_new_function()} with @cite{kind} 8484@ref{10a,,GCC_JIT_FUNCTION_EXPORTED}: 8485 8486@example 8487gcc_jit_context_new_function (ctxt, 8488 any_location, /* or NULL */ 8489 /* Required for func to be visible to 8490 gcc_jit_result_get_code: */ 8491 GCC_JIT_FUNCTION_EXPORTED, 8492 any_return_type, 8493 /* Must string-compare equal: */ 8494 funcname, 8495 /* etc */); 8496@end example 8497 8498If such a function is not found (or @cite{result} or @cite{funcname} are 8499@code{NULL}), an error message will be emitted on stderr and 8500@code{NULL} will be returned. 8501 8502If the function is found, the result will need to be cast to a 8503function pointer of the correct type before it can be called. 8504 8505Note that the resulting machine code becomes invalid after 8506@ref{39,,gcc_jit_result_release()} is called on the 8507@ref{16,,gcc_jit_result *}; attempting to call it after that may lead 8508to a segmentation fault. 8509@end deffn 8510 8511@geindex gcc_jit_result_get_global (C function) 8512@anchor{topics/compilation c gcc_jit_result_get_global}@anchor{f8} 8513@deffn {C Function} void * gcc_jit_result_get_global (gcc_jit_result@w{ }*result, const char@w{ }*name) 8514 8515Locate a given global within the built machine code. 8516 8517Globals are looked up by name. For this to succeed, a global 8518with a name matching @cite{name} must have been created on 8519@cite{result}���s context (or a parent context) via a call to 8520@ref{f5,,gcc_jit_context_new_global()} with @cite{kind} 8521@ref{f7,,GCC_JIT_GLOBAL_EXPORTED}. 8522 8523If the global is found, the result will need to be cast to a 8524pointer of the correct type before it can be called. 8525 8526This is a @emph{pointer} to the global, so e.g. for an @code{int} this is 8527an @code{int *}. 8528 8529For example, given an @code{int foo;} created this way: 8530 8531@example 8532gcc_jit_lvalue *exported_global = 8533 gcc_jit_context_new_global (ctxt, 8534 any_location, /* or NULL */ 8535 GCC_JIT_GLOBAL_EXPORTED, 8536 int_type, 8537 "foo"); 8538@end example 8539 8540we can access it like this: 8541 8542@example 8543int *ptr_to_foo = 8544 (int *)gcc_jit_result_get_global (result, "foo"); 8545@end example 8546 8547If such a global is not found (or @cite{result} or @cite{name} are 8548@code{NULL}), an error message will be emitted on stderr and 8549@code{NULL} will be returned. 8550 8551Note that the resulting address becomes invalid after 8552@ref{39,,gcc_jit_result_release()} is called on the 8553@ref{16,,gcc_jit_result *}; attempting to use it after that may lead 8554to a segmentation fault. 8555@end deffn 8556 8557@geindex gcc_jit_result_release (C function) 8558@anchor{topics/compilation c gcc_jit_result_release}@anchor{39} 8559@deffn {C Function} void gcc_jit_result_release (gcc_jit_result@w{ }*result) 8560 8561Once we���re done with the code, this unloads the built .so file. 8562This cleans up the result; after calling this, it���s no longer 8563valid to use the result, or any code or globals that were obtained 8564by calling @ref{17,,gcc_jit_result_get_code()} or 8565@ref{f8,,gcc_jit_result_get_global()} on it. 8566@end deffn 8567 8568@node Ahead-of-time compilation,,In-memory compilation,Compiling a context 8569@anchor{topics/compilation ahead-of-time-compilation}@anchor{12a} 8570@subsection Ahead-of-time compilation 8571 8572 8573Although libgccjit is primarily aimed at just-in-time compilation, it 8574can also be used for implementing more traditional ahead-of-time 8575compilers, via the @ref{4a,,gcc_jit_context_compile_to_file()} 8576API entrypoint. 8577 8578For linking in object files, use @ref{76,,gcc_jit_context_add_driver_option()}. 8579 8580@geindex gcc_jit_context_compile_to_file (C function) 8581@anchor{topics/compilation c gcc_jit_context_compile_to_file}@anchor{4a} 8582@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) 8583 8584Compile the @ref{8,,gcc_jit_context *} to a file of the given 8585kind. 8586@end deffn 8587 8588@ref{4a,,gcc_jit_context_compile_to_file()} ignores the suffix of 8589@code{output_path}, and insteads uses the given 8590@code{enum gcc_jit_output_kind} to decide what to do. 8591 8592@cartouche 8593@quotation Note 8594This is different from the @code{gcc} program, which does make use of the 8595suffix of the output file when determining what to do. 8596@end quotation 8597@end cartouche 8598 8599@geindex gcc_jit_output_kind (C type) 8600@anchor{topics/compilation c gcc_jit_output_kind}@anchor{12b} 8601@deffn {C Type} enum gcc_jit_output_kind 8602@end deffn 8603 8604The available kinds of output are: 8605 8606 8607@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxx} 8608@headitem 8609 8610Output kind 8611 8612@tab 8613 8614Typical suffix 8615 8616@item 8617 8618@ref{12c,,GCC_JIT_OUTPUT_KIND_ASSEMBLER} 8619 8620@tab 8621 8622.s 8623 8624@item 8625 8626@ref{12d,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE} 8627 8628@tab 8629 8630.o 8631 8632@item 8633 8634@ref{12e,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY} 8635 8636@tab 8637 8638.so or .dll 8639 8640@item 8641 8642@ref{12f,,GCC_JIT_OUTPUT_KIND_EXECUTABLE} 8643 8644@tab 8645 8646None, or .exe 8647 8648@end multitable 8649 8650 8651@geindex GCC_JIT_OUTPUT_KIND_ASSEMBLER (C macro) 8652@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{12c} 8653@deffn {C Macro} GCC_JIT_OUTPUT_KIND_ASSEMBLER 8654 8655Compile the context to an assembler file. 8656@end deffn 8657 8658@geindex GCC_JIT_OUTPUT_KIND_OBJECT_FILE (C macro) 8659@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{12d} 8660@deffn {C Macro} GCC_JIT_OUTPUT_KIND_OBJECT_FILE 8661 8662Compile the context to an object file. 8663@end deffn 8664 8665@geindex GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY (C macro) 8666@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{12e} 8667@deffn {C Macro} GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY 8668 8669Compile the context to a dynamic library. 8670@end deffn 8671 8672@geindex GCC_JIT_OUTPUT_KIND_EXECUTABLE (C macro) 8673@anchor{topics/compilation c GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{12f} 8674@deffn {C Macro} GCC_JIT_OUTPUT_KIND_EXECUTABLE 8675 8676Compile the context to an executable. 8677@end deffn 8678 8679@c Copyright (C) 2015-2022 Free Software Foundation, Inc. 8680@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8681@c 8682@c This is free software: you can redistribute it and/or modify it 8683@c under the terms of the GNU General Public License as published by 8684@c the Free Software Foundation, either version 3 of the License, or 8685@c (at your option) any later version. 8686@c 8687@c This program is distributed in the hope that it will be useful, but 8688@c WITHOUT ANY WARRANTY; without even the implied warranty of 8689@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8690@c General Public License for more details. 8691@c 8692@c You should have received a copy of the GNU General Public License 8693@c along with this program. If not, see 8694@c <https://www.gnu.org/licenses/>. 8695 8696@node ABI and API compatibility,Performance,Compiling a context,Topic Reference 8697@anchor{topics/compatibility doc}@anchor{130}@anchor{topics/compatibility abi-and-api-compatibility}@anchor{131} 8698@section ABI and API compatibility 8699 8700 8701The libgccjit developers strive for ABI and API backward-compatibility: 8702programs built against libgccjit.so stand a good chance of running 8703without recompilation against newer versions of libgccjit.so, and 8704ought to recompile without modification against newer versions of 8705libgccjit.h. 8706 8707@cartouche 8708@quotation Note 8709The libgccjit++.h C++ API is more experimental, and less 8710locked-down at this time. 8711@end quotation 8712@end cartouche 8713 8714API compatibility is achieved by extending the API rather than changing 8715it. For ABI compatiblity, we avoid bumping the SONAME, and instead use 8716symbol versioning to tag each symbol, so that a binary linked against 8717libgccjit.so is tagged according to the symbols that it uses. 8718 8719For example, @ref{74,,gcc_jit_context_add_command_line_option()} was added in 8720@code{LIBGCCJIT_ABI_1}. If a client program uses it, this can be detected 8721from metadata by using @code{objdump}: 8722 8723@example 8724$ objdump -p testsuite/jit/test-extra-options.c.exe | tail -n 8 8725 8726Version References: 8727 required from libgccjit.so.0: 8728 0x00824161 0x00 04 LIBGCCJIT_ABI_1 8729 0x00824160 0x00 03 LIBGCCJIT_ABI_0 8730 required from libc.so.6: 8731@end example 8732 8733You can see the symbol tags provided by libgccjit.so using @code{objdump}: 8734 8735@example 8736$ objdump -p libgccjit.so | less 8737[...snip...] 8738Version definitions: 87391 0x01 0x0ff81f20 libgccjit.so.0 87402 0x00 0x00824160 LIBGCCJIT_ABI_0 87413 0x00 0x00824161 LIBGCCJIT_ABI_1 8742 LIBGCCJIT_ABI_0 8743[...snip...] 8744@end example 8745 8746@menu 8747* Programmatically checking version:: 8748* ABI symbol tags:: 8749 8750@end menu 8751 8752@node Programmatically checking version,ABI symbol tags,,ABI and API compatibility 8753@anchor{topics/compatibility programmatically-checking-version}@anchor{132} 8754@subsection Programmatically checking version 8755 8756 8757Client code can programmatically check libgccjit version using: 8758 8759@geindex gcc_jit_version_major (C function) 8760@anchor{topics/compatibility c gcc_jit_version_major}@anchor{133} 8761@deffn {C Function} int gcc_jit_version_major (void) 8762 8763Return libgccjit major version. This is analogous to __GNUC__ in C code. 8764@end deffn 8765 8766@geindex gcc_jit_version_minor (C function) 8767@anchor{topics/compatibility c gcc_jit_version_minor}@anchor{134} 8768@deffn {C Function} int gcc_jit_version_minor (void) 8769 8770Return libgccjit minor version. This is analogous to 8771__GNUC_MINOR__ in C code. 8772@end deffn 8773 8774@geindex gcc_jit_version_patchlevel (C function) 8775@anchor{topics/compatibility c gcc_jit_version_patchlevel}@anchor{135} 8776@deffn {C Function} int gcc_jit_version_patchlevel (void) 8777 8778Return libgccjit patchlevel version. This is analogous to 8779__GNUC_PATCHLEVEL__ in C code. 8780@end deffn 8781 8782@cartouche 8783@quotation Note 8784These entry points has been added with @code{LIBGCCJIT_ABI_13} 8785(see below). 8786@end quotation 8787@end cartouche 8788 8789@node ABI symbol tags,,Programmatically checking version,ABI and API compatibility 8790@anchor{topics/compatibility abi-symbol-tags}@anchor{136} 8791@subsection ABI symbol tags 8792 8793 8794The initial release of libgccjit (in gcc 5.1) did not use symbol versioning. 8795 8796Newer releases use the following tags. 8797 8798@menu 8799* LIBGCCJIT_ABI_0:: 8800* LIBGCCJIT_ABI_1:: 8801* LIBGCCJIT_ABI_2:: 8802* LIBGCCJIT_ABI_3:: 8803* LIBGCCJIT_ABI_4:: 8804* LIBGCCJIT_ABI_5:: 8805* LIBGCCJIT_ABI_6:: 8806* LIBGCCJIT_ABI_7:: 8807* LIBGCCJIT_ABI_8:: 8808* LIBGCCJIT_ABI_9:: 8809* LIBGCCJIT_ABI_10:: 8810* LIBGCCJIT_ABI_11:: 8811* LIBGCCJIT_ABI_12:: 8812* LIBGCCJIT_ABI_13:: 8813* LIBGCCJIT_ABI_14:: 8814* LIBGCCJIT_ABI_15:: 8815* LIBGCCJIT_ABI_16:: 8816* LIBGCCJIT_ABI_17:: 8817* LIBGCCJIT_ABI_18:: 8818* LIBGCCJIT_ABI_19:: 8819* LIBGCCJIT_ABI_20:: 8820* LIBGCCJIT_ABI_21:: 8821* LIBGCCJIT_ABI_22:: 8822* LIBGCCJIT_ABI_23:: 8823* LIBGCCJIT_ABI_24:: 8824 8825@end menu 8826 8827@node LIBGCCJIT_ABI_0,LIBGCCJIT_ABI_1,,ABI symbol tags 8828@anchor{topics/compatibility id1}@anchor{137}@anchor{topics/compatibility libgccjit-abi-0}@anchor{138} 8829@subsubsection @code{LIBGCCJIT_ABI_0} 8830 8831 8832All entrypoints in the initial release of libgccjit are tagged with 8833@code{LIBGCCJIT_ABI_0}, to signify the transition to symbol versioning. 8834 8835Binaries built against older copies of @code{libgccjit.so} should 8836continue to work, with this being handled transparently by the linker 8837(see this post@footnote{https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html}) 8838 8839@node LIBGCCJIT_ABI_1,LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_0,ABI symbol tags 8840@anchor{topics/compatibility id2}@anchor{139}@anchor{topics/compatibility libgccjit-abi-1}@anchor{75} 8841@subsubsection @code{LIBGCCJIT_ABI_1} 8842 8843 8844@code{LIBGCCJIT_ABI_1} covers the addition of 8845@ref{74,,gcc_jit_context_add_command_line_option()} 8846 8847@node LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_1,ABI symbol tags 8848@anchor{topics/compatibility id3}@anchor{13a}@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c} 8849@subsubsection @code{LIBGCCJIT_ABI_2} 8850 8851 8852@code{LIBGCCJIT_ABI_2} covers the addition of 8853@ref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()} 8854 8855@node LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_2,ABI symbol tags 8856@anchor{topics/compatibility id4}@anchor{13b}@anchor{topics/compatibility libgccjit-abi-3}@anchor{11f} 8857@subsubsection @code{LIBGCCJIT_ABI_3} 8858 8859 8860@code{LIBGCCJIT_ABI_3} covers the addition of switch statements via API 8861entrypoints: 8862 8863@quotation 8864 8865 8866@itemize * 8867 8868@item 8869@ref{11c,,gcc_jit_block_end_with_switch()} 8870 8871@item 8872@ref{11d,,gcc_jit_case_as_object()} 8873 8874@item 8875@ref{11e,,gcc_jit_context_new_case()} 8876@end itemize 8877@end quotation 8878 8879@node LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_3,ABI symbol tags 8880@anchor{topics/compatibility id5}@anchor{13c}@anchor{topics/compatibility libgccjit-abi-4}@anchor{13d} 8881@subsubsection @code{LIBGCCJIT_ABI_4} 8882 8883 8884@code{LIBGCCJIT_ABI_4} covers the addition of timers via API 8885entrypoints: 8886 8887@quotation 8888 8889 8890@itemize * 8891 8892@item 8893@ref{13e,,gcc_jit_context_get_timer()} 8894 8895@item 8896@ref{13f,,gcc_jit_context_set_timer()} 8897 8898@item 8899@ref{140,,gcc_jit_timer_new()} 8900 8901@item 8902@ref{141,,gcc_jit_timer_release()} 8903 8904@item 8905@ref{142,,gcc_jit_timer_push()} 8906 8907@item 8908@ref{143,,gcc_jit_timer_pop()} 8909 8910@item 8911@ref{144,,gcc_jit_timer_print()} 8912@end itemize 8913@end quotation 8914 8915@node LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_6,LIBGCCJIT_ABI_4,ABI symbol tags 8916@anchor{topics/compatibility id6}@anchor{145}@anchor{topics/compatibility libgccjit-abi-5}@anchor{6e} 8917@subsubsection @code{LIBGCCJIT_ABI_5} 8918 8919 8920@code{LIBGCCJIT_ABI_5} covers the addition of 8921@ref{6d,,gcc_jit_context_set_bool_use_external_driver()} 8922 8923@node LIBGCCJIT_ABI_6,LIBGCCJIT_ABI_7,LIBGCCJIT_ABI_5,ABI symbol tags 8924@anchor{topics/compatibility id7}@anchor{146}@anchor{topics/compatibility libgccjit-abi-6}@anchor{db} 8925@subsubsection @code{LIBGCCJIT_ABI_6} 8926 8927 8928@code{LIBGCCJIT_ABI_6} covers the addition of 8929@ref{da,,gcc_jit_rvalue_set_bool_require_tail_call()} 8930 8931@node LIBGCCJIT_ABI_7,LIBGCCJIT_ABI_8,LIBGCCJIT_ABI_6,ABI symbol tags 8932@anchor{topics/compatibility id8}@anchor{147}@anchor{topics/compatibility libgccjit-abi-7}@anchor{85} 8933@subsubsection @code{LIBGCCJIT_ABI_7} 8934 8935 8936@code{LIBGCCJIT_ABI_7} covers the addition of 8937@ref{84,,gcc_jit_type_get_aligned()} 8938 8939@node LIBGCCJIT_ABI_8,LIBGCCJIT_ABI_9,LIBGCCJIT_ABI_7,ABI symbol tags 8940@anchor{topics/compatibility id9}@anchor{148}@anchor{topics/compatibility libgccjit-abi-8}@anchor{88} 8941@subsubsection @code{LIBGCCJIT_ABI_8} 8942 8943 8944@code{LIBGCCJIT_ABI_8} covers the addition of 8945@ref{87,,gcc_jit_type_get_vector()} 8946 8947@node LIBGCCJIT_ABI_9,LIBGCCJIT_ABI_10,LIBGCCJIT_ABI_8,ABI symbol tags 8948@anchor{topics/compatibility id10}@anchor{149}@anchor{topics/compatibility libgccjit-abi-9}@anchor{123} 8949@subsubsection @code{LIBGCCJIT_ABI_9} 8950 8951 8952@code{LIBGCCJIT_ABI_9} covers the addition of 8953@ref{dd,,gcc_jit_function_get_address()} 8954 8955@node LIBGCCJIT_ABI_10,LIBGCCJIT_ABI_11,LIBGCCJIT_ABI_9,ABI symbol tags 8956@anchor{topics/compatibility id11}@anchor{14a}@anchor{topics/compatibility libgccjit-abi-10}@anchor{bd} 8957@subsubsection @code{LIBGCCJIT_ABI_10} 8958 8959 8960@code{LIBGCCJIT_ABI_10} covers the addition of 8961@ref{89,,gcc_jit_context_new_rvalue_from_vector()} 8962 8963@node LIBGCCJIT_ABI_11,LIBGCCJIT_ABI_12,LIBGCCJIT_ABI_10,ABI symbol tags 8964@anchor{topics/compatibility id12}@anchor{14b}@anchor{topics/compatibility libgccjit-abi-11}@anchor{77} 8965@subsubsection @code{LIBGCCJIT_ABI_11} 8966 8967 8968@code{LIBGCCJIT_ABI_11} covers the addition of 8969@ref{76,,gcc_jit_context_add_driver_option()} 8970 8971@node LIBGCCJIT_ABI_12,LIBGCCJIT_ABI_13,LIBGCCJIT_ABI_11,ABI symbol tags 8972@anchor{topics/compatibility id13}@anchor{14c}@anchor{topics/compatibility libgccjit-abi-12}@anchor{8f} 8973@subsubsection @code{LIBGCCJIT_ABI_12} 8974 8975 8976@code{LIBGCCJIT_ABI_12} covers the addition of 8977@ref{8e,,gcc_jit_context_new_bitfield()} 8978 8979@node LIBGCCJIT_ABI_13,LIBGCCJIT_ABI_14,LIBGCCJIT_ABI_12,ABI symbol tags 8980@anchor{topics/compatibility id14}@anchor{14d}@anchor{topics/compatibility libgccjit-abi-13}@anchor{14e} 8981@subsubsection @code{LIBGCCJIT_ABI_13} 8982 8983 8984@code{LIBGCCJIT_ABI_13} covers the addition of version functions via API 8985entrypoints: 8986 8987@quotation 8988 8989 8990@itemize * 8991 8992@item 8993@ref{133,,gcc_jit_version_major()} 8994 8995@item 8996@ref{134,,gcc_jit_version_minor()} 8997 8998@item 8999@ref{135,,gcc_jit_version_patchlevel()} 9000@end itemize 9001@end quotation 9002 9003@node LIBGCCJIT_ABI_14,LIBGCCJIT_ABI_15,LIBGCCJIT_ABI_13,ABI symbol tags 9004@anchor{topics/compatibility id15}@anchor{14f}@anchor{topics/compatibility libgccjit-abi-14}@anchor{fc} 9005@subsubsection @code{LIBGCCJIT_ABI_14} 9006 9007 9008@code{LIBGCCJIT_ABI_14} covers the addition of 9009@ref{fb,,gcc_jit_global_set_initializer()} 9010 9011@node LIBGCCJIT_ABI_15,LIBGCCJIT_ABI_16,LIBGCCJIT_ABI_14,ABI symbol tags 9012@anchor{topics/compatibility id16}@anchor{150}@anchor{topics/compatibility libgccjit-abi-15}@anchor{151} 9013@subsubsection @code{LIBGCCJIT_ABI_15} 9014 9015 9016@code{LIBGCCJIT_ABI_15} covers the addition of API entrypoints for directly 9017embedding assembler instructions: 9018 9019@quotation 9020 9021 9022@itemize * 9023 9024@item 9025@ref{152,,gcc_jit_block_add_extended_asm()} 9026 9027@item 9028@ref{153,,gcc_jit_block_end_with_extended_asm_goto()} 9029 9030@item 9031@ref{154,,gcc_jit_extended_asm_as_object()} 9032 9033@item 9034@ref{155,,gcc_jit_extended_asm_set_volatile_flag()} 9035 9036@item 9037@ref{156,,gcc_jit_extended_asm_set_inline_flag()} 9038 9039@item 9040@ref{157,,gcc_jit_extended_asm_add_output_operand()} 9041 9042@item 9043@ref{158,,gcc_jit_extended_asm_add_input_operand()} 9044 9045@item 9046@ref{159,,gcc_jit_extended_asm_add_clobber()} 9047 9048@item 9049@ref{15a,,gcc_jit_context_add_top_level_asm()} 9050@end itemize 9051@end quotation 9052 9053@node LIBGCCJIT_ABI_16,LIBGCCJIT_ABI_17,LIBGCCJIT_ABI_15,ABI symbol tags 9054@anchor{topics/compatibility id17}@anchor{15b}@anchor{topics/compatibility libgccjit-abi-16}@anchor{a8} 9055@subsubsection @code{LIBGCCJIT_ABI_16} 9056 9057 9058@code{LIBGCCJIT_ABI_16} covers the addition of reflection functions via API 9059entrypoints: 9060 9061@quotation 9062 9063 9064@itemize * 9065 9066@item 9067@ref{112,,gcc_jit_function_get_return_type()} 9068 9069@item 9070@ref{111,,gcc_jit_function_get_param_count()} 9071 9072@item 9073@ref{99,,gcc_jit_type_dyncast_array()} 9074 9075@item 9076@ref{9a,,gcc_jit_type_is_bool()} 9077 9078@item 9079@ref{9f,,gcc_jit_type_is_integral()} 9080 9081@item 9082@ref{a0,,gcc_jit_type_is_pointer()} 9083 9084@item 9085@ref{a2,,gcc_jit_type_is_struct()} 9086 9087@item 9088@ref{a1,,gcc_jit_type_dyncast_vector()} 9089 9090@item 9091@ref{a5,,gcc_jit_type_unqualified()} 9092 9093@item 9094@ref{9b,,gcc_jit_type_dyncast_function_ptr_type()} 9095 9096@item 9097@ref{9c,,gcc_jit_function_type_get_return_type()} 9098 9099@item 9100@ref{9d,,gcc_jit_function_type_get_param_count()} 9101 9102@item 9103@ref{9e,,gcc_jit_function_type_get_param_type()} 9104 9105@item 9106@ref{a3,,gcc_jit_vector_type_get_num_units()} 9107 9108@item 9109@ref{a4,,gcc_jit_vector_type_get_element_type()} 9110 9111@item 9112@ref{a6,,gcc_jit_struct_get_field()} 9113 9114@item 9115@ref{a7,,gcc_jit_struct_get_field_count()} 9116@end itemize 9117@end quotation 9118 9119@node LIBGCCJIT_ABI_17,LIBGCCJIT_ABI_18,LIBGCCJIT_ABI_16,ABI symbol tags 9120@anchor{topics/compatibility id18}@anchor{15c}@anchor{topics/compatibility libgccjit-abi-17}@anchor{ed} 9121@subsubsection @code{LIBGCCJIT_ABI_17} 9122 9123 9124@code{LIBGCCJIT_ABI_17} covers the addition of an API entrypoint to set the 9125thread-local storage model of a variable: 9126 9127@quotation 9128 9129 9130@itemize * 9131 9132@item 9133@ref{e6,,gcc_jit_lvalue_set_tls_model()} 9134@end itemize 9135@end quotation 9136 9137@node LIBGCCJIT_ABI_18,LIBGCCJIT_ABI_19,LIBGCCJIT_ABI_17,ABI symbol tags 9138@anchor{topics/compatibility id19}@anchor{15d}@anchor{topics/compatibility libgccjit-abi-18}@anchor{ef} 9139@subsubsection @code{LIBGCCJIT_ABI_18} 9140 9141 9142@code{LIBGCCJIT_ABI_18} covers the addition of an API entrypoint to set the link 9143section of a variable: 9144 9145@quotation 9146 9147 9148@itemize * 9149 9150@item 9151@ref{ee,,gcc_jit_lvalue_set_link_section()} 9152@end itemize 9153@end quotation 9154 9155@node LIBGCCJIT_ABI_19,LIBGCCJIT_ABI_20,LIBGCCJIT_ABI_18,ABI symbol tags 9156@anchor{topics/compatibility id20}@anchor{15e}@anchor{topics/compatibility libgccjit-abi-19}@anchor{b8} 9157@subsubsection @code{LIBGCCJIT_ABI_19} 9158 9159 9160@code{LIBGCCJIT_ABI_19} covers the addition of API entrypoints to set the initial value 9161of a global with an rvalue and to use constructors: 9162 9163@quotation 9164 9165 9166@itemize * 9167 9168@item 9169@ref{b9,,gcc_jit_context_new_array_constructor()} 9170 9171@item 9172@ref{ba,,gcc_jit_context_new_struct_constructor()} 9173 9174@item 9175@ref{bb,,gcc_jit_context_new_union_constructor()} 9176 9177@item 9178@ref{b7,,gcc_jit_global_set_initializer_rvalue()} 9179@end itemize 9180@end quotation 9181 9182@node LIBGCCJIT_ABI_20,LIBGCCJIT_ABI_21,LIBGCCJIT_ABI_19,ABI symbol tags 9183@anchor{topics/compatibility id21}@anchor{15f}@anchor{topics/compatibility libgccjit-abi-20}@anchor{ab} 9184@subsubsection @code{LIBGCCJIT_ABI_20} 9185 9186 9187@code{LIBGCCJIT_ABI_20} covers the addition of sized integer types, including 9188128-bit integers and helper functions for types: 9189 9190@quotation 9191 9192 9193@itemize * 9194 9195@item 9196@ref{aa,,gcc_jit_compatible_types()} 9197 9198@item 9199@ref{ac,,gcc_jit_type_get_size()} 9200 9201@item 9202@code{GCC_JIT_TYPE_UINT8_T} 9203 9204@item 9205@code{GCC_JIT_TYPE_UINT16_T} 9206 9207@item 9208@code{GCC_JIT_TYPE_UINT32_T} 9209 9210@item 9211@code{GCC_JIT_TYPE_UINT64_T} 9212 9213@item 9214@code{GCC_JIT_TYPE_UINT128_T} 9215 9216@item 9217@code{GCC_JIT_TYPE_INT8_T} 9218 9219@item 9220@code{GCC_JIT_TYPE_INT16_T} 9221 9222@item 9223@code{GCC_JIT_TYPE_INT32_T} 9224 9225@item 9226@code{GCC_JIT_TYPE_INT64_T} 9227 9228@item 9229@code{GCC_JIT_TYPE_INT128_T} 9230@end itemize 9231@end quotation 9232 9233@node LIBGCCJIT_ABI_21,LIBGCCJIT_ABI_22,LIBGCCJIT_ABI_20,ABI symbol tags 9234@anchor{topics/compatibility id22}@anchor{160}@anchor{topics/compatibility libgccjit-abi-21}@anchor{e1} 9235@subsubsection @code{LIBGCCJIT_ABI_21} 9236 9237 9238@code{LIBGCCJIT_ABI_21} covers the addition of an API entrypoint to bitcast a 9239value from one type to another: 9240 9241@quotation 9242 9243 9244@itemize * 9245 9246@item 9247@ref{e0,,gcc_jit_context_new_bitcast()} 9248@end itemize 9249@end quotation 9250 9251@node LIBGCCJIT_ABI_22,LIBGCCJIT_ABI_23,LIBGCCJIT_ABI_21,ABI symbol tags 9252@anchor{topics/compatibility id23}@anchor{161}@anchor{topics/compatibility libgccjit-abi-22}@anchor{f0} 9253@subsubsection @code{LIBGCCJIT_ABI_22} 9254 9255 9256@code{LIBGCCJIT_ABI_22} covers the addition of an API entrypoint to set the 9257register name of a variable: 9258 9259@quotation 9260 9261 9262@itemize * 9263 9264@item 9265@code{gcc_jit_lvalue_set_register_name()} 9266@end itemize 9267@end quotation 9268 9269@node LIBGCCJIT_ABI_23,LIBGCCJIT_ABI_24,LIBGCCJIT_ABI_22,ABI symbol tags 9270@anchor{topics/compatibility id24}@anchor{162}@anchor{topics/compatibility libgccjit-abi-23}@anchor{70} 9271@subsubsection @code{LIBGCCJIT_ABI_23} 9272 9273 9274@code{LIBGCCJIT_ABI_23} covers the addition of an API entrypoint to hide stderr 9275logs: 9276 9277@quotation 9278 9279 9280@itemize * 9281 9282@item 9283@ref{6f,,gcc_jit_context_set_bool_print_errors_to_stderr()} 9284@end itemize 9285@end quotation 9286 9287@node LIBGCCJIT_ABI_24,,LIBGCCJIT_ABI_23,ABI symbol tags 9288@anchor{topics/compatibility id25}@anchor{163}@anchor{topics/compatibility libgccjit-abi-24}@anchor{f2} 9289@subsubsection @code{LIBGCCJIT_ABI_24} 9290 9291 9292@code{LIBGCCJIT_ABI_24} covers the addition of functions to get and set the 9293alignment of a variable: 9294 9295@quotation 9296 9297 9298@itemize * 9299 9300@item 9301@ref{f1,,gcc_jit_lvalue_set_alignment()} 9302 9303@item 9304@ref{f3,,gcc_jit_lvalue_get_alignment()} 9305@end itemize 9306@end quotation 9307 9308@c Copyright (C) 2015-2022 Free Software Foundation, Inc. 9309@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9310@c 9311@c This is free software: you can redistribute it and/or modify it 9312@c under the terms of the GNU General Public License as published by 9313@c the Free Software Foundation, either version 3 of the License, or 9314@c (at your option) any later version. 9315@c 9316@c This program is distributed in the hope that it will be useful, but 9317@c WITHOUT ANY WARRANTY; without even the implied warranty of 9318@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9319@c General Public License for more details. 9320@c 9321@c You should have received a copy of the GNU General Public License 9322@c along with this program. If not, see 9323@c <https://www.gnu.org/licenses/>. 9324 9325@node Performance,Using Assembly Language with libgccjit,ABI and API compatibility,Topic Reference 9326@anchor{topics/performance doc}@anchor{164}@anchor{topics/performance performance}@anchor{165} 9327@section Performance 9328 9329 9330@menu 9331* The timing API:: 9332 9333@end menu 9334 9335@node The timing API,,,Performance 9336@anchor{topics/performance the-timing-api}@anchor{166} 9337@subsection The timing API 9338 9339 9340As of GCC 6, libgccjit exposes a timing API, for printing reports on 9341how long was spent in different parts of code. 9342 9343You can create a @ref{167,,gcc_jit_timer} instance, which will 9344measure time spent since its creation. The timer maintains a stack 9345of ���timer items���: as control flow moves through your code, you can push 9346and pop named items relating to your code onto the stack, and the timer 9347will account the time spent accordingly. 9348 9349You can also asssociate a timer with a @ref{8,,gcc_jit_context}, in 9350which case the time spent inside compilation will be subdivided. 9351 9352For example, the following code uses a timer, recording client items 9353���create_code���, ���compile���, and ���running code���: 9354 9355@example 9356/* Create a timer. */ 9357gcc_jit_timer *timer = gcc_jit_timer_new (); 9358if (!timer) 9359 @{ 9360 error ("gcc_jit_timer_new failed"); 9361 return -1; 9362 @} 9363 9364/* Let's repeatedly compile and run some code, accumulating it 9365 all into the timer. */ 9366for (int i = 0; i < num_iterations; i++) 9367 @{ 9368 /* Create a context and associate it with the timer. */ 9369 gcc_jit_context *ctxt = gcc_jit_context_acquire (); 9370 if (!ctxt) 9371 @{ 9372 error ("gcc_jit_context_acquire failed"); 9373 return -1; 9374 @} 9375 gcc_jit_context_set_timer (ctxt, timer); 9376 9377 /* Populate the context, timing it as client item "create_code". */ 9378 gcc_jit_timer_push (timer, "create_code"); 9379 create_code (ctxt); 9380 gcc_jit_timer_pop (timer, "create_code"); 9381 9382 /* Compile the context, timing it as client item "compile". */ 9383 gcc_jit_timer_push (timer, "compile"); 9384 result = gcc_jit_context_compile (ctxt); 9385 gcc_jit_timer_pop (timer, "compile"); 9386 9387 /* Run the generated code, timing it as client item "running code". */ 9388 gcc_jit_timer_push (timer, "running code"); 9389 run_the_code (ctxt, result); 9390 gcc_jit_timer_pop (timer, "running code"); 9391 9392 /* Clean up. */ 9393 gcc_jit_context_release (ctxt); 9394 gcc_jit_result_release (result); 9395@} 9396 9397/* Print the accumulated timings. */ 9398gcc_jit_timer_print (timer, stderr); 9399gcc_jit_timer_release (timer); 9400@end example 9401 9402giving output like this, showing the internal GCC items at the top, then 9403client items, then the total: 9404 9405@example 9406Execution times (seconds) 9407GCC items: 9408 phase setup : 0.29 (14%) usr 0.00 ( 0%) sys 0.32 ( 5%) wall 10661 kB (50%) ggc 9409 phase parsing : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 653 kB ( 3%) ggc 9410 phase finalize : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 9411 dump files : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc 9412 callgraph construction : 0.02 ( 1%) usr 0.01 ( 6%) sys 0.01 ( 0%) wall 242 kB ( 1%) ggc 9413 callgraph optimization : 0.03 ( 2%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 142 kB ( 1%) ggc 9414 trivially dead code : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 9415 df scan insns : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 9 kB ( 0%) ggc 9416 df live regs : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc 9417 inline parameters : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 82 kB ( 0%) ggc 9418 tree CFG cleanup : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 9419 tree PHI insertion : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 64 kB ( 0%) ggc 9420 tree SSA other : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 18 kB ( 0%) ggc 9421 expand : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 398 kB ( 2%) ggc 9422 jump : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 9423 loop init : 0.01 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 67 kB ( 0%) ggc 9424 integrated RA : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 2468 kB (12%) ggc 9425 thread pro- & epilogue : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 162 kB ( 1%) ggc 9426 final : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 216 kB ( 1%) ggc 9427 rest of compilation : 1.37 (69%) usr 0.00 ( 0%) sys 1.13 (18%) wall 1391 kB ( 6%) ggc 9428 assemble JIT code : 0.01 ( 1%) usr 0.00 ( 0%) sys 4.04 (66%) wall 0 kB ( 0%) ggc 9429 load JIT result : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 9430 JIT client code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 9431Client items: 9432 create_code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 9433 compile : 0.36 (18%) usr 0.15 (83%) sys 0.86 (14%) wall 14939 kB (70%) ggc 9434 running code : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 9435 TOTAL : 2.00 0.18 6.12 21444 kB 9436@end example 9437 9438The exact format is intended to be human-readable, and is subject to change. 9439 9440@geindex LIBGCCJIT_HAVE_TIMING_API (C macro) 9441@anchor{topics/performance c LIBGCCJIT_HAVE_TIMING_API}@anchor{168} 9442@deffn {C Macro} LIBGCCJIT_HAVE_TIMING_API 9443 9444The timer API was added to libgccjit in GCC 6. 9445This macro is only defined in versions of libgccjit.h which have the 9446timer API, and so can be used to guard code that may need to compile 9447against earlier releases: 9448 9449@example 9450#ifdef LIBGCCJIT_HAVE_TIMING_API 9451gcc_jit_timer *t = gcc_jit_timer_new (); 9452gcc_jit_context_set_timer (ctxt, t); 9453#endif 9454@end example 9455@end deffn 9456 9457@geindex gcc_jit_timer (C type) 9458@anchor{topics/performance c gcc_jit_timer}@anchor{167} 9459@deffn {C Type} gcc_jit_timer 9460@end deffn 9461 9462@geindex gcc_jit_timer_new (C function) 9463@anchor{topics/performance c gcc_jit_timer_new}@anchor{140} 9464@deffn {C Function} gcc_jit_timer * gcc_jit_timer_new (void) 9465 9466Create a @ref{167,,gcc_jit_timer} instance, and start timing: 9467 9468@example 9469gcc_jit_timer *t = gcc_jit_timer_new (); 9470@end example 9471 9472This API entrypoint was added in @ref{13d,,LIBGCCJIT_ABI_4}; you can test 9473for its presence using 9474 9475@example 9476#ifdef LIBGCCJIT_HAVE_TIMING_API 9477@end example 9478@end deffn 9479 9480@geindex gcc_jit_timer_release (C function) 9481@anchor{topics/performance c gcc_jit_timer_release}@anchor{141} 9482@deffn {C Function} void gcc_jit_timer_release (gcc_jit_timer@w{ }*timer) 9483 9484Release a @ref{167,,gcc_jit_timer} instance: 9485 9486@example 9487gcc_jit_timer_release (t); 9488@end example 9489 9490This should be called exactly once on a timer. 9491 9492This API entrypoint was added in @ref{13d,,LIBGCCJIT_ABI_4}; you can test 9493for its presence using 9494 9495@example 9496#ifdef LIBGCCJIT_HAVE_TIMING_API 9497@end example 9498@end deffn 9499 9500@geindex gcc_jit_context_set_timer (C function) 9501@anchor{topics/performance c gcc_jit_context_set_timer}@anchor{13f} 9502@deffn {C Function} void gcc_jit_context_set_timer (gcc_jit_context@w{ }*ctxt, gcc_jit_timer@w{ }*timer) 9503 9504Associate a @ref{167,,gcc_jit_timer} instance with a context: 9505 9506@example 9507gcc_jit_context_set_timer (ctxt, t); 9508@end example 9509 9510A timer instance can be shared between multiple 9511@ref{8,,gcc_jit_context} instances. 9512 9513Timers have no locking, so if you have a multithreaded program, you 9514must provide your own locks if more than one thread could be working 9515with the same timer via timer-associated contexts. 9516 9517This API entrypoint was added in @ref{13d,,LIBGCCJIT_ABI_4}; you can test 9518for its presence using 9519 9520@example 9521#ifdef LIBGCCJIT_HAVE_TIMING_API 9522@end example 9523@end deffn 9524 9525@geindex gcc_jit_context_get_timer (C function) 9526@anchor{topics/performance c gcc_jit_context_get_timer}@anchor{13e} 9527@deffn {C Function} gcc_jit_timer *gcc_jit_context_get_timer (gcc_jit_context@w{ }*ctxt) 9528 9529Get the timer associated with a context (if any). 9530 9531This API entrypoint was added in @ref{13d,,LIBGCCJIT_ABI_4}; you can test 9532for its presence using 9533 9534@example 9535#ifdef LIBGCCJIT_HAVE_TIMING_API 9536@end example 9537@end deffn 9538 9539@geindex gcc_jit_timer_push (C function) 9540@anchor{topics/performance c gcc_jit_timer_push}@anchor{142} 9541@deffn {C Function} void gcc_jit_timer_push (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name) 9542 9543Push the given item onto the timer���s stack: 9544 9545@example 9546gcc_jit_timer_push (t, "running code"); 9547run_the_code (ctxt, result); 9548gcc_jit_timer_pop (t, "running code"); 9549@end example 9550 9551This API entrypoint was added in @ref{13d,,LIBGCCJIT_ABI_4}; you can test 9552for its presence using 9553 9554@example 9555#ifdef LIBGCCJIT_HAVE_TIMING_API 9556@end example 9557@end deffn 9558 9559@geindex gcc_jit_timer_pop (C function) 9560@anchor{topics/performance c gcc_jit_timer_pop}@anchor{143} 9561@deffn {C Function} void gcc_jit_timer_pop (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name) 9562 9563Pop the top item from the timer���s stack. 9564 9565If ���item_name��� is provided, it must match that of the top item. 9566Alternatively, @code{NULL} can be passed in, to suppress checking. 9567 9568This API entrypoint was added in @ref{13d,,LIBGCCJIT_ABI_4}; you can test 9569for its presence using 9570 9571@example 9572#ifdef LIBGCCJIT_HAVE_TIMING_API 9573@end example 9574@end deffn 9575 9576@geindex gcc_jit_timer_print (C function) 9577@anchor{topics/performance c gcc_jit_timer_print}@anchor{144} 9578@deffn {C Function} void gcc_jit_timer_print (gcc_jit_timer@w{ }*timer, FILE@w{ }*f_out) 9579 9580Print timing information to the given stream about activity since 9581the timer was started. 9582 9583This API entrypoint was added in @ref{13d,,LIBGCCJIT_ABI_4}; you can test 9584for its presence using 9585 9586@example 9587#ifdef LIBGCCJIT_HAVE_TIMING_API 9588@end example 9589@end deffn 9590 9591@c Copyright (C) 2020-2022 Free Software Foundation, Inc. 9592@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9593@c 9594@c This is free software: you can redistribute it and/or modify it 9595@c under the terms of the GNU General Public License as published by 9596@c the Free Software Foundation, either version 3 of the License, or 9597@c (at your option) any later version. 9598@c 9599@c This program is distributed in the hope that it will be useful, but 9600@c WITHOUT ANY WARRANTY; without even the implied warranty of 9601@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9602@c General Public License for more details. 9603@c 9604@c You should have received a copy of the GNU General Public License 9605@c along with this program. If not, see 9606@c <https://www.gnu.org/licenses/>. 9607 9608@node Using Assembly Language with libgccjit,,Performance,Topic Reference 9609@anchor{topics/asm doc}@anchor{169}@anchor{topics/asm using-assembly-language-with-libgccjit}@anchor{16a} 9610@section Using Assembly Language with libgccjit 9611 9612 9613libgccjit has some support for directly embedding assembler instructions. 9614This is based on GCC���s support for inline @code{asm} in C code, and the 9615following assumes a familiarity with that functionality. See 9616How to Use Inline Assembly Language in C Code@footnote{https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html} 9617in GCC���s documentation, the ���Extended Asm��� section in particular. 9618 9619These entrypoints were added in @ref{151,,LIBGCCJIT_ABI_15}; you can test 9620for their presence using 9621 9622@quotation 9623 9624@example 9625#ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS 9626@end example 9627@end quotation 9628 9629@menu 9630* Adding assembler instructions within a function:: 9631* Adding top-level assembler statements:: 9632 9633@end menu 9634 9635@node Adding assembler instructions within a function,Adding top-level assembler statements,,Using Assembly Language with libgccjit 9636@anchor{topics/asm adding-assembler-instructions-within-a-function}@anchor{16b} 9637@subsection Adding assembler instructions within a function 9638 9639 9640@geindex gcc_jit_extended_asm (C type) 9641@anchor{topics/asm c gcc_jit_extended_asm}@anchor{120} 9642@deffn {C Type} gcc_jit_extended_asm 9643 9644A @cite{gcc_jit_extended_asm} represents an extended @code{asm} statement: a 9645series of low-level instructions inside a function that convert inputs 9646to outputs. 9647 9648To avoid having an API entrypoint with a very large number of 9649parameters, an extended @code{asm} statement is made in stages: 9650an initial call to create the @ref{120,,gcc_jit_extended_asm}, 9651followed by calls to add operands and set other properties of the 9652statement. 9653 9654There are two API entrypoints for creating a @ref{120,,gcc_jit_extended_asm}: 9655 9656 9657@itemize * 9658 9659@item 9660@ref{152,,gcc_jit_block_add_extended_asm()} for an @code{asm} statement with 9661no control flow, and 9662 9663@item 9664@ref{153,,gcc_jit_block_end_with_extended_asm_goto()} for an @code{asm goto}. 9665@end itemize 9666 9667For example, to create the equivalent of: 9668 9669@example 9670 asm ("mov %1, %0\n\t" 9671 "add $1, %0" 9672 : "=r" (dst) 9673 : "r" (src)); 9674@end example 9675 9676the following API calls could be used: 9677 9678@example 9679 gcc_jit_extended_asm *ext_asm 9680 = gcc_jit_block_add_extended_asm (block, NULL, 9681 "mov %1, %0\n\t" 9682 "add $1, %0"); 9683 gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=r", dst); 9684 gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r", 9685 gcc_jit_lvalue_as_rvalue (src)); 9686@end example 9687 9688@cartouche 9689@quotation Warning 9690When considering the numbering of operands within an 9691extended @code{asm} statement (e.g. the @code{%0} and @code{%1} 9692above), the equivalent to the C syntax is followed i.e. all 9693output operands, then all input operands, regardless of 9694what order the calls to 9695@ref{157,,gcc_jit_extended_asm_add_output_operand()} and 9696@ref{158,,gcc_jit_extended_asm_add_input_operand()} were made in. 9697@end quotation 9698@end cartouche 9699 9700As in the C syntax, operands can be given symbolic names to avoid having 9701to number them. For example, to create the equivalent of: 9702 9703@example 9704 asm ("bsfl %[aMask], %[aIndex]" 9705 : [aIndex] "=r" (Index) 9706 : [aMask] "r" (Mask) 9707 : "cc"); 9708@end example 9709 9710the following API calls could be used: 9711 9712@example 9713 gcc_jit_extended_asm *ext_asm 9714 = gcc_jit_block_add_extended_asm (block, NULL, 9715 "bsfl %[aMask], %[aIndex]"); 9716 gcc_jit_extended_asm_add_output_operand (ext_asm, "aIndex", "=r", index); 9717 gcc_jit_extended_asm_add_input_operand (ext_asm, "aMask", "r", 9718 gcc_jit_param_as_rvalue (mask)); 9719 gcc_jit_extended_asm_add_clobber (ext_asm, "cc"); 9720@end example 9721@end deffn 9722 9723@geindex gcc_jit_block_add_extended_asm (C function) 9724@anchor{topics/asm c gcc_jit_block_add_extended_asm}@anchor{152} 9725@deffn {C Function} gcc_jit_extended_asm * gcc_jit_block_add_extended_asm (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*asm_template) 9726 9727Create a @ref{120,,gcc_jit_extended_asm} for an extended @code{asm} statement 9728with no control flow (i.e. without the @code{goto} qualifier). 9729 9730The parameter @code{asm_template} corresponds to the @cite{AssemblerTemplate} 9731within C���s extended @code{asm} syntax. It must be non-NULL. The call takes 9732a copy of the underlying string, so it is valid to pass in a pointer to 9733an on-stack buffer. 9734@end deffn 9735 9736@geindex gcc_jit_block_end_with_extended_asm_goto (C function) 9737@anchor{topics/asm c gcc_jit_block_end_with_extended_asm_goto}@anchor{153} 9738@deffn {C Function} gcc_jit_extended_asm * gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*asm_template, int@w{ }num_goto_blocks, gcc_jit_block@w{ }**goto_blocks, gcc_jit_block@w{ }*fallthrough_block) 9739 9740Create a @ref{120,,gcc_jit_extended_asm} for an extended @code{asm} statement 9741that may perform jumps, and use it to terminate the given block. 9742This is equivalent to the @code{goto} qualifier in C���s extended @code{asm} 9743syntax. 9744 9745For example, to create the equivalent of: 9746 9747@example 9748 asm goto ("btl %1, %0\n\t" 9749 "jc %l[carry]" 9750 : // No outputs 9751 : "r" (p1), "r" (p2) 9752 : "cc" 9753 : carry); 9754@end example 9755 9756the following API calls could be used: 9757 9758@example 9759 const char *asm_template = 9760 (use_name 9761 ? /* Label referred to by name: "%l[carry]". */ 9762 ("btl %1, %0\n\t" 9763 "jc %l[carry]") 9764 : /* Label referred to numerically: "%l2". */ 9765 ("btl %1, %0\n\t" 9766 "jc %l2")); 9767 9768 gcc_jit_extended_asm *ext_asm 9769 = gcc_jit_block_end_with_extended_asm_goto (b_start, NULL, 9770 asm_template, 9771 1, &b_carry, 9772 b_fallthru); 9773 gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r", 9774 gcc_jit_param_as_rvalue (p1)); 9775 gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r", 9776 gcc_jit_param_as_rvalue (p2)); 9777 gcc_jit_extended_asm_add_clobber (ext_asm, "cc"); 9778@end example 9779 9780here referencing a @ref{28,,gcc_jit_block} named ���carry���. 9781 9782@code{num_goto_blocks} must be >= 0. 9783 9784@code{goto_blocks} must be non-NULL. This corresponds to the @code{GotoLabels} 9785parameter within C���s extended @code{asm} syntax. The block names can be 9786referenced within the assembler template. 9787 9788@code{fallthrough_block} can be NULL. If non-NULL, it specifies the block 9789to fall through to after the statement. 9790 9791@cartouche 9792@quotation Note 9793This is needed since each @ref{28,,gcc_jit_block} must have a 9794single exit point, as a basic block: you can���t jump from the 9795middle of a block. A ���goto��� is implicitly added after the 9796asm to handle the fallthrough case, which is equivalent to what 9797would have happened in the C case. 9798@end quotation 9799@end cartouche 9800@end deffn 9801 9802@geindex gcc_jit_extended_asm_set_volatile_flag (C function) 9803@anchor{topics/asm c gcc_jit_extended_asm_set_volatile_flag}@anchor{155} 9804@deffn {C Function} void gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm@w{ }*ext_asm, int@w{ }flag) 9805 9806Set whether the @ref{120,,gcc_jit_extended_asm} has side-effects, equivalent to the 9807volatile@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile} 9808qualifier in C���s extended asm syntax. 9809 9810For example, to create the equivalent of: 9811 9812@example 9813asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX. 9814 "shl $32, %%rdx\n\t" // Shift the upper bits left. 9815 "or %%rdx, %0" // 'Or' in the lower bits. 9816 : "=a" (msr) 9817 : 9818 : "rdx"); 9819@end example 9820 9821the following API calls could be used: 9822 9823@example 9824 gcc_jit_extended_asm *ext_asm 9825 = gcc_jit_block_add_extended_asm 9826 (block, NULL, 9827 "rdtsc\n\t" /* Returns the time in EDX:EAX. */ 9828 "shl $32, %%rdx\n\t" /* Shift the upper bits left. */ 9829 "or %%rdx, %0"); /* 'Or' in the lower bits. */ 9830 gcc_jit_extended_asm_set_volatile_flag (ext_asm, 1); 9831 gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=a", msr); 9832 gcc_jit_extended_asm_add_clobber (ext_asm, "rdx"); 9833@end example 9834 9835where the @ref{120,,gcc_jit_extended_asm} is flagged as volatile. 9836@end deffn 9837 9838@geindex gcc_jit_extended_asm_set_inline_flag (C function) 9839@anchor{topics/asm c gcc_jit_extended_asm_set_inline_flag}@anchor{156} 9840@deffn {C Function} void gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm@w{ }*ext_asm, int@w{ }flag) 9841 9842Set the equivalent of the 9843inline@footnote{https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm} 9844qualifier in C���s extended @code{asm} syntax. 9845@end deffn 9846 9847@geindex gcc_jit_extended_asm_add_output_operand (C function) 9848@anchor{topics/asm c gcc_jit_extended_asm_add_output_operand}@anchor{157} 9849@deffn {C Function} void gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm@w{ }*ext_asm, const char@w{ }*asm_symbolic_name, const char@w{ }*constraint, gcc_jit_lvalue@w{ }*dest) 9850 9851Add an output operand to the extended @code{asm} statement. See the 9852Output Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands} 9853section of the documentation of the C syntax. 9854 9855@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component of C���s 9856extended @code{asm} syntax. It can be NULL. If non-NULL it specifies the 9857symbolic name for the operand. 9858 9859@code{constraint} corresponds to the @code{constraint} component of C���s extended 9860@code{asm} syntax. It must be non-NULL. 9861 9862@code{dest} corresponds to the @code{cvariablename} component of C���s extended 9863@code{asm} syntax. It must be non-NULL. 9864 9865@example 9866// Example with a NULL symbolic name, the equivalent of: 9867// : "=r" (dst) 9868gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=r", dst); 9869 9870// Example with a symbolic name ("aIndex"), the equivalent of: 9871// : [aIndex] "=r" (index) 9872gcc_jit_extended_asm_add_output_operand (ext_asm, "aIndex", "=r", index); 9873@end example 9874 9875This function can���t be called on an @code{asm goto} as such instructions can���t 9876have outputs; see the 9877Goto Labels@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels} 9878section of GCC���s ���Extended Asm��� documentation. 9879@end deffn 9880 9881@geindex gcc_jit_extended_asm_add_input_operand (C function) 9882@anchor{topics/asm c gcc_jit_extended_asm_add_input_operand}@anchor{158} 9883@deffn {C Function} void gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm@w{ }*ext_asm, const char@w{ }*asm_symbolic_name, const char@w{ }*constraint, gcc_jit_rvalue@w{ }*src) 9884 9885Add an input operand to the extended @code{asm} statement. See the 9886Input Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands} 9887section of the documentation of the C syntax. 9888 9889@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component of C���s 9890extended @code{asm} syntax. It can be NULL. If non-NULL it specifies the 9891symbolic name for the operand. 9892 9893@code{constraint} corresponds to the @code{constraint} component of C���s extended 9894@code{asm} syntax. It must be non-NULL. 9895 9896@code{src} corresponds to the @code{cexpression} component of C���s extended 9897@code{asm} syntax. It must be non-NULL. 9898 9899@example 9900// Example with a NULL symbolic name, the equivalent of: 9901// : "r" (src) 9902gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r", 9903 gcc_jit_lvalue_as_rvalue (src)); 9904 9905// Example with a symbolic name ("aMask"), the equivalent of: 9906// : [aMask] "r" (Mask) 9907gcc_jit_extended_asm_add_input_operand (ext_asm, "aMask", "r", 9908 gcc_jit_lvalue_as_rvalue (mask)); 9909@end example 9910@end deffn 9911 9912@geindex gcc_jit_extended_asm_add_clobber (C function) 9913@anchor{topics/asm c gcc_jit_extended_asm_add_clobber}@anchor{159} 9914@deffn {C Function} void gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm@w{ }*ext_asm, const char@w{ }*victim) 9915 9916Add @cite{victim} to the list of registers clobbered by the extended @code{asm} 9917statement. It must be non-NULL. See the 9918Clobbers and Scratch Registers@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#} 9919section of the documentation of the C syntax. 9920 9921Statements with multiple clobbers will require multiple calls, one per 9922clobber. 9923 9924For example: 9925 9926@example 9927gcc_jit_extended_asm_add_clobber (ext_asm, "r0"); 9928gcc_jit_extended_asm_add_clobber (ext_asm, "cc"); 9929gcc_jit_extended_asm_add_clobber (ext_asm, "memory"); 9930@end example 9931@end deffn 9932 9933A @ref{120,,gcc_jit_extended_asm} is a @ref{e,,gcc_jit_object} ���owned��� by 9934the block���s context. The following upcast is available: 9935 9936@geindex gcc_jit_extended_asm_as_object (C function) 9937@anchor{topics/asm c gcc_jit_extended_asm_as_object}@anchor{154} 9938@deffn {C Function} gcc_jit_object * gcc_jit_extended_asm_as_object (gcc_jit_extended_asm@w{ }*ext_asm) 9939 9940Upcast from extended @code{asm} to object. 9941@end deffn 9942 9943@node Adding top-level assembler statements,,Adding assembler instructions within a function,Using Assembly Language with libgccjit 9944@anchor{topics/asm adding-top-level-assembler-statements}@anchor{16c} 9945@subsection Adding top-level assembler statements 9946 9947 9948In addition to creating extended @code{asm} instructions within a function, 9949there is support for creating ���top-level��� assembler statements, outside 9950of any function. 9951 9952@geindex gcc_jit_context_add_top_level_asm (C function) 9953@anchor{topics/asm c gcc_jit_context_add_top_level_asm}@anchor{15a} 9954@deffn {C Function} void gcc_jit_context_add_top_level_asm (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*asm_stmts) 9955 9956Create a set of top-level asm statements, analogous to those created 9957by GCC���s ���basic��� @code{asm} syntax in C at file scope. 9958 9959For example, to create the equivalent of: 9960 9961@example 9962 asm ("\t.pushsection .text\n" 9963 "\t.globl add_asm\n" 9964 "\t.type add_asm, @@function\n" 9965 "add_asm:\n" 9966 "\tmovq %rdi, %rax\n" 9967 "\tadd %rsi, %rax\n" 9968 "\tret\n" 9969 "\t.popsection\n"); 9970@end example 9971 9972the following API calls could be used: 9973 9974@example 9975 gcc_jit_context_add_top_level_asm (ctxt, NULL, 9976 "\t.pushsection .text\n" 9977 "\t.globl add_asm\n" 9978 "\t.type add_asm, @@function\n" 9979 "add_asm:\n" 9980 "\tmovq %rdi, %rax\n" 9981 "\tadd %rsi, %rax\n" 9982 "\tret\n" 9983 "\t# some asm here\n" 9984 "\t.popsection\n"); 9985@end example 9986@end deffn 9987 9988@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 9989@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9990@c 9991@c This is free software: you can redistribute it and/or modify it 9992@c under the terms of the GNU General Public License as published by 9993@c the Free Software Foundation, either version 3 of the License, or 9994@c (at your option) any later version. 9995@c 9996@c This program is distributed in the hope that it will be useful, but 9997@c WITHOUT ANY WARRANTY; without even the implied warranty of 9998@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9999@c General Public License for more details. 10000@c 10001@c You should have received a copy of the GNU General Public License 10002@c along with this program. If not, see 10003@c <https://www.gnu.org/licenses/>. 10004 10005@node C++ bindings for libgccjit,Internals,Topic Reference,Top 10006@anchor{cp/index doc}@anchor{16d}@anchor{cp/index c-bindings-for-libgccjit}@anchor{16e} 10007@chapter C++ bindings for libgccjit 10008 10009 10010This document describes the C++ bindings to 10011libgccjit@footnote{https://gcc.gnu.org/wiki/JIT}, an API for embedding GCC 10012inside programs and libraries. 10013 10014The C++ bindings consist of a single header file @code{libgccjit++.h}. 10015 10016This is a collection of ���thin��� wrapper classes around the C API. 10017Everything is an inline function, implemented in terms of the C API, 10018so there is nothing extra to link against. 10019 10020Contents: 10021 10022@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 10023@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 10024@c 10025@c This is free software: you can redistribute it and/or modify it 10026@c under the terms of the GNU General Public License as published by 10027@c the Free Software Foundation, either version 3 of the License, or 10028@c (at your option) any later version. 10029@c 10030@c This program is distributed in the hope that it will be useful, but 10031@c WITHOUT ANY WARRANTY; without even the implied warranty of 10032@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10033@c General Public License for more details. 10034@c 10035@c You should have received a copy of the GNU General Public License 10036@c along with this program. If not, see 10037@c <https://www.gnu.org/licenses/>. 10038 10039@menu 10040* Tutorial: Tutorial<2>. 10041* Topic Reference: Topic Reference<2>. 10042 10043@end menu 10044 10045@node Tutorial<2>,Topic Reference<2>,,C++ bindings for libgccjit 10046@anchor{cp/intro/index doc}@anchor{16f}@anchor{cp/intro/index tutorial}@anchor{170} 10047@section Tutorial 10048 10049 10050@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 10051@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 10052@c 10053@c This is free software: you can redistribute it and/or modify it 10054@c under the terms of the GNU General Public License as published by 10055@c the Free Software Foundation, either version 3 of the License, or 10056@c (at your option) any later version. 10057@c 10058@c This program is distributed in the hope that it will be useful, but 10059@c WITHOUT ANY WARRANTY; without even the implied warranty of 10060@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10061@c General Public License for more details. 10062@c 10063@c You should have received a copy of the GNU General Public License 10064@c along with this program. If not, see 10065@c <https://www.gnu.org/licenses/>. 10066 10067@menu 10068* Tutorial part 1; ���Hello world���: Tutorial part 1 ���Hello world���<2>. 10069* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 10070* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 10071* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 10072 10073@end menu 10074 10075@node Tutorial part 1 ���Hello world���<2>,Tutorial part 2 Creating a trivial machine code function<2>,,Tutorial<2> 10076@anchor{cp/intro/tutorial01 doc}@anchor{171}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{172} 10077@subsection Tutorial part 1: ���Hello world��� 10078 10079 10080Before we look at the details of the API, let���s look at building and 10081running programs that use the library. 10082 10083Here���s a toy ���hello world��� program that uses the library���s C++ API to 10084synthesize a call to @cite{printf} and uses it to write a message to stdout. 10085 10086Don���t worry about the content of the program for now; we���ll cover 10087the details in later parts of this tutorial. 10088 10089@quotation 10090 10091@example 10092/* Smoketest example for libgccjit.so C++ API 10093 Copyright (C) 2014-2022 Free Software Foundation, Inc. 10094 10095This file is part of GCC. 10096 10097GCC is free software; you can redistribute it and/or modify it 10098under the terms of the GNU General Public License as published by 10099the Free Software Foundation; either version 3, or (at your option) 10100any later version. 10101 10102GCC is distributed in the hope that it will be useful, but 10103WITHOUT ANY WARRANTY; without even the implied warranty of 10104MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10105General Public License for more details. 10106 10107You should have received a copy of the GNU General Public License 10108along with GCC; see the file COPYING3. If not see 10109<http://www.gnu.org/licenses/>. */ 10110 10111#include <libgccjit++.h> 10112 10113#include <stdlib.h> 10114#include <stdio.h> 10115 10116static void 10117create_code (gccjit::context ctxt) 10118@{ 10119 /* Let's try to inject the equivalent of this C code: 10120 void 10121 greet (const char *name) 10122 @{ 10123 printf ("hello %s\n", name); 10124 @} 10125 */ 10126 gccjit::type void_type = ctxt.get_type (GCC_JIT_TYPE_VOID); 10127 gccjit::type const_char_ptr_type = 10128 ctxt.get_type (GCC_JIT_TYPE_CONST_CHAR_PTR); 10129 gccjit::param param_name = 10130 ctxt.new_param (const_char_ptr_type, "name"); 10131 std::vector<gccjit::param> func_params; 10132 func_params.push_back (param_name); 10133 gccjit::function func = 10134 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10135 void_type, 10136 "greet", 10137 func_params, 0); 10138 10139 gccjit::param param_format = 10140 ctxt.new_param (const_char_ptr_type, "format"); 10141 std::vector<gccjit::param> printf_params; 10142 printf_params.push_back (param_format); 10143 gccjit::function printf_func = 10144 ctxt.new_function (GCC_JIT_FUNCTION_IMPORTED, 10145 ctxt.get_type (GCC_JIT_TYPE_INT), 10146 "printf", 10147 printf_params, 1); 10148 10149 gccjit::block block = func.new_block (); 10150 block.add_eval (ctxt.new_call (printf_func, 10151 ctxt.new_rvalue ("hello %s\n"), 10152 param_name)); 10153 block.end_with_return (); 10154@} 10155 10156int 10157main (int argc, char **argv) 10158@{ 10159 gccjit::context ctxt; 10160 gcc_jit_result *result; 10161 10162 /* Get a "context" object for working with the library. */ 10163 ctxt = gccjit::context::acquire (); 10164 10165 /* Set some options on the context. 10166 Turn this on to see the code being generated, in assembler form. */ 10167 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 0); 10168 10169 /* Populate the context. */ 10170 create_code (ctxt); 10171 10172 /* Compile the code. */ 10173 result = ctxt.compile (); 10174 if (!result) 10175 @{ 10176 fprintf (stderr, "NULL result"); 10177 exit (1); 10178 @} 10179 10180 ctxt.release (); 10181 10182 /* Extract the generated code from "result". */ 10183 typedef void (*fn_type) (const char *); 10184 fn_type greet = 10185 (fn_type)gcc_jit_result_get_code (result, "greet"); 10186 if (!greet) 10187 @{ 10188 fprintf (stderr, "NULL greet"); 10189 exit (1); 10190 @} 10191 10192 /* Now call the generated function: */ 10193 greet ("world"); 10194 fflush (stdout); 10195 10196 gcc_jit_result_release (result); 10197 return 0; 10198@} 10199@end example 10200@end quotation 10201 10202Copy the above to @cite{tut01-hello-world.cc}. 10203 10204Assuming you have the jit library installed, build the test program 10205using: 10206 10207@example 10208$ gcc \ 10209 tut01-hello-world.cc \ 10210 -o tut01-hello-world \ 10211 -lgccjit 10212@end example 10213 10214You should then be able to run the built program: 10215 10216@example 10217$ ./tut01-hello-world 10218hello world 10219@end example 10220 10221@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 10222@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 10223@c 10224@c This is free software: you can redistribute it and/or modify it 10225@c under the terms of the GNU General Public License as published by 10226@c the Free Software Foundation, either version 3 of the License, or 10227@c (at your option) any later version. 10228@c 10229@c This program is distributed in the hope that it will be useful, but 10230@c WITHOUT ANY WARRANTY; without even the implied warranty of 10231@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10232@c General Public License for more details. 10233@c 10234@c You should have received a copy of the GNU General Public License 10235@c along with this program. If not, see 10236@c <https://www.gnu.org/licenses/>. 10237 10238@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> 10239@anchor{cp/intro/tutorial02 doc}@anchor{173}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{174} 10240@subsection Tutorial part 2: Creating a trivial machine code function 10241 10242 10243Consider this C function: 10244 10245@example 10246int square (int i) 10247@{ 10248 return i * i; 10249@} 10250@end example 10251 10252How can we construct this at run-time using libgccjit���s C++ API? 10253 10254First we need to include the relevant header: 10255 10256@example 10257#include <libgccjit++.h> 10258@end example 10259 10260All state associated with compilation is associated with a 10261@ref{175,,gccjit;;context}, which is a thin C++ wrapper around the C API���s 10262@ref{8,,gcc_jit_context *}. 10263 10264Create one using @ref{176,,gccjit;;context;;acquire()}: 10265 10266@example 10267gccjit::context ctxt; 10268ctxt = gccjit::context::acquire (); 10269@end example 10270 10271The JIT library has a system of types. It is statically-typed: every 10272expression is of a specific type, fixed at compile-time. In our example, 10273all of the expressions are of the C @cite{int} type, so let���s obtain this from 10274the context, as a @ref{177,,gccjit;;type}, using 10275@ref{178,,gccjit;;context;;get_type()}: 10276 10277@example 10278gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 10279@end example 10280 10281@ref{177,,gccjit;;type} is an example of a ���contextual��� object: every 10282entity in the API is associated with a @ref{175,,gccjit;;context}. 10283 10284Memory management is easy: all such ���contextual��� objects are automatically 10285cleaned up for you when the context is released, using 10286@ref{179,,gccjit;;context;;release()}: 10287 10288@example 10289ctxt.release (); 10290@end example 10291 10292so you don���t need to manually track and cleanup all objects, just the 10293contexts. 10294 10295All of the C++ classes in the API are thin wrappers around pointers to 10296types in the C API. 10297 10298The C++ class hierarchy within the @code{gccjit} namespace looks like this: 10299 10300@example 10301+- object 10302 +- location 10303 +- type 10304 +- struct 10305 +- field 10306 +- function 10307 +- block 10308 +- rvalue 10309 +- lvalue 10310 +- param 10311@end example 10312 10313One thing you can do with a @ref{17a,,gccjit;;object} is 10314to ask it for a human-readable description as a @code{std::string}, using 10315@ref{17b,,gccjit;;object;;get_debug_string()}: 10316 10317@example 10318printf ("obj: %s\n", obj.get_debug_string ().c_str ()); 10319@end example 10320 10321giving this text on stdout: 10322 10323@example 10324obj: int 10325@end example 10326 10327This is invaluable when debugging. 10328 10329Let���s create the function. To do so, we first need to construct 10330its single parameter, specifying its type and giving it a name, 10331using @ref{17c,,gccjit;;context;;new_param()}: 10332 10333@example 10334gccjit::param param_i = ctxt.new_param (int_type, "i"); 10335@end example 10336 10337and we can then make a vector of all of the params of the function, 10338in this case just one: 10339 10340@example 10341std::vector<gccjit::param> params; 10342params.push_back (param_i); 10343@end example 10344 10345Now we can create the function, using 10346@code{gccjit::context::new_function()}: 10347 10348@example 10349gccjit::function func = 10350 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10351 int_type, 10352 "square", 10353 params, 10354 0); 10355@end example 10356 10357To define the code within the function, we must create basic blocks 10358containing statements. 10359 10360Every basic block contains a list of statements, eventually terminated 10361by a statement that either returns, or jumps to another basic block. 10362 10363Our function has no control-flow, so we just need one basic block: 10364 10365@example 10366gccjit::block block = func.new_block (); 10367@end example 10368 10369Our basic block is relatively simple: it immediately terminates by 10370returning the value of an expression. 10371 10372We can build the expression using @ref{17d,,gccjit;;context;;new_binary_op()}: 10373 10374@example 10375gccjit::rvalue expr = 10376 ctxt.new_binary_op ( 10377 GCC_JIT_BINARY_OP_MULT, int_type, 10378 param_i, param_i); 10379@end example 10380 10381A @ref{17e,,gccjit;;rvalue} is another example of a 10382@ref{17a,,gccjit;;object} subclass. As before, we can print it with 10383@ref{17b,,gccjit;;object;;get_debug_string()}. 10384 10385@example 10386printf ("expr: %s\n", expr.get_debug_string ().c_str ()); 10387@end example 10388 10389giving this output: 10390 10391@example 10392expr: i * i 10393@end example 10394 10395Note that @ref{17e,,gccjit;;rvalue} provides numerous overloaded operators 10396which can be used to dramatically reduce the amount of typing needed. 10397We can build the above binary operation more directly with this one-liner: 10398 10399@example 10400gccjit::rvalue expr = param_i * param_i; 10401@end example 10402 10403Creating the expression in itself doesn���t do anything; we have to add 10404this expression to a statement within the block. In this case, we use it 10405to build a return statement, which terminates the basic block: 10406 10407@example 10408block.end_with_return (expr); 10409@end example 10410 10411OK, we���ve populated the context. We can now compile it using 10412@ref{17f,,gccjit;;context;;compile()}: 10413 10414@example 10415gcc_jit_result *result; 10416result = ctxt.compile (); 10417@end example 10418 10419and get a @ref{16,,gcc_jit_result *}. 10420 10421We can now use @ref{17,,gcc_jit_result_get_code()} to look up a specific 10422machine code routine within the result, in this case, the function we 10423created above. 10424 10425@example 10426void *fn_ptr = gcc_jit_result_get_code (result, "square"); 10427if (!fn_ptr) 10428 @{ 10429 fprintf (stderr, "NULL fn_ptr"); 10430 goto error; 10431 @} 10432@end example 10433 10434We can now cast the pointer to an appropriate function pointer type, and 10435then call it: 10436 10437@example 10438typedef int (*fn_type) (int); 10439fn_type square = (fn_type)fn_ptr; 10440printf ("result: %d", square (5)); 10441@end example 10442 10443@example 10444result: 25 10445@end example 10446 10447@menu 10448* Options: Options<3>. 10449* Full example: Full example<3>. 10450 10451@end menu 10452 10453@node Options<3>,Full example<3>,,Tutorial part 2 Creating a trivial machine code function<2> 10454@anchor{cp/intro/tutorial02 options}@anchor{180} 10455@subsubsection Options 10456 10457 10458To get more information on what���s going on, you can set debugging flags 10459on the context using @ref{181,,gccjit;;context;;set_bool_option()}. 10460 10461@c (I'm deliberately not mentioning 10462@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think 10463@c it's probably more of use to implementors than to users) 10464 10465Setting @ref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a 10466C-like representation to stderr when you compile (GCC���s ���GIMPLE��� 10467representation): 10468 10469@example 10470ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); 10471result = ctxt.compile (); 10472@end example 10473 10474@example 10475square (signed int i) 10476@{ 10477 signed int D.260; 10478 10479 entry: 10480 D.260 = i * i; 10481 return D.260; 10482@} 10483@end example 10484 10485We can see the generated machine code in assembler form (on stderr) by 10486setting @ref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context 10487before compiling: 10488 10489@example 10490ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); 10491result = ctxt.compile (); 10492@end example 10493 10494@example 10495 .file "fake.c" 10496 .text 10497 .globl square 10498 .type square, @@function 10499square: 10500.LFB6: 10501 .cfi_startproc 10502 pushq %rbp 10503 .cfi_def_cfa_offset 16 10504 .cfi_offset 6, -16 10505 movq %rsp, %rbp 10506 .cfi_def_cfa_register 6 10507 movl %edi, -4(%rbp) 10508.L14: 10509 movl -4(%rbp), %eax 10510 imull -4(%rbp), %eax 10511 popq %rbp 10512 .cfi_def_cfa 7, 8 10513 ret 10514 .cfi_endproc 10515.LFE6: 10516 .size square, .-square 10517 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 10518 .section .note.GNU-stack,"",@@progbits 10519@end example 10520 10521By default, no optimizations are performed, the equivalent of GCC���s 10522@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling 10523@ref{182,,gccjit;;context;;set_int_option()} with 10524@ref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 10525 10526@example 10527ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); 10528@end example 10529 10530@example 10531 .file "fake.c" 10532 .text 10533 .p2align 4,,15 10534 .globl square 10535 .type square, @@function 10536square: 10537.LFB7: 10538 .cfi_startproc 10539.L16: 10540 movl %edi, %eax 10541 imull %edi, %eax 10542 ret 10543 .cfi_endproc 10544.LFE7: 10545 .size square, .-square 10546 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 10547 .section .note.GNU-stack,"",@@progbits 10548@end example 10549 10550Naturally this has only a small effect on such a trivial function. 10551 10552@node Full example<3>,,Options<3>,Tutorial part 2 Creating a trivial machine code function<2> 10553@anchor{cp/intro/tutorial02 full-example}@anchor{183} 10554@subsubsection Full example 10555 10556 10557Here���s what the above looks like as a complete program: 10558 10559@quotation 10560 10561@example 10562/* Usage example for libgccjit.so's C++ API 10563 Copyright (C) 2014-2022 Free Software Foundation, Inc. 10564 10565This file is part of GCC. 10566 10567GCC is free software; you can redistribute it and/or modify it 10568under the terms of the GNU General Public License as published by 10569the Free Software Foundation; either version 3, or (at your option) 10570any later version. 10571 10572GCC is distributed in the hope that it will be useful, but 10573WITHOUT ANY WARRANTY; without even the implied warranty of 10574MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10575General Public License for more details. 10576 10577You should have received a copy of the GNU General Public License 10578along with GCC; see the file COPYING3. If not see 10579<http://www.gnu.org/licenses/>. */ 10580 10581#include <libgccjit++.h> 10582 10583#include <stdlib.h> 10584#include <stdio.h> 10585 10586void 10587create_code (gccjit::context ctxt) 10588@{ 10589 /* Let's try to inject the equivalent of this C code: 10590 10591 int square (int i) 10592 @{ 10593 return i * i; 10594 @} 10595 */ 10596 gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 10597 gccjit::param param_i = ctxt.new_param (int_type, "i"); 10598 std::vector<gccjit::param> params; 10599 params.push_back (param_i); 10600 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10601 int_type, 10602 "square", 10603 params, 0); 10604 10605 gccjit::block block = func.new_block (); 10606 10607 gccjit::rvalue expr = 10608 ctxt.new_binary_op (GCC_JIT_BINARY_OP_MULT, int_type, 10609 param_i, param_i); 10610 10611 block.end_with_return (expr); 10612@} 10613 10614int 10615main (int argc, char **argv) 10616@{ 10617 /* Get a "context" object for working with the library. */ 10618 gccjit::context ctxt = gccjit::context::acquire (); 10619 10620 /* Set some options on the context. 10621 Turn this on to see the code being generated, in assembler form. */ 10622 ctxt.set_bool_option ( 10623 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 10624 0); 10625 10626 /* Populate the context. */ 10627 create_code (ctxt); 10628 10629 /* Compile the code. */ 10630 gcc_jit_result *result = ctxt.compile (); 10631 10632 /* We're done with the context; we can release it: */ 10633 ctxt.release (); 10634 10635 if (!result) 10636 @{ 10637 fprintf (stderr, "NULL result"); 10638 return 1; 10639 @} 10640 10641 /* Extract the generated code from "result". */ 10642 void *fn_ptr = gcc_jit_result_get_code (result, "square"); 10643 if (!fn_ptr) 10644 @{ 10645 fprintf (stderr, "NULL fn_ptr"); 10646 gcc_jit_result_release (result); 10647 return 1; 10648 @} 10649 10650 typedef int (*fn_type) (int); 10651 fn_type square = (fn_type)fn_ptr; 10652 printf ("result: %d\n", square (5)); 10653 10654 gcc_jit_result_release (result); 10655 return 0; 10656@} 10657@end example 10658@end quotation 10659 10660Building and running it: 10661 10662@example 10663$ gcc \ 10664 tut02-square.cc \ 10665 -o tut02-square \ 10666 -lgccjit 10667 10668# Run the built program: 10669$ ./tut02-square 10670result: 25 10671@end example 10672 10673@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 10674@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 10675@c 10676@c This is free software: you can redistribute it and/or modify it 10677@c under the terms of the GNU General Public License as published by 10678@c the Free Software Foundation, either version 3 of the License, or 10679@c (at your option) any later version. 10680@c 10681@c This program is distributed in the hope that it will be useful, but 10682@c WITHOUT ANY WARRANTY; without even the implied warranty of 10683@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10684@c General Public License for more details. 10685@c 10686@c You should have received a copy of the GNU General Public License 10687@c along with this program. If not, see 10688@c <https://www.gnu.org/licenses/>. 10689 10690@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> 10691@anchor{cp/intro/tutorial03 doc}@anchor{184}@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{185} 10692@subsection Tutorial part 3: Loops and variables 10693 10694 10695Consider this C function: 10696 10697@quotation 10698 10699@example 10700int loop_test (int n) 10701@{ 10702 int sum = 0; 10703 for (int i = 0; i < n; i++) 10704 sum += i * i; 10705 return sum; 10706@} 10707@end example 10708@end quotation 10709 10710This example demonstrates some more features of libgccjit, with local 10711variables and a loop. 10712 10713To break this down into libgccjit terms, it���s usually easier to reword 10714the @cite{for} loop as a @cite{while} loop, giving: 10715 10716@quotation 10717 10718@example 10719int loop_test (int n) 10720@{ 10721 int sum = 0; 10722 int i = 0; 10723 while (i < n) 10724 @{ 10725 sum += i * i; 10726 i++; 10727 @} 10728 return sum; 10729@} 10730@end example 10731@end quotation 10732 10733Here���s what the final control flow graph will look like: 10734 10735@quotation 10736 10737 10738@float Figure 10739 10740@image{libgccjit-figures/sum-of-squares,,,image of a control flow graph,png} 10741 10742@end float 10743 10744@end quotation 10745 10746As before, we include the libgccjit++ header and make a 10747@ref{175,,gccjit;;context}. 10748 10749@example 10750#include <libgccjit++.h> 10751 10752void test (void) 10753@{ 10754 gccjit::context ctxt; 10755 ctxt = gccjit::context::acquire (); 10756@end example 10757 10758The function works with the C @cite{int} type. 10759 10760In the previous tutorial we acquired this via 10761 10762@example 10763gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_INT); 10764@end example 10765 10766though we could equally well make it work on, say, @cite{double}: 10767 10768@example 10769gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_DOUBLE); 10770@end example 10771 10772For integer types we can use @code{gccjit::context::get_int_type} 10773to directly bind a specific type: 10774 10775@example 10776gccjit::type the_type = ctxt.get_int_type <int> (); 10777@end example 10778 10779Let���s build the function: 10780 10781@example 10782gcc_jit_param n = ctxt.new_param (the_type, "n"); 10783std::vector<gccjit::param> params; 10784params.push_back (n); 10785gccjit::function func = 10786 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10787 return_type, 10788 "loop_test", 10789 params, 0); 10790@end example 10791 10792@menu 10793* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 10794* Control flow: Control flow<2>. 10795* Visualizing the control flow graph: Visualizing the control flow graph<2>. 10796* Full example: Full example<4>. 10797 10798@end menu 10799 10800@node Expressions lvalues and rvalues<2>,Control flow<2>,,Tutorial part 3 Loops and variables<2> 10801@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{186} 10802@subsubsection Expressions: lvalues and rvalues 10803 10804 10805The base class of expression is the @ref{17e,,gccjit;;rvalue}, 10806representing an expression that can be on the @emph{right}-hand side of 10807an assignment: a value that can be computed somehow, and assigned 10808@emph{to} a storage area (such as a variable). It has a specific 10809@ref{177,,gccjit;;type}. 10810 10811Anothe important class is @ref{187,,gccjit;;lvalue}. 10812A @ref{187,,gccjit;;lvalue}. is something that can of the @emph{left}-hand 10813side of an assignment: a storage area (such as a variable). 10814 10815In other words, every assignment can be thought of as: 10816 10817@example 10818LVALUE = RVALUE; 10819@end example 10820 10821Note that @ref{187,,gccjit;;lvalue} is a subclass of 10822@ref{17e,,gccjit;;rvalue}, where in an assignment of the form: 10823 10824@example 10825LVALUE_A = LVALUE_B; 10826@end example 10827 10828the @cite{LVALUE_B} implies reading the current value of that storage 10829area, assigning it into the @cite{LVALUE_A}. 10830 10831So far the only expressions we���ve seen are from the previous tutorial: 10832 10833 10834@enumerate 10835 10836@item 10837the multiplication @cite{i * i}: 10838@end enumerate 10839 10840@quotation 10841 10842@example 10843gccjit::rvalue expr = 10844 ctxt.new_binary_op ( 10845 GCC_JIT_BINARY_OP_MULT, int_type, 10846 param_i, param_i); 10847 10848/* Alternatively, using operator-overloading: */ 10849gccjit::rvalue expr = param_i * param_i; 10850@end example 10851 10852which is a @ref{17e,,gccjit;;rvalue}, and 10853@end quotation 10854 10855 10856@enumerate 2 10857 10858@item 10859the various function parameters: @cite{param_i} and @cite{param_n}, instances of 10860@ref{188,,gccjit;;param}, which is a subclass of @ref{187,,gccjit;;lvalue} 10861(and, in turn, of @ref{17e,,gccjit;;rvalue}): 10862we can both read from and write to function parameters within the 10863body of a function. 10864@end enumerate 10865 10866Our new example has a new kind of expression: we have two local 10867variables. We create them by calling 10868@ref{189,,gccjit;;function;;new_local()}, supplying a type and a name: 10869 10870@example 10871/* Build locals: */ 10872gccjit::lvalue i = func.new_local (the_type, "i"); 10873gccjit::lvalue sum = func.new_local (the_type, "sum"); 10874@end example 10875 10876These are instances of @ref{187,,gccjit;;lvalue} - they can be read from 10877and written to. 10878 10879Note that there is no precanned way to create @emph{and} initialize a variable 10880like in C: 10881 10882@example 10883int i = 0; 10884@end example 10885 10886Instead, having added the local to the function, we have to separately add 10887an assignment of @cite{0} to @cite{local_i} at the beginning of the function. 10888 10889@node Control flow<2>,Visualizing the control flow graph<2>,Expressions lvalues and rvalues<2>,Tutorial part 3 Loops and variables<2> 10890@anchor{cp/intro/tutorial03 control-flow}@anchor{18a} 10891@subsubsection Control flow 10892 10893 10894This function has a loop, so we need to build some basic blocks to 10895handle the control flow. In this case, we need 4 blocks: 10896 10897 10898@enumerate 10899 10900@item 10901before the loop (initializing the locals) 10902 10903@item 10904the conditional at the top of the loop (comparing @cite{i < n}) 10905 10906@item 10907the body of the loop 10908 10909@item 10910after the loop terminates (@cite{return sum}) 10911@end enumerate 10912 10913so we create these as @ref{18b,,gccjit;;block} instances within the 10914@ref{18c,,gccjit;;function}: 10915 10916@example 10917gccjit::block b_initial = func.new_block ("initial"); 10918gccjit::block b_loop_cond = func.new_block ("loop_cond"); 10919gccjit::block b_loop_body = func.new_block ("loop_body"); 10920gccjit::block b_after_loop = func.new_block ("after_loop"); 10921@end example 10922 10923We now populate each block with statements. 10924 10925The entry block @cite{b_initial} consists of initializations followed by a jump 10926to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using 10927@ref{18d,,gccjit;;block;;add_assignment()} to add 10928an assignment statement, and using @ref{18e,,gccjit;;context;;zero()} to get 10929the constant value @cite{0} for the relevant type for the right-hand side of 10930the assignment: 10931 10932@example 10933/* sum = 0; */ 10934b_initial.add_assignment (sum, ctxt.zero (the_type)); 10935 10936/* i = 0; */ 10937b_initial.add_assignment (i, ctxt.zero (the_type)); 10938@end example 10939 10940We can then terminate the entry block by jumping to the conditional: 10941 10942@example 10943b_initial.end_with_jump (b_loop_cond); 10944@end example 10945 10946The conditional block is equivalent to the line @cite{while (i < n)} from our 10947C example. It contains a single statement: a conditional, which jumps to 10948one of two destination blocks depending on a boolean 10949@ref{17e,,gccjit;;rvalue}, in this case the comparison of @cite{i} and @cite{n}. 10950 10951We could build the comparison using @ref{18f,,gccjit;;context;;new_comparison()}: 10952 10953@example 10954gccjit::rvalue guard = 10955 ctxt.new_comparison (GCC_JIT_COMPARISON_GE, 10956 i, n); 10957@end example 10958 10959and can then use this to add @cite{b_loop_cond}���s sole statement, via 10960@ref{190,,gccjit;;block;;end_with_conditional()}: 10961 10962@example 10963b_loop_cond.end_with_conditional (guard, 10964 b_after_loop, // on_true 10965 b_loop_body); // on_false 10966@end example 10967 10968However @ref{17e,,gccjit;;rvalue} has overloaded operators for this, so we 10969express the conditional as 10970 10971@example 10972gccjit::rvalue guard = (i >= n); 10973@end example 10974 10975and hence we can write the block more concisely as: 10976 10977@example 10978b_loop_cond.end_with_conditional ( 10979 i >= n, 10980 b_after_loop, // on_true 10981 b_loop_body); // on_false 10982@end example 10983 10984Next, we populate the body of the loop. 10985 10986The C statement @cite{sum += i * i;} is an assignment operation, where an 10987lvalue is modified ���in-place���. We use 10988@ref{191,,gccjit;;block;;add_assignment_op()} to handle these operations: 10989 10990@example 10991/* sum += i * i */ 10992b_loop_body.add_assignment_op (sum, 10993 GCC_JIT_BINARY_OP_PLUS, 10994 i * i); 10995@end example 10996 10997The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in 10998a similar way. We use @ref{2f,,gcc_jit_context_one()} to get the constant 10999value @cite{1} (for the relevant type) for the right-hand side 11000of the assignment. 11001 11002@example 11003/* i++ */ 11004b_loop_body.add_assignment_op (i, 11005 GCC_JIT_BINARY_OP_PLUS, 11006 ctxt.one (the_type)); 11007@end example 11008 11009@cartouche 11010@quotation Note 11011For numeric constants other than 0 or 1, we could use 11012@ref{192,,gccjit;;context;;new_rvalue()}, which has overloads 11013for both @code{int} and @code{double}. 11014@end quotation 11015@end cartouche 11016 11017The loop body completes by jumping back to the conditional: 11018 11019@example 11020b_loop_body.end_with_jump (b_loop_cond); 11021@end example 11022 11023Finally, we populate the @cite{b_after_loop} block, reached when the loop 11024conditional is false. We want to generate the equivalent of: 11025 11026@example 11027return sum; 11028@end example 11029 11030so the block is just one statement: 11031 11032@example 11033/* return sum */ 11034b_after_loop.end_with_return (sum); 11035@end example 11036 11037@cartouche 11038@quotation Note 11039You can intermingle block creation with statement creation, 11040but given that the terminator statements generally include references 11041to other blocks, I find it���s clearer to create all the blocks, 11042@emph{then} all the statements. 11043@end quotation 11044@end cartouche 11045 11046We���ve finished populating the function. As before, we can now compile it 11047to machine code: 11048 11049@example 11050gcc_jit_result *result; 11051result = ctxt.compile (); 11052 11053ctxt.release (); 11054 11055if (!result) 11056 @{ 11057 fprintf (stderr, "NULL result"); 11058 return 1; 11059 @} 11060 11061typedef int (*loop_test_fn_type) (int); 11062loop_test_fn_type loop_test = 11063 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 11064if (!loop_test) 11065 @{ 11066 fprintf (stderr, "NULL loop_test"); 11067 gcc_jit_result_release (result); 11068 return 1; 11069 @} 11070printf ("result: %d", loop_test (10)); 11071@end example 11072 11073@example 11074result: 285 11075@end example 11076 11077@node Visualizing the control flow graph<2>,Full example<4>,Control flow<2>,Tutorial part 3 Loops and variables<2> 11078@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{193} 11079@subsubsection Visualizing the control flow graph 11080 11081 11082You can see the control flow graph of a function using 11083@ref{194,,gccjit;;function;;dump_to_dot()}: 11084 11085@example 11086func.dump_to_dot ("/tmp/sum-of-squares.dot"); 11087@end example 11088 11089giving a .dot file in GraphViz format. 11090 11091You can convert this to an image using @cite{dot}: 11092 11093@example 11094$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png 11095@end example 11096 11097or use a viewer (my preferred one is xdot.py; see 11098@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can 11099install it with @cite{yum install python-xdot}): 11100 11101@quotation 11102 11103 11104@float Figure 11105 11106@image{libgccjit-figures/sum-of-squares,,,image of a control flow graph,png} 11107 11108@end float 11109 11110@end quotation 11111 11112@node Full example<4>,,Visualizing the control flow graph<2>,Tutorial part 3 Loops and variables<2> 11113@anchor{cp/intro/tutorial03 full-example}@anchor{195} 11114@subsubsection Full example 11115 11116 11117@quotation 11118 11119@example 11120/* Usage example for libgccjit.so's C++ API 11121 Copyright (C) 2014-2022 Free Software Foundation, Inc. 11122 11123This file is part of GCC. 11124 11125GCC is free software; you can redistribute it and/or modify it 11126under the terms of the GNU General Public License as published by 11127the Free Software Foundation; either version 3, or (at your option) 11128any later version. 11129 11130GCC is distributed in the hope that it will be useful, but 11131WITHOUT ANY WARRANTY; without even the implied warranty of 11132MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11133General Public License for more details. 11134 11135You should have received a copy of the GNU General Public License 11136along with GCC; see the file COPYING3. If not see 11137<http://www.gnu.org/licenses/>. */ 11138 11139#include <libgccjit++.h> 11140 11141#include <stdlib.h> 11142#include <stdio.h> 11143 11144void 11145create_code (gccjit::context ctxt) 11146@{ 11147 /* 11148 Simple sum-of-squares, to test conditionals and looping 11149 11150 int loop_test (int n) 11151 @{ 11152 int i; 11153 int sum = 0; 11154 for (i = 0; i < n ; i ++) 11155 @{ 11156 sum += i * i; 11157 @} 11158 return sum; 11159 */ 11160 gccjit::type the_type = ctxt.get_int_type <int> (); 11161 gccjit::type return_type = the_type; 11162 11163 gccjit::param n = ctxt.new_param (the_type, "n"); 11164 std::vector<gccjit::param> params; 11165 params.push_back (n); 11166 gccjit::function func = 11167 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 11168 return_type, 11169 "loop_test", 11170 params, 0); 11171 11172 /* Build locals: */ 11173 gccjit::lvalue i = func.new_local (the_type, "i"); 11174 gccjit::lvalue sum = func.new_local (the_type, "sum"); 11175 11176 gccjit::block b_initial = func.new_block ("initial"); 11177 gccjit::block b_loop_cond = func.new_block ("loop_cond"); 11178 gccjit::block b_loop_body = func.new_block ("loop_body"); 11179 gccjit::block b_after_loop = func.new_block ("after_loop"); 11180 11181 /* sum = 0; */ 11182 b_initial.add_assignment (sum, ctxt.zero (the_type)); 11183 11184 /* i = 0; */ 11185 b_initial.add_assignment (i, ctxt.zero (the_type)); 11186 11187 b_initial.end_with_jump (b_loop_cond); 11188 11189 /* if (i >= n) */ 11190 b_loop_cond.end_with_conditional ( 11191 i >= n, 11192 b_after_loop, 11193 b_loop_body); 11194 11195 /* sum += i * i */ 11196 b_loop_body.add_assignment_op (sum, 11197 GCC_JIT_BINARY_OP_PLUS, 11198 i * i); 11199 11200 /* i++ */ 11201 b_loop_body.add_assignment_op (i, 11202 GCC_JIT_BINARY_OP_PLUS, 11203 ctxt.one (the_type)); 11204 11205 b_loop_body.end_with_jump (b_loop_cond); 11206 11207 /* return sum */ 11208 b_after_loop.end_with_return (sum); 11209@} 11210 11211int 11212main (int argc, char **argv) 11213@{ 11214 gccjit::context ctxt; 11215 gcc_jit_result *result = NULL; 11216 11217 /* Get a "context" object for working with the library. */ 11218 ctxt = gccjit::context::acquire (); 11219 11220 /* Set some options on the context. 11221 Turn this on to see the code being generated, in assembler form. */ 11222 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 11223 0); 11224 11225 /* Populate the context. */ 11226 create_code (ctxt); 11227 11228 /* Compile the code. */ 11229 result = ctxt.compile (); 11230 11231 ctxt.release (); 11232 11233 if (!result) 11234 @{ 11235 fprintf (stderr, "NULL result"); 11236 return 1; 11237 @} 11238 11239 /* Extract the generated code from "result". */ 11240 typedef int (*loop_test_fn_type) (int); 11241 loop_test_fn_type loop_test = 11242 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 11243 if (!loop_test) 11244 @{ 11245 fprintf (stderr, "NULL loop_test"); 11246 gcc_jit_result_release (result); 11247 return 1; 11248 @} 11249 11250 /* Run the generated code. */ 11251 int val = loop_test (10); 11252 printf("loop_test returned: %d\n", val); 11253 11254 gcc_jit_result_release (result); 11255 return 0; 11256@} 11257@end example 11258@end quotation 11259 11260Building and running it: 11261 11262@example 11263$ gcc \ 11264 tut03-sum-of-squares.cc \ 11265 -o tut03-sum-of-squares \ 11266 -lgccjit 11267 11268# Run the built program: 11269$ ./tut03-sum-of-squares 11270loop_test returned: 285 11271@end example 11272 11273@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 11274@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 11275@c 11276@c This is free software: you can redistribute it and/or modify it 11277@c under the terms of the GNU General Public License as published by 11278@c the Free Software Foundation, either version 3 of the License, or 11279@c (at your option) any later version. 11280@c 11281@c This program is distributed in the hope that it will be useful, but 11282@c WITHOUT ANY WARRANTY; without even the implied warranty of 11283@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11284@c General Public License for more details. 11285@c 11286@c You should have received a copy of the GNU General Public License 11287@c along with this program. If not, see 11288@c <https://www.gnu.org/licenses/>. 11289 11290@node Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,,Tutorial part 3 Loops and variables<2>,Tutorial<2> 11291@anchor{cp/intro/tutorial04 doc}@anchor{196}@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{197} 11292@subsection Tutorial part 4: Adding JIT-compilation to a toy interpreter 11293 11294 11295In this example we construct a ���toy��� interpreter, and add JIT-compilation 11296to it. 11297 11298@menu 11299* Our toy interpreter: Our toy interpreter<2>. 11300* Compiling to machine code: Compiling to machine code<2>. 11301* Setting things up: Setting things up<2>. 11302* Populating the function: Populating the function<2>. 11303* Verifying the control flow graph: Verifying the control flow graph<2>. 11304* Compiling the context: Compiling the context<2>. 11305* Single-stepping through the generated code: Single-stepping through the generated code<2>. 11306* Examining the generated code: Examining the generated code<2>. 11307* Putting it all together: Putting it all together<2>. 11308* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 11309 11310@end menu 11311 11312@node Our toy interpreter<2>,Compiling to machine code<2>,,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 11313@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{198} 11314@subsubsection Our toy interpreter 11315 11316 11317It���s a stack-based interpreter, and is intended as a (very simple) example 11318of the kind of bytecode interpreter seen in dynamic languages such as 11319Python, Ruby etc. 11320 11321For the sake of simplicity, our toy virtual machine is very limited: 11322 11323@quotation 11324 11325 11326@itemize * 11327 11328@item 11329The only data type is @cite{int} 11330 11331@item 11332It can only work on one function at a time (so that the only 11333function call that can be made is to recurse). 11334 11335@item 11336Functions can only take one parameter. 11337 11338@item 11339Functions have a stack of @cite{int} values. 11340 11341@item 11342We���ll implement function call within the interpreter by calling a 11343function in our implementation, rather than implementing our own 11344frame stack. 11345 11346@item 11347The parser is only good enough to get the examples to work. 11348@end itemize 11349@end quotation 11350 11351Naturally, a real interpreter would be much more complicated that this. 11352 11353The following operations are supported: 11354 11355 11356@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx} 11357@headitem 11358 11359Operation 11360 11361@tab 11362 11363Meaning 11364 11365@tab 11366 11367Old Stack 11368 11369@tab 11370 11371New Stack 11372 11373@item 11374 11375DUP 11376 11377@tab 11378 11379Duplicate top of stack. 11380 11381@tab 11382 11383@code{[..., x]} 11384 11385@tab 11386 11387@code{[..., x, x]} 11388 11389@item 11390 11391ROT 11392 11393@tab 11394 11395Swap top two elements 11396of stack. 11397 11398@tab 11399 11400@code{[..., x, y]} 11401 11402@tab 11403 11404@code{[..., y, x]} 11405 11406@item 11407 11408BINARY_ADD 11409 11410@tab 11411 11412Add the top two elements 11413on the stack. 11414 11415@tab 11416 11417@code{[..., x, y]} 11418 11419@tab 11420 11421@code{[..., (x+y)]} 11422 11423@item 11424 11425BINARY_SUBTRACT 11426 11427@tab 11428 11429Likewise, but subtract. 11430 11431@tab 11432 11433@code{[..., x, y]} 11434 11435@tab 11436 11437@code{[..., (x-y)]} 11438 11439@item 11440 11441BINARY_MULT 11442 11443@tab 11444 11445Likewise, but multiply. 11446 11447@tab 11448 11449@code{[..., x, y]} 11450 11451@tab 11452 11453@code{[..., (x*y)]} 11454 11455@item 11456 11457BINARY_COMPARE_LT 11458 11459@tab 11460 11461Compare the top two 11462elements on the stack 11463and push a nonzero/zero 11464if (x<y). 11465 11466@tab 11467 11468@code{[..., x, y]} 11469 11470@tab 11471 11472@code{[..., (x<y)]} 11473 11474@item 11475 11476RECURSE 11477 11478@tab 11479 11480Recurse, passing the top 11481of the stack, and 11482popping the result. 11483 11484@tab 11485 11486@code{[..., x]} 11487 11488@tab 11489 11490@code{[..., fn(x)]} 11491 11492@item 11493 11494RETURN 11495 11496@tab 11497 11498Return the top of the 11499stack. 11500 11501@tab 11502 11503@code{[x]} 11504 11505@tab 11506 11507@code{[]} 11508 11509@item 11510 11511PUSH_CONST @cite{arg} 11512 11513@tab 11514 11515Push an int const. 11516 11517@tab 11518 11519@code{[...]} 11520 11521@tab 11522 11523@code{[..., arg]} 11524 11525@item 11526 11527JUMP_ABS_IF_TRUE @cite{arg} 11528 11529@tab 11530 11531Pop; if top of stack was 11532nonzero, jump to 11533@code{arg}. 11534 11535@tab 11536 11537@code{[..., x]} 11538 11539@tab 11540 11541@code{[...]} 11542 11543@end multitable 11544 11545 11546Programs can be interpreted, disassembled, and compiled to machine code. 11547 11548The interpreter reads @code{.toy} scripts. Here���s what a simple recursive 11549factorial program looks like, the script @code{factorial.toy}. 11550The parser ignores lines beginning with a @cite{#}. 11551 11552@quotation 11553 11554@example 11555# Simple recursive factorial implementation, roughly equivalent to: 11556# 11557# int factorial (int arg) 11558# @{ 11559# if (arg < 2) 11560# return arg 11561# return arg * factorial (arg - 1) 11562# @} 11563 11564# Initial state: 11565# stack: [arg] 11566 11567# 0: 11568DUP 11569# stack: [arg, arg] 11570 11571# 1: 11572PUSH_CONST 2 11573# stack: [arg, arg, 2] 11574 11575# 2: 11576BINARY_COMPARE_LT 11577# stack: [arg, (arg < 2)] 11578 11579# 3: 11580JUMP_ABS_IF_TRUE 9 11581# stack: [arg] 11582 11583# 4: 11584DUP 11585# stack: [arg, arg] 11586 11587# 5: 11588PUSH_CONST 1 11589# stack: [arg, arg, 1] 11590 11591# 6: 11592BINARY_SUBTRACT 11593# stack: [arg, (arg - 1) 11594 11595# 7: 11596RECURSE 11597# stack: [arg, factorial(arg - 1)] 11598 11599# 8: 11600BINARY_MULT 11601# stack: [arg * factorial(arg - 1)] 11602 11603# 9: 11604RETURN 11605@end example 11606@end quotation 11607 11608The interpreter is a simple infinite loop with a big @code{switch} statement 11609based on what the next opcode is: 11610 11611@quotation 11612 11613@example 11614 11615int 11616toyvm_function::interpret (int arg, FILE *trace) 11617@{ 11618 toyvm_frame frame; 11619#define PUSH(ARG) (frame.push (ARG)) 11620#define POP(ARG) (frame.pop ()) 11621 11622 frame.frm_function = this; 11623 frame.frm_pc = 0; 11624 frame.frm_cur_depth = 0; 11625 11626 PUSH (arg); 11627 11628 while (1) 11629 @{ 11630 toyvm_op *op; 11631 int x, y; 11632 assert (frame.frm_pc < fn_num_ops); 11633 op = &fn_ops[frame.frm_pc++]; 11634 11635 if (trace) 11636 @{ 11637 frame.dump_stack (trace); 11638 disassemble_op (op, frame.frm_pc, trace); 11639 @} 11640 11641 switch (op->op_opcode) 11642 @{ 11643 /* Ops taking no operand. */ 11644 case DUP: 11645 x = POP (); 11646 PUSH (x); 11647 PUSH (x); 11648 break; 11649 11650 case ROT: 11651 y = POP (); 11652 x = POP (); 11653 PUSH (y); 11654 PUSH (x); 11655 break; 11656 11657 case BINARY_ADD: 11658 y = POP (); 11659 x = POP (); 11660 PUSH (x + y); 11661 break; 11662 11663 case BINARY_SUBTRACT: 11664 y = POP (); 11665 x = POP (); 11666 PUSH (x - y); 11667 break; 11668 11669 case BINARY_MULT: 11670 y = POP (); 11671 x = POP (); 11672 PUSH (x * y); 11673 break; 11674 11675 case BINARY_COMPARE_LT: 11676 y = POP (); 11677 x = POP (); 11678 PUSH (x < y); 11679 break; 11680 11681 case RECURSE: 11682 x = POP (); 11683 x = interpret (x, trace); 11684 PUSH (x); 11685 break; 11686 11687 case RETURN: 11688 return POP (); 11689 11690 /* Ops taking an operand. */ 11691 case PUSH_CONST: 11692 PUSH (op->op_operand); 11693 break; 11694 11695 case JUMP_ABS_IF_TRUE: 11696 x = POP (); 11697 if (x) 11698 frame.frm_pc = op->op_operand; 11699 break; 11700 11701 default: 11702 assert (0); /* unknown opcode */ 11703 11704 @} /* end of switch on opcode */ 11705 @} /* end of while loop */ 11706 11707#undef PUSH 11708#undef POP 11709@} 11710 11711@end example 11712@end quotation 11713 11714@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> 11715@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{199} 11716@subsubsection Compiling to machine code 11717 11718 11719We want to generate machine code that can be cast to this type and 11720then directly executed in-process: 11721 11722@quotation 11723 11724@example 11725typedef int (*toyvm_compiled_func) (int); 11726 11727@end example 11728@end quotation 11729 11730Our compiler isn���t very sophisticated; it takes the implementation of 11731each opcode above, and maps it directly to the operations supported by 11732the libgccjit API. 11733 11734How should we handle the stack? In theory we could calculate what the 11735stack depth will be at each opcode, and optimize away the stack 11736manipulation ���by hand���. We���ll see below that libgccjit is able to do 11737this for us, so we���ll implement stack manipulation 11738in a direct way, by creating a @code{stack} array and @code{stack_depth} 11739variables, local within the generated function, equivalent to this C code: 11740 11741@example 11742int stack_depth; 11743int stack[MAX_STACK_DEPTH]; 11744@end example 11745 11746We���ll also have local variables @code{x} and @code{y} for use when implementing 11747the opcodes, equivalent to this: 11748 11749@example 11750int x; 11751int y; 11752@end example 11753 11754This means our compiler has the following state: 11755 11756@quotation 11757 11758@example 11759 11760 toyvm_function &toyvmfn; 11761 11762 gccjit::context ctxt; 11763 11764 gccjit::type int_type; 11765 gccjit::type bool_type; 11766 gccjit::type stack_type; /* int[MAX_STACK_DEPTH] */ 11767 11768 gccjit::rvalue const_one; 11769 11770 gccjit::function fn; 11771 gccjit::param param_arg; 11772 gccjit::lvalue stack; 11773 gccjit::lvalue stack_depth; 11774 gccjit::lvalue x; 11775 gccjit::lvalue y; 11776 11777 gccjit::location op_locs[MAX_OPS]; 11778 gccjit::block initial_block; 11779 gccjit::block op_blocks[MAX_OPS]; 11780 11781@end example 11782@end quotation 11783 11784@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> 11785@anchor{cp/intro/tutorial04 setting-things-up}@anchor{19a} 11786@subsubsection Setting things up 11787 11788 11789First we create our types: 11790 11791@quotation 11792 11793@example 11794 11795void 11796compilation_state::create_types () 11797@{ 11798 /* Create types. */ 11799 int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 11800 bool_type = ctxt.get_type (GCC_JIT_TYPE_BOOL); 11801 stack_type = ctxt.new_array_type (int_type, MAX_STACK_DEPTH); 11802 11803@end example 11804@end quotation 11805 11806along with extracting a useful @cite{int} constant: 11807 11808@quotation 11809 11810@example 11811 const_one = ctxt.one (int_type); 11812 11813@} 11814 11815@end example 11816@end quotation 11817 11818We���ll implement push and pop in terms of the @code{stack} array and 11819@code{stack_depth}. Here are helper functions for adding statements to 11820a block, implementing pushing and popping values: 11821 11822@quotation 11823 11824@example 11825 11826void 11827compilation_state::add_push (gccjit::block block, 11828 gccjit::rvalue rvalue, 11829 gccjit::location loc) 11830@{ 11831 /* stack[stack_depth] = RVALUE */ 11832 block.add_assignment ( 11833 /* stack[stack_depth] */ 11834 ctxt.new_array_access ( 11835 stack, 11836 stack_depth, 11837 loc), 11838 rvalue, 11839 loc); 11840 11841 /* "stack_depth++;". */ 11842 block.add_assignment_op ( 11843 stack_depth, 11844 GCC_JIT_BINARY_OP_PLUS, 11845 const_one, 11846 loc); 11847@} 11848 11849void 11850compilation_state::add_pop (gccjit::block block, 11851 gccjit::lvalue lvalue, 11852 gccjit::location loc) 11853@{ 11854 /* "--stack_depth;". */ 11855 block.add_assignment_op ( 11856 stack_depth, 11857 GCC_JIT_BINARY_OP_MINUS, 11858 const_one, 11859 loc); 11860 11861 /* "LVALUE = stack[stack_depth];". */ 11862 block.add_assignment ( 11863 lvalue, 11864 /* stack[stack_depth] */ 11865 ctxt.new_array_access (stack, 11866 stack_depth, 11867 loc), 11868 loc); 11869@} 11870 11871@end example 11872@end quotation 11873 11874We will support single-stepping through the generated code in the 11875debugger, so we need to create @ref{19b,,gccjit;;location} instances, one 11876per operation in the source code. These will reference the lines of 11877e.g. @code{factorial.toy}. 11878 11879@quotation 11880 11881@example 11882 11883void 11884compilation_state::create_locations () 11885@{ 11886 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 11887 @{ 11888 toyvm_op *op = &toyvmfn.fn_ops[pc]; 11889 11890 op_locs[pc] = ctxt.new_location (toyvmfn.fn_filename, 11891 op->op_linenum, 11892 0); /* column */ 11893 @} 11894@} 11895 11896@end example 11897@end quotation 11898 11899Let���s create the function itself. As usual, we create its parameter 11900first, then use the parameter to create the function: 11901 11902@quotation 11903 11904@example 11905 11906void 11907compilation_state::create_function (const char *funcname) 11908@{ 11909 std::vector <gccjit::param> params; 11910 param_arg = ctxt.new_param (int_type, "arg", op_locs[0]); 11911 params.push_back (param_arg); 11912 fn = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 11913 int_type, 11914 funcname, 11915 params, 0, 11916 op_locs[0]); 11917 11918@end example 11919@end quotation 11920 11921We create the locals within the function. 11922 11923@quotation 11924 11925@example 11926 stack = fn.new_local (stack_type, "stack"); 11927 stack_depth = fn.new_local (int_type, "stack_depth"); 11928 x = fn.new_local (int_type, "x"); 11929 y = fn.new_local (int_type, "y"); 11930 11931@end example 11932@end quotation 11933 11934@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> 11935@anchor{cp/intro/tutorial04 populating-the-function}@anchor{19c} 11936@subsubsection Populating the function 11937 11938 11939There���s some one-time initialization, and the API treats the first block 11940you create as the entrypoint of the function, so we need to create that 11941block first: 11942 11943@quotation 11944 11945@example 11946 initial_block = fn.new_block ("initial"); 11947 11948@end example 11949@end quotation 11950 11951We can now create blocks for each of the operations. Most of these will 11952be consolidated into larger blocks when the optimizer runs. 11953 11954@quotation 11955 11956@example 11957 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 11958 @{ 11959 char buf[100]; 11960 sprintf (buf, "instr%i", pc); 11961 op_blocks[pc] = fn.new_block (buf); 11962 @} 11963 11964@end example 11965@end quotation 11966 11967Now that we have a block it can jump to when it���s done, we can populate 11968the initial block: 11969 11970@quotation 11971 11972@example 11973 11974 /* "stack_depth = 0;". */ 11975 initial_block.add_assignment (stack_depth, 11976 ctxt.zero (int_type), 11977 op_locs[0]); 11978 11979 /* "PUSH (arg);". */ 11980 add_push (initial_block, 11981 param_arg, 11982 op_locs[0]); 11983 11984 /* ...and jump to insn 0. */ 11985 initial_block.end_with_jump (op_blocks[0], 11986 op_locs[0]); 11987 11988@end example 11989@end quotation 11990 11991We can now populate the blocks for the individual operations. We loop 11992through them, adding instructions to their blocks: 11993 11994@quotation 11995 11996@example 11997 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 11998 @{ 11999 gccjit::location loc = op_locs[pc]; 12000 12001 gccjit::block block = op_blocks[pc]; 12002 gccjit::block next_block = (pc < toyvmfn.fn_num_ops 12003 ? op_blocks[pc + 1] 12004 : NULL); 12005 12006 toyvm_op *op; 12007 op = &toyvmfn.fn_ops[pc]; 12008 12009@end example 12010@end quotation 12011 12012We���re going to have another big @code{switch} statement for implementing 12013the opcodes, this time for compiling them, rather than interpreting 12014them. It���s helpful to have macros for implementing push and pop, so that 12015we can make the @code{switch} statement that���s coming up look as much as 12016possible like the one above within the interpreter: 12017 12018@example 12019 12020#define X_EQUALS_POP()\ 12021 add_pop (block, x, loc) 12022#define Y_EQUALS_POP()\ 12023 add_pop (block, y, loc) 12024#define PUSH_RVALUE(RVALUE)\ 12025 add_push (block, (RVALUE), loc) 12026#define PUSH_X()\ 12027 PUSH_RVALUE (x) 12028#define PUSH_Y() \ 12029 PUSH_RVALUE (y) 12030 12031@end example 12032 12033@cartouche 12034@quotation Note 12035A particularly clever implementation would have an @emph{identical} 12036@code{switch} statement shared by the interpreter and the compiler, with 12037some preprocessor ���magic���. We���re not doing that here, for the sake 12038of simplicity. 12039@end quotation 12040@end cartouche 12041 12042When I first implemented this compiler, I accidentally missed an edit 12043when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the 12044stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y} 12045uninitialized. 12046 12047To track this kind of thing down, we can use 12048@ref{19d,,gccjit;;block;;add_comment()} to add descriptive comments 12049to the internal representation. This is invaluable when looking through 12050the generated IR for, say @code{factorial}: 12051 12052@quotation 12053 12054@example 12055 12056 block.add_comment (opcode_names[op->op_opcode], loc); 12057 12058@end example 12059@end quotation 12060 12061We can now write the big @code{switch} statement that implements the 12062individual opcodes, populating the relevant block with statements: 12063 12064@quotation 12065 12066@example 12067 12068 switch (op->op_opcode) 12069 @{ 12070 case DUP: 12071 X_EQUALS_POP (); 12072 PUSH_X (); 12073 PUSH_X (); 12074 break; 12075 12076 case ROT: 12077 Y_EQUALS_POP (); 12078 X_EQUALS_POP (); 12079 PUSH_Y (); 12080 PUSH_X (); 12081 break; 12082 12083 case BINARY_ADD: 12084 Y_EQUALS_POP (); 12085 X_EQUALS_POP (); 12086 PUSH_RVALUE ( 12087 ctxt.new_binary_op ( 12088 GCC_JIT_BINARY_OP_PLUS, 12089 int_type, 12090 x, y, 12091 loc)); 12092 break; 12093 12094 case BINARY_SUBTRACT: 12095 Y_EQUALS_POP (); 12096 X_EQUALS_POP (); 12097 PUSH_RVALUE ( 12098 ctxt.new_binary_op ( 12099 GCC_JIT_BINARY_OP_MINUS, 12100 int_type, 12101 x, y, 12102 loc)); 12103 break; 12104 12105 case BINARY_MULT: 12106 Y_EQUALS_POP (); 12107 X_EQUALS_POP (); 12108 PUSH_RVALUE ( 12109 ctxt.new_binary_op ( 12110 GCC_JIT_BINARY_OP_MULT, 12111 int_type, 12112 x, y, 12113 loc)); 12114 break; 12115 12116 case BINARY_COMPARE_LT: 12117 Y_EQUALS_POP (); 12118 X_EQUALS_POP (); 12119 PUSH_RVALUE ( 12120 /* cast of bool to int */ 12121 ctxt.new_cast ( 12122 /* (x < y) as a bool */ 12123 ctxt.new_comparison ( 12124 GCC_JIT_COMPARISON_LT, 12125 x, y, 12126 loc), 12127 int_type, 12128 loc)); 12129 break; 12130 12131 case RECURSE: 12132 @{ 12133 X_EQUALS_POP (); 12134 PUSH_RVALUE ( 12135 ctxt.new_call ( 12136 fn, 12137 x, 12138 loc)); 12139 break; 12140 @} 12141 12142 case RETURN: 12143 X_EQUALS_POP (); 12144 block.end_with_return (x, loc); 12145 break; 12146 12147 /* Ops taking an operand. */ 12148 case PUSH_CONST: 12149 PUSH_RVALUE ( 12150 ctxt.new_rvalue (int_type, op->op_operand)); 12151 break; 12152 12153 case JUMP_ABS_IF_TRUE: 12154 X_EQUALS_POP (); 12155 block.end_with_conditional ( 12156 /* "(bool)x". */ 12157 ctxt.new_cast (x, bool_type, loc), 12158 op_blocks[op->op_operand], /* on_true */ 12159 next_block, /* on_false */ 12160 loc); 12161 break; 12162 12163 default: 12164 assert(0); 12165 @} /* end of switch on opcode */ 12166 12167@end example 12168@end quotation 12169 12170Every block must be terminated, via a call to one of the 12171@code{gccjit::block::end_with_} entrypoints. This has been done for two 12172of the opcodes, but we need to do it for the other ones, by jumping 12173to the next block. 12174 12175@quotation 12176 12177@example 12178 if (op->op_opcode != JUMP_ABS_IF_TRUE 12179 && op->op_opcode != RETURN) 12180 block.end_with_jump (next_block, loc); 12181 12182@end example 12183@end quotation 12184 12185This is analogous to simply incrementing the program counter. 12186 12187@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> 12188@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{19e} 12189@subsubsection Verifying the control flow graph 12190 12191 12192Having finished looping over the blocks, the context is complete. 12193 12194As before, we can verify that the control flow and statements are sane by 12195using @ref{194,,gccjit;;function;;dump_to_dot()}: 12196 12197@example 12198fn.dump_to_dot ("/tmp/factorial.dot"); 12199@end example 12200 12201and viewing the result. Note how the label names, comments, and 12202variable names show up in the dump, to make it easier to spot 12203errors in our compiler. 12204 12205@quotation 12206 12207 12208@float Figure 12209 12210@image{libgccjit-figures/factorial,,,image of a control flow graph,png} 12211 12212@end float 12213 12214@end quotation 12215 12216@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> 12217@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{19f} 12218@subsubsection Compiling the context 12219 12220 12221Having finished looping over the blocks and populating them with 12222statements, the context is complete. 12223 12224We can now compile it, extract machine code from the result, and 12225run it: 12226 12227@quotation 12228 12229@example 12230 12231class compilation_result 12232@{ 12233public: 12234 compilation_result (gcc_jit_result *result) : 12235 m_result (result) 12236 @{ 12237 @} 12238 ~compilation_result () 12239 @{ 12240 gcc_jit_result_release (m_result); 12241 @} 12242 12243 void *get_code (const char *funcname) 12244 @{ 12245 return gcc_jit_result_get_code (m_result, funcname); 12246 @} 12247 12248private: 12249 gcc_jit_result *m_result; 12250@}; 12251 12252@end example 12253 12254@example 12255 compilation_result compiler_result = fn->compile (); 12256 12257 const char *funcname = fn->get_function_name (); 12258 toyvm_compiled_func code 12259 = (toyvm_compiled_func)compiler_result.get_code (funcname); 12260 12261 printf ("compiler result: %d\n", 12262 code (atoi (argv[2]))); 12263 12264@end example 12265@end quotation 12266 12267@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> 12268@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{1a0} 12269@subsubsection Single-stepping through the generated code 12270 12271 12272It���s possible to debug the generated code. To do this we need to both: 12273 12274@quotation 12275 12276 12277@itemize * 12278 12279@item 12280Set up source code locations for our statements, so that we can 12281meaningfully step through the code. We did this above by 12282calling @ref{1a1,,gccjit;;context;;new_location()} and using the 12283results. 12284 12285@item 12286Enable the generation of debugging information, by setting 12287@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 12288@ref{175,,gccjit;;context} via 12289@ref{181,,gccjit;;context;;set_bool_option()}: 12290 12291@example 12292ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1); 12293@end example 12294@end itemize 12295@end quotation 12296 12297Having done this, we can put a breakpoint on the generated function: 12298 12299@example 12300$ gdb --args ./toyvm factorial.toy 10 12301(gdb) break factorial 12302Function "factorial" not defined. 12303Make breakpoint pending on future shared library load? (y or [n]) y 12304Breakpoint 1 (factorial) pending. 12305(gdb) run 12306Breakpoint 1, factorial (arg=10) at factorial.toy:14 1230714 DUP 12308@end example 12309 12310We���ve set up location information, which references @code{factorial.toy}. 12311This allows us to use e.g. @code{list} to see where we are in the script: 12312 12313@example 12314(gdb) list 123159 1231610 # Initial state: 1231711 # stack: [arg] 1231812 1231913 # 0: 1232014 DUP 1232115 # stack: [arg, arg] 1232216 1232317 # 1: 1232418 PUSH_CONST 2 12325@end example 12326 12327and to step through the function, examining the data: 12328 12329@example 12330(gdb) n 1233118 PUSH_CONST 2 12332(gdb) n 1233322 BINARY_COMPARE_LT 12334(gdb) print stack 12335$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@} 12336(gdb) print stack_depth 12337$6 = 3 12338@end example 12339 12340You���ll see that the parts of the @code{stack} array that haven���t been 12341touched yet are uninitialized. 12342 12343@cartouche 12344@quotation Note 12345Turning on optimizations may lead to unpredictable results when 12346stepping through the generated code: the execution may appear to 12347���jump around��� the source code. This is analogous to turning up the 12348optimization level in a regular compiler. 12349@end quotation 12350@end cartouche 12351 12352@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> 12353@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{1a2} 12354@subsubsection Examining the generated code 12355 12356 12357How good is the optimized code? 12358 12359We can turn up optimizations, by calling 12360@ref{182,,gccjit;;context;;set_int_option()} with 12361@ref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 12362 12363@example 12364ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); 12365@end example 12366 12367One of GCC���s internal representations is called ���gimple���. A dump of the 12368initial gimple representation of the code can be seen by setting: 12369 12370@example 12371ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); 12372@end example 12373 12374With optimization on and source locations displayed, this gives: 12375 12376@c We'll use "c" for gimple dumps 12377 12378@example 12379factorial (signed int arg) 12380@{ 12381 <unnamed type> D.80; 12382 signed int D.81; 12383 signed int D.82; 12384 signed int D.83; 12385 signed int D.84; 12386 signed int D.85; 12387 signed int y; 12388 signed int x; 12389 signed int stack_depth; 12390 signed int stack[8]; 12391 12392 try 12393 @{ 12394 initial: 12395 stack_depth = 0; 12396 stack[stack_depth] = arg; 12397 stack_depth = stack_depth + 1; 12398 goto instr0; 12399 instr0: 12400 /* DUP */: 12401 stack_depth = stack_depth + -1; 12402 x = stack[stack_depth]; 12403 stack[stack_depth] = x; 12404 stack_depth = stack_depth + 1; 12405 stack[stack_depth] = x; 12406 stack_depth = stack_depth + 1; 12407 goto instr1; 12408 instr1: 12409 /* PUSH_CONST */: 12410 stack[stack_depth] = 2; 12411 stack_depth = stack_depth + 1; 12412 goto instr2; 12413 12414 /* etc */ 12415@end example 12416 12417You can see the generated machine code in assembly form via: 12418 12419@example 12420ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); 12421result = ctxt.compile (); 12422@end example 12423 12424which shows that (on this x86_64 box) the compiler has unrolled the loop 12425and is using MMX instructions to perform several multiplications 12426simultaneously: 12427 12428@example 12429 .file "fake.c" 12430 .text 12431.Ltext0: 12432 .p2align 4,,15 12433 .globl factorial 12434 .type factorial, @@function 12435factorial: 12436.LFB0: 12437 .file 1 "factorial.toy" 12438 .loc 1 14 0 12439 .cfi_startproc 12440.LVL0: 12441.L2: 12442 .loc 1 26 0 12443 cmpl $1, %edi 12444 jle .L13 12445 leal -1(%rdi), %edx 12446 movl %edx, %ecx 12447 shrl $2, %ecx 12448 leal 0(,%rcx,4), %esi 12449 testl %esi, %esi 12450 je .L14 12451 cmpl $9, %edx 12452 jbe .L14 12453 leal -2(%rdi), %eax 12454 movl %eax, -16(%rsp) 12455 leal -3(%rdi), %eax 12456 movd -16(%rsp), %xmm0 12457 movl %edi, -16(%rsp) 12458 movl %eax, -12(%rsp) 12459 movd -16(%rsp), %xmm1 12460 xorl %eax, %eax 12461 movl %edx, -16(%rsp) 12462 movd -12(%rsp), %xmm4 12463 movd -16(%rsp), %xmm6 12464 punpckldq %xmm4, %xmm0 12465 movdqa .LC1(%rip), %xmm4 12466 punpckldq %xmm6, %xmm1 12467 punpcklqdq %xmm0, %xmm1 12468 movdqa .LC0(%rip), %xmm0 12469 jmp .L5 12470 # etc - edited for brevity 12471@end example 12472 12473This is clearly overkill for a function that will likely overflow the 12474@code{int} type before the vectorization is worthwhile - but then again, this 12475is a toy example. 12476 12477Turning down the optimization level to 2: 12478 12479@example 12480ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2); 12481@end example 12482 12483yields this code, which is simple enough to quote in its entirety: 12484 12485@example 12486 .file "fake.c" 12487 .text 12488 .p2align 4,,15 12489 .globl factorial 12490 .type factorial, @@function 12491factorial: 12492.LFB0: 12493 .cfi_startproc 12494.L2: 12495 cmpl $1, %edi 12496 jle .L8 12497 movl $1, %edx 12498 jmp .L4 12499 .p2align 4,,10 12500 .p2align 3 12501.L6: 12502 movl %eax, %edi 12503.L4: 12504.L5: 12505 leal -1(%rdi), %eax 12506 imull %edi, %edx 12507 cmpl $1, %eax 12508 jne .L6 12509.L3: 12510.L7: 12511 imull %edx, %eax 12512 ret 12513.L8: 12514 movl %edi, %eax 12515 movl $1, %edx 12516 jmp .L7 12517 .cfi_endproc 12518.LFE0: 12519 .size factorial, .-factorial 12520 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})" 12521 .section .note.GNU-stack,"",@@progbits 12522@end example 12523 12524Note that the stack pushing and popping have been eliminated, as has the 12525recursive call (in favor of an iteration). 12526 12527@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> 12528@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{1a3} 12529@subsubsection Putting it all together 12530 12531 12532The complete example can be seen in the source tree at 12533@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.cc} 12534 12535along with a Makefile and a couple of sample .toy scripts: 12536 12537@example 12538$ ls -al 12539drwxrwxr-x. 2 david david 4096 Sep 19 17:46 . 12540drwxrwxr-x. 3 david david 4096 Sep 19 15:26 .. 12541-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy 12542-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy 12543-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile 12544-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.cc 12545 12546$ make toyvm 12547g++ -Wall -g -o toyvm toyvm.cc -lgccjit 12548 12549$ ./toyvm factorial.toy 10 12550interpreter result: 3628800 12551compiler result: 3628800 12552 12553$ ./toyvm fibonacci.toy 10 12554interpreter result: 55 12555compiler result: 55 12556@end example 12557 12558@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> 12559@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{1a4} 12560@subsubsection Behind the curtain: How does our code get optimized? 12561 12562 12563Our example is done, but you may be wondering about exactly how the 12564compiler turned what we gave it into the machine code seen above. 12565 12566We can examine what the compiler is doing in detail by setting: 12567 12568@example 12569state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 1); 12570state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 1); 12571@end example 12572 12573This will dump detailed information about the compiler���s state to a 12574directory under @code{/tmp}, and keep it from being cleaned up. 12575 12576The precise names and their formats of these files is subject to change. 12577Higher optimization levels lead to more files. 12578Here���s what I saw (edited for brevity; there were almost 200 files): 12579 12580@example 12581intermediate files written to /tmp/libgccjit-KPQbGw 12582$ ls /tmp/libgccjit-KPQbGw/ 12583fake.c.000i.cgraph 12584fake.c.000i.type-inheritance 12585fake.c.004t.gimple 12586fake.c.007t.omplower 12587fake.c.008t.lower 12588fake.c.011t.eh 12589fake.c.012t.cfg 12590fake.c.014i.visibility 12591fake.c.015i.early_local_cleanups 12592fake.c.016t.ssa 12593# etc 12594@end example 12595 12596The gimple code is converted into Static Single Assignment form, 12597with annotations for use when generating the debuginfo: 12598 12599@example 12600$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa 12601@end example 12602 12603@example 12604;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12605 12606factorial (signed int arg) 12607@{ 12608 signed int stack[8]; 12609 signed int stack_depth; 12610 signed int x; 12611 signed int y; 12612 <unnamed type> _20; 12613 signed int _21; 12614 signed int _38; 12615 signed int _44; 12616 signed int _51; 12617 signed int _56; 12618 12619initial: 12620 stack_depth_3 = 0; 12621 # DEBUG stack_depth => stack_depth_3 12622 stack[stack_depth_3] = arg_5(D); 12623 stack_depth_7 = stack_depth_3 + 1; 12624 # DEBUG stack_depth => stack_depth_7 12625 # DEBUG instr0 => NULL 12626 # DEBUG /* DUP */ => NULL 12627 stack_depth_8 = stack_depth_7 + -1; 12628 # DEBUG stack_depth => stack_depth_8 12629 x_9 = stack[stack_depth_8]; 12630 # DEBUG x => x_9 12631 stack[stack_depth_8] = x_9; 12632 stack_depth_11 = stack_depth_8 + 1; 12633 # DEBUG stack_depth => stack_depth_11 12634 stack[stack_depth_11] = x_9; 12635 stack_depth_13 = stack_depth_11 + 1; 12636 # DEBUG stack_depth => stack_depth_13 12637 # DEBUG instr1 => NULL 12638 # DEBUG /* PUSH_CONST */ => NULL 12639 stack[stack_depth_13] = 2; 12640 12641 /* etc; edited for brevity */ 12642@end example 12643 12644We can perhaps better see the code by turning off 12645@ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG} 12646statements, giving: 12647 12648@example 12649$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa 12650@end example 12651 12652@example 12653;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12654 12655factorial (signed int arg) 12656@{ 12657 signed int stack[8]; 12658 signed int stack_depth; 12659 signed int x; 12660 signed int y; 12661 <unnamed type> _20; 12662 signed int _21; 12663 signed int _38; 12664 signed int _44; 12665 signed int _51; 12666 signed int _56; 12667 12668initial: 12669 stack_depth_3 = 0; 12670 stack[stack_depth_3] = arg_5(D); 12671 stack_depth_7 = stack_depth_3 + 1; 12672 stack_depth_8 = stack_depth_7 + -1; 12673 x_9 = stack[stack_depth_8]; 12674 stack[stack_depth_8] = x_9; 12675 stack_depth_11 = stack_depth_8 + 1; 12676 stack[stack_depth_11] = x_9; 12677 stack_depth_13 = stack_depth_11 + 1; 12678 stack[stack_depth_13] = 2; 12679 stack_depth_15 = stack_depth_13 + 1; 12680 stack_depth_16 = stack_depth_15 + -1; 12681 y_17 = stack[stack_depth_16]; 12682 stack_depth_18 = stack_depth_16 + -1; 12683 x_19 = stack[stack_depth_18]; 12684 _20 = x_19 < y_17; 12685 _21 = (signed int) _20; 12686 stack[stack_depth_18] = _21; 12687 stack_depth_23 = stack_depth_18 + 1; 12688 stack_depth_24 = stack_depth_23 + -1; 12689 x_25 = stack[stack_depth_24]; 12690 if (x_25 != 0) 12691 goto <bb 4> (instr9); 12692 else 12693 goto <bb 3> (instr4); 12694 12695instr4: 12696/* DUP */: 12697 stack_depth_26 = stack_depth_24 + -1; 12698 x_27 = stack[stack_depth_26]; 12699 stack[stack_depth_26] = x_27; 12700 stack_depth_29 = stack_depth_26 + 1; 12701 stack[stack_depth_29] = x_27; 12702 stack_depth_31 = stack_depth_29 + 1; 12703 stack[stack_depth_31] = 1; 12704 stack_depth_33 = stack_depth_31 + 1; 12705 stack_depth_34 = stack_depth_33 + -1; 12706 y_35 = stack[stack_depth_34]; 12707 stack_depth_36 = stack_depth_34 + -1; 12708 x_37 = stack[stack_depth_36]; 12709 _38 = x_37 - y_35; 12710 stack[stack_depth_36] = _38; 12711 stack_depth_40 = stack_depth_36 + 1; 12712 stack_depth_41 = stack_depth_40 + -1; 12713 x_42 = stack[stack_depth_41]; 12714 _44 = factorial (x_42); 12715 stack[stack_depth_41] = _44; 12716 stack_depth_46 = stack_depth_41 + 1; 12717 stack_depth_47 = stack_depth_46 + -1; 12718 y_48 = stack[stack_depth_47]; 12719 stack_depth_49 = stack_depth_47 + -1; 12720 x_50 = stack[stack_depth_49]; 12721 _51 = x_50 * y_48; 12722 stack[stack_depth_49] = _51; 12723 stack_depth_53 = stack_depth_49 + 1; 12724 12725 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)> 12726instr9: 12727/* RETURN */: 12728 stack_depth_54 = stack_depth_1 + -1; 12729 x_55 = stack[stack_depth_54]; 12730 _56 = x_55; 12731 stack =@{v@} @{CLOBBER@}; 12732 return _56; 12733 12734@} 12735@end example 12736 12737Note in the above how all the @ref{18b,,gccjit;;block} instances we 12738created have been consolidated into just 3 blocks in GCC���s internal 12739representation: @code{initial}, @code{instr4} and @code{instr9}. 12740 12741@menu 12742* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 12743* Elimination of tail recursion: Elimination of tail recursion<2>. 12744 12745@end menu 12746 12747@node Optimizing away stack manipulation<2>,Elimination of tail recursion<2>,,Behind the curtain How does our code get optimized?<2> 12748@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{1a5} 12749@subsubsection Optimizing away stack manipulation 12750 12751 12752Recall our simple implementation of stack operations. Let���s examine 12753how the stack operations are optimized away. 12754 12755After a pass of constant-propagation, the depth of the stack at each 12756opcode can be determined at compile-time: 12757 12758@example 12759$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1 12760@end example 12761 12762@example 12763;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12764 12765factorial (signed int arg) 12766@{ 12767 signed int stack[8]; 12768 signed int stack_depth; 12769 signed int x; 12770 signed int y; 12771 <unnamed type> _20; 12772 signed int _21; 12773 signed int _38; 12774 signed int _44; 12775 signed int _51; 12776 12777initial: 12778 stack[0] = arg_5(D); 12779 x_9 = stack[0]; 12780 stack[0] = x_9; 12781 stack[1] = x_9; 12782 stack[2] = 2; 12783 y_17 = stack[2]; 12784 x_19 = stack[1]; 12785 _20 = x_19 < y_17; 12786 _21 = (signed int) _20; 12787 stack[1] = _21; 12788 x_25 = stack[1]; 12789 if (x_25 != 0) 12790 goto <bb 4> (instr9); 12791 else 12792 goto <bb 3> (instr4); 12793 12794instr4: 12795/* DUP */: 12796 x_27 = stack[0]; 12797 stack[0] = x_27; 12798 stack[1] = x_27; 12799 stack[2] = 1; 12800 y_35 = stack[2]; 12801 x_37 = stack[1]; 12802 _38 = x_37 - y_35; 12803 stack[1] = _38; 12804 x_42 = stack[1]; 12805 _44 = factorial (x_42); 12806 stack[1] = _44; 12807 y_48 = stack[1]; 12808 x_50 = stack[0]; 12809 _51 = x_50 * y_48; 12810 stack[0] = _51; 12811 12812instr9: 12813/* RETURN */: 12814 x_55 = stack[0]; 12815 x_56 = x_55; 12816 stack =@{v@} @{CLOBBER@}; 12817 return x_56; 12818 12819@} 12820@end example 12821 12822Note how, in the above, all those @code{stack_depth} values are now just 12823constants: we���re accessing specific stack locations at each opcode. 12824 12825The ���esra��� pass (���Early Scalar Replacement of Aggregates���) breaks 12826out our ���stack��� array into individual elements: 12827 12828@example 12829$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra 12830@end example 12831 12832@example 12833;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12834 12835Created a replacement for stack offset: 0, size: 32: stack$0 12836Created a replacement for stack offset: 32, size: 32: stack$1 12837Created a replacement for stack offset: 64, size: 32: stack$2 12838 12839Symbols to be put in SSA form 12840@{ D.89 D.90 D.91 @} 12841Incremental SSA update started at block: 0 12842Number of blocks in CFG: 5 12843Number of blocks to update: 4 ( 80%) 12844 12845 12846factorial (signed int arg) 12847@{ 12848 signed int stack$2; 12849 signed int stack$1; 12850 signed int stack$0; 12851 signed int stack[8]; 12852 signed int stack_depth; 12853 signed int x; 12854 signed int y; 12855 <unnamed type> _20; 12856 signed int _21; 12857 signed int _38; 12858 signed int _44; 12859 signed int _51; 12860 12861initial: 12862 stack$0_45 = arg_5(D); 12863 x_9 = stack$0_45; 12864 stack$0_39 = x_9; 12865 stack$1_32 = x_9; 12866 stack$2_30 = 2; 12867 y_17 = stack$2_30; 12868 x_19 = stack$1_32; 12869 _20 = x_19 < y_17; 12870 _21 = (signed int) _20; 12871 stack$1_28 = _21; 12872 x_25 = stack$1_28; 12873 if (x_25 != 0) 12874 goto <bb 4> (instr9); 12875 else 12876 goto <bb 3> (instr4); 12877 12878instr4: 12879/* DUP */: 12880 x_27 = stack$0_39; 12881 stack$0_22 = x_27; 12882 stack$1_14 = x_27; 12883 stack$2_12 = 1; 12884 y_35 = stack$2_12; 12885 x_37 = stack$1_14; 12886 _38 = x_37 - y_35; 12887 stack$1_10 = _38; 12888 x_42 = stack$1_10; 12889 _44 = factorial (x_42); 12890 stack$1_6 = _44; 12891 y_48 = stack$1_6; 12892 x_50 = stack$0_22; 12893 _51 = x_50 * y_48; 12894 stack$0_1 = _51; 12895 12896 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)> 12897instr9: 12898/* RETURN */: 12899 x_55 = stack$0_52; 12900 x_56 = x_55; 12901 stack =@{v@} @{CLOBBER@}; 12902 return x_56; 12903 12904@} 12905@end example 12906 12907Hence at this point, all those pushes and pops of the stack are now 12908simply assignments to specific temporary variables. 12909 12910After some copy propagation, the stack manipulation has been completely 12911optimized away: 12912 12913@example 12914$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1 12915@end example 12916 12917@example 12918;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12919 12920factorial (signed int arg) 12921@{ 12922 signed int stack$2; 12923 signed int stack$1; 12924 signed int stack$0; 12925 signed int stack[8]; 12926 signed int stack_depth; 12927 signed int x; 12928 signed int y; 12929 <unnamed type> _20; 12930 signed int _21; 12931 signed int _38; 12932 signed int _44; 12933 signed int _51; 12934 12935initial: 12936 stack$0_39 = arg_5(D); 12937 _20 = arg_5(D) <= 1; 12938 _21 = (signed int) _20; 12939 if (_21 != 0) 12940 goto <bb 4> (instr9); 12941 else 12942 goto <bb 3> (instr4); 12943 12944instr4: 12945/* DUP */: 12946 _38 = arg_5(D) + -1; 12947 _44 = factorial (_38); 12948 _51 = arg_5(D) * _44; 12949 stack$0_1 = _51; 12950 12951 # stack$0_52 = PHI <arg_5(D)(2), _51(3)> 12952instr9: 12953/* RETURN */: 12954 stack =@{v@} @{CLOBBER@}; 12955 return stack$0_52; 12956 12957@} 12958@end example 12959 12960Later on, another pass finally eliminated @code{stack_depth} local and the 12961unused parts of the @cite{stack`} array altogether: 12962 12963@example 12964$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa 12965@end example 12966 12967@example 12968;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12969 12970Released 44 names, 314.29%, removed 44 holes 12971factorial (signed int arg) 12972@{ 12973 signed int stack$0; 12974 signed int mult_acc_1; 12975 <unnamed type> _5; 12976 signed int _6; 12977 signed int _7; 12978 signed int mul_tmp_10; 12979 signed int mult_acc_11; 12980 signed int mult_acc_13; 12981 12982 # arg_9 = PHI <arg_8(D)(0)> 12983 # mult_acc_13 = PHI <1(0)> 12984initial: 12985 12986 <bb 5>: 12987 # arg_4 = PHI <arg_9(2), _7(3)> 12988 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)> 12989 _5 = arg_4 <= 1; 12990 _6 = (signed int) _5; 12991 if (_6 != 0) 12992 goto <bb 4> (instr9); 12993 else 12994 goto <bb 3> (instr4); 12995 12996instr4: 12997/* DUP */: 12998 _7 = arg_4 + -1; 12999 mult_acc_11 = mult_acc_1 * arg_4; 13000 goto <bb 5>; 13001 13002 # stack$0_12 = PHI <arg_4(5)> 13003instr9: 13004/* RETURN */: 13005 mul_tmp_10 = mult_acc_1 * stack$0_12; 13006 return mul_tmp_10; 13007 13008@} 13009@end example 13010 13011@node Elimination of tail recursion<2>,,Optimizing away stack manipulation<2>,Behind the curtain How does our code get optimized?<2> 13012@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{1a6} 13013@subsubsection Elimination of tail recursion 13014 13015 13016Another significant optimization is the detection that the call to 13017@code{factorial} is tail recursion, which can be eliminated in favor of 13018an iteration: 13019 13020@example 13021$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1 13022@end example 13023 13024@example 13025;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 13026 13027 13028Symbols to be put in SSA form 13029@{ D.88 @} 13030Incremental SSA update started at block: 0 13031Number of blocks in CFG: 5 13032Number of blocks to update: 4 ( 80%) 13033 13034 13035factorial (signed int arg) 13036@{ 13037 signed int stack$2; 13038 signed int stack$1; 13039 signed int stack$0; 13040 signed int stack[8]; 13041 signed int stack_depth; 13042 signed int x; 13043 signed int y; 13044 signed int mult_acc_1; 13045 <unnamed type> _20; 13046 signed int _21; 13047 signed int _38; 13048 signed int mul_tmp_44; 13049 signed int mult_acc_51; 13050 13051 # arg_5 = PHI <arg_39(D)(0), _38(3)> 13052 # mult_acc_1 = PHI <1(0), mult_acc_51(3)> 13053initial: 13054 _20 = arg_5 <= 1; 13055 _21 = (signed int) _20; 13056 if (_21 != 0) 13057 goto <bb 4> (instr9); 13058 else 13059 goto <bb 3> (instr4); 13060 13061instr4: 13062/* DUP */: 13063 _38 = arg_5 + -1; 13064 mult_acc_51 = mult_acc_1 * arg_5; 13065 goto <bb 2> (initial); 13066 13067 # stack$0_52 = PHI <arg_5(2)> 13068instr9: 13069/* RETURN */: 13070 stack =@{v@} @{CLOBBER@}; 13071 mul_tmp_44 = mult_acc_1 * stack$0_52; 13072 return mul_tmp_44; 13073 13074@} 13075@end example 13076 13077@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 13078@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13079@c 13080@c This is free software: you can redistribute it and/or modify it 13081@c under the terms of the GNU General Public License as published by 13082@c the Free Software Foundation, either version 3 of the License, or 13083@c (at your option) any later version. 13084@c 13085@c This program is distributed in the hope that it will be useful, but 13086@c WITHOUT ANY WARRANTY; without even the implied warranty of 13087@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13088@c General Public License for more details. 13089@c 13090@c You should have received a copy of the GNU General Public License 13091@c along with this program. If not, see 13092@c <https://www.gnu.org/licenses/>. 13093 13094@node Topic Reference<2>,,Tutorial<2>,C++ bindings for libgccjit 13095@anchor{cp/topics/index doc}@anchor{1a7}@anchor{cp/topics/index topic-reference}@anchor{1a8} 13096@section Topic Reference 13097 13098 13099@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 13100@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13101@c 13102@c This is free software: you can redistribute it and/or modify it 13103@c under the terms of the GNU General Public License as published by 13104@c the Free Software Foundation, either version 3 of the License, or 13105@c (at your option) any later version. 13106@c 13107@c This program is distributed in the hope that it will be useful, but 13108@c WITHOUT ANY WARRANTY; without even the implied warranty of 13109@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13110@c General Public License for more details. 13111@c 13112@c You should have received a copy of the GNU General Public License 13113@c along with this program. If not, see 13114@c <https://www.gnu.org/licenses/>. 13115 13116@menu 13117* Compilation contexts: Compilation contexts<2>. 13118* Objects: Objects<2>. 13119* Types: Types<2>. 13120* Expressions: Expressions<2>. 13121* Creating and using functions: Creating and using functions<2>. 13122* Source Locations: Source Locations<2>. 13123* Compiling a context: Compiling a context<2>. 13124* Using Assembly Language with libgccjit++:: 13125 13126@end menu 13127 13128@node Compilation contexts<2>,Objects<2>,,Topic Reference<2> 13129@anchor{cp/topics/contexts doc}@anchor{1a9}@anchor{cp/topics/contexts compilation-contexts}@anchor{1aa} 13130@subsection Compilation contexts 13131 13132 13133@geindex gccjit;;context (C++ class) 13134@anchor{cp/topics/contexts _CPPv4N6gccjit7contextE}@anchor{175}@anchor{cp/topics/contexts _CPPv3N6gccjit7contextE}@anchor{1ab}@anchor{cp/topics/contexts _CPPv2N6gccjit7contextE}@anchor{1ac}@anchor{cp/topics/contexts gccjit context}@anchor{1ad} 13135@deffn {C++ Class} gccjit::context 13136@end deffn 13137 13138The top-level of the C++ API is the @ref{175,,gccjit;;context} type. 13139 13140A @ref{175,,gccjit;;context} instance encapsulates the state of a 13141compilation. 13142 13143You can set up options on it, and add types, functions and code. 13144Invoking @ref{17f,,gccjit;;context;;compile()} on it gives you a 13145@ref{16,,gcc_jit_result *}. 13146 13147It is a thin wrapper around the C API���s @ref{8,,gcc_jit_context *}. 13148 13149@menu 13150* Lifetime-management: Lifetime-management<2>. 13151* Thread-safety: Thread-safety<2>. 13152* Error-handling: Error-handling<3>. 13153* Debugging: Debugging<2>. 13154* Options: Options<4>. 13155 13156@end menu 13157 13158@node Lifetime-management<2>,Thread-safety<2>,,Compilation contexts<2> 13159@anchor{cp/topics/contexts lifetime-management}@anchor{1ae} 13160@subsubsection Lifetime-management 13161 13162 13163Contexts are the unit of lifetime-management within the API: objects 13164have their lifetime bounded by the context they are created within, and 13165cleanup of such objects is done for you when the context is released. 13166 13167@geindex gccjit;;context;;acquire (C++ function) 13168@anchor{cp/topics/contexts _CPPv4N6gccjit7context7acquireEv}@anchor{176}@anchor{cp/topics/contexts _CPPv3N6gccjit7context7acquireEv}@anchor{1af}@anchor{cp/topics/contexts _CPPv2N6gccjit7context7acquireEv}@anchor{1b0}@anchor{cp/topics/contexts gccjit context acquire}@anchor{1b1} 13169@deffn {C++ Function} gccjit::@ref{175,,context} gccjit::@ref{175,,context}::acquire () 13170 13171This function acquires a new @ref{175,,gccjit;;context} instance, 13172which is independent of any others that may be present within this 13173process. 13174@end deffn 13175 13176@geindex gccjit;;context;;release (C++ function) 13177@anchor{cp/topics/contexts _CPPv4N6gccjit7context7releaseEv}@anchor{179}@anchor{cp/topics/contexts _CPPv3N6gccjit7context7releaseEv}@anchor{1b2}@anchor{cp/topics/contexts _CPPv2N6gccjit7context7releaseEv}@anchor{1b3}@anchor{cp/topics/contexts gccjit context release}@anchor{1b4} 13178@deffn {C++ Function} void gccjit::@ref{175,,context}::release () 13179 13180This function releases all resources associated with the given context. 13181Both the context itself and all of its @code{gccjit::object *} 13182instances are cleaned up. It should be called exactly once on a given 13183context. 13184 13185It is invalid to use the context or any of its ���contextual��� objects 13186after calling this. 13187 13188@example 13189ctxt.release (); 13190@end example 13191@end deffn 13192 13193@geindex gccjit;;context;;new_child_context (C++ function) 13194@anchor{cp/topics/contexts _CPPv4N6gccjit7context17new_child_contextEv}@anchor{1b5}@anchor{cp/topics/contexts _CPPv3N6gccjit7context17new_child_contextEv}@anchor{1b6}@anchor{cp/topics/contexts _CPPv2N6gccjit7context17new_child_contextEv}@anchor{1b7}@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{1b8} 13195@deffn {C++ Function} gccjit::@ref{175,,context} gccjit::@ref{175,,context}::new_child_context () 13196 13197Given an existing JIT context, create a child context. 13198 13199The child inherits a copy of all option-settings from the parent. 13200 13201The child can reference objects created within the parent, but not 13202vice-versa. 13203 13204The lifetime of the child context must be bounded by that of the 13205parent: you should release a child context before releasing the parent 13206context. 13207 13208If you use a function from a parent context within a child context, 13209you have to compile the parent context before you can compile the 13210child context, and the gccjit::result of the parent context must 13211outlive the gccjit::result of the child context. 13212 13213This allows caching of shared initializations. For example, you could 13214create types and declarations of global functions in a parent context 13215once within a process, and then create child contexts whenever a 13216function or loop becomes hot. Each such child context can be used for 13217JIT-compiling just one function or loop, but can reference types 13218and helper functions created within the parent context. 13219 13220Contexts can be arbitrarily nested, provided the above rules are 13221followed, but it���s probably not worth going above 2 or 3 levels, and 13222there will likely be a performance hit for such nesting. 13223@end deffn 13224 13225@node Thread-safety<2>,Error-handling<3>,Lifetime-management<2>,Compilation contexts<2> 13226@anchor{cp/topics/contexts thread-safety}@anchor{1b9} 13227@subsubsection Thread-safety 13228 13229 13230Instances of @ref{175,,gccjit;;context} created via 13231@ref{176,,gccjit;;context;;acquire()} are independent from each other: 13232only one thread may use a given context at once, but multiple threads 13233could each have their own contexts without needing locks. 13234 13235Contexts created via @ref{1b5,,gccjit;;context;;new_child_context()} are 13236related to their parent context. They can be partitioned by their 13237ultimate ancestor into independent ���family trees���. Only one thread 13238within a process may use a given ���family tree��� of such contexts at once, 13239and if you���re using multiple threads you should provide your own locking 13240around entire such context partitions. 13241 13242@node Error-handling<3>,Debugging<2>,Thread-safety<2>,Compilation contexts<2> 13243@anchor{cp/topics/contexts error-handling}@anchor{1ba} 13244@subsubsection Error-handling 13245 13246 13247@c FIXME: How does error-handling work for C++ API? 13248 13249You can only compile and get code from a context if no errors occur. 13250 13251In general, if an error occurs when using an API entrypoint, it returns 13252NULL. You don���t have to check everywhere for NULL results, since the 13253API gracefully handles a NULL being passed in for any argument. 13254 13255Errors are printed on stderr and can be queried using 13256@ref{1bb,,gccjit;;context;;get_first_error()}. 13257 13258@geindex gccjit;;context;;get_first_error (C++ function) 13259@anchor{cp/topics/contexts _CPPv4N6gccjit7context15get_first_errorEPN6gccjit7contextE}@anchor{1bb}@anchor{cp/topics/contexts _CPPv3N6gccjit7context15get_first_errorEPN6gccjit7contextE}@anchor{1bc}@anchor{cp/topics/contexts _CPPv2N6gccjit7context15get_first_errorEPN6gccjit7contextE}@anchor{1bd}@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{1be} 13260@deffn {C++ Function} const char *gccjit::@ref{175,,context}::get_first_error (gccjit::context *ctxt) 13261 13262Returns the first error message that occurred on the context. 13263 13264The returned string is valid for the rest of the lifetime of the 13265context. 13266 13267If no errors occurred, this will be NULL. 13268@end deffn 13269 13270@node Debugging<2>,Options<4>,Error-handling<3>,Compilation contexts<2> 13271@anchor{cp/topics/contexts debugging}@anchor{1bf} 13272@subsubsection Debugging 13273 13274 13275@geindex gccjit;;context;;dump_to_file (C++ function) 13276@anchor{cp/topics/contexts _CPPv4N6gccjit7context12dump_to_fileERKNSt6stringEi}@anchor{1c0}@anchor{cp/topics/contexts _CPPv3N6gccjit7context12dump_to_fileERKNSt6stringEi}@anchor{1c1}@anchor{cp/topics/contexts _CPPv2N6gccjit7context12dump_to_fileERKNSt6stringEi}@anchor{1c2}@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{1c3} 13277@deffn {C++ Function} void gccjit::@ref{175,,context}::dump_to_file (const std::string &path, int update_locations) 13278 13279To help with debugging: dump a C-like representation to the given path, 13280describing what���s been set up on the context. 13281 13282If ���update_locations��� is true, then also set up @ref{19b,,gccjit;;location} 13283information throughout the context, pointing at the dump file as if it 13284were a source file. This may be of use in conjunction with 13285@code{GCCJIT::BOOL_OPTION_DEBUGINFO} to allow stepping through the 13286code in a debugger. 13287@end deffn 13288 13289@geindex gccjit;;context;;dump_reproducer_to_file (C++ function) 13290@anchor{cp/topics/contexts _CPPv4N6gccjit7context23dump_reproducer_to_fileEP15gcc_jit_contextPKc}@anchor{1c4}@anchor{cp/topics/contexts _CPPv3N6gccjit7context23dump_reproducer_to_fileEP15gcc_jit_contextPKc}@anchor{1c5}@anchor{cp/topics/contexts _CPPv2N6gccjit7context23dump_reproducer_to_fileEP15gcc_jit_contextPKc}@anchor{1c6}@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{1c7} 13291@deffn {C++ Function} void gccjit::@ref{175,,context}::dump_reproducer_to_file (gcc_jit_context *ctxt, const char *path) 13292 13293This is a thin wrapper around the C API 13294@ref{5d,,gcc_jit_context_dump_reproducer_to_file()}, and hence works the 13295same way. 13296 13297Note that the generated source is C code, not C++; this might be of use 13298for seeing what the C++ bindings are doing at the C level. 13299@end deffn 13300 13301@node Options<4>,,Debugging<2>,Compilation contexts<2> 13302@anchor{cp/topics/contexts options}@anchor{1c8} 13303@subsubsection Options 13304 13305 13306@menu 13307* String Options: String Options<2>. 13308* Boolean options: Boolean options<2>. 13309* Integer options: Integer options<2>. 13310* Additional command-line options: Additional command-line options<2>. 13311 13312@end menu 13313 13314@node String Options<2>,Boolean options<2>,,Options<4> 13315@anchor{cp/topics/contexts string-options}@anchor{1c9} 13316@subsubsection String Options 13317 13318 13319@geindex gccjit;;context;;set_str_option (C++ function) 13320@anchor{cp/topics/contexts _CPPv4N6gccjit7context14set_str_optionE18gcc_jit_str_optionPKc}@anchor{1ca}@anchor{cp/topics/contexts _CPPv3N6gccjit7context14set_str_optionE18gcc_jit_str_optionPKc}@anchor{1cb}@anchor{cp/topics/contexts _CPPv2N6gccjit7context14set_str_optionE18gcc_jit_str_optionPKc}@anchor{1cc}@anchor{cp/topics/contexts gccjit context set_str_option__gcc_jit_str_option cCP}@anchor{1cd} 13321@deffn {C++ Function} void gccjit::@ref{175,,context}::set_str_option (enum gcc_jit_str_option, const char *value) 13322 13323Set a string option of the context. 13324 13325This is a thin wrapper around the C API 13326@ref{61,,gcc_jit_context_set_str_option()}; the options have the same 13327meaning. 13328@end deffn 13329 13330@node Boolean options<2>,Integer options<2>,String Options<2>,Options<4> 13331@anchor{cp/topics/contexts boolean-options}@anchor{1ce} 13332@subsubsection Boolean options 13333 13334 13335@geindex gccjit;;context;;set_bool_option (C++ function) 13336@anchor{cp/topics/contexts _CPPv4N6gccjit7context15set_bool_optionE19gcc_jit_bool_optioni}@anchor{181}@anchor{cp/topics/contexts _CPPv3N6gccjit7context15set_bool_optionE19gcc_jit_bool_optioni}@anchor{1cf}@anchor{cp/topics/contexts _CPPv2N6gccjit7context15set_bool_optionE19gcc_jit_bool_optioni}@anchor{1d0}@anchor{cp/topics/contexts gccjit context set_bool_option__gcc_jit_bool_option i}@anchor{1d1} 13337@deffn {C++ Function} void gccjit::@ref{175,,context}::set_bool_option (enum gcc_jit_bool_option, int value) 13338 13339Set a boolean option of the context. 13340 13341This is a thin wrapper around the C API 13342@ref{1b,,gcc_jit_context_set_bool_option()}; the options have the same 13343meaning. 13344@end deffn 13345 13346@geindex gccjit;;context;;set_bool_allow_unreachable_blocks (C++ function) 13347@anchor{cp/topics/contexts _CPPv4N6gccjit7context33set_bool_allow_unreachable_blocksEi}@anchor{1d2}@anchor{cp/topics/contexts _CPPv3N6gccjit7context33set_bool_allow_unreachable_blocksEi}@anchor{1d3}@anchor{cp/topics/contexts _CPPv2N6gccjit7context33set_bool_allow_unreachable_blocksEi}@anchor{1d4}@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{1d5} 13348@deffn {C++ Function} void gccjit::@ref{175,,context}::set_bool_allow_unreachable_blocks (int bool_value) 13349 13350By default, libgccjit will issue an error about unreachable blocks 13351within a function. 13352 13353This entrypoint can be used to disable that error; it is a thin wrapper 13354around the C API 13355@ref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}. 13356 13357This entrypoint was added in @ref{6c,,LIBGCCJIT_ABI_2}; you can test for 13358its presence using 13359 13360@example 13361#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 13362@end example 13363@end deffn 13364 13365@geindex gccjit;;context;;set_bool_use_external_driver (C++ function) 13366@anchor{cp/topics/contexts _CPPv4N6gccjit7context28set_bool_use_external_driverEi}@anchor{1d6}@anchor{cp/topics/contexts _CPPv3N6gccjit7context28set_bool_use_external_driverEi}@anchor{1d7}@anchor{cp/topics/contexts _CPPv2N6gccjit7context28set_bool_use_external_driverEi}@anchor{1d8}@anchor{cp/topics/contexts gccjit context set_bool_use_external_driver__i}@anchor{1d9} 13367@deffn {C++ Function} void gccjit::@ref{175,,context}::set_bool_use_external_driver (int bool_value) 13368 13369libgccjit internally generates assembler, and uses ���driver��� code 13370for converting it to other formats (e.g. shared libraries). 13371 13372By default, libgccjit will use an embedded copy of the driver 13373code. 13374 13375This option can be used to instead invoke an external driver executable 13376as a subprocess; it is a thin wrapper around the C API 13377@ref{6d,,gcc_jit_context_set_bool_use_external_driver()}. 13378 13379This entrypoint was added in @ref{6e,,LIBGCCJIT_ABI_5}; you can test for 13380its presence using 13381 13382@example 13383#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver 13384@end example 13385@end deffn 13386 13387@node Integer options<2>,Additional command-line options<2>,Boolean options<2>,Options<4> 13388@anchor{cp/topics/contexts integer-options}@anchor{1da} 13389@subsubsection Integer options 13390 13391 13392@geindex gccjit;;context;;set_int_option (C++ function) 13393@anchor{cp/topics/contexts _CPPv4N6gccjit7context14set_int_optionE18gcc_jit_int_optioni}@anchor{182}@anchor{cp/topics/contexts _CPPv3N6gccjit7context14set_int_optionE18gcc_jit_int_optioni}@anchor{1db}@anchor{cp/topics/contexts _CPPv2N6gccjit7context14set_int_optionE18gcc_jit_int_optioni}@anchor{1dc}@anchor{cp/topics/contexts gccjit context set_int_option__gcc_jit_int_option i}@anchor{1dd} 13394@deffn {C++ Function} void gccjit::@ref{175,,context}::set_int_option (enum gcc_jit_int_option, int value) 13395 13396Set an integer option of the context. 13397 13398This is a thin wrapper around the C API 13399@ref{1e,,gcc_jit_context_set_int_option()}; the options have the same 13400meaning. 13401@end deffn 13402 13403@node Additional command-line options<2>,,Integer options<2>,Options<4> 13404@anchor{cp/topics/contexts additional-command-line-options}@anchor{1de} 13405@subsubsection Additional command-line options 13406 13407 13408@geindex gccjit;;context;;add_command_line_option (C++ function) 13409@anchor{cp/topics/contexts _CPPv4N6gccjit7context23add_command_line_optionEPKc}@anchor{1df}@anchor{cp/topics/contexts _CPPv3N6gccjit7context23add_command_line_optionEPKc}@anchor{1e0}@anchor{cp/topics/contexts _CPPv2N6gccjit7context23add_command_line_optionEPKc}@anchor{1e1}@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{1e2} 13410@deffn {C++ Function} void gccjit::@ref{175,,context}::add_command_line_option (const char *optname) 13411 13412Add an arbitrary gcc command-line option to the context for use 13413when compiling. 13414 13415This is a thin wrapper around the C API 13416@ref{74,,gcc_jit_context_add_command_line_option()}. 13417 13418This entrypoint was added in @ref{75,,LIBGCCJIT_ABI_1}; you can test for 13419its presence using 13420 13421@example 13422#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 13423@end example 13424@end deffn 13425 13426@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 13427@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13428@c 13429@c This is free software: you can redistribute it and/or modify it 13430@c under the terms of the GNU General Public License as published by 13431@c the Free Software Foundation, either version 3 of the License, or 13432@c (at your option) any later version. 13433@c 13434@c This program is distributed in the hope that it will be useful, but 13435@c WITHOUT ANY WARRANTY; without even the implied warranty of 13436@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13437@c General Public License for more details. 13438@c 13439@c You should have received a copy of the GNU General Public License 13440@c along with this program. If not, see 13441@c <https://www.gnu.org/licenses/>. 13442 13443@node Objects<2>,Types<2>,Compilation contexts<2>,Topic Reference<2> 13444@anchor{cp/topics/objects doc}@anchor{1e3}@anchor{cp/topics/objects objects}@anchor{1e4} 13445@subsection Objects 13446 13447 13448@geindex gccjit;;object (C++ class) 13449@anchor{cp/topics/objects _CPPv4N6gccjit6objectE}@anchor{17a}@anchor{cp/topics/objects _CPPv3N6gccjit6objectE}@anchor{1e5}@anchor{cp/topics/objects _CPPv2N6gccjit6objectE}@anchor{1e6}@anchor{cp/topics/objects gccjit object}@anchor{1e7} 13450@deffn {C++ Class} gccjit::object 13451@end deffn 13452 13453Almost every entity in the API (with the exception of 13454@ref{175,,gccjit;;context} and @ref{16,,gcc_jit_result *}) is a 13455���contextual��� object, a @ref{17a,,gccjit;;object}. 13456 13457A JIT object: 13458 13459@quotation 13460 13461 13462@itemize * 13463 13464@item 13465is associated with a @ref{175,,gccjit;;context}. 13466 13467@item 13468is automatically cleaned up for you when its context is released so 13469you don���t need to manually track and cleanup all objects, just the 13470contexts. 13471@end itemize 13472@end quotation 13473 13474The C++ class hierarchy within the @code{gccjit} namespace looks like this: 13475 13476@example 13477+- object 13478 +- location 13479 +- type 13480 +- struct 13481 +- field 13482 +- function 13483 +- block 13484 +- rvalue 13485 +- lvalue 13486 +- param 13487 +- case_ 13488@end example 13489 13490The @ref{17a,,gccjit;;object} base class has the following operations: 13491 13492@geindex gccjit;;object;;get_context (C++ function) 13493@anchor{cp/topics/objects _CPPv4NK6gccjit6object11get_contextEv}@anchor{1e8}@anchor{cp/topics/objects _CPPv3NK6gccjit6object11get_contextEv}@anchor{1e9}@anchor{cp/topics/objects _CPPv2NK6gccjit6object11get_contextEv}@anchor{1ea}@anchor{cp/topics/objects gccjit object get_contextC}@anchor{1eb} 13494@deffn {C++ Function} gccjit::@ref{175,,context} gccjit::@ref{17a,,object}::get_context () const 13495 13496Which context is the obj within? 13497@end deffn 13498 13499@geindex gccjit;;object;;get_debug_string (C++ function) 13500@anchor{cp/topics/objects _CPPv4NK6gccjit6object16get_debug_stringEv}@anchor{17b}@anchor{cp/topics/objects _CPPv3NK6gccjit6object16get_debug_stringEv}@anchor{1ec}@anchor{cp/topics/objects _CPPv2NK6gccjit6object16get_debug_stringEv}@anchor{1ed}@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{1ee} 13501@deffn {C++ Function} std::string gccjit::@ref{17a,,object}::get_debug_string () const 13502 13503Generate a human-readable description for the given object. 13504 13505For example, 13506 13507@example 13508printf ("obj: %s\n", obj.get_debug_string ().c_str ()); 13509@end example 13510 13511might give this text on stdout: 13512 13513@example 13514obj: 4.0 * (float)i 13515@end example 13516@end deffn 13517 13518@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 13519@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13520@c 13521@c This is free software: you can redistribute it and/or modify it 13522@c under the terms of the GNU General Public License as published by 13523@c the Free Software Foundation, either version 3 of the License, or 13524@c (at your option) any later version. 13525@c 13526@c This program is distributed in the hope that it will be useful, but 13527@c WITHOUT ANY WARRANTY; without even the implied warranty of 13528@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13529@c General Public License for more details. 13530@c 13531@c You should have received a copy of the GNU General Public License 13532@c along with this program. If not, see 13533@c <https://www.gnu.org/licenses/>. 13534 13535@node Types<2>,Expressions<2>,Objects<2>,Topic Reference<2> 13536@anchor{cp/topics/types doc}@anchor{1ef}@anchor{cp/topics/types types}@anchor{1f0} 13537@subsection Types 13538 13539 13540@geindex gccjit;;type (C++ class) 13541@anchor{cp/topics/types _CPPv4N6gccjit4typeE}@anchor{177}@anchor{cp/topics/types _CPPv3N6gccjit4typeE}@anchor{1f1}@anchor{cp/topics/types _CPPv2N6gccjit4typeE}@anchor{1f2}@anchor{cp/topics/types gccjit type}@anchor{1f3} 13542@deffn {C++ Class} gccjit::type 13543 13544gccjit::type represents a type within the library. It is a subclass 13545of @ref{17a,,gccjit;;object}. 13546@end deffn 13547 13548Types can be created in several ways: 13549 13550 13551@itemize * 13552 13553@item 13554fundamental types can be accessed using 13555@ref{178,,gccjit;;context;;get_type()}: 13556 13557@example 13558gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 13559@end example 13560 13561or using the @code{gccjit::context::get_int_type} template: 13562 13563@example 13564gccjit::type t = ctxt.get_int_type <unsigned short> (); 13565@end example 13566 13567See @ref{b,,gcc_jit_context_get_type()} for the available types. 13568 13569@item 13570derived types can be accessed by using functions such as 13571@ref{1f4,,gccjit;;type;;get_pointer()} and @ref{1f5,,gccjit;;type;;get_const()}: 13572 13573@example 13574gccjit::type const_int_star = int_type.get_const ().get_pointer (); 13575gccjit::type int_const_star = int_type.get_pointer ().get_const (); 13576@end example 13577 13578@item 13579by creating structures (see below). 13580@end itemize 13581 13582@menu 13583* Standard types: Standard types<2>. 13584* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 13585* Vector types: Vector types<2>. 13586* Structures and unions: Structures and unions<2>. 13587 13588@end menu 13589 13590@node Standard types<2>,Pointers const and volatile<2>,,Types<2> 13591@anchor{cp/topics/types standard-types}@anchor{1f6} 13592@subsubsection Standard types 13593 13594 13595@geindex gccjit;;context;;get_type (C++ function) 13596@anchor{cp/topics/types _CPPv4N6gccjit7context8get_typeE13gcc_jit_types}@anchor{178}@anchor{cp/topics/types _CPPv3N6gccjit7context8get_typeE13gcc_jit_types}@anchor{1f7}@anchor{cp/topics/types _CPPv2N6gccjit7context8get_typeE13gcc_jit_types}@anchor{1f8}@anchor{cp/topics/types gccjit context get_type__gcc_jit_types}@anchor{1f9} 13597@deffn {C++ Function} gccjit::@ref{177,,type} gccjit::@ref{175,,context}::get_type (enum gcc_jit_types) 13598 13599Access a specific type. This is a thin wrapper around 13600@ref{b,,gcc_jit_context_get_type()}; the parameter has the same meaning. 13601@end deffn 13602 13603@geindex gccjit;;context;;get_int_type (C++ function) 13604@anchor{cp/topics/types _CPPv4N6gccjit7context12get_int_typeE6size_ti}@anchor{1fa}@anchor{cp/topics/types _CPPv3N6gccjit7context12get_int_typeE6size_ti}@anchor{1fb}@anchor{cp/topics/types _CPPv2N6gccjit7context12get_int_typeE6size_ti}@anchor{1fc}@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{1fd} 13605@deffn {C++ Function} gccjit::@ref{177,,type} gccjit::@ref{175,,context}::get_int_type (size_t num_bytes, int is_signed) 13606 13607Access the integer type of the given size. 13608@end deffn 13609 13610@geindex gccjit;;context;;get_int_type<T> (C++ function) 13611@anchor{cp/topics/types _CPPv4IEN6gccjit7context12get_int_typeI1TEEN6gccjit4typeEv}@anchor{1fe}@anchor{cp/topics/types _CPPv3IEN6gccjit7context12get_int_typeI1TEEv}@anchor{1ff}@anchor{cp/topics/types _CPPv2IEN6gccjit7context12get_int_typeI1TEEv}@anchor{200} 13612@deffn {C++ Function} template<>gccjit::@ref{177,,type} gccjit::@ref{175,,context}::get_int_type<T> () 13613 13614Access the given integer type. For example, you could map the 13615@code{unsigned short} type into a gccjit::type via: 13616 13617@example 13618gccjit::type t = ctxt.get_int_type <unsigned short> (); 13619@end example 13620@end deffn 13621 13622@node Pointers const and volatile<2>,Vector types<2>,Standard types<2>,Types<2> 13623@anchor{cp/topics/types pointers-const-and-volatile}@anchor{201} 13624@subsubsection Pointers, @cite{const}, and @cite{volatile} 13625 13626 13627@geindex gccjit;;type;;get_pointer (C++ function) 13628@anchor{cp/topics/types _CPPv4N6gccjit4type11get_pointerEv}@anchor{1f4}@anchor{cp/topics/types _CPPv3N6gccjit4type11get_pointerEv}@anchor{202}@anchor{cp/topics/types _CPPv2N6gccjit4type11get_pointerEv}@anchor{203}@anchor{cp/topics/types gccjit type get_pointer}@anchor{204} 13629@deffn {C++ Function} gccjit::@ref{177,,type} gccjit::@ref{177,,type}::get_pointer () 13630 13631Given type ���T���, get type ���T*���. 13632@end deffn 13633 13634@geindex gccjit;;type;;get_const (C++ function) 13635@anchor{cp/topics/types _CPPv4N6gccjit4type9get_constEv}@anchor{1f5}@anchor{cp/topics/types _CPPv3N6gccjit4type9get_constEv}@anchor{205}@anchor{cp/topics/types _CPPv2N6gccjit4type9get_constEv}@anchor{206}@anchor{cp/topics/types gccjit type get_const}@anchor{207} 13636@deffn {C++ Function} gccjit::@ref{177,,type} gccjit::@ref{177,,type}::get_const () 13637 13638Given type ���T���, get type ���const T���. 13639@end deffn 13640 13641@geindex gccjit;;type;;get_volatile (C++ function) 13642@anchor{cp/topics/types _CPPv4N6gccjit4type12get_volatileEv}@anchor{208}@anchor{cp/topics/types _CPPv3N6gccjit4type12get_volatileEv}@anchor{209}@anchor{cp/topics/types _CPPv2N6gccjit4type12get_volatileEv}@anchor{20a}@anchor{cp/topics/types gccjit type get_volatile}@anchor{20b} 13643@deffn {C++ Function} gccjit::@ref{177,,type} gccjit::@ref{177,,type}::get_volatile () 13644 13645Given type ���T���, get type ���volatile T���. 13646@end deffn 13647 13648@geindex gccjit;;type;;get_aligned (C++ function) 13649@anchor{cp/topics/types _CPPv4N6gccjit4type11get_alignedE6size_t}@anchor{20c}@anchor{cp/topics/types _CPPv3N6gccjit4type11get_alignedE6size_t}@anchor{20d}@anchor{cp/topics/types _CPPv2N6gccjit4type11get_alignedE6size_t}@anchor{20e}@anchor{cp/topics/types gccjit type get_aligned__s}@anchor{20f} 13650@deffn {C++ Function} gccjit::@ref{177,,type} gccjit::@ref{177,,type}::get_aligned (size_t alignment_in_bytes) 13651 13652Given type ���T���, get type: 13653 13654@example 13655T __attribute__ ((aligned (ALIGNMENT_IN_BYTES))) 13656@end example 13657 13658The alignment must be a power of two. 13659@end deffn 13660 13661@geindex gccjit;;context;;new_array_type (C++ function) 13662@anchor{cp/topics/types _CPPv4N6gccjit7context14new_array_typeEN6gccjit4typeEiN6gccjit8locationE}@anchor{210}@anchor{cp/topics/types _CPPv3N6gccjit7context14new_array_typeEN6gccjit4typeEiN6gccjit8locationE}@anchor{211}@anchor{cp/topics/types _CPPv2N6gccjit7context14new_array_typeEN6gccjit4typeEiN6gccjit8locationE}@anchor{212}@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{213} 13663@deffn {C++ Function} gccjit::@ref{177,,type} gccjit::@ref{175,,context}::new_array_type (gccjit::type element_type, int num_elements, gccjit::location loc) 13664 13665Given type ���T���, get type ���T[N]��� (for a constant N). 13666Param ���loc��� is optional. 13667@end deffn 13668 13669@node Vector types<2>,Structures and unions<2>,Pointers const and volatile<2>,Types<2> 13670@anchor{cp/topics/types vector-types}@anchor{214} 13671@subsubsection Vector types 13672 13673 13674@geindex gccjit;;type;;get_vector (C++ function) 13675@anchor{cp/topics/types _CPPv4N6gccjit4type10get_vectorE6size_t}@anchor{215}@anchor{cp/topics/types _CPPv3N6gccjit4type10get_vectorE6size_t}@anchor{216}@anchor{cp/topics/types _CPPv2N6gccjit4type10get_vectorE6size_t}@anchor{217}@anchor{cp/topics/types gccjit type get_vector__s}@anchor{218} 13676@deffn {C++ Function} gccjit::@ref{177,,type} gccjit::@ref{177,,type}::get_vector (size_t num_units) 13677 13678Given type ���T���, get type: 13679 13680@example 13681T __attribute__ ((vector_size (sizeof(T) * num_units)) 13682@end example 13683 13684T must be integral or floating point; num_units must be a power of two. 13685@end deffn 13686 13687@node Structures and unions<2>,,Vector types<2>,Types<2> 13688@anchor{cp/topics/types structures-and-unions}@anchor{219} 13689@subsubsection Structures and unions 13690 13691 13692@geindex gccjit;;struct_ (C++ class) 13693@anchor{cp/topics/types _CPPv4N6gccjit7struct_E}@anchor{21a}@anchor{cp/topics/types _CPPv3N6gccjit7struct_E}@anchor{21b}@anchor{cp/topics/types _CPPv2N6gccjit7struct_E}@anchor{21c}@anchor{cp/topics/types gccjit struct_}@anchor{21d} 13694@deffn {C++ Class} gccjit::struct_ 13695@end deffn 13696 13697A compound type analagous to a C @cite{struct}. 13698 13699@ref{21a,,gccjit;;struct_} is a subclass of @ref{177,,gccjit;;type} (and thus 13700of @ref{17a,,gccjit;;object} in turn). 13701 13702@geindex gccjit;;field (C++ class) 13703@anchor{cp/topics/types _CPPv4N6gccjit5fieldE}@anchor{21e}@anchor{cp/topics/types _CPPv3N6gccjit5fieldE}@anchor{21f}@anchor{cp/topics/types _CPPv2N6gccjit5fieldE}@anchor{220}@anchor{cp/topics/types gccjit field}@anchor{221} 13704@deffn {C++ Class} gccjit::field 13705@end deffn 13706 13707A field within a @ref{21a,,gccjit;;struct_}. 13708 13709@ref{21e,,gccjit;;field} is a subclass of @ref{17a,,gccjit;;object}. 13710 13711You can model C @cite{struct} types by creating @ref{21a,,gccjit;;struct_} and 13712@ref{21e,,gccjit;;field} instances, in either order: 13713 13714 13715@itemize * 13716 13717@item 13718by creating the fields, then the structure. For example, to model: 13719 13720@example 13721struct coord @{double x; double y; @}; 13722@end example 13723 13724you could call: 13725 13726@example 13727gccjit::field field_x = ctxt.new_field (double_type, "x"); 13728gccjit::field field_y = ctxt.new_field (double_type, "y"); 13729std::vector fields; 13730fields.push_back (field_x); 13731fields.push_back (field_y); 13732gccjit::struct_ coord = ctxt.new_struct_type ("coord", fields); 13733@end example 13734 13735@item 13736by creating the structure, then populating it with fields, typically 13737to allow modelling self-referential structs such as: 13738 13739@example 13740struct node @{ int m_hash; struct node *m_next; @}; 13741@end example 13742 13743like this: 13744 13745@example 13746gccjit::struct_ node = ctxt.new_opaque_struct_type ("node"); 13747gccjit::type node_ptr = node.get_pointer (); 13748gccjit::field field_hash = ctxt.new_field (int_type, "m_hash"); 13749gccjit::field field_next = ctxt.new_field (node_ptr, "m_next"); 13750std::vector fields; 13751fields.push_back (field_hash); 13752fields.push_back (field_next); 13753node.set_fields (fields); 13754@end example 13755@end itemize 13756 13757@c FIXME: the above API doesn't seem to exist yet 13758 13759@geindex gccjit;;context;;new_field (C++ function) 13760@anchor{cp/topics/types _CPPv4N6gccjit7context9new_fieldEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{222}@anchor{cp/topics/types _CPPv3N6gccjit7context9new_fieldEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{223}@anchor{cp/topics/types _CPPv2N6gccjit7context9new_fieldEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{224}@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{225} 13761@deffn {C++ Function} gccjit::@ref{21e,,field} gccjit::@ref{175,,context}::new_field (gccjit::type type, const char *name, gccjit::location loc) 13762 13763Construct a new field, with the given type and name. 13764@end deffn 13765 13766@geindex gccjit;;context;;new_struct_type (C++ function) 13767@anchor{cp/topics/types _CPPv4N6gccjit7context15new_struct_typeERKNSt6stringERNSt6vectorI5fieldEEN6gccjit8locationE}@anchor{226}@anchor{cp/topics/types _CPPv3N6gccjit7context15new_struct_typeERKNSt6stringERNSt6vectorI5fieldEEN6gccjit8locationE}@anchor{227}@anchor{cp/topics/types _CPPv2N6gccjit7context15new_struct_typeERKNSt6stringERNSt6vectorI5fieldEEN6gccjit8locationE}@anchor{228}@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{229} 13768@deffn {C++ Function} gccjit::@ref{21a,,struct_} gccjit::@ref{175,,context}::new_struct_type (const std::string &name, std::vector<field> &fields, gccjit::location loc) 13769 13770@quotation 13771 13772Construct a new struct type, with the given name and fields. 13773@end quotation 13774@end deffn 13775 13776@geindex gccjit;;context;;new_opaque_struct (C++ function) 13777@anchor{cp/topics/types _CPPv4N6gccjit7context17new_opaque_structERKNSt6stringEN6gccjit8locationE}@anchor{22a}@anchor{cp/topics/types _CPPv3N6gccjit7context17new_opaque_structERKNSt6stringEN6gccjit8locationE}@anchor{22b}@anchor{cp/topics/types _CPPv2N6gccjit7context17new_opaque_structERKNSt6stringEN6gccjit8locationE}@anchor{22c}@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{22d} 13778@deffn {C++ Function} gccjit::@ref{21a,,struct_} gccjit::@ref{175,,context}::new_opaque_struct (const std::string &name, gccjit::location loc) 13779 13780Construct a new struct type, with the given name, but without 13781specifying the fields. The fields can be omitted (in which case the 13782size of the struct is not known), or later specified using 13783@ref{93,,gcc_jit_struct_set_fields()}. 13784@end deffn 13785 13786@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 13787@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13788@c 13789@c This is free software: you can redistribute it and/or modify it 13790@c under the terms of the GNU General Public License as published by 13791@c the Free Software Foundation, either version 3 of the License, or 13792@c (at your option) any later version. 13793@c 13794@c This program is distributed in the hope that it will be useful, but 13795@c WITHOUT ANY WARRANTY; without even the implied warranty of 13796@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13797@c General Public License for more details. 13798@c 13799@c You should have received a copy of the GNU General Public License 13800@c along with this program. If not, see 13801@c <https://www.gnu.org/licenses/>. 13802 13803@node Expressions<2>,Creating and using functions<2>,Types<2>,Topic Reference<2> 13804@anchor{cp/topics/expressions doc}@anchor{22e}@anchor{cp/topics/expressions expressions}@anchor{22f} 13805@subsection Expressions 13806 13807 13808@menu 13809* Rvalues: Rvalues<2>. 13810* Lvalues: Lvalues<2>. 13811* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 13812 13813@end menu 13814 13815@node Rvalues<2>,Lvalues<2>,,Expressions<2> 13816@anchor{cp/topics/expressions rvalues}@anchor{230} 13817@subsubsection Rvalues 13818 13819 13820@geindex gccjit;;rvalue (C++ class) 13821@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalueE}@anchor{17e}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalueE}@anchor{231}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalueE}@anchor{232}@anchor{cp/topics/expressions gccjit rvalue}@anchor{233} 13822@deffn {C++ Class} gccjit::rvalue 13823@end deffn 13824 13825A @ref{17e,,gccjit;;rvalue} is an expression that can be computed. It is a 13826subclass of @ref{17a,,gccjit;;object}, and is a thin wrapper around 13827@ref{13,,gcc_jit_rvalue *} from the C API. 13828 13829It can be simple, e.g.: 13830 13831@quotation 13832 13833 13834@itemize * 13835 13836@item 13837an integer value e.g. @cite{0} or @cite{42} 13838 13839@item 13840a string literal e.g. @cite{���Hello world���} 13841 13842@item 13843a variable e.g. @cite{i}. These are also lvalues (see below). 13844@end itemize 13845@end quotation 13846 13847or compound e.g.: 13848 13849@quotation 13850 13851 13852@itemize * 13853 13854@item 13855a unary expression e.g. @cite{!cond} 13856 13857@item 13858a binary expression e.g. @cite{(a + b)} 13859 13860@item 13861a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} 13862 13863@item 13864etc. 13865@end itemize 13866@end quotation 13867 13868Every rvalue has an associated type, and the API will check to ensure 13869that types match up correctly (otherwise the context will emit an error). 13870 13871@geindex gccjit;;rvalue;;get_type (C++ function) 13872@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue8get_typeEv}@anchor{234}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue8get_typeEv}@anchor{235}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue8get_typeEv}@anchor{236}@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{237} 13873@deffn {C++ Function} gccjit::@ref{177,,type} gccjit::@ref{17e,,rvalue}::get_type () 13874 13875Get the type of this rvalue. 13876@end deffn 13877 13878@menu 13879* Simple expressions: Simple expressions<2>. 13880* Vector expressions: Vector expressions<2>. 13881* Unary Operations: Unary Operations<2>. 13882* Binary Operations: Binary Operations<2>. 13883* Comparisons: Comparisons<2>. 13884* Function calls: Function calls<2>. 13885* Function pointers: Function pointers<3>. 13886* Type-coercion: Type-coercion<2>. 13887 13888@end menu 13889 13890@node Simple expressions<2>,Vector expressions<2>,,Rvalues<2> 13891@anchor{cp/topics/expressions simple-expressions}@anchor{238} 13892@subsubsection Simple expressions 13893 13894 13895@geindex gccjit;;context;;new_rvalue (C++ function) 13896@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEi}@anchor{192}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEi}@anchor{239}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEi}@anchor{23a}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{23b} 13897@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_rvalue (gccjit::type numeric_type, int value) const 13898 13899Given a numeric type (integer or floating point), build an rvalue for 13900the given constant @code{int} value. 13901@end deffn 13902 13903@geindex gccjit;;context;;new_rvalue (C++ function) 13904@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEl}@anchor{23c}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEl}@anchor{23d}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEl}@anchor{23e}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{23f} 13905@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_rvalue (gccjit::type numeric_type, long value) const 13906 13907Given a numeric type (integer or floating point), build an rvalue for 13908the given constant @code{long} value. 13909@end deffn 13910 13911@geindex gccjit;;context;;zero (C++ function) 13912@anchor{cp/topics/expressions _CPPv4NK6gccjit7context4zeroEN6gccjit4typeE}@anchor{18e}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context4zeroEN6gccjit4typeE}@anchor{240}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context4zeroEN6gccjit4typeE}@anchor{241}@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{242} 13913@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::zero (gccjit::type numeric_type) const 13914 13915Given a numeric type (integer or floating point), get the rvalue for 13916zero. Essentially this is just a shortcut for: 13917 13918@example 13919ctxt.new_rvalue (numeric_type, 0) 13920@end example 13921@end deffn 13922 13923@geindex gccjit;;context;;one (C++ function) 13924@anchor{cp/topics/expressions _CPPv4NK6gccjit7context3oneEN6gccjit4typeE}@anchor{243}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context3oneEN6gccjit4typeE}@anchor{244}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context3oneEN6gccjit4typeE}@anchor{245}@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{246} 13925@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::one (gccjit::type numeric_type) const 13926 13927Given a numeric type (integer or floating point), get the rvalue for 13928one. Essentially this is just a shortcut for: 13929 13930@example 13931ctxt.new_rvalue (numeric_type, 1) 13932@end example 13933@end deffn 13934 13935@geindex gccjit;;context;;new_rvalue (C++ function) 13936@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEd}@anchor{247}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEd}@anchor{248}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEd}@anchor{249}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{24a} 13937@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_rvalue (gccjit::type numeric_type, double value) const 13938 13939Given a numeric type (integer or floating point), build an rvalue for 13940the given constant @code{double} value. 13941@end deffn 13942 13943@geindex gccjit;;context;;new_rvalue (C++ function) 13944@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeEPv}@anchor{24b}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeEPv}@anchor{24c}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeEPv}@anchor{24d}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{24e} 13945@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_rvalue (gccjit::type pointer_type, void *value) const 13946 13947Given a pointer type, build an rvalue for the given address. 13948@end deffn 13949 13950@geindex gccjit;;context;;new_rvalue (C++ function) 13951@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueERKNSt6stringE}@anchor{24f}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueERKNSt6stringE}@anchor{250}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueERKNSt6stringE}@anchor{251}@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{252} 13952@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_rvalue (const std::string &value) const 13953 13954Generate an rvalue of type @code{GCC_JIT_TYPE_CONST_CHAR_PTR} for 13955the given string. This is akin to a string literal. 13956@end deffn 13957 13958@node Vector expressions<2>,Unary Operations<2>,Simple expressions<2>,Rvalues<2> 13959@anchor{cp/topics/expressions vector-expressions}@anchor{253} 13960@subsubsection Vector expressions 13961 13962 13963@geindex gccjit;;context;;new_rvalue (C++ function) 13964@anchor{cp/topics/expressions _CPPv4NK6gccjit7context10new_rvalueEN6gccjit4typeENSt6vectorIN6gccjit6rvalueEEE}@anchor{254}@anchor{cp/topics/expressions _CPPv3NK6gccjit7context10new_rvalueEN6gccjit4typeENSt6vectorIN6gccjit6rvalueEEE}@anchor{255}@anchor{cp/topics/expressions _CPPv2NK6gccjit7context10new_rvalueEN6gccjit4typeENSt6vectorIN6gccjit6rvalueEEE}@anchor{256}@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type std vector gccjit rvalue C}@anchor{257} 13965@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_rvalue (gccjit::type vector_type, std::vector<gccjit::rvalue> elements) const 13966 13967Given a vector type, and a vector of scalar rvalue elements, generate a 13968vector rvalue. 13969 13970The number of elements needs to match that of the vector type. 13971@end deffn 13972 13973@node Unary Operations<2>,Binary Operations<2>,Vector expressions<2>,Rvalues<2> 13974@anchor{cp/topics/expressions unary-operations}@anchor{258} 13975@subsubsection Unary Operations 13976 13977 13978@geindex gccjit;;context;;new_unary_op (C++ function) 13979@anchor{cp/topics/expressions _CPPv4N6gccjit7context12new_unary_opE16gcc_jit_unary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{259}@anchor{cp/topics/expressions _CPPv3N6gccjit7context12new_unary_opE16gcc_jit_unary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context12new_unary_opE16gcc_jit_unary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25b}@anchor{cp/topics/expressions gccjit context new_unary_op__gcc_jit_unary_op gccjit type gccjit rvalue gccjit location}@anchor{25c} 13980@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_unary_op (enum gcc_jit_unary_op, gccjit::type result_type, gccjit::rvalue rvalue, gccjit::location loc) 13981 13982Build a unary operation out of an input rvalue. 13983 13984Parameter @code{loc} is optional. 13985 13986This is a thin wrapper around the C API���s 13987@ref{bf,,gcc_jit_context_new_unary_op()} and the available unary 13988operations are documented there. 13989@end deffn 13990 13991There are shorter ways to spell the various specific kinds of unary 13992operation: 13993 13994@geindex gccjit;;context;;new_minus (C++ function) 13995@anchor{cp/topics/expressions _CPPv4N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{25f}@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{260} 13996@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 13997 13998Negate an arithmetic value; for example: 13999 14000@example 14001gccjit::rvalue negpi = ctxt.new_minus (t_double, pi); 14002@end example 14003 14004builds the equivalent of this C expression: 14005 14006@example 14007-pi 14008@end example 14009@end deffn 14010 14011@geindex new_bitwise_negate (C++ function) 14012@anchor{cp/topics/expressions _CPPv418new_bitwise_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{261}@anchor{cp/topics/expressions _CPPv318new_bitwise_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{262}@anchor{cp/topics/expressions _CPPv218new_bitwise_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{263}@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{264} 14013@deffn {C++ Function} gccjit::@ref{17e,,rvalue} new_bitwise_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 14014 14015Bitwise negation of an integer value (one���s complement); for example: 14016 14017@example 14018gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a); 14019@end example 14020 14021builds the equivalent of this C expression: 14022 14023@example 14024~a 14025@end example 14026@end deffn 14027 14028@geindex new_logical_negate (C++ function) 14029@anchor{cp/topics/expressions _CPPv418new_logical_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{265}@anchor{cp/topics/expressions _CPPv318new_logical_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{266}@anchor{cp/topics/expressions _CPPv218new_logical_negateN6gccjit4typeEN6gccjit6rvalueEN6gccjit8locationE}@anchor{267}@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{268} 14030@deffn {C++ Function} gccjit::@ref{17e,,rvalue} new_logical_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 14031 14032Logical negation of an arithmetic or pointer value; for example: 14033 14034@example 14035gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond); 14036@end example 14037 14038builds the equivalent of this C expression: 14039 14040@example 14041!cond 14042@end example 14043@end deffn 14044 14045The most concise way to spell them is with overloaded operators: 14046 14047@geindex operator- (C++ function) 14048@anchor{cp/topics/expressions _CPPv4miN6gccjit6rvalueE}@anchor{269}@anchor{cp/topics/expressions _CPPv3miN6gccjit6rvalueE}@anchor{26a}@anchor{cp/topics/expressions _CPPv2miN6gccjit6rvalueE}@anchor{26b}@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{26c} 14049@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator@w{-} (gccjit::rvalue a) 14050 14051@example 14052gccjit::rvalue negpi = -pi; 14053@end example 14054@end deffn 14055 14056@geindex operator~ (C++ function) 14057@anchor{cp/topics/expressions _CPPv4coN6gccjit6rvalueE}@anchor{26d}@anchor{cp/topics/expressions _CPPv3coN6gccjit6rvalueE}@anchor{26e}@anchor{cp/topics/expressions _CPPv2coN6gccjit6rvalueE}@anchor{26f}@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{270} 14058@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator~ (gccjit::rvalue a) 14059 14060@example 14061gccjit::rvalue mask = ~a; 14062@end example 14063@end deffn 14064 14065@geindex operator! (C++ function) 14066@anchor{cp/topics/expressions _CPPv4ntN6gccjit6rvalueE}@anchor{271}@anchor{cp/topics/expressions _CPPv3ntN6gccjit6rvalueE}@anchor{272}@anchor{cp/topics/expressions _CPPv2ntN6gccjit6rvalueE}@anchor{273}@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{274} 14067@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator! (gccjit::rvalue a) 14068 14069@example 14070gccjit::rvalue guard = !cond; 14071@end example 14072@end deffn 14073 14074@node Binary Operations<2>,Comparisons<2>,Unary Operations<2>,Rvalues<2> 14075@anchor{cp/topics/expressions binary-operations}@anchor{275} 14076@subsubsection Binary Operations 14077 14078 14079@geindex gccjit;;context;;new_binary_op (C++ function) 14080@anchor{cp/topics/expressions _CPPv4N6gccjit7context13new_binary_opE17gcc_jit_binary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{17d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context13new_binary_opE17gcc_jit_binary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{276}@anchor{cp/topics/expressions _CPPv2N6gccjit7context13new_binary_opE17gcc_jit_binary_opN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{277}@anchor{cp/topics/expressions gccjit context new_binary_op__gcc_jit_binary_op gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{278} 14081@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_binary_op (enum gcc_jit_binary_op, gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14082 14083Build a binary operation out of two constituent rvalues. 14084 14085Parameter @code{loc} is optional. 14086 14087This is a thin wrapper around the C API���s 14088@ref{12,,gcc_jit_context_new_binary_op()} and the available binary 14089operations are documented there. 14090@end deffn 14091 14092There are shorter ways to spell the various specific kinds of binary 14093operation: 14094 14095@geindex gccjit;;context;;new_plus (C++ function) 14096@anchor{cp/topics/expressions _CPPv4N6gccjit7context8new_plusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{279}@anchor{cp/topics/expressions _CPPv3N6gccjit7context8new_plusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{27a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_plusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{27b}@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{27c} 14097@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_plus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14098@end deffn 14099 14100@geindex gccjit;;context;;new_minus (C++ function) 14101@anchor{cp/topics/expressions _CPPv4N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{27d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{27e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context9new_minusEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{27f}@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{280} 14102@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14103@end deffn 14104 14105@geindex gccjit;;context;;new_mult (C++ function) 14106@anchor{cp/topics/expressions _CPPv4N6gccjit7context8new_multEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{281}@anchor{cp/topics/expressions _CPPv3N6gccjit7context8new_multEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{282}@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_multEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{283}@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{284} 14107@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_mult (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14108@end deffn 14109 14110@geindex gccjit;;context;;new_divide (C++ function) 14111@anchor{cp/topics/expressions _CPPv4N6gccjit7context10new_divideEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{285}@anchor{cp/topics/expressions _CPPv3N6gccjit7context10new_divideEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{286}@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_divideEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{287}@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{288} 14112@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_divide (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14113@end deffn 14114 14115@geindex gccjit;;context;;new_modulo (C++ function) 14116@anchor{cp/topics/expressions _CPPv4N6gccjit7context10new_moduloEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{289}@anchor{cp/topics/expressions _CPPv3N6gccjit7context10new_moduloEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{28a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_moduloEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{28b}@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{28c} 14117@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_modulo (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14118@end deffn 14119 14120@geindex gccjit;;context;;new_bitwise_and (C++ function) 14121@anchor{cp/topics/expressions _CPPv4N6gccjit7context15new_bitwise_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{28d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context15new_bitwise_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{28e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_bitwise_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{28f}@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{290} 14122@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_bitwise_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14123@end deffn 14124 14125@geindex gccjit;;context;;new_bitwise_xor (C++ function) 14126@anchor{cp/topics/expressions _CPPv4N6gccjit7context15new_bitwise_xorEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{291}@anchor{cp/topics/expressions _CPPv3N6gccjit7context15new_bitwise_xorEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{292}@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_bitwise_xorEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{293}@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{294} 14127@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_bitwise_xor (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14128@end deffn 14129 14130@geindex gccjit;;context;;new_bitwise_or (C++ function) 14131@anchor{cp/topics/expressions _CPPv4N6gccjit7context14new_bitwise_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{295}@anchor{cp/topics/expressions _CPPv3N6gccjit7context14new_bitwise_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{296}@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_bitwise_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{297}@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{298} 14132@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_bitwise_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14133@end deffn 14134 14135@geindex gccjit;;context;;new_logical_and (C++ function) 14136@anchor{cp/topics/expressions _CPPv4N6gccjit7context15new_logical_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{299}@anchor{cp/topics/expressions _CPPv3N6gccjit7context15new_logical_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context15new_logical_andEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29b}@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{29c} 14137@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_logical_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14138@end deffn 14139 14140@geindex gccjit;;context;;new_logical_or (C++ function) 14141@anchor{cp/topics/expressions _CPPv4N6gccjit7context14new_logical_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29d}@anchor{cp/topics/expressions _CPPv3N6gccjit7context14new_logical_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29e}@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_logical_orEN6gccjit4typeEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{29f}@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{2a0} 14142@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_logical_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14143@end deffn 14144 14145The most concise way to spell them is with overloaded operators: 14146 14147@geindex operator+ (C++ function) 14148@anchor{cp/topics/expressions _CPPv4plN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2a1}@anchor{cp/topics/expressions _CPPv3plN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2a2}@anchor{cp/topics/expressions _CPPv2plN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2a3}@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{2a4} 14149@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator+ (gccjit::rvalue a, gccjit::rvalue b) 14150 14151@example 14152gccjit::rvalue sum = a + b; 14153@end example 14154@end deffn 14155 14156@geindex operator- (C++ function) 14157@anchor{cp/topics/expressions _CPPv4miN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2a5}@anchor{cp/topics/expressions _CPPv3miN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2a6}@anchor{cp/topics/expressions _CPPv2miN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2a7}@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{2a8} 14158@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator@w{-} (gccjit::rvalue a, gccjit::rvalue b) 14159 14160@example 14161gccjit::rvalue diff = a - b; 14162@end example 14163@end deffn 14164 14165@geindex operator* (C++ function) 14166@anchor{cp/topics/expressions _CPPv4mlN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2a9}@anchor{cp/topics/expressions _CPPv3mlN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2aa}@anchor{cp/topics/expressions _CPPv2mlN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ab}@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{2ac} 14167@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator* (gccjit::rvalue a, gccjit::rvalue b) 14168 14169@example 14170gccjit::rvalue prod = a * b; 14171@end example 14172@end deffn 14173 14174@geindex operator/ (C++ function) 14175@anchor{cp/topics/expressions _CPPv4dvN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ad}@anchor{cp/topics/expressions _CPPv3dvN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ae}@anchor{cp/topics/expressions _CPPv2dvN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2af}@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{2b0} 14176@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator/ (gccjit::rvalue a, gccjit::rvalue b) 14177 14178@example 14179gccjit::rvalue result = a / b; 14180@end example 14181@end deffn 14182 14183@geindex operator% (C++ function) 14184@anchor{cp/topics/expressions _CPPv4rmN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b1}@anchor{cp/topics/expressions _CPPv3rmN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b2}@anchor{cp/topics/expressions _CPPv2rmN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b3}@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{2b4} 14185@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator% (gccjit::rvalue a, gccjit::rvalue b) 14186 14187@example 14188gccjit::rvalue mod = a % b; 14189@end example 14190@end deffn 14191 14192@geindex operator& (C++ function) 14193@anchor{cp/topics/expressions _CPPv4anN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b5}@anchor{cp/topics/expressions _CPPv3anN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b6}@anchor{cp/topics/expressions _CPPv2anN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b7}@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{2b8} 14194@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator& (gccjit::rvalue a, gccjit::rvalue b) 14195 14196@example 14197gccjit::rvalue x = a & b; 14198@end example 14199@end deffn 14200 14201@geindex operator^ (C++ function) 14202@anchor{cp/topics/expressions _CPPv4eoN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2b9}@anchor{cp/topics/expressions _CPPv3eoN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ba}@anchor{cp/topics/expressions _CPPv2eoN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2bb}@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{2bc} 14203@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator^ (gccjit::rvalue a, gccjit::rvalue b) 14204 14205@example 14206gccjit::rvalue x = a ^ b; 14207@end example 14208@end deffn 14209 14210@geindex operator| (C++ function) 14211@anchor{cp/topics/expressions _CPPv4orN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2bd}@anchor{cp/topics/expressions _CPPv3orN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2be}@anchor{cp/topics/expressions _CPPv2orN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2bf}@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{2c0} 14212@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator| (gccjit::rvalue a, gccjit::rvalue b) 14213 14214@example 14215gccjit::rvalue x = a | b; 14216@end example 14217@end deffn 14218 14219@geindex operator&& (C++ function) 14220@anchor{cp/topics/expressions _CPPv4aaN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c1}@anchor{cp/topics/expressions _CPPv3aaN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c2}@anchor{cp/topics/expressions _CPPv2aaN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c3}@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{2c4} 14221@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator&& (gccjit::rvalue a, gccjit::rvalue b) 14222 14223@example 14224gccjit::rvalue cond = a && b; 14225@end example 14226@end deffn 14227 14228@geindex operator|| (C++ function) 14229@anchor{cp/topics/expressions _CPPv4ooN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c5}@anchor{cp/topics/expressions _CPPv3ooN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c6}@anchor{cp/topics/expressions _CPPv2ooN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2c7}@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{2c8} 14230@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator|| (gccjit::rvalue a, gccjit::rvalue b) 14231 14232@example 14233gccjit::rvalue cond = a || b; 14234@end example 14235@end deffn 14236 14237These can of course be combined, giving a terse way to build compound 14238expressions: 14239 14240@quotation 14241 14242@example 14243gccjit::rvalue discriminant = (b * b) - (four * a * c); 14244@end example 14245@end quotation 14246 14247@node Comparisons<2>,Function calls<2>,Binary Operations<2>,Rvalues<2> 14248@anchor{cp/topics/expressions comparisons}@anchor{2c9} 14249@subsubsection Comparisons 14250 14251 14252@geindex gccjit;;context;;new_comparison (C++ function) 14253@anchor{cp/topics/expressions _CPPv4N6gccjit7context14new_comparisonE18gcc_jit_comparisonN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{18f}@anchor{cp/topics/expressions _CPPv3N6gccjit7context14new_comparisonE18gcc_jit_comparisonN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2ca}@anchor{cp/topics/expressions _CPPv2N6gccjit7context14new_comparisonE18gcc_jit_comparisonN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2cb}@anchor{cp/topics/expressions gccjit context new_comparison__gcc_jit_comparison gccjit rvalue gccjit rvalue gccjit location}@anchor{2cc} 14254@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_comparison (enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14255 14256Build a boolean rvalue out of the comparison of two other rvalues. 14257 14258Parameter @code{loc} is optional. 14259 14260This is a thin wrapper around the C API���s 14261@ref{2c,,gcc_jit_context_new_comparison()} and the available kinds 14262of comparison are documented there. 14263@end deffn 14264 14265There are shorter ways to spell the various specific kinds of binary 14266operation: 14267 14268@geindex gccjit;;context;;new_eq (C++ function) 14269@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_eqEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2cd}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_eqEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2ce}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_eqEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2cf}@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{2d0} 14270@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_eq (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14271@end deffn 14272 14273@geindex gccjit;;context;;new_ne (C++ function) 14274@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_neEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2d1}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_neEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2d2}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_neEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2d3}@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{2d4} 14275@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_ne (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14276@end deffn 14277 14278@geindex gccjit;;context;;new_lt (C++ function) 14279@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_ltEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2d5}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_ltEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2d6}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_ltEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2d7}@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{2d8} 14280@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_lt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14281@end deffn 14282 14283@geindex gccjit;;context;;new_le (C++ function) 14284@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_leEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2d9}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_leEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2da}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_leEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2db}@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{2dc} 14285@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_le (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14286@end deffn 14287 14288@geindex gccjit;;context;;new_gt (C++ function) 14289@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_gtEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2dd}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_gtEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2de}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_gtEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2df}@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{2e0} 14290@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_gt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14291@end deffn 14292 14293@geindex gccjit;;context;;new_ge (C++ function) 14294@anchor{cp/topics/expressions _CPPv4N6gccjit7context6new_geEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2e1}@anchor{cp/topics/expressions _CPPv3N6gccjit7context6new_geEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2e2}@anchor{cp/topics/expressions _CPPv2N6gccjit7context6new_geEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{2e3}@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{2e4} 14295@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_ge (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 14296@end deffn 14297 14298The most concise way to spell them is with overloaded operators: 14299 14300@geindex operator== (C++ function) 14301@anchor{cp/topics/expressions _CPPv4eqN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2e5}@anchor{cp/topics/expressions _CPPv3eqN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2e6}@anchor{cp/topics/expressions _CPPv2eqN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2e7}@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{2e8} 14302@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator== (gccjit::rvalue a, gccjit::rvalue b) 14303 14304@example 14305gccjit::rvalue cond = (a == ctxt.zero (t_int)); 14306@end example 14307@end deffn 14308 14309@geindex operator!= (C++ function) 14310@anchor{cp/topics/expressions _CPPv4neN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2e9}@anchor{cp/topics/expressions _CPPv3neN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ea}@anchor{cp/topics/expressions _CPPv2neN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2eb}@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{2ec} 14311@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator!= (gccjit::rvalue a, gccjit::rvalue b) 14312 14313@example 14314gccjit::rvalue cond = (i != j); 14315@end example 14316@end deffn 14317 14318@geindex operator< (C++ function) 14319@anchor{cp/topics/expressions _CPPv4ltN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ed}@anchor{cp/topics/expressions _CPPv3ltN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ee}@anchor{cp/topics/expressions _CPPv2ltN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2ef}@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{2f0} 14320@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator< (gccjit::rvalue a, gccjit::rvalue b) 14321 14322@example 14323gccjit::rvalue cond = i < n; 14324@end example 14325@end deffn 14326 14327@geindex operator<= (C++ function) 14328@anchor{cp/topics/expressions _CPPv4leN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2f1}@anchor{cp/topics/expressions _CPPv3leN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2f2}@anchor{cp/topics/expressions _CPPv2leN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2f3}@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{2f4} 14329@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator<= (gccjit::rvalue a, gccjit::rvalue b) 14330 14331@example 14332gccjit::rvalue cond = i <= n; 14333@end example 14334@end deffn 14335 14336@geindex operator> (C++ function) 14337@anchor{cp/topics/expressions _CPPv4gtN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2f5}@anchor{cp/topics/expressions _CPPv3gtN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2f6}@anchor{cp/topics/expressions _CPPv2gtN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2f7}@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{2f8} 14338@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator> (gccjit::rvalue a, gccjit::rvalue b) 14339 14340@example 14341gccjit::rvalue cond = (ch > limit); 14342@end example 14343@end deffn 14344 14345@geindex operator>= (C++ function) 14346@anchor{cp/topics/expressions _CPPv4geN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2f9}@anchor{cp/topics/expressions _CPPv3geN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2fa}@anchor{cp/topics/expressions _CPPv2geN6gccjit6rvalueEN6gccjit6rvalueE}@anchor{2fb}@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{2fc} 14347@deffn {C++ Function} gccjit::@ref{17e,,rvalue} operator>= (gccjit::rvalue a, gccjit::rvalue b) 14348 14349@example 14350gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100)); 14351@end example 14352@end deffn 14353 14354@c TODO: beyond this point 14355 14356@node Function calls<2>,Function pointers<3>,Comparisons<2>,Rvalues<2> 14357@anchor{cp/topics/expressions function-calls}@anchor{2fd} 14358@subsubsection Function calls 14359 14360 14361@geindex gcc_jit_context_new_call (C++ function) 14362@anchor{cp/topics/expressions _CPPv424gcc_jit_context_new_callP15gcc_jit_contextP16gcc_jit_locationP16gcc_jit_functioniPP14gcc_jit_rvalue}@anchor{2fe}@anchor{cp/topics/expressions _CPPv324gcc_jit_context_new_callP15gcc_jit_contextP16gcc_jit_locationP16gcc_jit_functioniPP14gcc_jit_rvalue}@anchor{2ff}@anchor{cp/topics/expressions _CPPv224gcc_jit_context_new_callP15gcc_jit_contextP16gcc_jit_locationP16gcc_jit_functioniPP14gcc_jit_rvalue}@anchor{300}@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{301} 14363@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) 14364 14365Given a function and the given table of argument rvalues, construct a 14366call to the function, with the result as an rvalue. 14367 14368@cartouche 14369@quotation Note 14370@code{gccjit::context::new_call()} merely builds a 14371@ref{17e,,gccjit;;rvalue} i.e. an expression that can be evaluated, 14372perhaps as part of a more complicated expression. 14373The call @emph{won���t} happen unless you add a statement to a function 14374that evaluates the expression. 14375 14376For example, if you want to call a function and discard the result 14377(or to call a function with @code{void} return type), use 14378@ref{302,,gccjit;;block;;add_eval()}: 14379 14380@example 14381/* Add "(void)printf (arg0, arg1);". */ 14382block.add_eval (ctxt.new_call (printf_func, arg0, arg1)); 14383@end example 14384@end quotation 14385@end cartouche 14386@end deffn 14387 14388@node Function pointers<3>,Type-coercion<2>,Function calls<2>,Rvalues<2> 14389@anchor{cp/topics/expressions function-pointers}@anchor{303} 14390@subsubsection Function pointers 14391 14392 14393@geindex gccjit;;function;;get_address (C++ function) 14394@anchor{cp/topics/expressions _CPPv4N6gccjit8function11get_addressEN6gccjit8locationE}@anchor{304}@anchor{cp/topics/expressions _CPPv3N6gccjit8function11get_addressEN6gccjit8locationE}@anchor{305}@anchor{cp/topics/expressions _CPPv2N6gccjit8function11get_addressEN6gccjit8locationE}@anchor{306}@anchor{cp/topics/expressions gccjit function get_address__gccjit location}@anchor{307} 14395@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{18c,,function}::get_address (gccjit::location loc) 14396 14397Get the address of a function as an rvalue, of function pointer 14398type. 14399@end deffn 14400 14401@node Type-coercion<2>,,Function pointers<3>,Rvalues<2> 14402@anchor{cp/topics/expressions type-coercion}@anchor{308} 14403@subsubsection Type-coercion 14404 14405 14406@geindex gccjit;;context;;new_cast (C++ function) 14407@anchor{cp/topics/expressions _CPPv4N6gccjit7context8new_castEN6gccjit6rvalueEN6gccjit4typeEN6gccjit8locationE}@anchor{309}@anchor{cp/topics/expressions _CPPv3N6gccjit7context8new_castEN6gccjit6rvalueEN6gccjit4typeEN6gccjit8locationE}@anchor{30a}@anchor{cp/topics/expressions _CPPv2N6gccjit7context8new_castEN6gccjit6rvalueEN6gccjit4typeEN6gccjit8locationE}@anchor{30b}@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{30c} 14408@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{175,,context}::new_cast (gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc) 14409 14410Given an rvalue of T, construct another rvalue of another type. 14411 14412Currently only a limited set of conversions are possible: 14413 14414@quotation 14415 14416 14417@itemize * 14418 14419@item 14420int <-> float 14421 14422@item 14423int <-> bool 14424 14425@item 14426P* <-> Q*, for pointer types P and Q 14427@end itemize 14428@end quotation 14429@end deffn 14430 14431@node Lvalues<2>,Working with pointers structs and unions<2>,Rvalues<2>,Expressions<2> 14432@anchor{cp/topics/expressions lvalues}@anchor{30d} 14433@subsubsection Lvalues 14434 14435 14436@geindex gccjit;;lvalue (C++ class) 14437@anchor{cp/topics/expressions _CPPv4N6gccjit6lvalueE}@anchor{187}@anchor{cp/topics/expressions _CPPv3N6gccjit6lvalueE}@anchor{30e}@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalueE}@anchor{30f}@anchor{cp/topics/expressions gccjit lvalue}@anchor{310} 14438@deffn {C++ Class} gccjit::lvalue 14439@end deffn 14440 14441An lvalue is something that can of the @emph{left}-hand side of an assignment: 14442a storage area (such as a variable). It is a subclass of 14443@ref{17e,,gccjit;;rvalue}, where the rvalue is computed by reading from the 14444storage area. 14445 14446It iss a thin wrapper around @ref{24,,gcc_jit_lvalue *} from the C API. 14447 14448@geindex gccjit;;lvalue;;get_address (C++ function) 14449@anchor{cp/topics/expressions _CPPv4N6gccjit6lvalue11get_addressEN6gccjit8locationE}@anchor{311}@anchor{cp/topics/expressions _CPPv3N6gccjit6lvalue11get_addressEN6gccjit8locationE}@anchor{312}@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalue11get_addressEN6gccjit8locationE}@anchor{313}@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{314} 14450@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{187,,lvalue}::get_address (gccjit::location loc) 14451 14452Take the address of an lvalue; analogous to: 14453 14454@example 14455&(EXPR) 14456@end example 14457 14458in C. 14459 14460Parameter ���loc��� is optional. 14461@end deffn 14462 14463@menu 14464* Global variables: Global variables<2>. 14465 14466@end menu 14467 14468@node Global variables<2>,,,Lvalues<2> 14469@anchor{cp/topics/expressions global-variables}@anchor{315} 14470@subsubsection Global variables 14471 14472 14473@geindex gccjit;;context;;new_global (C++ function) 14474@anchor{cp/topics/expressions _CPPv4N6gccjit7context10new_globalE19gcc_jit_global_kindN6gccjit4typeEPKcN6gccjit8locationE}@anchor{316}@anchor{cp/topics/expressions _CPPv3N6gccjit7context10new_globalE19gcc_jit_global_kindN6gccjit4typeEPKcN6gccjit8locationE}@anchor{317}@anchor{cp/topics/expressions _CPPv2N6gccjit7context10new_globalE19gcc_jit_global_kindN6gccjit4typeEPKcN6gccjit8locationE}@anchor{318}@anchor{cp/topics/expressions gccjit context new_global__gcc_jit_global_kind gccjit type cCP gccjit location}@anchor{319} 14475@deffn {C++ Function} gccjit::@ref{187,,lvalue} gccjit::@ref{175,,context}::new_global (enum gcc_jit_global_kind, gccjit::type type, const char *name, gccjit::location loc) 14476 14477Add a new global variable of the given type and name to the context. 14478 14479This is a thin wrapper around @ref{f5,,gcc_jit_context_new_global()} from 14480the C API; the ���kind��� parameter has the same meaning as there. 14481@end deffn 14482 14483@node Working with pointers structs and unions<2>,,Lvalues<2>,Expressions<2> 14484@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{31a} 14485@subsubsection Working with pointers, structs and unions 14486 14487 14488@geindex gccjit;;rvalue;;dereference (C++ function) 14489@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue11dereferenceEN6gccjit8locationE}@anchor{31b}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue11dereferenceEN6gccjit8locationE}@anchor{31c}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue11dereferenceEN6gccjit8locationE}@anchor{31d}@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{31e} 14490@deffn {C++ Function} gccjit::@ref{187,,lvalue} gccjit::@ref{17e,,rvalue}::dereference (gccjit::location loc) 14491 14492Given an rvalue of pointer type @code{T *}, dereferencing the pointer, 14493getting an lvalue of type @code{T}. Analogous to: 14494 14495@example 14496*(EXPR) 14497@end example 14498 14499in C. 14500 14501Parameter ���loc��� is optional. 14502@end deffn 14503 14504If you don���t need to specify the location, this can also be expressed using 14505an overloaded operator: 14506 14507@geindex gccjit;;rvalue;;operator* (C++ function) 14508@anchor{cp/topics/expressions _CPPv4N6gccjit6rvaluemlEv}@anchor{31f}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvaluemlEv}@anchor{320}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvaluemlEv}@anchor{321}@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{322} 14509@deffn {C++ Function} gccjit::@ref{187,,lvalue} gccjit::@ref{17e,,rvalue}::operator* () 14510 14511@example 14512gccjit::lvalue content = *ptr; 14513@end example 14514@end deffn 14515 14516Field access is provided separately for both lvalues and rvalues: 14517 14518@geindex gccjit;;lvalue;;access_field (C++ function) 14519@anchor{cp/topics/expressions _CPPv4N6gccjit6lvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{323}@anchor{cp/topics/expressions _CPPv3N6gccjit6lvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{324}@anchor{cp/topics/expressions _CPPv2N6gccjit6lvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{325}@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{326} 14520@deffn {C++ Function} gccjit::@ref{187,,lvalue} gccjit::@ref{187,,lvalue}::access_field (gccjit::field field, gccjit::location loc) 14521 14522Given an lvalue of struct or union type, access the given field, 14523getting an lvalue of the field���s type. Analogous to: 14524 14525@example 14526(EXPR).field = ...; 14527@end example 14528 14529in C. 14530@end deffn 14531 14532@geindex gccjit;;rvalue;;access_field (C++ function) 14533@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{327}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{328}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue12access_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{329}@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{32a} 14534@deffn {C++ Function} gccjit::@ref{17e,,rvalue} gccjit::@ref{17e,,rvalue}::access_field (gccjit::field field, gccjit::location loc) 14535 14536Given an rvalue of struct or union type, access the given field 14537as an rvalue. Analogous to: 14538 14539@example 14540(EXPR).field 14541@end example 14542 14543in C. 14544@end deffn 14545 14546@geindex gccjit;;rvalue;;dereference_field (C++ function) 14547@anchor{cp/topics/expressions _CPPv4N6gccjit6rvalue17dereference_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{32b}@anchor{cp/topics/expressions _CPPv3N6gccjit6rvalue17dereference_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{32c}@anchor{cp/topics/expressions _CPPv2N6gccjit6rvalue17dereference_fieldEN6gccjit5fieldEN6gccjit8locationE}@anchor{32d}@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{32e} 14548@deffn {C++ Function} gccjit::@ref{187,,lvalue} gccjit::@ref{17e,,rvalue}::dereference_field (gccjit::field field, gccjit::location loc) 14549 14550Given an rvalue of pointer type @code{T *} where T is of struct or union 14551type, access the given field as an lvalue. Analogous to: 14552 14553@example 14554(EXPR)->field 14555@end example 14556 14557in C, itself equivalent to @code{(*EXPR).FIELD}. 14558@end deffn 14559 14560@geindex gccjit;;context;;new_array_access (C++ function) 14561@anchor{cp/topics/expressions _CPPv4N6gccjit7context16new_array_accessEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{32f}@anchor{cp/topics/expressions _CPPv3N6gccjit7context16new_array_accessEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{330}@anchor{cp/topics/expressions _CPPv2N6gccjit7context16new_array_accessEN6gccjit6rvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{331}@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{332} 14562@deffn {C++ Function} gccjit::@ref{187,,lvalue} gccjit::@ref{175,,context}::new_array_access (gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc) 14563 14564Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at 14565the given index, using standard C array indexing rules i.e. each 14566increment of @code{index} corresponds to @code{sizeof(T)} bytes. 14567Analogous to: 14568 14569@example 14570PTR[INDEX] 14571@end example 14572 14573in C (or, indeed, to @code{PTR + INDEX}). 14574 14575Parameter ���loc��� is optional. 14576@end deffn 14577 14578For array accesses where you don���t need to specify a @ref{19b,,gccjit;;location}, 14579two overloaded operators are available: 14580 14581@quotation 14582 14583gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index) 14584 14585@example 14586gccjit::lvalue element = array[idx]; 14587@end example 14588 14589gccjit::lvalue gccjit::rvalue::operator[] (int index) 14590 14591@example 14592gccjit::lvalue element = array[0]; 14593@end example 14594@end quotation 14595 14596@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 14597@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14598@c 14599@c This is free software: you can redistribute it and/or modify it 14600@c under the terms of the GNU General Public License as published by 14601@c the Free Software Foundation, either version 3 of the License, or 14602@c (at your option) any later version. 14603@c 14604@c This program is distributed in the hope that it will be useful, but 14605@c WITHOUT ANY WARRANTY; without even the implied warranty of 14606@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14607@c General Public License for more details. 14608@c 14609@c You should have received a copy of the GNU General Public License 14610@c along with this program. If not, see 14611@c <https://www.gnu.org/licenses/>. 14612 14613@node Creating and using functions<2>,Source Locations<2>,Expressions<2>,Topic Reference<2> 14614@anchor{cp/topics/functions doc}@anchor{333}@anchor{cp/topics/functions creating-and-using-functions}@anchor{334} 14615@subsection Creating and using functions 14616 14617 14618@menu 14619* Params: Params<2>. 14620* Functions: Functions<2>. 14621* Blocks: Blocks<2>. 14622* Statements: Statements<2>. 14623 14624@end menu 14625 14626@node Params<2>,Functions<2>,,Creating and using functions<2> 14627@anchor{cp/topics/functions params}@anchor{335} 14628@subsubsection Params 14629 14630 14631@geindex gccjit;;param (C++ class) 14632@anchor{cp/topics/functions _CPPv4N6gccjit5paramE}@anchor{188}@anchor{cp/topics/functions _CPPv3N6gccjit5paramE}@anchor{336}@anchor{cp/topics/functions _CPPv2N6gccjit5paramE}@anchor{337}@anchor{cp/topics/functions gccjit param}@anchor{338} 14633@deffn {C++ Class} gccjit::param 14634 14635A @cite{gccjit::param} represents a parameter to a function. 14636@end deffn 14637 14638@geindex gccjit;;context;;new_param (C++ function) 14639@anchor{cp/topics/functions _CPPv4N6gccjit7context9new_paramEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{17c}@anchor{cp/topics/functions _CPPv3N6gccjit7context9new_paramEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{339}@anchor{cp/topics/functions _CPPv2N6gccjit7context9new_paramEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{33a}@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{33b} 14640@deffn {C++ Function} gccjit::@ref{188,,param} gccjit::@ref{175,,context}::new_param (gccjit::type type, const char *name, gccjit::location loc) 14641 14642In preparation for creating a function, create a new parameter of the 14643given type and name. 14644@end deffn 14645 14646@ref{188,,gccjit;;param} is a subclass of @ref{187,,gccjit;;lvalue} (and thus 14647of @ref{17e,,gccjit;;rvalue} and @ref{17a,,gccjit;;object}). It is a thin 14648wrapper around the C API���s @ref{25,,gcc_jit_param *}. 14649 14650@node Functions<2>,Blocks<2>,Params<2>,Creating and using functions<2> 14651@anchor{cp/topics/functions functions}@anchor{33c} 14652@subsubsection Functions 14653 14654 14655@geindex gccjit;;function (C++ class) 14656@anchor{cp/topics/functions _CPPv4N6gccjit8functionE}@anchor{18c}@anchor{cp/topics/functions _CPPv3N6gccjit8functionE}@anchor{33d}@anchor{cp/topics/functions _CPPv2N6gccjit8functionE}@anchor{33e}@anchor{cp/topics/functions gccjit function}@anchor{33f} 14657@deffn {C++ Class} gccjit::function 14658 14659A @cite{gccjit::function} represents a function - either one that we���re 14660creating ourselves, or one that we���re referencing. 14661@end deffn 14662 14663@geindex gccjit;;context;;new_function (C++ function) 14664@anchor{cp/topics/functions _CPPv4N6gccjit7context12new_functionE21gcc_jit_function_kindN6gccjit4typeEPKcRNSt6vectorI5paramEEiN6gccjit8locationE}@anchor{340}@anchor{cp/topics/functions _CPPv3N6gccjit7context12new_functionE21gcc_jit_function_kindN6gccjit4typeEPKcRNSt6vectorI5paramEEiN6gccjit8locationE}@anchor{341}@anchor{cp/topics/functions _CPPv2N6gccjit7context12new_functionE21gcc_jit_function_kindN6gccjit4typeEPKcRNSt6vectorI5paramEEiN6gccjit8locationE}@anchor{342}@anchor{cp/topics/functions gccjit context new_function__gcc_jit_function_kind gccjit type cCP std vector param R i gccjit location}@anchor{343} 14665@deffn {C++ Function} gccjit::@ref{18c,,function} gccjit::@ref{175,,context}::new_function (enum gcc_jit_function_kind, gccjit::type return_type, const char *name, std::vector<param> ¶ms, int is_variadic, gccjit::location loc) 14666 14667Create a gcc_jit_function with the given name and parameters. 14668 14669Parameters ���is_variadic��� and ���loc��� are optional. 14670 14671This is a wrapper around the C API���s @ref{11,,gcc_jit_context_new_function()}. 14672@end deffn 14673 14674@geindex gccjit;;context;;get_builtin_function (C++ function) 14675@anchor{cp/topics/functions _CPPv4N6gccjit7context20get_builtin_functionEPKc}@anchor{344}@anchor{cp/topics/functions _CPPv3N6gccjit7context20get_builtin_functionEPKc}@anchor{345}@anchor{cp/topics/functions _CPPv2N6gccjit7context20get_builtin_functionEPKc}@anchor{346}@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{347} 14676@deffn {C++ Function} gccjit::@ref{18c,,function} gccjit::@ref{175,,context}::get_builtin_function (const char *name) 14677 14678This is a wrapper around the C API���s 14679@ref{10e,,gcc_jit_context_get_builtin_function()}. 14680@end deffn 14681 14682@geindex gccjit;;function;;get_param (C++ function) 14683@anchor{cp/topics/functions _CPPv4NK6gccjit8function9get_paramEi}@anchor{348}@anchor{cp/topics/functions _CPPv3NK6gccjit8function9get_paramEi}@anchor{349}@anchor{cp/topics/functions _CPPv2NK6gccjit8function9get_paramEi}@anchor{34a}@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{34b} 14684@deffn {C++ Function} gccjit::@ref{188,,param} gccjit::@ref{18c,,function}::get_param (int index) const 14685 14686Get the param of the given index (0-based). 14687@end deffn 14688 14689@geindex gccjit;;function;;dump_to_dot (C++ function) 14690@anchor{cp/topics/functions _CPPv4N6gccjit8function11dump_to_dotEPKc}@anchor{194}@anchor{cp/topics/functions _CPPv3N6gccjit8function11dump_to_dotEPKc}@anchor{34c}@anchor{cp/topics/functions _CPPv2N6gccjit8function11dump_to_dotEPKc}@anchor{34d}@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{34e} 14691@deffn {C++ Function} void gccjit::@ref{18c,,function}::dump_to_dot (const char *path) 14692 14693Emit the function in graphviz format to the given path. 14694@end deffn 14695 14696@geindex gccjit;;function;;new_local (C++ function) 14697@anchor{cp/topics/functions _CPPv4N6gccjit8function9new_localEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{189}@anchor{cp/topics/functions _CPPv3N6gccjit8function9new_localEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{34f}@anchor{cp/topics/functions _CPPv2N6gccjit8function9new_localEN6gccjit4typeEPKcN6gccjit8locationE}@anchor{350}@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{351} 14698@deffn {C++ Function} gccjit::@ref{187,,lvalue} gccjit::@ref{18c,,function}::new_local (gccjit::type type, const char *name, gccjit::location loc) 14699 14700Create a new local variable within the function, of the given type and 14701name. 14702@end deffn 14703 14704@node Blocks<2>,Statements<2>,Functions<2>,Creating and using functions<2> 14705@anchor{cp/topics/functions blocks}@anchor{352} 14706@subsubsection Blocks 14707 14708 14709@geindex gccjit;;block (C++ class) 14710@anchor{cp/topics/functions _CPPv4N6gccjit5blockE}@anchor{18b}@anchor{cp/topics/functions _CPPv3N6gccjit5blockE}@anchor{353}@anchor{cp/topics/functions _CPPv2N6gccjit5blockE}@anchor{354}@anchor{cp/topics/functions gccjit block}@anchor{355} 14711@deffn {C++ Class} gccjit::block 14712 14713A @cite{gccjit::block} represents a basic block within a function i.e. a 14714sequence of statements with a single entry point and a single exit 14715point. 14716 14717@ref{18b,,gccjit;;block} is a subclass of @ref{17a,,gccjit;;object}. 14718 14719The first basic block that you create within a function will 14720be the entrypoint. 14721 14722Each basic block that you create within a function must be 14723terminated, either with a conditional, a jump, a return, or 14724a switch. 14725 14726It���s legal to have multiple basic blocks that return within 14727one function. 14728@end deffn 14729 14730@geindex gccjit;;function;;new_block (C++ function) 14731@anchor{cp/topics/functions _CPPv4N6gccjit8function9new_blockEPKc}@anchor{356}@anchor{cp/topics/functions _CPPv3N6gccjit8function9new_blockEPKc}@anchor{357}@anchor{cp/topics/functions _CPPv2N6gccjit8function9new_blockEPKc}@anchor{358}@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{359} 14732@deffn {C++ Function} gccjit::@ref{18b,,block} gccjit::@ref{18c,,function}::new_block (const char *name) 14733 14734Create a basic block of the given name. The name may be NULL, but 14735providing meaningful names is often helpful when debugging: it may 14736show up in dumps of the internal representation, and in error 14737messages. 14738@end deffn 14739 14740@node Statements<2>,,Blocks<2>,Creating and using functions<2> 14741@anchor{cp/topics/functions statements}@anchor{35a} 14742@subsubsection Statements 14743 14744 14745@geindex gccjit;;block;;add_eval (C++ function) 14746@anchor{cp/topics/functions _CPPv4N6gccjit5block8add_evalEN6gccjit6rvalueEN6gccjit8locationE}@anchor{302}@anchor{cp/topics/functions _CPPv3N6gccjit5block8add_evalEN6gccjit6rvalueEN6gccjit8locationE}@anchor{35b}@anchor{cp/topics/functions _CPPv2N6gccjit5block8add_evalEN6gccjit6rvalueEN6gccjit8locationE}@anchor{35c}@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{35d} 14747@deffn {C++ Function} void gccjit::@ref{18b,,block}::add_eval (gccjit::rvalue rvalue, gccjit::location loc) 14748 14749Add evaluation of an rvalue, discarding the result 14750(e.g. a function call that ���returns��� void). 14751 14752This is equivalent to this C code: 14753 14754@example 14755(void)expression; 14756@end example 14757@end deffn 14758 14759@geindex gccjit;;block;;add_assignment (C++ function) 14760@anchor{cp/topics/functions _CPPv4N6gccjit5block14add_assignmentEN6gccjit6lvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{18d}@anchor{cp/topics/functions _CPPv3N6gccjit5block14add_assignmentEN6gccjit6lvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{35e}@anchor{cp/topics/functions _CPPv2N6gccjit5block14add_assignmentEN6gccjit6lvalueEN6gccjit6rvalueEN6gccjit8locationE}@anchor{35f}@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{360} 14761@deffn {C++ Function} void gccjit::@ref{18b,,block}::add_assignment (gccjit::lvalue lvalue, gccjit::rvalue rvalue, gccjit::location loc) 14762 14763Add evaluation of an rvalue, assigning the result to the given 14764lvalue. 14765 14766This is roughly equivalent to this C code: 14767 14768@example 14769lvalue = rvalue; 14770@end example 14771@end deffn 14772 14773@geindex gccjit;;block;;add_assignment_op (C++ function) 14774@anchor{cp/topics/functions _CPPv4N6gccjit5block17add_assignment_opEN6gccjit6lvalueE17gcc_jit_binary_opN6gccjit6rvalueEN6gccjit8locationE}@anchor{191}@anchor{cp/topics/functions _CPPv3N6gccjit5block17add_assignment_opEN6gccjit6lvalueE17gcc_jit_binary_opN6gccjit6rvalueEN6gccjit8locationE}@anchor{361}@anchor{cp/topics/functions _CPPv2N6gccjit5block17add_assignment_opEN6gccjit6lvalueE17gcc_jit_binary_opN6gccjit6rvalueEN6gccjit8locationE}@anchor{362}@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue gcc_jit_binary_op gccjit rvalue gccjit location}@anchor{363} 14775@deffn {C++ Function} void gccjit::@ref{18b,,block}::add_assignment_op (gccjit::lvalue lvalue, enum gcc_jit_binary_op, gccjit::rvalue rvalue, gccjit::location loc) 14776 14777Add evaluation of an rvalue, using the result to modify an 14778lvalue. 14779 14780This is analogous to ���+=��� and friends: 14781 14782@example 14783lvalue += rvalue; 14784lvalue *= rvalue; 14785lvalue /= rvalue; 14786@end example 14787 14788etc. For example: 14789 14790@example 14791/* "i++" */ 14792loop_body.add_assignment_op ( 14793 i, 14794 GCC_JIT_BINARY_OP_PLUS, 14795 ctxt.one (int_type)); 14796@end example 14797@end deffn 14798 14799@geindex gccjit;;block;;add_comment (C++ function) 14800@anchor{cp/topics/functions _CPPv4N6gccjit5block11add_commentEPKcN6gccjit8locationE}@anchor{19d}@anchor{cp/topics/functions _CPPv3N6gccjit5block11add_commentEPKcN6gccjit8locationE}@anchor{364}@anchor{cp/topics/functions _CPPv2N6gccjit5block11add_commentEPKcN6gccjit8locationE}@anchor{365}@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{366} 14801@deffn {C++ Function} void gccjit::@ref{18b,,block}::add_comment (const char *text, gccjit::location loc) 14802 14803Add a no-op textual comment to the internal representation of the 14804code. It will be optimized away, but will be visible in the dumps 14805seen via @ref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} 14806and @ref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, 14807and thus may be of use when debugging how your project���s internal 14808representation gets converted to the libgccjit IR. 14809 14810Parameter ���loc��� is optional. 14811@end deffn 14812 14813@geindex gccjit;;block;;end_with_conditional (C++ function) 14814@anchor{cp/topics/functions _CPPv4N6gccjit5block20end_with_conditionalEN6gccjit6rvalueEN6gccjit5blockEN6gccjit5blockEN6gccjit8locationE}@anchor{190}@anchor{cp/topics/functions _CPPv3N6gccjit5block20end_with_conditionalEN6gccjit6rvalueEN6gccjit5blockEN6gccjit5blockEN6gccjit8locationE}@anchor{367}@anchor{cp/topics/functions _CPPv2N6gccjit5block20end_with_conditionalEN6gccjit6rvalueEN6gccjit5blockEN6gccjit5blockEN6gccjit8locationE}@anchor{368}@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{369} 14815@deffn {C++ Function} void gccjit::@ref{18b,,block}::end_with_conditional (gccjit::rvalue boolval, gccjit::block on_true, gccjit::block on_false, gccjit::location loc) 14816 14817Terminate a block by adding evaluation of an rvalue, branching on the 14818result to the appropriate successor block. 14819 14820This is roughly equivalent to this C code: 14821 14822@example 14823if (boolval) 14824 goto on_true; 14825else 14826 goto on_false; 14827@end example 14828 14829block, boolval, on_true, and on_false must be non-NULL. 14830@end deffn 14831 14832@geindex gccjit;;block;;end_with_jump (C++ function) 14833@anchor{cp/topics/functions _CPPv4N6gccjit5block13end_with_jumpEN6gccjit5blockEN6gccjit8locationE}@anchor{36a}@anchor{cp/topics/functions _CPPv3N6gccjit5block13end_with_jumpEN6gccjit5blockEN6gccjit8locationE}@anchor{36b}@anchor{cp/topics/functions _CPPv2N6gccjit5block13end_with_jumpEN6gccjit5blockEN6gccjit8locationE}@anchor{36c}@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{36d} 14834@deffn {C++ Function} void gccjit::@ref{18b,,block}::end_with_jump (gccjit::block target, gccjit::location loc) 14835 14836Terminate a block by adding a jump to the given target block. 14837 14838This is roughly equivalent to this C code: 14839 14840@example 14841goto target; 14842@end example 14843@end deffn 14844 14845@geindex gccjit;;block;;end_with_return (C++ function) 14846@anchor{cp/topics/functions _CPPv4N6gccjit5block15end_with_returnEN6gccjit6rvalueEN6gccjit8locationE}@anchor{36e}@anchor{cp/topics/functions _CPPv3N6gccjit5block15end_with_returnEN6gccjit6rvalueEN6gccjit8locationE}@anchor{36f}@anchor{cp/topics/functions _CPPv2N6gccjit5block15end_with_returnEN6gccjit6rvalueEN6gccjit8locationE}@anchor{370}@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{371} 14847@deffn {C++ Function} void gccjit::@ref{18b,,block}::end_with_return (gccjit::rvalue rvalue, gccjit::location loc) 14848 14849Terminate a block. 14850 14851Both params are optional. 14852 14853An rvalue must be provided for a function returning non-void, and 14854must not be provided by a function ���returning��� @cite{void}. 14855 14856If an rvalue is provided, the block is terminated by evaluating the 14857rvalue and returning the value. 14858 14859This is roughly equivalent to this C code: 14860 14861@example 14862return expression; 14863@end example 14864 14865If an rvalue is not provided, the block is terminated by adding a 14866valueless return, for use within a function with ���void��� return type. 14867 14868This is equivalent to this C code: 14869 14870@example 14871return; 14872@end example 14873@end deffn 14874 14875@geindex gccjit;;block;;end_with_switch (C++ function) 14876@anchor{cp/topics/functions _CPPv4N6gccjit5block15end_with_switchEN6gccjit6rvalueEN6gccjit5blockENSt6vectorIN6gccjit5case_EEEN6gccjit8locationE}@anchor{372}@anchor{cp/topics/functions _CPPv3N6gccjit5block15end_with_switchEN6gccjit6rvalueEN6gccjit5blockENSt6vectorIN6gccjit5case_EEEN6gccjit8locationE}@anchor{373}@anchor{cp/topics/functions _CPPv2N6gccjit5block15end_with_switchEN6gccjit6rvalueEN6gccjit5blockENSt6vectorIN6gccjit5case_EEEN6gccjit8locationE}@anchor{374}@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{375} 14877@deffn {C++ Function} void gccjit::@ref{18b,,block}::end_with_switch (gccjit::rvalue expr, gccjit::block default_block, std::vector<gccjit::case_> cases, gccjit::location loc) 14878 14879Terminate a block by adding evalation of an rvalue, then performing 14880a multiway branch. 14881 14882This is roughly equivalent to this C code: 14883 14884@example 14885switch (expr) 14886 @{ 14887 default: 14888 goto default_block; 14889 14890 case C0.min_value ... C0.max_value: 14891 goto C0.dest_block; 14892 14893 case C1.min_value ... C1.max_value: 14894 goto C1.dest_block; 14895 14896 ...etc... 14897 14898 case C[N - 1].min_value ... C[N - 1].max_value: 14899 goto C[N - 1].dest_block; 14900@} 14901@end example 14902 14903@code{expr} must be of the same integer type as all of the @code{min_value} 14904and @code{max_value} within the cases. 14905 14906The ranges of the cases must not overlap (or have duplicate 14907values). 14908 14909The API entrypoints relating to switch statements and cases: 14910 14911@quotation 14912 14913 14914@itemize * 14915 14916@item 14917@ref{372,,gccjit;;block;;end_with_switch()} 14918 14919@item 14920@code{gccjit::context::new_case()} 14921@end itemize 14922@end quotation 14923 14924were added in @ref{11f,,LIBGCCJIT_ABI_3}; you can test for their presence 14925using 14926 14927@example 14928#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 14929@end example 14930 14931A @cite{gccjit::case_} represents a case within a switch statement, and 14932is created within a particular @ref{175,,gccjit;;context} using 14933@code{gccjit::context::new_case()}. It is a subclass of 14934@ref{17a,,gccjit;;object}. 14935 14936Each case expresses a multivalued range of integer values. You 14937can express single-valued cases by passing in the same value for 14938both @cite{min_value} and @cite{max_value}. 14939 14940Here���s an example of creating a switch statement: 14941 14942@quotation 14943 14944@example 14945 14946void 14947create_code (gcc_jit_context *c_ctxt, void *user_data) 14948@{ 14949 /* Let's try to inject the equivalent of: 14950 int 14951 test_switch (int x) 14952 @{ 14953 switch (x) 14954 @{ 14955 case 0 ... 5: 14956 return 3; 14957 14958 case 25 ... 27: 14959 return 4; 14960 14961 case -42 ... -17: 14962 return 83; 14963 14964 case 40: 14965 return 8; 14966 14967 default: 14968 return 10; 14969 @} 14970 @} 14971 */ 14972 gccjit::context ctxt (c_ctxt); 14973 gccjit::type t_int = ctxt.get_type (GCC_JIT_TYPE_INT); 14974 gccjit::type return_type = t_int; 14975 gccjit::param x = ctxt.new_param (t_int, "x"); 14976 std::vector <gccjit::param> params; 14977 params.push_back (x); 14978 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 14979 return_type, 14980 "test_switch", 14981 params, 0); 14982 14983 gccjit::block b_initial = func.new_block ("initial"); 14984 14985 gccjit::block b_default = func.new_block ("default"); 14986 gccjit::block b_case_0_5 = func.new_block ("case_0_5"); 14987 gccjit::block b_case_25_27 = func.new_block ("case_25_27"); 14988 gccjit::block b_case_m42_m17 = func.new_block ("case_m42_m17"); 14989 gccjit::block b_case_40 = func.new_block ("case_40"); 14990 14991 std::vector <gccjit::case_> cases; 14992 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 0), 14993 ctxt.new_rvalue (t_int, 5), 14994 b_case_0_5)); 14995 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 25), 14996 ctxt.new_rvalue (t_int, 27), 14997 b_case_25_27)); 14998 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, -42), 14999 ctxt.new_rvalue (t_int, -17), 15000 b_case_m42_m17)); 15001 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 40), 15002 ctxt.new_rvalue (t_int, 40), 15003 b_case_40)); 15004 b_initial.end_with_switch (x, 15005 b_default, 15006 cases); 15007 15008 b_case_0_5.end_with_return (ctxt.new_rvalue (t_int, 3)); 15009 b_case_25_27.end_with_return (ctxt.new_rvalue (t_int, 4)); 15010 b_case_m42_m17.end_with_return (ctxt.new_rvalue (t_int, 83)); 15011 b_case_40.end_with_return (ctxt.new_rvalue (t_int, 8)); 15012 b_default.end_with_return (ctxt.new_rvalue (t_int, 10)); 15013@} 15014 15015@end example 15016@end quotation 15017@end deffn 15018 15019@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 15020@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 15021@c 15022@c This is free software: you can redistribute it and/or modify it 15023@c under the terms of the GNU General Public License as published by 15024@c the Free Software Foundation, either version 3 of the License, or 15025@c (at your option) any later version. 15026@c 15027@c This program is distributed in the hope that it will be useful, but 15028@c WITHOUT ANY WARRANTY; without even the implied warranty of 15029@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15030@c General Public License for more details. 15031@c 15032@c You should have received a copy of the GNU General Public License 15033@c along with this program. If not, see 15034@c <https://www.gnu.org/licenses/>. 15035 15036@node Source Locations<2>,Compiling a context<2>,Creating and using functions<2>,Topic Reference<2> 15037@anchor{cp/topics/locations doc}@anchor{376}@anchor{cp/topics/locations source-locations}@anchor{377} 15038@subsection Source Locations 15039 15040 15041@geindex gccjit;;location (C++ class) 15042@anchor{cp/topics/locations _CPPv4N6gccjit8locationE}@anchor{19b}@anchor{cp/topics/locations _CPPv3N6gccjit8locationE}@anchor{378}@anchor{cp/topics/locations _CPPv2N6gccjit8locationE}@anchor{379}@anchor{cp/topics/locations gccjit location}@anchor{37a} 15043@deffn {C++ Class} gccjit::location 15044 15045A @cite{gccjit::location} encapsulates a source code location, so that 15046you can (optionally) associate locations in your language with 15047statements in the JIT-compiled code, allowing the debugger to 15048single-step through your language. 15049 15050@cite{gccjit::location} instances are optional: you can always omit them 15051from any C++ API entrypoint accepting one. 15052 15053You can construct them using @ref{1a1,,gccjit;;context;;new_location()}. 15054 15055You need to enable @ref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 15056@ref{175,,gccjit;;context} for these locations to actually be usable by 15057the debugger: 15058 15059@example 15060ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1); 15061@end example 15062@end deffn 15063 15064@geindex gccjit;;context;;new_location (C++ function) 15065@anchor{cp/topics/locations _CPPv4N6gccjit7context12new_locationEPKcii}@anchor{1a1}@anchor{cp/topics/locations _CPPv3N6gccjit7context12new_locationEPKcii}@anchor{37b}@anchor{cp/topics/locations _CPPv2N6gccjit7context12new_locationEPKcii}@anchor{37c}@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{37d} 15066@deffn {C++ Function} gccjit::@ref{19b,,location} gccjit::@ref{175,,context}::new_location (const char *filename, int line, int column) 15067 15068Create a @cite{gccjit::location} instance representing the given source 15069location. 15070@end deffn 15071 15072@menu 15073* Faking it: Faking it<2>. 15074 15075@end menu 15076 15077@node Faking it<2>,,,Source Locations<2> 15078@anchor{cp/topics/locations faking-it}@anchor{37e} 15079@subsubsection Faking it 15080 15081 15082If you don���t have source code for your internal representation, but need 15083to debug, you can generate a C-like representation of the functions in 15084your context using @ref{1c0,,gccjit;;context;;dump_to_file()}: 15085 15086@example 15087ctxt.dump_to_file ("/tmp/something.c", 15088 1 /* update_locations */); 15089@end example 15090 15091This will dump C-like code to the given path. If the @cite{update_locations} 15092argument is true, this will also set up @cite{gccjit::location} information 15093throughout the context, pointing at the dump file as if it were a source 15094file, giving you @emph{something} you can step through in the debugger. 15095 15096@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 15097@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 15098@c 15099@c This is free software: you can redistribute it and/or modify it 15100@c under the terms of the GNU General Public License as published by 15101@c the Free Software Foundation, either version 3 of the License, or 15102@c (at your option) any later version. 15103@c 15104@c This program is distributed in the hope that it will be useful, but 15105@c WITHOUT ANY WARRANTY; without even the implied warranty of 15106@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15107@c General Public License for more details. 15108@c 15109@c You should have received a copy of the GNU General Public License 15110@c along with this program. If not, see 15111@c <https://www.gnu.org/licenses/>. 15112 15113@node Compiling a context<2>,Using Assembly Language with libgccjit++,Source Locations<2>,Topic Reference<2> 15114@anchor{cp/topics/compilation doc}@anchor{37f}@anchor{cp/topics/compilation compiling-a-context}@anchor{380} 15115@subsection Compiling a context 15116 15117 15118Once populated, a @ref{175,,gccjit;;context} can be compiled to 15119machine code, either in-memory via @ref{17f,,gccjit;;context;;compile()} or 15120to disk via @ref{381,,gccjit;;context;;compile_to_file()}. 15121 15122You can compile a context multiple times (using either form of 15123compilation), although any errors that occur on the context will 15124prevent any future compilation of that context. 15125 15126@menu 15127* In-memory compilation: In-memory compilation<2>. 15128* Ahead-of-time compilation: Ahead-of-time compilation<2>. 15129 15130@end menu 15131 15132@node In-memory compilation<2>,Ahead-of-time compilation<2>,,Compiling a context<2> 15133@anchor{cp/topics/compilation in-memory-compilation}@anchor{382} 15134@subsubsection In-memory compilation 15135 15136 15137@geindex gccjit;;context;;compile (C++ function) 15138@anchor{cp/topics/compilation _CPPv4N6gccjit7context7compileEv}@anchor{17f}@anchor{cp/topics/compilation _CPPv3N6gccjit7context7compileEv}@anchor{383}@anchor{cp/topics/compilation _CPPv2N6gccjit7context7compileEv}@anchor{384}@anchor{cp/topics/compilation gccjit context compile}@anchor{385} 15139@deffn {C++ Function} gcc_jit_result *gccjit::@ref{175,,context}::compile () 15140 15141This calls into GCC and builds the code, returning a 15142@cite{gcc_jit_result *}. 15143 15144This is a thin wrapper around the 15145@ref{15,,gcc_jit_context_compile()} API entrypoint. 15146@end deffn 15147 15148@node Ahead-of-time compilation<2>,,In-memory compilation<2>,Compiling a context<2> 15149@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{386} 15150@subsubsection Ahead-of-time compilation 15151 15152 15153Although libgccjit is primarily aimed at just-in-time compilation, it 15154can also be used for implementing more traditional ahead-of-time 15155compilers, via the @ref{381,,gccjit;;context;;compile_to_file()} method. 15156 15157@geindex gccjit;;context;;compile_to_file (C++ function) 15158@anchor{cp/topics/compilation _CPPv4N6gccjit7context15compile_to_fileE19gcc_jit_output_kindPKc}@anchor{381}@anchor{cp/topics/compilation _CPPv3N6gccjit7context15compile_to_fileE19gcc_jit_output_kindPKc}@anchor{387}@anchor{cp/topics/compilation _CPPv2N6gccjit7context15compile_to_fileE19gcc_jit_output_kindPKc}@anchor{388}@anchor{cp/topics/compilation gccjit context compile_to_file__gcc_jit_output_kind cCP}@anchor{389} 15159@deffn {C++ Function} void gccjit::@ref{175,,context}::compile_to_file (enum gcc_jit_output_kind, const char *output_path) 15160 15161Compile the @ref{175,,gccjit;;context} to a file of the given 15162kind. 15163 15164This is a thin wrapper around the 15165@ref{4a,,gcc_jit_context_compile_to_file()} API entrypoint. 15166@end deffn 15167 15168@c Copyright (C) 2020-2022 Free Software Foundation, Inc. 15169@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 15170@c 15171@c This is free software: you can redistribute it and/or modify it 15172@c under the terms of the GNU General Public License as published by 15173@c the Free Software Foundation, either version 3 of the License, or 15174@c (at your option) any later version. 15175@c 15176@c This program is distributed in the hope that it will be useful, but 15177@c WITHOUT ANY WARRANTY; without even the implied warranty of 15178@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15179@c General Public License for more details. 15180@c 15181@c You should have received a copy of the GNU General Public License 15182@c along with this program. If not, see 15183@c <https://www.gnu.org/licenses/>. 15184 15185@node Using Assembly Language with libgccjit++,,Compiling a context<2>,Topic Reference<2> 15186@anchor{cp/topics/asm doc}@anchor{38a}@anchor{cp/topics/asm using-assembly-language-with-libgccjit}@anchor{38b} 15187@subsection Using Assembly Language with libgccjit++ 15188 15189 15190libgccjit has some support for directly embedding assembler instructions. 15191This is based on GCC���s support for inline @code{asm} in C code, and the 15192following assumes a familiarity with that functionality. See 15193How to Use Inline Assembly Language in C Code@footnote{https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html} 15194in GCC���s documentation, the ���Extended Asm��� section in particular. 15195 15196These entrypoints were added in @ref{151,,LIBGCCJIT_ABI_15}; you can test 15197for their presence using 15198 15199@quotation 15200 15201@example 15202#ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS 15203@end example 15204@end quotation 15205 15206@menu 15207* Adding assembler instructions within a function: Adding assembler instructions within a function<2>. 15208* Adding top-level assembler statements: Adding top-level assembler statements<2>. 15209 15210@end menu 15211 15212@node Adding assembler instructions within a function<2>,Adding top-level assembler statements<2>,,Using Assembly Language with libgccjit++ 15213@anchor{cp/topics/asm adding-assembler-instructions-within-a-function}@anchor{38c} 15214@subsubsection Adding assembler instructions within a function 15215 15216 15217@geindex gccjit;;extended_asm (C++ class) 15218@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asmE}@anchor{38d}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asmE}@anchor{38e}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asmE}@anchor{38f}@anchor{cp/topics/asm gccjit extended_asm}@anchor{390} 15219@deffn {C++ Class} gccjit::extended_asm 15220 15221A @cite{gccjit::extended_asm} represents an extended @code{asm} statement: a 15222series of low-level instructions inside a function that convert inputs 15223to outputs. 15224 15225@ref{38d,,gccjit;;extended_asm} is a subclass of @ref{17a,,gccjit;;object}. 15226It is a thin wrapper around the C API���s @ref{120,,gcc_jit_extended_asm *}. 15227 15228To avoid having an API entrypoint with a very large number of 15229parameters, an extended @code{asm} statement is made in stages: 15230an initial call to create the @ref{38d,,gccjit;;extended_asm}, 15231followed by calls to add operands and set other properties of the 15232statement. 15233 15234There are two API entrypoints for creating a @ref{38d,,gccjit;;extended_asm}: 15235 15236 15237@itemize * 15238 15239@item 15240@ref{391,,gccjit;;block;;add_extended_asm()} for an @code{asm} statement with 15241no control flow, and 15242 15243@item 15244@ref{392,,gccjit;;block;;end_with_extended_asm_goto()} for an @code{asm goto}. 15245@end itemize 15246 15247For example, to create the equivalent of: 15248 15249@example 15250 asm ("mov %1, %0\n\t" 15251 "add $1, %0" 15252 : "=r" (dst) 15253 : "r" (src)); 15254@end example 15255 15256the following API calls could be used: 15257 15258@example 15259 block.add_extended_asm ("mov %1, %0\n\t" 15260 "add $1, %0") 15261 .add_output_operand ("=r", dst) 15262 .add_input_operand ("r", src); 15263@end example 15264 15265@cartouche 15266@quotation Warning 15267When considering the numbering of operands within an 15268extended @code{asm} statement (e.g. the @code{%0} and @code{%1} 15269above), the equivalent to the C syntax is followed i.e. all 15270output operands, then all input operands, regardless of 15271what order the calls to 15272@ref{393,,gccjit;;extended_asm;;add_output_operand()} and 15273@ref{394,,gccjit;;extended_asm;;add_input_operand()} were made in. 15274@end quotation 15275@end cartouche 15276 15277As in the C syntax, operands can be given symbolic names to avoid having 15278to number them. For example, to create the equivalent of: 15279 15280@example 15281 asm ("bsfl %[aMask], %[aIndex]" 15282 : [aIndex] "=r" (Index) 15283 : [aMask] "r" (Mask) 15284 : "cc"); 15285@end example 15286 15287the following API calls could be used: 15288 15289@example 15290 block.add_extended_asm ("bsfl %[aMask], %[aIndex]") 15291 .add_output_operand ("aIndex", "=r", index) 15292 .add_input_operand ("aMask", "r", mask) 15293 .add_clobber ("cc"); 15294@end example 15295@end deffn 15296 15297@geindex gccjit;;block;;add_extended_asm (C++ function) 15298@anchor{cp/topics/asm _CPPv4N6gccjit5block16add_extended_asmERKNSt6stringEN6gccjit8locationE}@anchor{391}@anchor{cp/topics/asm _CPPv3N6gccjit5block16add_extended_asmERKNSt6stringEN6gccjit8locationE}@anchor{395}@anchor{cp/topics/asm _CPPv2N6gccjit5block16add_extended_asmERKNSt6stringEN6gccjit8locationE}@anchor{396}@anchor{cp/topics/asm gccjit block add_extended_asm__ssCR gccjit location}@anchor{397} 15299@deffn {C++ Function} @ref{38d,,extended_asm} gccjit::@ref{18b,,block}::add_extended_asm (const std::string &asm_template, gccjit::location loc = location()) 15300 15301Create a @ref{38d,,gccjit;;extended_asm} for an extended @code{asm} statement 15302with no control flow (i.e. without the @code{goto} qualifier). 15303 15304The parameter @code{asm_template} corresponds to the @cite{AssemblerTemplate} 15305within C���s extended @code{asm} syntax. It must be non-NULL. The call takes 15306a copy of the underlying string, so it is valid to pass in a pointer to 15307an on-stack buffer. 15308@end deffn 15309 15310@geindex gccjit;;block;;end_with_extended_asm_goto (C++ function) 15311@anchor{cp/topics/asm _CPPv4N6gccjit5block26end_with_extended_asm_gotoERKNSt6stringENSt6vectorI5blockEEP5block8location}@anchor{392}@anchor{cp/topics/asm _CPPv3N6gccjit5block26end_with_extended_asm_gotoERKNSt6stringENSt6vectorI5blockEEP5block8location}@anchor{398}@anchor{cp/topics/asm _CPPv2N6gccjit5block26end_with_extended_asm_gotoERKNSt6stringENSt6vectorI5blockEEP5block8location}@anchor{399}@anchor{cp/topics/asm gccjit block end_with_extended_asm_goto__ssCR std vector block blockP location}@anchor{39a} 15312@deffn {C++ Function} @ref{38d,,extended_asm} gccjit::@ref{18b,,block}::end_with_extended_asm_goto (const std::string &asm_template, std::vector<block> goto_blocks, block *fallthrough_block, location loc = location()) 15313 15314Create a @ref{38d,,gccjit;;extended_asm} for an extended @code{asm} statement 15315that may perform jumps, and use it to terminate the given block. 15316This is equivalent to the @code{goto} qualifier in C���s extended @code{asm} 15317syntax. 15318 15319For example, to create the equivalent of: 15320 15321@example 15322 asm goto ("btl %1, %0\n\t" 15323 "jc %l[carry]" 15324 : // No outputs 15325 : "r" (p1), "r" (p2) 15326 : "cc" 15327 : carry); 15328@end example 15329 15330the following API calls could be used: 15331 15332@example 15333 const char *asm_template = 15334 (use_name 15335 ? /* Label referred to by name: "%l[carry]". */ 15336 ("btl %1, %0\n\t" 15337 "jc %l[carry]") 15338 : /* Label referred to numerically: "%l2". */ 15339 ("btl %1, %0\n\t" 15340 "jc %l2")); 15341 15342 std::vector<gccjit::block> goto_blocks (@{b_carry@}); 15343 gccjit::extended_asm ext_asm 15344 = (b_start.end_with_extended_asm_goto (asm_template, 15345 goto_blocks, 15346 &b_fallthru) 15347 .add_input_operand ("r", p1) 15348 .add_input_operand ("r", p2) 15349 .add_clobber ("cc")); 15350@end example 15351 15352here referencing a @code{gcc_jit_block} named ���carry���. 15353 15354@code{num_goto_blocks} corresponds to the @code{GotoLabels} parameter within C���s 15355extended @code{asm} syntax. The block names can be referenced within the 15356assembler template. 15357 15358@code{fallthrough_block} can be NULL. If non-NULL, it specifies the block 15359to fall through to after the statement. 15360 15361@cartouche 15362@quotation Note 15363This is needed since each @ref{18b,,gccjit;;block} must have a 15364single exit point, as a basic block: you can���t jump from the 15365middle of a block. A ���goto��� is implicitly added after the 15366asm to handle the fallthrough case, which is equivalent to what 15367would have happened in the C case. 15368@end quotation 15369@end cartouche 15370@end deffn 15371 15372@geindex gccjit;;extended_asm;;set_volatile_flag (C++ function) 15373@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm17set_volatile_flagEb}@anchor{39b}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm17set_volatile_flagEb}@anchor{39c}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm17set_volatile_flagEb}@anchor{39d}@anchor{cp/topics/asm gccjit extended_asm set_volatile_flag__b}@anchor{39e} 15374@deffn {C++ Function} gccjit::@ref{38d,,extended_asm} &gccjit::@ref{38d,,extended_asm}::set_volatile_flag (bool flag) 15375 15376Set whether the @ref{38d,,gccjit;;extended_asm} has side-effects, equivalent to the 15377volatile@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile} 15378qualifier in C���s extended asm syntax. 15379 15380For example, to create the equivalent of: 15381 15382@example 15383asm volatile ("rdtsc\n\t" // Returns the time in EDX:EAX. 15384 "shl $32, %%rdx\n\t" // Shift the upper bits left. 15385 "or %%rdx, %0" // 'Or' in the lower bits. 15386 : "=a" (msr) 15387 : 15388 : "rdx"); 15389@end example 15390 15391the following API calls could be used: 15392 15393@example 15394 gccjit::extended_asm ext_asm 15395 = block.add_extended_asm 15396 ("rdtsc\n\t" /* Returns the time in EDX:EAX. */ 15397 "shl $32, %%rdx\n\t" /* Shift the upper bits left. */ 15398 "or %%rdx, %0") /* 'Or' in the lower bits. */ 15399 .set_volatile_flag (true) 15400 .add_output_operand ("=a", msr) 15401 .add_clobber ("rdx"); 15402@end example 15403 15404where the @ref{38d,,gccjit;;extended_asm} is flagged as volatile. 15405@end deffn 15406 15407@geindex gccjit;;extended_asm;;set_inline_flag (C++ function) 15408@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm15set_inline_flagEb}@anchor{39f}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm15set_inline_flagEb}@anchor{3a0}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm15set_inline_flagEb}@anchor{3a1}@anchor{cp/topics/asm gccjit extended_asm set_inline_flag__b}@anchor{3a2} 15409@deffn {C++ Function} gccjit::@ref{38d,,extended_asm} &gccjit::@ref{38d,,extended_asm}::set_inline_flag (bool flag) 15410 15411Set the equivalent of the 15412inline@footnote{https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm} 15413qualifier in C���s extended @code{asm} syntax. 15414@end deffn 15415 15416@geindex gccjit;;extended_asm;;add_output_operand (C++ function) 15417@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm18add_output_operandERKNSt6stringERKNSt6stringEN6gccjit6lvalueE}@anchor{393}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm18add_output_operandERKNSt6stringERKNSt6stringEN6gccjit6lvalueE}@anchor{3a3}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm18add_output_operandERKNSt6stringERKNSt6stringEN6gccjit6lvalueE}@anchor{3a4}@anchor{cp/topics/asm gccjit extended_asm add_output_operand__ssCR ssCR gccjit lvalue}@anchor{3a5} 15418@deffn {C++ Function} gccjit::@ref{38d,,extended_asm} &gccjit::@ref{38d,,extended_asm}::add_output_operand (const std::string &asm_symbolic_name, const std::string &constraint, gccjit::lvalue dest) 15419 15420Add an output operand to the extended @code{asm} statement. See the 15421Output Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands} 15422section of the documentation of the C syntax. 15423 15424@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component of 15425C���s extended @code{asm} syntax, and specifies the symbolic name for the operand. 15426See the overload below for an alternative that does not supply a symbolic 15427name. 15428 15429@code{constraint} corresponds to the @code{constraint} component of C���s extended 15430@code{asm} syntax. 15431 15432@code{dest} corresponds to the @code{cvariablename} component of C���s extended 15433@code{asm} syntax. 15434 15435@example 15436// Example with a symbolic name ("aIndex"), the equivalent of: 15437// : [aIndex] "=r" (index) 15438ext_asm.add_output_operand ("aIndex", "=r", index); 15439@end example 15440 15441This function can���t be called on an @code{asm goto} as such instructions can���t 15442have outputs; see the 15443Goto Labels@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels} 15444section of GCC���s ���Extended Asm��� documentation. 15445@end deffn 15446 15447@geindex gccjit;;extended_asm;;add_output_operand (C++ function) 15448@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm18add_output_operandERKNSt6stringEN6gccjit6lvalueE}@anchor{3a6}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm18add_output_operandERKNSt6stringEN6gccjit6lvalueE}@anchor{3a7}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm18add_output_operandERKNSt6stringEN6gccjit6lvalueE}@anchor{3a8}@anchor{cp/topics/asm gccjit extended_asm add_output_operand__ssCR gccjit lvalue}@anchor{3a9} 15449@deffn {C++ Function} gccjit::@ref{38d,,extended_asm} &gccjit::@ref{38d,,extended_asm}::add_output_operand (const std::string &constraint, gccjit::lvalue dest) 15450 15451As above, but don���t supply a symbolic name for the operand. 15452 15453@example 15454// Example without a symbolic name, the equivalent of: 15455// : "=r" (dst) 15456ext_asm.add_output_operand ("=r", dst); 15457@end example 15458@end deffn 15459 15460@geindex gccjit;;extended_asm;;add_input_operand (C++ function) 15461@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm17add_input_operandERKNSt6stringERKNSt6stringEN6gccjit6rvalueE}@anchor{394}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm17add_input_operandERKNSt6stringERKNSt6stringEN6gccjit6rvalueE}@anchor{3aa}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm17add_input_operandERKNSt6stringERKNSt6stringEN6gccjit6rvalueE}@anchor{3ab}@anchor{cp/topics/asm gccjit extended_asm add_input_operand__ssCR ssCR gccjit rvalue}@anchor{3ac} 15462@deffn {C++ Function} gccjit::@ref{38d,,extended_asm} &gccjit::@ref{38d,,extended_asm}::add_input_operand (const std::string &asm_symbolic_name, const std::string &constraint, gccjit::rvalue src) 15463 15464Add an input operand to the extended @code{asm} statement. See the 15465Input Operands@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands} 15466section of the documentation of the C syntax. 15467 15468@code{asm_symbolic_name} corresponds to the @code{asmSymbolicName} component 15469of C���s extended @code{asm} syntax. See the overload below for an alternative 15470that does not supply a symbolic name. 15471 15472@code{constraint} corresponds to the @code{constraint} component of C���s extended 15473@code{asm} syntax. 15474 15475@code{src} corresponds to the @code{cexpression} component of C���s extended 15476@code{asm} syntax. 15477 15478@example 15479// Example with a symbolic name ("aMask"), the equivalent of: 15480// : [aMask] "r" (Mask) 15481ext_asm.add_input_operand ("aMask", "r", mask); 15482@end example 15483@end deffn 15484 15485@geindex gccjit;;extended_asm;;add_input_operand (C++ function) 15486@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm17add_input_operandERKNSt6stringEN6gccjit6rvalueE}@anchor{3ad}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm17add_input_operandERKNSt6stringEN6gccjit6rvalueE}@anchor{3ae}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm17add_input_operandERKNSt6stringEN6gccjit6rvalueE}@anchor{3af}@anchor{cp/topics/asm gccjit extended_asm add_input_operand__ssCR gccjit rvalue}@anchor{3b0} 15487@deffn {C++ Function} gccjit::@ref{38d,,extended_asm} &gccjit::@ref{38d,,extended_asm}::add_input_operand (const std::string &constraint, gccjit::rvalue src) 15488 15489As above, but don���t supply a symbolic name for the operand. 15490 15491@example 15492// Example without a symbolic name, the equivalent of: 15493// : "r" (src) 15494ext_asm.add_input_operand ("r", src); 15495@end example 15496@end deffn 15497 15498@geindex gccjit;;extended_asm;;add_clobber (C++ function) 15499@anchor{cp/topics/asm _CPPv4N6gccjit12extended_asm11add_clobberERKNSt6stringE}@anchor{3b1}@anchor{cp/topics/asm _CPPv3N6gccjit12extended_asm11add_clobberERKNSt6stringE}@anchor{3b2}@anchor{cp/topics/asm _CPPv2N6gccjit12extended_asm11add_clobberERKNSt6stringE}@anchor{3b3}@anchor{cp/topics/asm gccjit extended_asm add_clobber__ssCR}@anchor{3b4} 15500@deffn {C++ Function} gccjit::@ref{38d,,extended_asm} &gccjit::@ref{38d,,extended_asm}::add_clobber (const std::string &victim) 15501 15502Add @cite{victim} to the list of registers clobbered by the extended @code{asm} 15503statement. See the 15504Clobbers and Scratch Registers@footnote{https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#} 15505section of the documentation of the C syntax. 15506 15507Statements with multiple clobbers will require multiple calls, one per 15508clobber. 15509 15510For example: 15511 15512@example 15513ext_asm.add_clobber ("r0").add_clobber ("cc").add_clobber ("memory"); 15514@end example 15515@end deffn 15516 15517@node Adding top-level assembler statements<2>,,Adding assembler instructions within a function<2>,Using Assembly Language with libgccjit++ 15518@anchor{cp/topics/asm adding-top-level-assembler-statements}@anchor{3b5} 15519@subsubsection Adding top-level assembler statements 15520 15521 15522In addition to creating extended @code{asm} instructions within a function, 15523there is support for creating ���top-level��� assembler statements, outside 15524of any function. 15525 15526@geindex gccjit;;context;;add_top_level_asm (C++ function) 15527@anchor{cp/topics/asm _CPPv4N6gccjit7context17add_top_level_asmEPKcN6gccjit8locationE}@anchor{3b6}@anchor{cp/topics/asm _CPPv3N6gccjit7context17add_top_level_asmEPKcN6gccjit8locationE}@anchor{3b7}@anchor{cp/topics/asm _CPPv2N6gccjit7context17add_top_level_asmEPKcN6gccjit8locationE}@anchor{3b8}@anchor{cp/topics/asm gccjit context add_top_level_asm__cCP gccjit location}@anchor{3b9} 15528@deffn {C++ Function} void gccjit::@ref{175,,context}::add_top_level_asm (const char *asm_stmts, gccjit::location loc = location()) 15529 15530Create a set of top-level asm statements, analogous to those created 15531by GCC���s ���basic��� @code{asm} syntax in C at file scope. 15532 15533For example, to create the equivalent of: 15534 15535@example 15536 asm ("\t.pushsection .text\n" 15537 "\t.globl add_asm\n" 15538 "\t.type add_asm, @@function\n" 15539 "add_asm:\n" 15540 "\tmovq %rdi, %rax\n" 15541 "\tadd %rsi, %rax\n" 15542 "\tret\n" 15543 "\t.popsection\n"); 15544@end example 15545 15546the following API calls could be used: 15547 15548@example 15549 ctxt.add_top_level_asm ("\t.pushsection .text\n" 15550 "\t.globl add_asm\n" 15551 "\t.type add_asm, @@function\n" 15552 "add_asm:\n" 15553 "\tmovq %rdi, %rax\n" 15554 "\tadd %rsi, %rax\n" 15555 "\tret\n" 15556 "\t# some asm here\n" 15557 "\t.popsection\n"); 15558@end example 15559@end deffn 15560 15561@c Copyright (C) 2014-2022 Free Software Foundation, Inc. 15562@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 15563@c 15564@c This is free software: you can redistribute it and/or modify it 15565@c under the terms of the GNU General Public License as published by 15566@c the Free Software Foundation, either version 3 of the License, or 15567@c (at your option) any later version. 15568@c 15569@c This program is distributed in the hope that it will be useful, but 15570@c WITHOUT ANY WARRANTY; without even the implied warranty of 15571@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15572@c General Public License for more details. 15573@c 15574@c You should have received a copy of the GNU General Public License 15575@c along with this program. If not, see 15576@c <https://www.gnu.org/licenses/>. 15577 15578@node Internals,Indices and tables,C++ bindings for libgccjit,Top 15579@anchor{internals/index doc}@anchor{3ba}@anchor{internals/index internals}@anchor{3bb} 15580@chapter Internals 15581 15582 15583@menu 15584* Working on the JIT library:: 15585* Running the test suite:: 15586* Environment variables:: 15587* Packaging notes:: 15588* Overview of code structure:: 15589* Design notes:: 15590* Submitting patches:: 15591 15592@end menu 15593 15594@node Working on the JIT library,Running the test suite,,Internals 15595@anchor{internals/index working-on-the-jit-library}@anchor{3bc} 15596@section Working on the JIT library 15597 15598 15599Having checked out the source code (to ���src���), you can configure and build 15600the JIT library like this: 15601 15602@example 15603mkdir build 15604mkdir install 15605PREFIX=$(pwd)/install 15606cd build 15607../src/configure \ 15608 --enable-host-shared \ 15609 --enable-languages=jit,c++ \ 15610 --disable-bootstrap \ 15611 --enable-checking=release \ 15612 --prefix=$PREFIX 15613nice make -j4 # altering the "4" to however many cores you have 15614@end example 15615 15616This should build a libgccjit.so within jit/build/gcc: 15617 15618@example 15619[build] $ file gcc/libgccjit.so* 15620gcc/libgccjit.so: symbolic link to `libgccjit.so.0' 15621gcc/libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' 15622gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped 15623@end example 15624 15625Here���s what those configuration options mean: 15626 15627@geindex command line option; --enable-host-shared 15628@anchor{internals/index cmdoption-enable-host-shared}@anchor{3bd} 15629@deffn {Option} @w{-}@w{-}enable@w{-}host@w{-}shared 15630 15631Configuring with this option means that the compiler is built as 15632position-independent code, which incurs a slight performance hit, 15633but it necessary for a shared library. 15634@end deffn 15635 15636@geindex command line option; --enable-languages=jit@comma{}c++ 15637@anchor{internals/index cmdoption-enable-languages}@anchor{3be} 15638@deffn {Option} @w{-}@w{-}enable@w{-}languages=jit,c++ 15639 15640This specifies which frontends to build. The JIT library looks like 15641a frontend to the rest of the code. 15642 15643The C++ portion of the JIT test suite requires the C++ frontend to be 15644enabled at configure-time, or you may see errors like this when 15645running the test suite: 15646 15647@example 15648xgcc: error: /home/david/jit/src/gcc/testsuite/jit.dg/test-quadratic.cc: C++ compiler not installed on this system 15649c++: error trying to exec 'cc1plus': execvp: No such file or directory 15650@end example 15651@end deffn 15652 15653@geindex command line option; --disable-bootstrap 15654@anchor{internals/index cmdoption-disable-bootstrap}@anchor{3bf} 15655@deffn {Option} @w{-}@w{-}disable@w{-}bootstrap 15656 15657For hacking on the ���jit��� subdirectory, performing a full 15658bootstrap can be overkill, since it���s unused by a bootstrap. However, 15659when submitting patches, you should remove this option, to ensure that 15660the compiler can still bootstrap itself. 15661@end deffn 15662 15663@geindex command line option; --enable-checking=release 15664@anchor{internals/index cmdoption-enable-checking}@anchor{3c0} 15665@deffn {Option} @w{-}@w{-}enable@w{-}checking=release 15666 15667The compile can perform extensive self-checking as it runs, useful when 15668debugging, but slowing things down. 15669 15670For maximum speed, configure with @code{--enable-checking=release} to 15671disable this self-checking. 15672@end deffn 15673 15674@node Running the test suite,Environment variables,Working on the JIT library,Internals 15675@anchor{internals/index running-the-test-suite}@anchor{3c1} 15676@section Running the test suite 15677 15678 15679@example 15680[build] $ cd gcc 15681[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v" 15682@end example 15683 15684A summary of the tests can then be seen in: 15685 15686@example 15687jit/build/gcc/testsuite/jit/jit.sum 15688@end example 15689 15690and detailed logs in: 15691 15692@example 15693jit/build/gcc/testsuite/jit/jit.log 15694@end example 15695 15696The test executables are normally deleted after each test is run. For 15697debugging, they can be preserved by setting 15698@geindex PRESERVE_EXECUTABLES 15699@geindex environment variable; PRESERVE_EXECUTABLES 15700@code{PRESERVE_EXECUTABLES} 15701in the environment. If so, they can then be seen as: 15702 15703@example 15704jit/build/gcc/testsuite/jit/*.exe 15705@end example 15706 15707which can be run independently. 15708 15709You can compile and run individual tests by passing ���jit.exp=TESTNAME��� to RUNTESTFLAGS e.g.: 15710 15711@example 15712[gcc] $ PRESERVE_EXECUTABLES= \ 15713 make check-jit \ 15714 RUNTESTFLAGS="-v -v -v jit.exp=test-factorial.c" 15715@end example 15716 15717and once a test has been compiled, you can debug it directly: 15718 15719@example 15720[gcc] $ PATH=.:$PATH \ 15721 LD_LIBRARY_PATH=. \ 15722 LIBRARY_PATH=. \ 15723 gdb --args \ 15724 testsuite/jit/test-factorial.c.exe 15725@end example 15726 15727@menu 15728* Running under valgrind:: 15729 15730@end menu 15731 15732@node Running under valgrind,,,Running the test suite 15733@anchor{internals/index running-under-valgrind}@anchor{3c2} 15734@subsection Running under valgrind 15735 15736 15737The jit testsuite detects if 15738@geindex RUN_UNDER_VALGRIND 15739@geindex environment variable; RUN_UNDER_VALGRIND 15740@code{RUN_UNDER_VALGRIND} is present in the 15741environment (with any value). If it is present, it runs the test client 15742code under valgrind@footnote{https://valgrind.org}, 15743specifcally, the default 15744memcheck@footnote{https://valgrind.org/docs/manual/mc-manual.html} 15745tool with 15746--leak-check=full@footnote{https://valgrind.org/docs/manual/mc-manual.html#opt.leak-check}. 15747 15748It automatically parses the output from valgrind, injecting XFAIL results if 15749any issues are found, or PASS results if the output is clean. The output 15750is saved to @code{TESTNAME.exe.valgrind.txt}. 15751 15752For example, the following invocation verbosely runs the testcase 15753@code{test-sum-of-squares.c} under valgrind, showing an issue: 15754 15755@example 15756$ RUN_UNDER_VALGRIND= \ 15757 make check-jit \ 15758 RUNTESTFLAGS="-v -v -v jit.exp=test-sum-of-squares.c" 15759 15760(...verbose log contains detailed valgrind errors, if any...) 15761 15762 === jit Summary === 15763 15764# of expected passes 28 15765# of expected failures 2 15766 15767$ less testsuite/jit/jit.sum 15768(...other results...) 15769XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: definitely lost: 8 bytes in 1 blocks 15770XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: unsuppressed errors: 1 15771(...other results...) 15772 15773$ less testsuite/jit/test-sum-of-squares.c.exe.valgrind.txt 15774(...shows full valgrind report for this test case...) 15775@end example 15776 15777When running under valgrind, it���s best to have configured gcc with 15778@code{--enable-valgrind-annotations}, which automatically suppresses 15779various known false positives. 15780 15781@node Environment variables,Packaging notes,Running the test suite,Internals 15782@anchor{internals/index environment-variables}@anchor{3c3} 15783@section Environment variables 15784 15785 15786When running client code against a locally-built libgccjit, three 15787environment variables need to be set up: 15788 15789@geindex environment variable; LD_LIBRARY_PATH 15790@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{3c4} 15791@deffn {Environment Variable} LD_LIBRARY_PATH 15792 15793@quotation 15794 15795@cite{libgccjit.so} is dynamically linked into client code, so if running 15796against a locally-built library, @code{LD_LIBRARY_PATH} needs to be set 15797up appropriately. The library can be found within the ���gcc��� 15798subdirectory of the build tree: 15799@end quotation 15800 15801@example 15802$ file libgccjit.so* 15803libgccjit.so: symbolic link to `libgccjit.so.0' 15804libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' 15805libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, not stripped 15806@end example 15807@end deffn 15808 15809@geindex environment variable; PATH 15810@anchor{internals/index envvar-PATH}@anchor{3c5} 15811@deffn {Environment Variable} PATH 15812 15813The library uses a driver executable for converting from .s assembler 15814files to .so shared libraries. Specifically, it looks for a name 15815expanded from 15816@code{$@{target_noncanonical@}-gcc-$@{gcc_BASEVER@}$@{exeext@}} 15817such as @code{x86_64-unknown-linux-gnu-gcc-5.0.0}. 15818 15819Hence @code{PATH} needs to include a directory where the library can 15820locate this executable. 15821 15822The executable is normally installed to the installation bindir 15823(e.g. /usr/bin), but a copy is also created within the ���gcc��� 15824subdirectory of the build tree for running the testsuite, and for ease 15825of development. 15826@end deffn 15827 15828@geindex environment variable; LIBRARY_PATH 15829@anchor{internals/index envvar-LIBRARY_PATH}@anchor{3c6} 15830@deffn {Environment Variable} LIBRARY_PATH 15831 15832The driver executable invokes the linker, and the latter needs to locate 15833support libraries needed by the generated code, or you will see errors 15834like: 15835 15836@example 15837ld: cannot find crtbeginS.o: No such file or directory 15838ld: cannot find -lgcc 15839ld: cannot find -lgcc_s 15840@end example 15841 15842Hence if running directly from a locally-built copy (without installing), 15843@code{LIBRARY_PATH} needs to contain the ���gcc��� subdirectory of the build 15844tree. 15845@end deffn 15846 15847For example, to run a binary that uses the library against a non-installed 15848build of the library in LIBGCCJIT_BUILD_DIR you need an invocation of the 15849client code like this, to preprend the dir to each of the environment 15850variables: 15851 15852@example 15853$ LD_LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LD_LIBRARY_PATH) \ 15854 PATH=$(LIBGCCJIT_BUILD_DIR):$(PATH) \ 15855 LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LIBRARY_PATH) \ 15856 ./jit-hello-world 15857hello world 15858@end example 15859 15860@node Packaging notes,Overview of code structure,Environment variables,Internals 15861@anchor{internals/index packaging-notes}@anchor{3c7} 15862@section Packaging notes 15863 15864 15865The configure-time option @ref{3bd,,--enable-host-shared} is needed when 15866building the jit in order to get position-independent code. This will 15867slow down the regular compiler by a few percent. Hence when packaging gcc 15868with libgccjit, please configure and build twice: 15869 15870@quotation 15871 15872 15873@itemize * 15874 15875@item 15876once without @ref{3bd,,--enable-host-shared} for most languages, and 15877 15878@item 15879once with @ref{3bd,,--enable-host-shared} for the jit 15880@end itemize 15881@end quotation 15882 15883For example: 15884 15885@example 15886# Configure and build with --enable-host-shared 15887# for the jit: 15888mkdir configuration-for-jit 15889pushd configuration-for-jit 15890$(SRCDIR)/configure \ 15891 --enable-host-shared \ 15892 --enable-languages=jit \ 15893 --prefix=$(DESTDIR) 15894make 15895popd 15896 15897# Configure and build *without* --enable-host-shared 15898# for maximum speed: 15899mkdir standard-configuration 15900pushd standard-configuration 15901$(SRCDIR)/configure \ 15902 --enable-languages=all \ 15903 --prefix=$(DESTDIR) 15904make 15905popd 15906 15907# Both of the above are configured to install to $(DESTDIR) 15908# Install the configuration with --enable-host-shared first 15909# *then* the one without, so that the faster build 15910# of "cc1" et al overwrites the slower build. 15911pushd configuration-for-jit 15912make install 15913popd 15914 15915pushd standard-configuration 15916make install 15917popd 15918@end example 15919 15920@node Overview of code structure,Design notes,Packaging notes,Internals 15921@anchor{internals/index overview-of-code-structure}@anchor{3c8} 15922@section Overview of code structure 15923 15924 15925The library is implemented in C++. The source files have the @code{.c} 15926extension for legacy reasons. 15927 15928 15929@itemize * 15930 15931@item 15932@code{libgccjit.cc} implements the API entrypoints. It performs error 15933checking, then calls into classes of the gcc::jit::recording namespace 15934within @code{jit-recording.cc} and @code{jit-recording.h}. 15935 15936@item 15937The gcc::jit::recording classes (within @code{jit-recording.cc} and 15938@code{jit-recording.h}) record the API calls that are made: 15939 15940@quotation 15941 15942@example 15943 15944 /* Indentation indicates inheritance: */ 15945 class context; 15946 class memento; 15947 class string; 15948 class location; 15949 class type; 15950 class function_type; 15951 class compound_type; 15952 class struct_; 15953 class union_; 15954 class vector_type; 15955 class field; 15956 class bitfield; 15957 class fields; 15958 class function; 15959 class block; 15960 class rvalue; 15961 class lvalue; 15962 class local; 15963 class global; 15964 class param; 15965 class base_call; 15966 class function_pointer; 15967 class statement; 15968 class extended_asm; 15969 class case_; 15970 class top_level_asm; 15971 15972@end example 15973@end quotation 15974 15975@item 15976When the context is compiled, the gcc::jit::playback classes (within 15977@code{jit-playback.cc} and @code{jit-playback.h}) replay the API calls 15978within langhook:parse_file: 15979 15980@quotation 15981 15982@example 15983 15984 /* Indentation indicates inheritance: */ 15985 class context; 15986 class wrapper; 15987 class type; 15988 class compound_type; 15989 class field; 15990 class function; 15991 class block; 15992 class rvalue; 15993 class lvalue; 15994 class param; 15995 class source_file; 15996 class source_line; 15997 class location; 15998 class case_; 15999 16000@end example 16001 16002@example 16003Client Code . Generated . libgccjit.so 16004 . code . 16005 . . JIT API . JIT "Frontend". (libbackend.a) 16006.................................................................................... 16007 ��� . . . . 16008 ������������������������������������������������������������������������������> . . 16009 . . ��� . . 16010 . . V . . 16011 . . ������> libgccjit.cc . 16012 . . ��� (error-checking). 16013 . . ��� . 16014 . . ������> jit-recording.cc 16015 . . (record API calls) 16016 . . <��������������������� . 16017 . . ��� . . 16018 <��������������������������������������������������������������������������������� . . 16019 ��� . . . . 16020 ��� . . . . 16021 V . . gcc_jit_context_compile . 16022 ������������������������������������������������������������������������������> . . 16023 . . ��� start of recording::context::compile () 16024 . . ��� . . 16025 . . ��� start of playback::context::compile () 16026 . . ��� (create tempdir) . 16027 . . ��� . . 16028 . . ��� ACQUIRE MUTEX . 16029 . . ��� . . 16030 . . V���������������������������������������������������������������������> toplev::main (for now) 16031 . . . . ��� 16032 . . . . (various code) 16033 . . . . ��� 16034 . . . . V 16035 . . . <��������������������������������������������������� langhook:parse_file 16036 . . . ��� . 16037 . . . ��� (jit_langhook_parse_file) 16038 . . . ��� . 16039..........................................���..................VVVVVVVVVVVVV... 16040 . . . ��� . No GC in here 16041 . . . ��� jit-playback.cc 16042 . . . ��� (playback of API calls) 16043 . . . ���������������������������������������������> creation of functions, 16044 . . . . types, expression trees 16045 . . . <������������������������������������������������ etc 16046 . . . ���(handle_locations: add locations to 16047 . . . ��� linemap and associate them with trees) 16048 . . . ��� . 16049 . . . ��� . No GC in here 16050..........................................���..................AAAAAAAAAAAAA... 16051 . . . ��� for each function 16052 . . . ������> postprocess 16053 . . . ��� . 16054 . . . ������������������������������������> cgraph_finalize_function 16055 . . . <������������������������������������ 16056 . . . <������ . 16057 . . . ��� . 16058 . . . ������������������������������������������������������> (end of 16059 . . . . ��� langhook_parse_file) 16060 . . . . ��� 16061 . . . . (various code) 16062 . . . . ��� 16063 . . . . ��� 16064 . . . <��������������������������������������������������� langhook:write_globals 16065 . . . ��� . 16066 . . . ��� (jit_langhook_write_globals) 16067 . . . ��� . 16068 . . . ��� . 16069 . . . ������������������������������������������������������> finalize_compilation_unit 16070 . . . . ��� 16071 . . . . (the middle���end and backend) 16072 . . . . ��� 16073 . . <��������������������������������������������������������������������������������������� end of toplev::main 16074 . . ��� . . 16075 . . V���������������������������������������������������������������������> toplev::finalize 16076 . . . . ��� (purge internal state) 16077 . . <������������������������������������������������������������������������ end of toplev::finalize 16078 . . ��� . . 16079 . . V���> playback::context::postprocess: 16080 . . ��� . . 16081 . . ��� (assuming an in-memory compile): 16082 . . ��� . . 16083 . . --> Convert assembler to DSO, via embedded 16084 . . copy of driver: 16085 . . driver::main () 16086 . . invocation of "as" 16087 . . invocation of "ld" 16088 . . driver::finalize () 16089 . . <---- 16090 . . ��� . . 16091 . . ��� . Load DSO (dlopen "fake.so") 16092 . . ��� . . 16093 . . ��� . Bundle it up in a jit::result 16094 . . <������ . . 16095 . . ��� . . 16096 . . ��� RELEASE MUTEX . 16097 . . ��� . . 16098 . . ��� end of playback::context::compile () 16099 . . ��� . . 16100 . . ��� playback::context dtor 16101 . . ������> . . 16102 . . ��� Normally we cleanup the tempdir here: 16103 . . ��� ("fake.so" is unlinked from the 16104 . . ��� filesystem at this point) 16105 . . ��� If the client code requested debuginfo, the 16106 . . ��� cleanup happens later (in gcc_jit_result_release) 16107 . . ��� to make it easier on the debugger (see PR jit/64206) 16108 . . <������ . . 16109 . . ��� . . 16110 . . ��� end of recording::context::compile () 16111 <��������������������������������������������������������������������������������� . . 16112 ��� . . . . 16113 V . . gcc_jit_result_get_code . 16114 ������������������������������������������������������������������������������> . . 16115 . . ��� dlsym () within loaded DSO 16116 <��������������������������������������������������������������������������������� . . 16117 Get (void*). . . . 16118 ��� . . . . 16119 ��� Call it . . . . 16120 ���������������������������������������������> . . . 16121 . ��� . . . 16122 . ��� . . . 16123 <��������������������������������������������� . . . 16124 ��� . . . . 16125etc��� . . . . 16126 ��� . . . . 16127 V . . gcc_jit_result_release . 16128 ������������������������������������������������������������������������������> . . 16129 . . ��� dlclose () the loaded DSO 16130 . . ��� (code becomes uncallable) 16131 . . ��� . . 16132 . . ��� If the client code requested debuginfo, then 16133 . . ��� cleanup of the tempdir was delayed. 16134 . . ��� If that was the case, clean it up now. 16135 <��������������������������������������������������������������������������������� . . 16136 ��� . . . . 16137@end example 16138@end quotation 16139@end itemize 16140 16141Here is a high-level summary from @code{jit-common.h}: 16142 16143@quotation 16144 16145In order to allow jit objects to be usable outside of a compile 16146whilst working with the existing structure of GCC���s code the 16147C API is implemented in terms of a gcc::jit::recording::context, 16148which records the calls made to it. 16149 16150When a gcc_jit_context is compiled, the recording context creates a 16151playback context. The playback context invokes the bulk of the GCC 16152code, and within the ���frontend��� parsing hook, plays back the recorded 16153API calls, creating GCC tree objects. 16154 16155So there are two parallel families of classes: those relating to 16156recording, and those relating to playback: 16157 16158 16159@itemize * 16160 16161@item 16162Visibility: recording objects are exposed back to client code, 16163whereas playback objects are internal to the library. 16164 16165@item 16166Lifetime: recording objects have a lifetime equal to that of the 16167recording context that created them, whereas playback objects only 16168exist within the frontend hook. 16169 16170@item 16171Memory allocation: recording objects are allocated by the recording 16172context, and automatically freed by it when the context is released, 16173whereas playback objects are allocated within the GC heap, and 16174garbage-collected; they can own GC-references. 16175 16176@item 16177Integration with rest of GCC: recording objects are unrelated to the 16178rest of GCC, whereas playback objects are wrappers around ���tree��� 16179instances. Hence you can���t ask a recording rvalue or lvalue what its 16180type is, whereas you can for a playback rvalue of lvalue (since it 16181can work with the underlying GCC tree nodes). 16182 16183@item 16184Instancing: There can be multiple recording contexts ���alive��� at once 16185(albeit it only one compiling at once), whereas there can only be one 16186playback context alive at one time (since it interacts with the GC). 16187@end itemize 16188 16189Ultimately if GCC could support multiple GC heaps and contexts, and 16190finer-grained initialization, then this recording vs playback 16191distinction could be eliminated. 16192 16193During a playback, we associate objects from the recording with 16194their counterparts during this playback. For simplicity, we store this 16195within the recording objects, as @code{void *m_playback_obj}, casting it to 16196the appropriate playback object subclass. For these casts to make 16197sense, the two class hierarchies need to have the same structure. 16198 16199Note that the playback objects that @code{m_playback_obj} points to are 16200GC-allocated, but the recording objects don���t own references: 16201these associations only exist within a part of the code where 16202the GC doesn���t collect, and are set back to NULL before the GC can 16203run. 16204@end quotation 16205@anchor{internals/index example-of-log-file}@anchor{5c} 16206Another way to understand the structure of the code is to enable logging, 16207via @ref{5b,,gcc_jit_context_set_logfile()}. Here is an example of a log 16208generated via this call: 16209 16210@example 16211JIT: libgccjit (GCC) version 6.0.0 20150803 (experimental) (x86_64-pc-linux-gnu) 16212JIT: 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 16213JIT: entering: gcc_jit_context_set_str_option 16214JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe" 16215JIT: exiting: gcc_jit_context_set_str_option 16216JIT: entering: gcc_jit_context_set_int_option 16217JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3 16218JIT: exiting: gcc_jit_context_set_int_option 16219JIT: entering: gcc_jit_context_set_bool_option 16220JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true 16221JIT: exiting: gcc_jit_context_set_bool_option 16222JIT: entering: gcc_jit_context_set_bool_option 16223JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false 16224JIT: exiting: gcc_jit_context_set_bool_option 16225JIT: entering: gcc_jit_context_set_bool_option 16226JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false 16227JIT: exiting: gcc_jit_context_set_bool_option 16228JIT: entering: gcc_jit_context_set_bool_option 16229JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true 16230JIT: exiting: gcc_jit_context_set_bool_option 16231JIT: entering: gcc_jit_context_set_bool_option 16232JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false 16233JIT: exiting: gcc_jit_context_set_bool_option 16234JIT: entering: gcc_jit_context_get_type 16235JIT: exiting: gcc_jit_context_get_type 16236JIT: entering: gcc_jit_context_get_type 16237JIT: exiting: gcc_jit_context_get_type 16238JIT: entering: gcc_jit_context_new_param 16239JIT: exiting: gcc_jit_context_new_param 16240JIT: entering: gcc_jit_context_new_function 16241JIT: exiting: gcc_jit_context_new_function 16242JIT: entering: gcc_jit_context_new_param 16243JIT: exiting: gcc_jit_context_new_param 16244JIT: entering: gcc_jit_context_get_type 16245JIT: exiting: gcc_jit_context_get_type 16246JIT: entering: gcc_jit_context_new_function 16247JIT: exiting: gcc_jit_context_new_function 16248JIT: entering: gcc_jit_context_new_string_literal 16249JIT: exiting: gcc_jit_context_new_string_literal 16250JIT: entering: gcc_jit_function_new_block 16251JIT: exiting: gcc_jit_function_new_block 16252JIT: entering: gcc_jit_block_add_comment 16253JIT: exiting: gcc_jit_block_add_comment 16254JIT: entering: gcc_jit_context_new_call 16255JIT: exiting: gcc_jit_context_new_call 16256JIT: entering: gcc_jit_block_add_eval 16257JIT: exiting: gcc_jit_block_add_eval 16258JIT: entering: gcc_jit_block_end_with_void_return 16259JIT: exiting: gcc_jit_block_end_with_void_return 16260JIT: entering: gcc_jit_context_dump_reproducer_to_file 16261JIT: entering: void gcc::jit::recording::context::dump_reproducer_to_file(const char*) 16262JIT: exiting: void gcc::jit::recording::context::dump_reproducer_to_file(const char*) 16263JIT: exiting: gcc_jit_context_dump_reproducer_to_file 16264JIT: entering: gcc_jit_context_compile 16265JIT: in-memory compile of ctxt: 0x1283e20 16266JIT: entering: gcc::jit::result* gcc::jit::recording::context::compile() 16267JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe" 16268JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3 16269JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true 16270JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false 16271JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false 16272JIT: GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE: false 16273JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false 16274JIT: GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING: false 16275JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true 16276JIT: GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES: false 16277JIT: gcc_jit_context_set_bool_allow_unreachable_blocks: false 16278JIT: gcc_jit_context_set_bool_use_external_driver: false 16279JIT: entering: void gcc::jit::recording::context::validate() 16280JIT: exiting: void gcc::jit::recording::context::validate() 16281JIT: entering: gcc::jit::playback::context::context(gcc::jit::recording::context*) 16282JIT: exiting: gcc::jit::playback::context::context(gcc::jit::recording::context*) 16283JIT: entering: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*) 16284JIT: exiting: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*) 16285JIT: entering: void gcc::jit::playback::context::compile() 16286JIT: entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int) 16287JIT: exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int) 16288JIT: entering: bool gcc::jit::tempdir::create() 16289JIT: m_path_template: /tmp/libgccjit-XXXXXX 16290JIT: m_path_tempdir: /tmp/libgccjit-CKq1M9 16291JIT: exiting: bool gcc::jit::tempdir::create() 16292JIT: entering: void gcc::jit::playback::context::acquire_mutex() 16293JIT: exiting: void gcc::jit::playback::context::acquire_mutex() 16294JIT: entering: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*) 16295JIT: reusing cached configure-time options 16296JIT: configure_time_options[0]: -mtune=generic 16297JIT: configure_time_options[1]: -march=x86-64 16298JIT: exiting: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*) 16299JIT: entering: toplev::main 16300JIT: argv[0]: ./test-hello-world.c.exe 16301JIT: argv[1]: /tmp/libgccjit-CKq1M9/fake.c 16302JIT: argv[2]: -fPIC 16303JIT: argv[3]: -O3 16304JIT: argv[4]: -g 16305JIT: argv[5]: -quiet 16306JIT: argv[6]: --param 16307JIT: argv[7]: ggc-min-expand=0 16308JIT: argv[8]: --param 16309JIT: argv[9]: ggc-min-heapsize=0 16310JIT: argv[10]: -mtune=generic 16311JIT: argv[11]: -march=x86-64 16312JIT: entering: bool jit_langhook_init() 16313JIT: exiting: bool jit_langhook_init() 16314JIT: entering: void gcc::jit::playback::context::replay() 16315JIT: entering: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*) 16316JIT: exiting: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*) 16317JIT: entering: void gcc::jit::recording::context::disassociate_from_playback() 16318JIT: exiting: void gcc::jit::recording::context::disassociate_from_playback() 16319JIT: entering: void gcc::jit::playback::context::handle_locations() 16320JIT: exiting: void gcc::jit::playback::context::handle_locations() 16321JIT: entering: void gcc::jit::playback::function::build_stmt_list() 16322JIT: exiting: void gcc::jit::playback::function::build_stmt_list() 16323JIT: entering: void gcc::jit::playback::function::build_stmt_list() 16324JIT: exiting: void gcc::jit::playback::function::build_stmt_list() 16325JIT: entering: void gcc::jit::playback::function::postprocess() 16326JIT: exiting: void gcc::jit::playback::function::postprocess() 16327JIT: entering: void gcc::jit::playback::function::postprocess() 16328JIT: exiting: void gcc::jit::playback::function::postprocess() 16329JIT: exiting: void gcc::jit::playback::context::replay() 16330JIT: exiting: toplev::main 16331JIT: entering: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*) 16332JIT: exiting: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*) 16333JIT: entering: toplev::finalize 16334JIT: exiting: toplev::finalize 16335JIT: entering: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*) 16336JIT: entering: void gcc::jit::playback::context::convert_to_dso(const char*) 16337JIT: entering: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool) 16338JIT: entering: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*) 16339JIT: exiting: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*) 16340JIT: argv[0]: x86_64-unknown-linux-gnu-gcc-6.0.0 16341JIT: argv[1]: -m64 16342JIT: argv[2]: -shared 16343JIT: argv[3]: /tmp/libgccjit-CKq1M9/fake.s 16344JIT: argv[4]: -o 16345JIT: argv[5]: /tmp/libgccjit-CKq1M9/fake.so 16346JIT: argv[6]: -fno-use-linker-plugin 16347JIT: entering: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*) 16348JIT: exiting: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*) 16349JIT: exiting: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool) 16350JIT: exiting: void gcc::jit::playback::context::convert_to_dso(const char*) 16351JIT: entering: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso() 16352JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir to jit::result 16353JIT: entering: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*) 16354JIT: exiting: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*) 16355JIT: exiting: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso() 16356JIT: exiting: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*) 16357JIT: entering: void gcc::jit::playback::context::release_mutex() 16358JIT: exiting: void gcc::jit::playback::context::release_mutex() 16359JIT: exiting: void gcc::jit::playback::context::compile() 16360JIT: entering: gcc::jit::playback::context::~context() 16361JIT: exiting: gcc::jit::playback::context::~context() 16362JIT: exiting: gcc::jit::result* gcc::jit::recording::context::compile() 16363JIT: gcc_jit_context_compile: returning (gcc_jit_result *)0x12f75d0 16364JIT: exiting: gcc_jit_context_compile 16365JIT: entering: gcc_jit_result_get_code 16366JIT: locating fnname: hello_world 16367JIT: entering: void* gcc::jit::result::get_code(const char*) 16368JIT: exiting: void* gcc::jit::result::get_code(const char*) 16369JIT: gcc_jit_result_get_code: returning (void *)0x7ff6b8cd87f0 16370JIT: exiting: gcc_jit_result_get_code 16371JIT: entering: gcc_jit_context_release 16372JIT: deleting ctxt: 0x1283e20 16373JIT: entering: gcc::jit::recording::context::~context() 16374JIT: exiting: gcc::jit::recording::context::~context() 16375JIT: exiting: gcc_jit_context_release 16376JIT: entering: gcc_jit_result_release 16377JIT: deleting result: 0x12f75d0 16378JIT: entering: virtual gcc::jit::result::~result() 16379JIT: entering: gcc::jit::tempdir::~tempdir() 16380JIT: unlinking .s file: /tmp/libgccjit-CKq1M9/fake.s 16381JIT: unlinking .so file: /tmp/libgccjit-CKq1M9/fake.so 16382JIT: removing tempdir: /tmp/libgccjit-CKq1M9 16383JIT: exiting: gcc::jit::tempdir::~tempdir() 16384JIT: exiting: virtual gcc::jit::result::~result() 16385JIT: exiting: gcc_jit_result_release 16386JIT: gcc::jit::logger::~logger() 16387@end example 16388 16389@node Design notes,Submitting patches,Overview of code structure,Internals 16390@anchor{internals/index design-notes}@anchor{3c9} 16391@section Design notes 16392 16393 16394It should not be possible for client code to cause an internal compiler 16395error. If this @emph{does} happen, the root cause should be isolated (perhaps 16396using @ref{5d,,gcc_jit_context_dump_reproducer_to_file()}) and the cause 16397should be rejected via additional checking. The checking ideally should 16398be within the libgccjit API entrypoints in libgccjit.cc, since this is as 16399close as possible to the error; failing that, a good place is within 16400@code{recording::context::validate ()} in jit-recording.cc. 16401 16402@node Submitting patches,,Design notes,Internals 16403@anchor{internals/index submitting-patches}@anchor{3ca} 16404@section Submitting patches 16405 16406 16407Please read the contribution guidelines for gcc at 16408@indicateurl{https://gcc.gnu.org/contribute.html}. 16409 16410Patches for the jit should be sent to both the 16411@email{gcc-patches@@gcc.gnu.org} and @email{jit@@gcc.gnu.org} mailing lists, 16412with ���jit��� and ���PATCH��� in the Subject line. 16413 16414You don���t need to do a full bootstrap for code that just touches the 16415@code{jit} and @code{testsuite/jit.dg} subdirectories. However, please run 16416@code{make check-jit} before submitting the patch, and mention the results 16417in your email (along with the host triple that the tests were run on). 16418 16419A good patch should contain the information listed in the 16420gcc contribution guide linked to above; for a @code{jit} patch, the patch 16421shold contain: 16422 16423@quotation 16424 16425 16426@itemize * 16427 16428@item 16429the code itself (for example, a new API entrypoint will typically 16430touch @code{libgccjit.h} and @code{.c}, along with support code in 16431@code{jit-recording.[ch]} and @code{jit-playback.[ch]} as appropriate) 16432 16433@item 16434test coverage 16435 16436@item 16437documentation for the C API 16438 16439@item 16440documentation for the C++ API 16441@end itemize 16442@end quotation 16443 16444A patch that adds new API entrypoints should also contain: 16445 16446@quotation 16447 16448 16449@itemize * 16450 16451@item 16452a feature macro in @code{libgccjit.h} so that client code that doesn���t 16453use a ���configure��� mechanism can still easily detect the presence of 16454the entrypoint. See e.g. @code{LIBGCCJIT_HAVE_SWITCH_STATEMENTS} (for 16455a category of entrypoints) and 16456@code{LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks} 16457(for an individual entrypoint). 16458 16459@item 16460a new ABI tag containing the new symbols (in @code{libgccjit.map}), so 16461that we can detect client code that uses them 16462 16463@item 16464Support for @ref{5d,,gcc_jit_context_dump_reproducer_to_file()}. Most 16465jit testcases attempt to dump their contexts to a .c file; @code{jit.exp} 16466then sanity-checks the generated c by compiling them (though 16467not running them). A new API entrypoint 16468needs to ���know��� how to write itself back out to C (by implementing 16469@code{gcc::jit::recording::memento::write_reproducer} for the appropriate 16470@code{memento} subclass). 16471 16472@item 16473C++ bindings for the new entrypoints (see @code{libgccjit++.h}); ideally 16474with test coverage, though the C++ API test coverage is admittedly 16475spotty at the moment 16476 16477@item 16478documentation for the new C entrypoints 16479 16480@item 16481documentation for the new C++ entrypoints 16482 16483@item 16484documentation for the new ABI tag (see @code{topics/compatibility.rst}). 16485@end itemize 16486@end quotation 16487 16488Depending on the patch you can either extend an existing test case, or 16489add a new test case. If you add an entirely new testcase: @code{jit.exp} 16490expects jit testcases to begin with @code{test-}, or @code{test-error-} (for a 16491testcase that generates an error on a @ref{8,,gcc_jit_context}). 16492 16493Every new testcase that doesn���t generate errors should also touch 16494@code{gcc/testsuite/jit.dg/all-non-failing-tests.h}: 16495 16496@quotation 16497 16498 16499@itemize * 16500 16501@item 16502Testcases that don���t generate errors should ideally be added to the 16503@code{testcases} array in that file; this means that, in addition 16504to being run standalone, they also get run within 16505@code{test-combination.c} (which runs all successful tests inside one 16506big @ref{8,,gcc_jit_context}), and @code{test-threads.c} (which runs all 16507successful tests in one process, each one running in a different 16508thread on a different @ref{8,,gcc_jit_context}). 16509 16510@cartouche 16511@quotation Note 16512Given that exported functions within a @ref{8,,gcc_jit_context} 16513must have unique names, and most testcases are run within 16514@code{test-combination.c}, this means that every jit-compiled test 16515function typically needs a name that���s unique across the entire 16516test suite. 16517@end quotation 16518@end cartouche 16519 16520@item 16521Testcases that aren���t to be added to the @code{testcases} array should 16522instead add a comment to the file clarifying why they���re not in that 16523array. See the file for examples. 16524@end itemize 16525@end quotation 16526 16527Typically a patch that touches the .rst documentation will also need the 16528texinfo to be regenerated. You can do this with 16529Sphinx 1.0@footnote{https://sphinx-doc.org/} or later by 16530running @code{make texinfo} within @code{SRCDIR/gcc/jit/docs}. Don���t do this 16531within the patch sent to the mailing list; it can often be relatively 16532large and inconsequential (e.g. anchor renumbering), rather like generated 16533���configure��� changes from configure.ac. You can regenerate it when 16534committing to svn. 16535 16536@node Indices and tables,Index,Internals,Top 16537@anchor{index indices-and-tables}@anchor{3cb} 16538@unnumbered Indices and tables 16539 16540 16541 16542@itemize * 16543 16544@item 16545genindex 16546 16547@item 16548modindex 16549 16550@item 16551search 16552@end itemize 16553 16554@c Some notes: 16555@c 16556@c The Sphinx C domain appears to lack explicit support for enum values, 16557@c so I've been using :c:macro: for them. 16558@c 16559@c See https://sphinx-doc.org/domains.html#the-c-domain 16560 16561@node Index,,Indices and tables,Top 16562@unnumbered Index 16563 16564 16565@printindex ge 16566 16567 16568@c %**end of body 16569@bye 16570