libgccjit.texi revision 1.1
1\input texinfo @c -*-texinfo-*- 2@c %**start of header 3@setfilename libgccjit.info 4@documentencoding UTF-8 5@ifinfo 6@*Generated by Sphinx 1.1.3.@* 7@end ifinfo 8@settitle libgccjit Documentation 9@defindex ge 10@paragraphindent 2 11@exampleindent 4 12@afourlatex 13@dircategory Miscellaneous 14@direntry 15* libgccjit: (libgccjit.info). One line description of project. 16@end direntry 17 18@c %**end of header 19 20@copying 21@quotation 22libgccjit 5.2.1 ( 20150723), July 23, 2015 23 24David Malcolm 25 26Copyright @copyright{} 2014-2015 Free Software Foundation, Inc. 27@end quotation 28 29@end copying 30 31@titlepage 32@title libgccjit Documentation 33@insertcopying 34@end titlepage 35@contents 36 37@c %** start of user preamble 38 39@c %** end of user preamble 40 41@ifnottex 42@node Top 43@top libgccjit Documentation 44@insertcopying 45@end ifnottex 46 47@c %**start of body 48@anchor{index doc}@anchor{0} 49@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 50@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 51@c 52@c This is free software: you can redistribute it and/or modify it 53@c under the terms of the GNU General Public License as published by 54@c the Free Software Foundation, either version 3 of the License, or 55@c (at your option) any later version. 56@c 57@c This program is distributed in the hope that it will be useful, but 58@c WITHOUT ANY WARRANTY; without even the implied warranty of 59@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 60@c General Public License for more details. 61@c 62@c You should have received a copy of the GNU General Public License 63@c along with this program. If not, see 64@c <http://www.gnu.org/licenses/>. 65 66This document describes libgccjit@footnote{http://gcc.gnu.org/wiki/JIT}, an API 67for embedding GCC inside programs and libraries. 68 69Note that libgccjit is currently of "Alpha" quality; 70the APIs are not yet set in stone, and they shouldn't be used in 71production yet. 72 73There are actually two APIs for the library: 74 75 76@itemize * 77 78@item 79a pure C API: @code{libgccjit.h} 80 81@item 82a C++ wrapper API: @code{libgccjit++.h}. This is a collection of "thin" 83wrapper classes around the C API, to save typing. 84@end itemize 85 86Contents: 87 88@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 89@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 90@c 91@c This is free software: you can redistribute it and/or modify it 92@c under the terms of the GNU General Public License as published by 93@c the Free Software Foundation, either version 3 of the License, or 94@c (at your option) any later version. 95@c 96@c This program is distributed in the hope that it will be useful, but 97@c WITHOUT ANY WARRANTY; without even the implied warranty of 98@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 99@c General Public License for more details. 100@c 101@c You should have received a copy of the GNU General Public License 102@c along with this program. If not, see 103@c <http://www.gnu.org/licenses/>. 104 105@menu 106* Tutorial:: 107* Topic Reference:: 108* C++ bindings for libgccjit:: 109* Internals:: 110* Indices and tables:: 111* Index:: 112 113@detailmenu 114 --- The Detailed Node Listing --- 115 116Tutorial 117 118* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world". 119* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function. 120* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables. 121* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter. 122* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler. 123 124Tutorial part 2: Creating a trivial machine code function 125 126* Error-handling:: 127* Options:: 128* Full example:: 129 130Tutorial part 3: Loops and variables 131 132* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. 133* Control flow:: 134* Visualizing the control flow graph:: 135* Full example: Full example<2>. 136 137Tutorial part 4: Adding JIT-compilation to a toy interpreter 138 139* Our toy interpreter:: 140* Compiling to machine code:: 141* Setting things up:: 142* Populating the function:: 143* Verifying the control flow graph:: 144* Compiling the context:: 145* Single-stepping through the generated code:: 146* Examining the generated code:: 147* Putting it all together:: 148* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?. 149 150Behind the curtain: How does our code get optimized? 151 152* Optimizing away stack manipulation:: 153* Elimination of tail recursion:: 154 155Tutorial part 5: Implementing an Ahead-of-Time compiler 156 157* The "brainf" language:: 158* Converting a brainf script to libgccjit IR:: 159* Compiling a context to a file:: 160* Other forms of ahead-of-time-compilation:: 161 162Topic Reference 163 164* Compilation contexts:: 165* Objects:: 166* Types:: 167* Expressions:: 168* Creating and using functions:: 169* Source Locations:: 170* Compiling a context:: 171* ABI and API compatibility:: 172 173Compilation contexts 174 175* Lifetime-management:: 176* Thread-safety:: 177* Error-handling: Error-handling<2>. 178* Debugging:: 179* Options: Options<2>. 180 181Options 182 183* String Options:: 184* Boolean options:: 185* Integer options:: 186* Additional command-line options:: 187 188Types 189 190* Standard types:: 191* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 192* Structures and unions:: 193 194Expressions 195 196* Rvalues:: 197* Lvalues:: 198* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 199 200Rvalues 201 202* Simple expressions:: 203* Unary Operations:: 204* Binary Operations:: 205* Comparisons:: 206* Function calls:: 207* Type-coercion:: 208 209Lvalues 210 211* Global variables:: 212 213Creating and using functions 214 215* Params:: 216* Functions:: 217* Blocks:: 218* Statements:: 219 220Source Locations 221 222* Faking it:: 223 224Compiling a context 225 226* In-memory compilation:: 227* Ahead-of-time compilation:: 228 229ABI and API compatibility 230 231* ABI symbol tags:: 232 233ABI symbol tags 234 235* LIBGCCJIT_ABI_0:: 236* LIBGCCJIT_ABI_1:: 237* LIBGCCJIT_ABI_2:: 238* LIBGCCJIT_ABI_3:: 239 240C++ bindings for libgccjit 241 242* Tutorial: Tutorial<2>. 243* Topic Reference: Topic Reference<2>. 244 245Tutorial 246 247* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 248* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 249* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 250* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 251 252Tutorial part 2: Creating a trivial machine code function 253 254* Options: Options<3>. 255* Full example: Full example<3>. 256 257Tutorial part 3: Loops and variables 258 259* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 260* Control flow: Control flow<2>. 261* Visualizing the control flow graph: Visualizing the control flow graph<2>. 262* Full example: Full example<4>. 263 264Tutorial part 4: Adding JIT-compilation to a toy interpreter 265 266* Our toy interpreter: Our toy interpreter<2>. 267* Compiling to machine code: Compiling to machine code<2>. 268* Setting things up: Setting things up<2>. 269* Populating the function: Populating the function<2>. 270* Verifying the control flow graph: Verifying the control flow graph<2>. 271* Compiling the context: Compiling the context<2>. 272* Single-stepping through the generated code: Single-stepping through the generated code<2>. 273* Examining the generated code: Examining the generated code<2>. 274* Putting it all together: Putting it all together<2>. 275* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 276 277Behind the curtain: How does our code get optimized? 278 279* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 280* Elimination of tail recursion: Elimination of tail recursion<2>. 281 282Topic Reference 283 284* Compilation contexts: Compilation contexts<2>. 285* Objects: Objects<2>. 286* Types: Types<2>. 287* Expressions: Expressions<2>. 288* Creating and using functions: Creating and using functions<2>. 289* Source Locations: Source Locations<2>. 290* Compiling a context: Compiling a context<2>. 291 292Compilation contexts 293 294* Lifetime-management: Lifetime-management<2>. 295* Thread-safety: Thread-safety<2>. 296* Error-handling: Error-handling<3>. 297* Debugging: Debugging<2>. 298* Options: Options<4>. 299 300Options 301 302* String Options: String Options<2>. 303* Boolean options: Boolean options<2>. 304* Integer options: Integer options<2>. 305* Additional command-line options: Additional command-line options<2>. 306 307Types 308 309* Standard types: Standard types<2>. 310* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 311* Structures and unions: Structures and unions<2>. 312 313Expressions 314 315* Rvalues: Rvalues<2>. 316* Lvalues: Lvalues<2>. 317* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 318 319Rvalues 320 321* Simple expressions: Simple expressions<2>. 322* Unary Operations: Unary Operations<2>. 323* Binary Operations: Binary Operations<2>. 324* Comparisons: Comparisons<2>. 325* Function calls: Function calls<2>. 326* Type-coercion: Type-coercion<2>. 327 328Lvalues 329 330* Global variables: Global variables<2>. 331 332Creating and using functions 333 334* Params: Params<2>. 335* Functions: Functions<2>. 336* Blocks: Blocks<2>. 337* Statements: Statements<2>. 338 339Source Locations 340 341* Faking it: Faking it<2>. 342 343Compiling a context 344 345* In-memory compilation: In-memory compilation<2>. 346* Ahead-of-time compilation: Ahead-of-time compilation<2>. 347 348Internals 349 350* Working on the JIT library:: 351* Running the test suite:: 352* Environment variables:: 353* Packaging notes:: 354* Overview of code structure:: 355* Design notes:: 356 357Running the test suite 358 359* Running under valgrind:: 360 361@end detailmenu 362@end menu 363 364 365@node Tutorial,Topic Reference,Top,Top 366@anchor{intro/index libgccjit}@anchor{1}@anchor{intro/index doc}@anchor{2}@anchor{intro/index tutorial}@anchor{3} 367@chapter Tutorial 368 369 370@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 371@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 372@c 373@c This is free software: you can redistribute it and/or modify it 374@c under the terms of the GNU General Public License as published by 375@c the Free Software Foundation, either version 3 of the License, or 376@c (at your option) any later version. 377@c 378@c This program is distributed in the hope that it will be useful, but 379@c WITHOUT ANY WARRANTY; without even the implied warranty of 380@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 381@c General Public License for more details. 382@c 383@c You should have received a copy of the GNU General Public License 384@c along with this program. If not, see 385@c <http://www.gnu.org/licenses/>. 386 387@menu 388* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world". 389* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function. 390* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables. 391* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter. 392* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler. 393 394@end menu 395 396@node Tutorial part 1 "Hello world",Tutorial part 2 Creating a trivial machine code function,,Tutorial 397@anchor{intro/tutorial01 doc}@anchor{4}@anchor{intro/tutorial01 tutorial-part-1-hello-world}@anchor{5} 398@section Tutorial part 1: "Hello world" 399 400 401Before we look at the details of the API, let's look at building and 402running programs that use the library. 403 404Here's a toy "hello world" program that uses the library to synthesize 405a call to @cite{printf} and uses it to write a message to stdout. 406 407Don't worry about the content of the program for now; we'll cover 408the details in later parts of this tutorial. 409 410@quotation 411 412@example 413/* Smoketest example for libgccjit.so 414 Copyright (C) 2014-2015 Free Software Foundation, Inc. 415 416This file is part of GCC. 417 418GCC is free software; you can redistribute it and/or modify it 419under the terms of the GNU General Public License as published by 420the Free Software Foundation; either version 3, or (at your option) 421any later version. 422 423GCC is distributed in the hope that it will be useful, but 424WITHOUT ANY WARRANTY; without even the implied warranty of 425MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 426General Public License for more details. 427 428You should have received a copy of the GNU General Public License 429along with GCC; see the file COPYING3. If not see 430<http://www.gnu.org/licenses/>. */ 431 432#include <libgccjit.h> 433 434#include <stdlib.h> 435#include <stdio.h> 436 437static void 438create_code (gcc_jit_context *ctxt) 439@{ 440 /* Let's try to inject the equivalent of: 441 void 442 greet (const char *name) 443 @{ 444 printf ("hello %s\n", name); 445 @} 446 */ 447 gcc_jit_type *void_type = 448 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); 449 gcc_jit_type *const_char_ptr_type = 450 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); 451 gcc_jit_param *param_name = 452 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); 453 gcc_jit_function *func = 454 gcc_jit_context_new_function (ctxt, NULL, 455 GCC_JIT_FUNCTION_EXPORTED, 456 void_type, 457 "greet", 458 1, ¶m_name, 459 0); 460 461 gcc_jit_param *param_format = 462 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); 463 gcc_jit_function *printf_func = 464 gcc_jit_context_new_function (ctxt, NULL, 465 GCC_JIT_FUNCTION_IMPORTED, 466 gcc_jit_context_get_type ( 467 ctxt, GCC_JIT_TYPE_INT), 468 "printf", 469 1, ¶m_format, 470 1); 471 gcc_jit_rvalue *args[2]; 472 args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); 473 args[1] = gcc_jit_param_as_rvalue (param_name); 474 475 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 476 477 gcc_jit_block_add_eval ( 478 block, NULL, 479 gcc_jit_context_new_call (ctxt, 480 NULL, 481 printf_func, 482 2, args)); 483 gcc_jit_block_end_with_void_return (block, NULL); 484@} 485 486int 487main (int argc, char **argv) 488@{ 489 gcc_jit_context *ctxt; 490 gcc_jit_result *result; 491 492 /* Get a "context" object for working with the library. */ 493 ctxt = gcc_jit_context_acquire (); 494 if (!ctxt) 495 @{ 496 fprintf (stderr, "NULL ctxt"); 497 exit (1); 498 @} 499 500 /* Set some options on the context. 501 Let's see the code being generated, in assembler form. */ 502 gcc_jit_context_set_bool_option ( 503 ctxt, 504 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 505 0); 506 507 /* Populate the context. */ 508 create_code (ctxt); 509 510 /* Compile the code. */ 511 result = gcc_jit_context_compile (ctxt); 512 if (!result) 513 @{ 514 fprintf (stderr, "NULL result"); 515 exit (1); 516 @} 517 518 /* Extract the generated code from "result". */ 519 typedef void (*fn_type) (const char *); 520 fn_type greet = 521 (fn_type)gcc_jit_result_get_code (result, "greet"); 522 if (!greet) 523 @{ 524 fprintf (stderr, "NULL greet"); 525 exit (1); 526 @} 527 528 /* Now call the generated function: */ 529 greet ("world"); 530 fflush (stdout); 531 532 gcc_jit_context_release (ctxt); 533 gcc_jit_result_release (result); 534 return 0; 535@} 536 537@end example 538 539@noindent 540@end quotation 541 542Copy the above to @cite{tut01-hello-world.c}. 543 544Assuming you have the jit library installed, build the test program 545using: 546 547@example 548$ gcc \ 549 tut01-hello-world.c \ 550 -o tut01-hello-world \ 551 -lgccjit 552@end example 553 554@noindent 555 556You should then be able to run the built program: 557 558@example 559$ ./tut01-hello-world 560hello world 561@end example 562 563@noindent 564 565@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 566@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 567@c 568@c This is free software: you can redistribute it and/or modify it 569@c under the terms of the GNU General Public License as published by 570@c the Free Software Foundation, either version 3 of the License, or 571@c (at your option) any later version. 572@c 573@c This program is distributed in the hope that it will be useful, but 574@c WITHOUT ANY WARRANTY; without even the implied warranty of 575@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 576@c General Public License for more details. 577@c 578@c You should have received a copy of the GNU General Public License 579@c along with this program. If not, see 580@c <http://www.gnu.org/licenses/>. 581 582@node Tutorial part 2 Creating a trivial machine code function,Tutorial part 3 Loops and variables,Tutorial part 1 "Hello world",Tutorial 583@anchor{intro/tutorial02 doc}@anchor{6}@anchor{intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{7} 584@section Tutorial part 2: Creating a trivial machine code function 585 586 587Consider this C function: 588 589@example 590int square (int i) 591@{ 592 return i * i; 593@} 594@end example 595 596@noindent 597 598How can we construct this at run-time using libgccjit? 599 600First we need to include the relevant header: 601 602@example 603#include <libgccjit.h> 604@end example 605 606@noindent 607 608All state associated with compilation is associated with a 609@pxref{8,,gcc_jit_context *}. 610 611Create one using @pxref{9,,gcc_jit_context_acquire()}: 612 613@example 614gcc_jit_context *ctxt; 615ctxt = gcc_jit_context_acquire (); 616@end example 617 618@noindent 619 620The JIT library has a system of types. It is statically-typed: every 621expression is of a specific type, fixed at compile-time. In our example, 622all of the expressions are of the C @cite{int} type, so let's obtain this from 623the context, as a @pxref{a,,gcc_jit_type *}, using 624@pxref{b,,gcc_jit_context_get_type()}: 625 626@example 627gcc_jit_type *int_type = 628 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 629@end example 630 631@noindent 632 633@pxref{a,,gcc_jit_type *} is an example of a "contextual" object: every 634entity in the API is associated with a @pxref{8,,gcc_jit_context *}. 635 636Memory management is easy: all such "contextual" objects are automatically 637cleaned up for you when the context is released, using 638@pxref{c,,gcc_jit_context_release()}: 639 640@example 641gcc_jit_context_release (ctxt); 642@end example 643 644@noindent 645 646so you don't need to manually track and cleanup all objects, just the 647contexts. 648 649Although the API is C-based, there is a form of class hierarchy, which 650looks like this: 651 652@example 653+- gcc_jit_object 654 +- gcc_jit_location 655 +- gcc_jit_type 656 +- gcc_jit_struct 657 +- gcc_jit_field 658 +- gcc_jit_function 659 +- gcc_jit_block 660 +- gcc_jit_rvalue 661 +- gcc_jit_lvalue 662 +- gcc_jit_param 663@end example 664 665@noindent 666 667There are casting methods for upcasting from subclasses to parent classes. 668For example, @pxref{d,,gcc_jit_type_as_object()}: 669 670@example 671gcc_jit_object *obj = gcc_jit_type_as_object (int_type); 672@end example 673 674@noindent 675 676One thing you can do with a @pxref{e,,gcc_jit_object *} is 677to ask it for a human-readable description, using 678@pxref{f,,gcc_jit_object_get_debug_string()}: 679 680@example 681printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); 682@end example 683 684@noindent 685 686giving this text on stdout: 687 688@example 689obj: int 690@end example 691 692@noindent 693 694This is invaluable when debugging. 695 696Let's create the function. To do so, we first need to construct 697its single parameter, specifying its type and giving it a name, 698using @pxref{10,,gcc_jit_context_new_param()}: 699 700@example 701gcc_jit_param *param_i = 702 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 703@end example 704 705@noindent 706 707Now we can create the function, using 708@pxref{11,,gcc_jit_context_new_function()}: 709 710@example 711gcc_jit_function *func = 712 gcc_jit_context_new_function (ctxt, NULL, 713 GCC_JIT_FUNCTION_EXPORTED, 714 int_type, 715 "square", 716 1, ¶m_i, 717 0); 718@end example 719 720@noindent 721 722To define the code within the function, we must create basic blocks 723containing statements. 724 725Every basic block contains a list of statements, eventually terminated 726by a statement that either returns, or jumps to another basic block. 727 728Our function has no control-flow, so we just need one basic block: 729 730@example 731gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 732@end example 733 734@noindent 735 736Our basic block is relatively simple: it immediately terminates by 737returning the value of an expression. 738 739We can build the expression using @pxref{12,,gcc_jit_context_new_binary_op()}: 740 741@example 742gcc_jit_rvalue *expr = 743 gcc_jit_context_new_binary_op ( 744 ctxt, NULL, 745 GCC_JIT_BINARY_OP_MULT, int_type, 746 gcc_jit_param_as_rvalue (param_i), 747 gcc_jit_param_as_rvalue (param_i)); 748@end example 749 750@noindent 751 752A @pxref{13,,gcc_jit_rvalue *} is another example of a 753@pxref{e,,gcc_jit_object *} subclass. We can upcast it using 754@pxref{14,,gcc_jit_rvalue_as_object()} and as before print it with 755@pxref{f,,gcc_jit_object_get_debug_string()}. 756 757@example 758printf ("expr: %s\n", 759 gcc_jit_object_get_debug_string ( 760 gcc_jit_rvalue_as_object (expr))); 761@end example 762 763@noindent 764 765giving this output: 766 767@example 768expr: i * i 769@end example 770 771@noindent 772 773Creating the expression in itself doesn't do anything; we have to add 774this expression to a statement within the block. In this case, we use it 775to build a return statement, which terminates the basic block: 776 777@example 778gcc_jit_block_end_with_return (block, NULL, expr); 779@end example 780 781@noindent 782 783OK, we've populated the context. We can now compile it using 784@pxref{15,,gcc_jit_context_compile()}: 785 786@example 787gcc_jit_result *result; 788result = gcc_jit_context_compile (ctxt); 789@end example 790 791@noindent 792 793and get a @pxref{16,,gcc_jit_result *}. 794 795At this point we're done with the context; we can release it: 796 797@example 798gcc_jit_context_release (ctxt); 799@end example 800 801@noindent 802 803We can now use @pxref{17,,gcc_jit_result_get_code()} to look up a specific 804machine code routine within the result, in this case, the function we 805created above. 806 807@example 808void *fn_ptr = gcc_jit_result_get_code (result, "square"); 809if (!fn_ptr) 810 @{ 811 fprintf (stderr, "NULL fn_ptr"); 812 goto error; 813 @} 814@end example 815 816@noindent 817 818We can now cast the pointer to an appropriate function pointer type, and 819then call it: 820 821@example 822typedef int (*fn_type) (int); 823fn_type square = (fn_type)fn_ptr; 824printf ("result: %d", square (5)); 825@end example 826 827@noindent 828 829@example 830result: 25 831@end example 832 833@noindent 834 835Once we're done with the code, we can release the result: 836 837@example 838gcc_jit_result_release (result); 839@end example 840 841@noindent 842 843We can't call @code{square} anymore once we've released @code{result}. 844 845@menu 846* Error-handling:: 847* Options:: 848* Full example:: 849 850@end menu 851 852@node Error-handling,Options,,Tutorial part 2 Creating a trivial machine code function 853@anchor{intro/tutorial02 error-handling}@anchor{18} 854@subsection Error-handling 855 856 857Various kinds of errors are possible when using the API, such as 858mismatched types in an assignment. You can only compile and get code 859from a context if no errors occur. 860 861Errors are printed on stderr; they typically contain the name of the API 862entrypoint where the error occurred, and pertinent information on the 863problem: 864 865@example 866./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *) 867@end example 868 869@noindent 870 871The API is designed to cope with errors without crashing, so you can get 872away with having a single error-handling check in your code: 873 874@example 875void *fn_ptr = gcc_jit_result_get_code (result, "square"); 876if (!fn_ptr) 877 @{ 878 fprintf (stderr, "NULL fn_ptr"); 879 goto error; 880 @} 881@end example 882 883@noindent 884 885For more information, see the @pxref{19,,error-handling guide} 886within the Topic eference. 887 888@node Options,Full example,Error-handling,Tutorial part 2 Creating a trivial machine code function 889@anchor{intro/tutorial02 options}@anchor{1a} 890@subsection Options 891 892 893To get more information on what's going on, you can set debugging flags 894on the context using @pxref{1b,,gcc_jit_context_set_bool_option()}. 895 896@c (I'm deliberately not mentioning 897@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think 898@c it's probably more of use to implementors than to users) 899 900Setting @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a 901C-like representation to stderr when you compile (GCC's "GIMPLE" 902representation): 903 904@example 905gcc_jit_context_set_bool_option ( 906 ctxt, 907 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 908 1); 909result = gcc_jit_context_compile (ctxt); 910@end example 911 912@noindent 913 914@example 915square (signed int i) 916@{ 917 signed int D.260; 918 919 entry: 920 D.260 = i * i; 921 return D.260; 922@} 923@end example 924 925@noindent 926 927We can see the generated machine code in assembler form (on stderr) by 928setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context 929before compiling: 930 931@example 932gcc_jit_context_set_bool_option ( 933 ctxt, 934 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 935 1); 936result = gcc_jit_context_compile (ctxt); 937@end example 938 939@noindent 940 941@example 942 .file "fake.c" 943 .text 944 .globl square 945 .type square, @@function 946square: 947.LFB6: 948 .cfi_startproc 949 pushq %rbp 950 .cfi_def_cfa_offset 16 951 .cfi_offset 6, -16 952 movq %rsp, %rbp 953 .cfi_def_cfa_register 6 954 movl %edi, -4(%rbp) 955.L14: 956 movl -4(%rbp), %eax 957 imull -4(%rbp), %eax 958 popq %rbp 959 .cfi_def_cfa 7, 8 960 ret 961 .cfi_endproc 962.LFE6: 963 .size square, .-square 964 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 965 .section .note.GNU-stack,"",@@progbits 966@end example 967 968@noindent 969 970By default, no optimizations are performed, the equivalent of GCC's 971@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling 972@pxref{1e,,gcc_jit_context_set_int_option()} with 973@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 974 975@example 976gcc_jit_context_set_int_option ( 977 ctxt, 978 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 979 3); 980@end example 981 982@noindent 983 984@example 985 .file "fake.c" 986 .text 987 .p2align 4,,15 988 .globl square 989 .type square, @@function 990square: 991.LFB7: 992 .cfi_startproc 993.L16: 994 movl %edi, %eax 995 imull %edi, %eax 996 ret 997 .cfi_endproc 998.LFE7: 999 .size square, .-square 1000 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 1001 .section .note.GNU-stack,"",@@progbits 1002@end example 1003 1004@noindent 1005 1006Naturally this has only a small effect on such a trivial function. 1007 1008@node Full example,,Options,Tutorial part 2 Creating a trivial machine code function 1009@anchor{intro/tutorial02 full-example}@anchor{20} 1010@subsection Full example 1011 1012 1013Here's what the above looks like as a complete program: 1014 1015@quotation 1016 1017@example 1018/* Usage example for libgccjit.so 1019 Copyright (C) 2014-2015 Free Software Foundation, Inc. 1020 1021This file is part of GCC. 1022 1023GCC is free software; you can redistribute it and/or modify it 1024under the terms of the GNU General Public License as published by 1025the Free Software Foundation; either version 3, or (at your option) 1026any later version. 1027 1028GCC is distributed in the hope that it will be useful, but 1029WITHOUT ANY WARRANTY; without even the implied warranty of 1030MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1031General Public License for more details. 1032 1033You should have received a copy of the GNU General Public License 1034along with GCC; see the file COPYING3. If not see 1035<http://www.gnu.org/licenses/>. */ 1036 1037#include <libgccjit.h> 1038 1039#include <stdlib.h> 1040#include <stdio.h> 1041 1042void 1043create_code (gcc_jit_context *ctxt) 1044@{ 1045 /* Let's try to inject the equivalent of: 1046 1047 int square (int i) 1048 @{ 1049 return i * i; 1050 @} 1051 */ 1052 gcc_jit_type *int_type = 1053 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1054 gcc_jit_param *param_i = 1055 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 1056 gcc_jit_function *func = 1057 gcc_jit_context_new_function (ctxt, NULL, 1058 GCC_JIT_FUNCTION_EXPORTED, 1059 int_type, 1060 "square", 1061 1, ¶m_i, 1062 0); 1063 1064 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 1065 1066 gcc_jit_rvalue *expr = 1067 gcc_jit_context_new_binary_op ( 1068 ctxt, NULL, 1069 GCC_JIT_BINARY_OP_MULT, int_type, 1070 gcc_jit_param_as_rvalue (param_i), 1071 gcc_jit_param_as_rvalue (param_i)); 1072 1073 gcc_jit_block_end_with_return (block, NULL, expr); 1074@} 1075 1076int 1077main (int argc, char **argv) 1078@{ 1079 gcc_jit_context *ctxt = NULL; 1080 gcc_jit_result *result = NULL; 1081 1082 /* Get a "context" object for working with the library. */ 1083 ctxt = gcc_jit_context_acquire (); 1084 if (!ctxt) 1085 @{ 1086 fprintf (stderr, "NULL ctxt"); 1087 goto error; 1088 @} 1089 1090 /* Set some options on the context. 1091 Let's see the code being generated, in assembler form. */ 1092 gcc_jit_context_set_bool_option ( 1093 ctxt, 1094 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1095 0); 1096 1097 /* Populate the context. */ 1098 create_code (ctxt); 1099 1100 /* Compile the code. */ 1101 result = gcc_jit_context_compile (ctxt); 1102 if (!result) 1103 @{ 1104 fprintf (stderr, "NULL result"); 1105 goto error; 1106 @} 1107 1108 /* We're done with the context; we can release it: */ 1109 gcc_jit_context_release (ctxt); 1110 ctxt = NULL; 1111 1112 /* Extract the generated code from "result". */ 1113 void *fn_ptr = gcc_jit_result_get_code (result, "square"); 1114 if (!fn_ptr) 1115 @{ 1116 fprintf (stderr, "NULL fn_ptr"); 1117 goto error; 1118 @} 1119 1120 typedef int (*fn_type) (int); 1121 fn_type square = (fn_type)fn_ptr; 1122 printf ("result: %d\n", square (5)); 1123 1124 error: 1125 if (ctxt) 1126 gcc_jit_context_release (ctxt); 1127 if (result) 1128 gcc_jit_result_release (result); 1129 return 0; 1130@} 1131 1132@end example 1133 1134@noindent 1135@end quotation 1136 1137Building and running it: 1138 1139@example 1140$ gcc \ 1141 tut02-square.c \ 1142 -o tut02-square \ 1143 -lgccjit 1144 1145# Run the built program: 1146$ ./tut02-square 1147result: 25 1148@end example 1149 1150@noindent 1151 1152@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 1153@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 1154@c 1155@c This is free software: you can redistribute it and/or modify it 1156@c under the terms of the GNU General Public License as published by 1157@c the Free Software Foundation, either version 3 of the License, or 1158@c (at your option) any later version. 1159@c 1160@c This program is distributed in the hope that it will be useful, but 1161@c WITHOUT ANY WARRANTY; without even the implied warranty of 1162@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1163@c General Public License for more details. 1164@c 1165@c You should have received a copy of the GNU General Public License 1166@c along with this program. If not, see 1167@c <http://www.gnu.org/licenses/>. 1168 1169@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 1170@anchor{intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{21}@anchor{intro/tutorial03 doc}@anchor{22} 1171@section Tutorial part 3: Loops and variables 1172 1173 1174Consider this C function: 1175 1176@quotation 1177 1178@example 1179int loop_test (int n) 1180@{ 1181 int sum = 0; 1182 for (int i = 0; i < n; i++) 1183 sum += i * i; 1184 return sum; 1185@} 1186@end example 1187 1188@noindent 1189@end quotation 1190 1191This example demonstrates some more features of libgccjit, with local 1192variables and a loop. 1193 1194To break this down into libgccjit terms, it's usually easier to reword 1195the @cite{for} loop as a @cite{while} loop, giving: 1196 1197@quotation 1198 1199@example 1200int loop_test (int n) 1201@{ 1202 int sum = 0; 1203 int i = 0; 1204 while (i < n) 1205 @{ 1206 sum += i * i; 1207 i++; 1208 @} 1209 return sum; 1210@} 1211@end example 1212 1213@noindent 1214@end quotation 1215 1216Here's what the final control flow graph will look like: 1217 1218@quotation 1219 1220 1221@float Figure 1222 1223@image{sum-of-squares1,,,image of a control flow graph,png} 1224 1225@end float 1226 1227@end quotation 1228 1229As before, we include the libgccjit header and make a 1230@pxref{8,,gcc_jit_context *}. 1231 1232@example 1233#include <libgccjit.h> 1234 1235void test (void) 1236@{ 1237 gcc_jit_context *ctxt; 1238 ctxt = gcc_jit_context_acquire (); 1239@end example 1240 1241@noindent 1242 1243The function works with the C @cite{int} type: 1244 1245@example 1246gcc_jit_type *the_type = 1247 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1248gcc_jit_type *return_type = the_type; 1249@end example 1250 1251@noindent 1252 1253though we could equally well make it work on, say, @cite{double}: 1254 1255@example 1256gcc_jit_type *the_type = 1257 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE); 1258@end example 1259 1260@noindent 1261 1262Let's build the function: 1263 1264@example 1265gcc_jit_param *n = 1266 gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); 1267gcc_jit_param *params[1] = @{n@}; 1268gcc_jit_function *func = 1269 gcc_jit_context_new_function (ctxt, NULL, 1270 GCC_JIT_FUNCTION_EXPORTED, 1271 return_type, 1272 "loop_test", 1273 1, params, 0); 1274@end example 1275 1276@noindent 1277 1278@menu 1279* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. 1280* Control flow:: 1281* Visualizing the control flow graph:: 1282* Full example: Full example<2>. 1283 1284@end menu 1285 1286@node Expressions lvalues and rvalues,Control flow,,Tutorial part 3 Loops and variables 1287@anchor{intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{23} 1288@subsection Expressions: lvalues and rvalues 1289 1290 1291The base class of expression is the @pxref{13,,gcc_jit_rvalue *}, 1292representing an expression that can be on the @emph{right}-hand side of 1293an assignment: a value that can be computed somehow, and assigned 1294@emph{to} a storage area (such as a variable). It has a specific 1295@pxref{a,,gcc_jit_type *}. 1296 1297Anothe important class is @pxref{24,,gcc_jit_lvalue *}. 1298A @pxref{24,,gcc_jit_lvalue *}. is something that can of the @emph{left}-hand 1299side of an assignment: a storage area (such as a variable). 1300 1301In other words, every assignment can be thought of as: 1302 1303@example 1304LVALUE = RVALUE; 1305@end example 1306 1307@noindent 1308 1309Note that @pxref{24,,gcc_jit_lvalue *} is a subclass of 1310@pxref{13,,gcc_jit_rvalue *}, where in an assignment of the form: 1311 1312@example 1313LVALUE_A = LVALUE_B; 1314@end example 1315 1316@noindent 1317 1318the @cite{LVALUE_B} implies reading the current value of that storage 1319area, assigning it into the @cite{LVALUE_A}. 1320 1321So far the only expressions we've seen are @cite{i * i}: 1322 1323@example 1324gcc_jit_rvalue *expr = 1325 gcc_jit_context_new_binary_op ( 1326 ctxt, NULL, 1327 GCC_JIT_BINARY_OP_MULT, int_type, 1328 gcc_jit_param_as_rvalue (param_i), 1329 gcc_jit_param_as_rvalue (param_i)); 1330@end example 1331 1332@noindent 1333 1334which is a @pxref{13,,gcc_jit_rvalue *}, and the various function 1335parameters: @cite{param_i} and @cite{param_n}, instances of 1336@pxref{25,,gcc_jit_param *}, which is a subclass of 1337@pxref{24,,gcc_jit_lvalue *} (and, in turn, of @pxref{13,,gcc_jit_rvalue *}): 1338we can both read from and write to function parameters within the 1339body of a function. 1340 1341Our new example has a couple of local variables. We create them by 1342calling @pxref{26,,gcc_jit_function_new_local()}, supplying a type and a 1343name: 1344 1345@example 1346/* Build locals: */ 1347gcc_jit_lvalue *i = 1348 gcc_jit_function_new_local (func, NULL, the_type, "i"); 1349gcc_jit_lvalue *sum = 1350 gcc_jit_function_new_local (func, NULL, the_type, "sum"); 1351@end example 1352 1353@noindent 1354 1355These are instances of @pxref{24,,gcc_jit_lvalue *} - they can be read from 1356and written to. 1357 1358Note that there is no precanned way to create @emph{and} initialize a variable 1359like in C: 1360 1361@example 1362int i = 0; 1363@end example 1364 1365@noindent 1366 1367Instead, having added the local to the function, we have to separately add 1368an assignment of @cite{0} to @cite{local_i} at the beginning of the function. 1369 1370@node Control flow,Visualizing the control flow graph,Expressions lvalues and rvalues,Tutorial part 3 Loops and variables 1371@anchor{intro/tutorial03 control-flow}@anchor{27} 1372@subsection Control flow 1373 1374 1375This function has a loop, so we need to build some basic blocks to 1376handle the control flow. In this case, we need 4 blocks: 1377 1378 1379@enumerate 1380 1381@item 1382before the loop (initializing the locals) 1383 1384@item 1385the conditional at the top of the loop (comparing @cite{i < n}) 1386 1387@item 1388the body of the loop 1389 1390@item 1391after the loop terminates (@cite{return sum}) 1392@end enumerate 1393 1394so we create these as @pxref{28,,gcc_jit_block *} instances within the 1395@pxref{29,,gcc_jit_function *}: 1396 1397@example 1398gcc_jit_block *b_initial = 1399 gcc_jit_function_new_block (func, "initial"); 1400gcc_jit_block *b_loop_cond = 1401 gcc_jit_function_new_block (func, "loop_cond"); 1402gcc_jit_block *b_loop_body = 1403 gcc_jit_function_new_block (func, "loop_body"); 1404gcc_jit_block *b_after_loop = 1405 gcc_jit_function_new_block (func, "after_loop"); 1406@end example 1407 1408@noindent 1409 1410We now populate each block with statements. 1411 1412The entry block @cite{b_initial} consists of initializations followed by a jump 1413to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using 1414@pxref{2a,,gcc_jit_block_add_assignment()} to add 1415an assignment statement, and using @pxref{2b,,gcc_jit_context_zero()} to get 1416the constant value @cite{0} for the relevant type for the right-hand side of 1417the assignment: 1418 1419@example 1420/* sum = 0; */ 1421gcc_jit_block_add_assignment ( 1422 b_initial, NULL, 1423 sum, 1424 gcc_jit_context_zero (ctxt, the_type)); 1425 1426/* i = 0; */ 1427gcc_jit_block_add_assignment ( 1428 b_initial, NULL, 1429 i, 1430 gcc_jit_context_zero (ctxt, the_type)); 1431@end example 1432 1433@noindent 1434 1435We can then terminate the entry block by jumping to the conditional: 1436 1437@example 1438gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); 1439@end example 1440 1441@noindent 1442 1443The conditional block is equivalent to the line @cite{while (i < n)} from our 1444C example. It contains a single statement: a conditional, which jumps to 1445one of two destination blocks depending on a boolean 1446@pxref{13,,gcc_jit_rvalue *}, in this case the comparison of @cite{i} and @cite{n}. 1447We build the comparison using @pxref{2c,,gcc_jit_context_new_comparison()}: 1448 1449@example 1450/* (i >= n) */ 1451 gcc_jit_rvalue *guard = 1452 gcc_jit_context_new_comparison ( 1453 ctxt, NULL, 1454 GCC_JIT_COMPARISON_GE, 1455 gcc_jit_lvalue_as_rvalue (i), 1456 gcc_jit_param_as_rvalue (n)); 1457@end example 1458 1459@noindent 1460 1461and can then use this to add @cite{b_loop_cond}'s sole statement, via 1462@pxref{2d,,gcc_jit_block_end_with_conditional()}: 1463 1464@example 1465/* Equivalent to: 1466 if (guard) 1467 goto after_loop; 1468 else 1469 goto loop_body; */ 1470gcc_jit_block_end_with_conditional ( 1471 b_loop_cond, NULL, 1472 guard, 1473 b_after_loop, /* on_true */ 1474 b_loop_body); /* on_false */ 1475@end example 1476 1477@noindent 1478 1479Next, we populate the body of the loop. 1480 1481The C statement @cite{sum += i * i;} is an assignment operation, where an 1482lvalue is modified "in-place". We use 1483@pxref{2e,,gcc_jit_block_add_assignment_op()} to handle these operations: 1484 1485@example 1486/* sum += i * i */ 1487gcc_jit_block_add_assignment_op ( 1488 b_loop_body, NULL, 1489 sum, 1490 GCC_JIT_BINARY_OP_PLUS, 1491 gcc_jit_context_new_binary_op ( 1492 ctxt, NULL, 1493 GCC_JIT_BINARY_OP_MULT, the_type, 1494 gcc_jit_lvalue_as_rvalue (i), 1495 gcc_jit_lvalue_as_rvalue (i))); 1496@end example 1497 1498@noindent 1499 1500The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in 1501a similar way. We use @pxref{2f,,gcc_jit_context_one()} to get the constant 1502value @cite{1} (for the relevant type) for the right-hand side 1503of the assignment. 1504 1505@example 1506/* i++ */ 1507gcc_jit_block_add_assignment_op ( 1508 b_loop_body, NULL, 1509 i, 1510 GCC_JIT_BINARY_OP_PLUS, 1511 gcc_jit_context_one (ctxt, the_type)); 1512@end example 1513 1514@noindent 1515 1516@cartouche 1517@quotation Note 1518For numeric constants other than 0 or 1, we could use 1519@pxref{30,,gcc_jit_context_new_rvalue_from_int()} and 1520@pxref{31,,gcc_jit_context_new_rvalue_from_double()}. 1521@end quotation 1522@end cartouche 1523 1524The loop body completes by jumping back to the conditional: 1525 1526@example 1527gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); 1528@end example 1529 1530@noindent 1531 1532Finally, we populate the @cite{b_after_loop} block, reached when the loop 1533conditional is false. We want to generate the equivalent of: 1534 1535@example 1536return sum; 1537@end example 1538 1539@noindent 1540 1541so the block is just one statement: 1542 1543@example 1544/* return sum */ 1545gcc_jit_block_end_with_return ( 1546 b_after_loop, 1547 NULL, 1548 gcc_jit_lvalue_as_rvalue (sum)); 1549@end example 1550 1551@noindent 1552 1553@cartouche 1554@quotation Note 1555You can intermingle block creation with statement creation, 1556but given that the terminator statements generally include references 1557to other blocks, I find it's clearer to create all the blocks, 1558@emph{then} all the statements. 1559@end quotation 1560@end cartouche 1561 1562We've finished populating the function. As before, we can now compile it 1563to machine code: 1564 1565@example 1566gcc_jit_result *result; 1567result = gcc_jit_context_compile (ctxt); 1568 1569typedef int (*loop_test_fn_type) (int); 1570loop_test_fn_type loop_test = 1571 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 1572if (!loop_test) 1573 goto error; 1574printf ("result: %d", loop_test (10)); 1575@end example 1576 1577@noindent 1578 1579@example 1580result: 285 1581@end example 1582 1583@noindent 1584 1585@node Visualizing the control flow graph,Full example<2>,Control flow,Tutorial part 3 Loops and variables 1586@anchor{intro/tutorial03 visualizing-the-control-flow-graph}@anchor{32} 1587@subsection Visualizing the control flow graph 1588 1589 1590You can see the control flow graph of a function using 1591@pxref{33,,gcc_jit_function_dump_to_dot()}: 1592 1593@example 1594gcc_jit_function_dump_to_dot (func, "/tmp/sum-of-squares.dot"); 1595@end example 1596 1597@noindent 1598 1599giving a .dot file in GraphViz format. 1600 1601You can convert this to an image using @cite{dot}: 1602 1603@example 1604$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png 1605@end example 1606 1607@noindent 1608 1609or use a viewer (my preferred one is xdot.py; see 1610@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can 1611install it with @cite{yum install python-xdot}): 1612 1613@quotation 1614 1615 1616@float Figure 1617 1618@image{sum-of-squares1,,,image of a control flow graph,png} 1619 1620@end float 1621 1622@end quotation 1623 1624@node Full example<2>,,Visualizing the control flow graph,Tutorial part 3 Loops and variables 1625@anchor{intro/tutorial03 full-example}@anchor{34} 1626@subsection Full example 1627 1628 1629@quotation 1630 1631@example 1632/* Usage example for libgccjit.so 1633 Copyright (C) 2014-2015 Free Software Foundation, Inc. 1634 1635This file is part of GCC. 1636 1637GCC is free software; you can redistribute it and/or modify it 1638under the terms of the GNU General Public License as published by 1639the Free Software Foundation; either version 3, or (at your option) 1640any later version. 1641 1642GCC is distributed in the hope that it will be useful, but 1643WITHOUT ANY WARRANTY; without even the implied warranty of 1644MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1645General Public License for more details. 1646 1647You should have received a copy of the GNU General Public License 1648along with GCC; see the file COPYING3. If not see 1649<http://www.gnu.org/licenses/>. */ 1650 1651#include <libgccjit.h> 1652 1653#include <stdlib.h> 1654#include <stdio.h> 1655 1656void 1657create_code (gcc_jit_context *ctxt) 1658@{ 1659 /* 1660 Simple sum-of-squares, to test conditionals and looping 1661 1662 int loop_test (int n) 1663 @{ 1664 int i; 1665 int sum = 0; 1666 for (i = 0; i < n ; i ++) 1667 @{ 1668 sum += i * i; 1669 @} 1670 return sum; 1671 */ 1672 gcc_jit_type *the_type = 1673 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1674 gcc_jit_type *return_type = the_type; 1675 1676 gcc_jit_param *n = 1677 gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); 1678 gcc_jit_param *params[1] = @{n@}; 1679 gcc_jit_function *func = 1680 gcc_jit_context_new_function (ctxt, NULL, 1681 GCC_JIT_FUNCTION_EXPORTED, 1682 return_type, 1683 "loop_test", 1684 1, params, 0); 1685 1686 /* Build locals: */ 1687 gcc_jit_lvalue *i = 1688 gcc_jit_function_new_local (func, NULL, the_type, "i"); 1689 gcc_jit_lvalue *sum = 1690 gcc_jit_function_new_local (func, NULL, the_type, "sum"); 1691 1692 gcc_jit_block *b_initial = 1693 gcc_jit_function_new_block (func, "initial"); 1694 gcc_jit_block *b_loop_cond = 1695 gcc_jit_function_new_block (func, "loop_cond"); 1696 gcc_jit_block *b_loop_body = 1697 gcc_jit_function_new_block (func, "loop_body"); 1698 gcc_jit_block *b_after_loop = 1699 gcc_jit_function_new_block (func, "after_loop"); 1700 1701 /* sum = 0; */ 1702 gcc_jit_block_add_assignment ( 1703 b_initial, NULL, 1704 sum, 1705 gcc_jit_context_zero (ctxt, the_type)); 1706 1707 /* i = 0; */ 1708 gcc_jit_block_add_assignment ( 1709 b_initial, NULL, 1710 i, 1711 gcc_jit_context_zero (ctxt, the_type)); 1712 1713 gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); 1714 1715 /* if (i >= n) */ 1716 gcc_jit_block_end_with_conditional ( 1717 b_loop_cond, NULL, 1718 gcc_jit_context_new_comparison ( 1719 ctxt, NULL, 1720 GCC_JIT_COMPARISON_GE, 1721 gcc_jit_lvalue_as_rvalue (i), 1722 gcc_jit_param_as_rvalue (n)), 1723 b_after_loop, 1724 b_loop_body); 1725 1726 /* sum += i * i */ 1727 gcc_jit_block_add_assignment_op ( 1728 b_loop_body, NULL, 1729 sum, 1730 GCC_JIT_BINARY_OP_PLUS, 1731 gcc_jit_context_new_binary_op ( 1732 ctxt, NULL, 1733 GCC_JIT_BINARY_OP_MULT, the_type, 1734 gcc_jit_lvalue_as_rvalue (i), 1735 gcc_jit_lvalue_as_rvalue (i))); 1736 1737 /* i++ */ 1738 gcc_jit_block_add_assignment_op ( 1739 b_loop_body, NULL, 1740 i, 1741 GCC_JIT_BINARY_OP_PLUS, 1742 gcc_jit_context_one (ctxt, the_type)); 1743 1744 gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); 1745 1746 /* return sum */ 1747 gcc_jit_block_end_with_return ( 1748 b_after_loop, 1749 NULL, 1750 gcc_jit_lvalue_as_rvalue (sum)); 1751@} 1752 1753int 1754main (int argc, char **argv) 1755@{ 1756 gcc_jit_context *ctxt = NULL; 1757 gcc_jit_result *result = NULL; 1758 1759 /* Get a "context" object for working with the library. */ 1760 ctxt = gcc_jit_context_acquire (); 1761 if (!ctxt) 1762 @{ 1763 fprintf (stderr, "NULL ctxt"); 1764 goto error; 1765 @} 1766 1767 /* Set some options on the context. 1768 Let's see the code being generated, in assembler form. */ 1769 gcc_jit_context_set_bool_option ( 1770 ctxt, 1771 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1772 0); 1773 1774 /* Populate the context. */ 1775 create_code (ctxt); 1776 1777 /* Compile the code. */ 1778 result = gcc_jit_context_compile (ctxt); 1779 if (!result) 1780 @{ 1781 fprintf (stderr, "NULL result"); 1782 goto error; 1783 @} 1784 1785 /* Extract the generated code from "result". */ 1786 typedef int (*loop_test_fn_type) (int); 1787 loop_test_fn_type loop_test = 1788 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 1789 if (!loop_test) 1790 @{ 1791 fprintf (stderr, "NULL loop_test"); 1792 goto error; 1793 @} 1794 1795 /* Run the generated code. */ 1796 int val = loop_test (10); 1797 printf("loop_test returned: %d\n", val); 1798 1799 error: 1800 gcc_jit_context_release (ctxt); 1801 gcc_jit_result_release (result); 1802 return 0; 1803@} 1804 1805@end example 1806 1807@noindent 1808@end quotation 1809 1810Building and running it: 1811 1812@example 1813$ gcc \ 1814 tut03-sum-of-squares.c \ 1815 -o tut03-sum-of-squares \ 1816 -lgccjit 1817 1818# Run the built program: 1819$ ./tut03-sum-of-squares 1820loop_test returned: 285 1821@end example 1822 1823@noindent 1824 1825@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 1826@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 1827@c 1828@c This is free software: you can redistribute it and/or modify it 1829@c under the terms of the GNU General Public License as published by 1830@c the Free Software Foundation, either version 3 of the License, or 1831@c (at your option) any later version. 1832@c 1833@c This program is distributed in the hope that it will be useful, but 1834@c WITHOUT ANY WARRANTY; without even the implied warranty of 1835@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1836@c General Public License for more details. 1837@c 1838@c You should have received a copy of the GNU General Public License 1839@c along with this program. If not, see 1840@c <http://www.gnu.org/licenses/>. 1841 1842@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 1843@anchor{intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{35}@anchor{intro/tutorial04 doc}@anchor{36} 1844@section Tutorial part 4: Adding JIT-compilation to a toy interpreter 1845 1846 1847In this example we construct a "toy" interpreter, and add JIT-compilation 1848to it. 1849 1850@menu 1851* Our toy interpreter:: 1852* Compiling to machine code:: 1853* Setting things up:: 1854* Populating the function:: 1855* Verifying the control flow graph:: 1856* Compiling the context:: 1857* Single-stepping through the generated code:: 1858* Examining the generated code:: 1859* Putting it all together:: 1860* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?. 1861 1862@end menu 1863 1864@node Our toy interpreter,Compiling to machine code,,Tutorial part 4 Adding JIT-compilation to a toy interpreter 1865@anchor{intro/tutorial04 our-toy-interpreter}@anchor{37} 1866@subsection Our toy interpreter 1867 1868 1869It's a stack-based interpreter, and is intended as a (very simple) example 1870of the kind of bytecode interpreter seen in dynamic languages such as 1871Python, Ruby etc. 1872 1873For the sake of simplicity, our toy virtual machine is very limited: 1874 1875@quotation 1876 1877 1878@itemize * 1879 1880@item 1881The only data type is @cite{int} 1882 1883@item 1884It can only work on one function at a time (so that the only 1885function call that can be made is to recurse). 1886 1887@item 1888Functions can only take one parameter. 1889 1890@item 1891Functions have a stack of @cite{int} values. 1892 1893@item 1894We'll implement function call within the interpreter by calling a 1895function in our implementation, rather than implementing our own 1896frame stack. 1897 1898@item 1899The parser is only good enough to get the examples to work. 1900@end itemize 1901@end quotation 1902 1903Naturally, a real interpreter would be much more complicated that this. 1904 1905The following operations are supported: 1906 1907 1908@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx} 1909@headitem 1910 1911Operation 1912 1913@tab 1914 1915Meaning 1916 1917@tab 1918 1919Old Stack 1920 1921@tab 1922 1923New Stack 1924 1925@item 1926 1927DUP 1928 1929@tab 1930 1931Duplicate top of stack. 1932 1933@tab 1934 1935@code{[..., x]} 1936 1937@tab 1938 1939@code{[..., x, x]} 1940 1941@item 1942 1943ROT 1944 1945@tab 1946 1947Swap top two elements 1948of stack. 1949 1950@tab 1951 1952@code{[..., x, y]} 1953 1954@tab 1955 1956@code{[..., y, x]} 1957 1958@item 1959 1960BINARY_ADD 1961 1962@tab 1963 1964Add the top two elements 1965on the stack. 1966 1967@tab 1968 1969@code{[..., x, y]} 1970 1971@tab 1972 1973@code{[..., (x+y)]} 1974 1975@item 1976 1977BINARY_SUBTRACT 1978 1979@tab 1980 1981Likewise, but subtract. 1982 1983@tab 1984 1985@code{[..., x, y]} 1986 1987@tab 1988 1989@code{[..., (x-y)]} 1990 1991@item 1992 1993BINARY_MULT 1994 1995@tab 1996 1997Likewise, but multiply. 1998 1999@tab 2000 2001@code{[..., x, y]} 2002 2003@tab 2004 2005@code{[..., (x*y)]} 2006 2007@item 2008 2009BINARY_COMPARE_LT 2010 2011@tab 2012 2013Compare the top two 2014elements on the stack 2015and push a nonzero/zero 2016if (x<y). 2017 2018@tab 2019 2020@code{[..., x, y]} 2021 2022@tab 2023 2024@code{[..., (x<y)]} 2025 2026@item 2027 2028RECURSE 2029 2030@tab 2031 2032Recurse, passing the top 2033of the stack, and 2034popping the result. 2035 2036@tab 2037 2038@code{[..., x]} 2039 2040@tab 2041 2042@code{[..., fn(x)]} 2043 2044@item 2045 2046RETURN 2047 2048@tab 2049 2050Return the top of the 2051stack. 2052 2053@tab 2054 2055@code{[x]} 2056 2057@tab 2058 2059@code{[]} 2060 2061@item 2062 2063PUSH_CONST @cite{arg} 2064 2065@tab 2066 2067Push an int const. 2068 2069@tab 2070 2071@code{[...]} 2072 2073@tab 2074 2075@code{[..., arg]} 2076 2077@item 2078 2079JUMP_ABS_IF_TRUE @cite{arg} 2080 2081@tab 2082 2083Pop; if top of stack was 2084nonzero, jump to 2085@code{arg}. 2086 2087@tab 2088 2089@code{[..., x]} 2090 2091@tab 2092 2093@code{[...]} 2094 2095@end multitable 2096 2097 2098Programs can be interpreted, disassembled, and compiled to machine code. 2099 2100The interpreter reads @code{.toy} scripts. Here's what a simple recursive 2101factorial program looks like, the script @code{factorial.toy}. 2102The parser ignores lines beginning with a @cite{#}. 2103 2104@quotation 2105 2106@example 2107# Simple recursive factorial implementation, roughly equivalent to: 2108# 2109# int factorial (int arg) 2110# @{ 2111# if (arg < 2) 2112# return arg 2113# return arg * factorial (arg - 1) 2114# @} 2115 2116# Initial state: 2117# stack: [arg] 2118 2119# 0: 2120DUP 2121# stack: [arg, arg] 2122 2123# 1: 2124PUSH_CONST 2 2125# stack: [arg, arg, 2] 2126 2127# 2: 2128BINARY_COMPARE_LT 2129# stack: [arg, (arg < 2)] 2130 2131# 3: 2132JUMP_ABS_IF_TRUE 9 2133# stack: [arg] 2134 2135# 4: 2136DUP 2137# stack: [arg, arg] 2138 2139# 5: 2140PUSH_CONST 1 2141# stack: [arg, arg, 1] 2142 2143# 6: 2144BINARY_SUBTRACT 2145# stack: [arg, (arg - 1) 2146 2147# 7: 2148RECURSE 2149# stack: [arg, factorial(arg - 1)] 2150 2151# 8: 2152BINARY_MULT 2153# stack: [arg * factorial(arg - 1)] 2154 2155# 9: 2156RETURN 2157 2158@end example 2159 2160@noindent 2161@end quotation 2162 2163The interpreter is a simple infinite loop with a big @code{switch} statement 2164based on what the next opcode is: 2165 2166@quotation 2167 2168@example 2169 2170static int 2171toyvm_function_interpret (toyvm_function *fn, int arg, FILE *trace) 2172@{ 2173 toyvm_frame frame; 2174#define PUSH(ARG) (toyvm_frame_push (&frame, (ARG))) 2175#define POP(ARG) (toyvm_frame_pop (&frame)) 2176 2177 frame.frm_function = fn; 2178 frame.frm_pc = 0; 2179 frame.frm_cur_depth = 0; 2180 2181 PUSH (arg); 2182 2183 while (1) 2184 @{ 2185 toyvm_op *op; 2186 int x, y; 2187 assert (frame.frm_pc < fn->fn_num_ops); 2188 op = &fn->fn_ops[frame.frm_pc++]; 2189 2190 if (trace) 2191 @{ 2192 toyvm_frame_dump_stack (&frame, trace); 2193 toyvm_function_disassemble_op (fn, op, frame.frm_pc, trace); 2194 @} 2195 2196 switch (op->op_opcode) 2197 @{ 2198 /* Ops taking no operand. */ 2199 case DUP: 2200 x = POP (); 2201 PUSH (x); 2202 PUSH (x); 2203 break; 2204 2205 case ROT: 2206 y = POP (); 2207 x = POP (); 2208 PUSH (y); 2209 PUSH (x); 2210 break; 2211 2212 case BINARY_ADD: 2213 y = POP (); 2214 x = POP (); 2215 PUSH (x + y); 2216 break; 2217 2218 case BINARY_SUBTRACT: 2219 y = POP (); 2220 x = POP (); 2221 PUSH (x - y); 2222 break; 2223 2224 case BINARY_MULT: 2225 y = POP (); 2226 x = POP (); 2227 PUSH (x * y); 2228 break; 2229 2230 case BINARY_COMPARE_LT: 2231 y = POP (); 2232 x = POP (); 2233 PUSH (x < y); 2234 break; 2235 2236 case RECURSE: 2237 x = POP (); 2238 x = toyvm_function_interpret (fn, x, trace); 2239 PUSH (x); 2240 break; 2241 2242 case RETURN: 2243 return POP (); 2244 2245 /* Ops taking an operand. */ 2246 case PUSH_CONST: 2247 PUSH (op->op_operand); 2248 break; 2249 2250 case JUMP_ABS_IF_TRUE: 2251 x = POP (); 2252 if (x) 2253 frame.frm_pc = op->op_operand; 2254 break; 2255 2256 default: 2257 assert (0); /* unknown opcode */ 2258 2259 @} /* end of switch on opcode */ 2260 @} /* end of while loop */ 2261 2262#undef PUSH 2263#undef POP 2264@} 2265 2266 2267@end example 2268 2269@noindent 2270@end quotation 2271 2272@node Compiling to machine code,Setting things up,Our toy interpreter,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2273@anchor{intro/tutorial04 compiling-to-machine-code}@anchor{38} 2274@subsection Compiling to machine code 2275 2276 2277We want to generate machine code that can be cast to this type and 2278then directly executed in-process: 2279 2280@quotation 2281 2282@example 2283typedef int (*toyvm_compiled_code) (int); 2284 2285 2286@end example 2287 2288@noindent 2289@end quotation 2290 2291The lifetime of the code is tied to that of a @pxref{16,,gcc_jit_result *}. 2292We'll handle this by bundling them up in a structure, so that we can 2293clean them up together by calling @pxref{39,,gcc_jit_result_release()}: 2294 2295@quotation 2296 2297@example 2298 2299struct toyvm_compiled_function 2300@{ 2301 gcc_jit_result *cf_jit_result; 2302 toyvm_compiled_code cf_code; 2303@}; 2304 2305 2306@end example 2307 2308@noindent 2309@end quotation 2310 2311Our compiler isn't very sophisticated; it takes the implementation of 2312each opcode above, and maps it directly to the operations supported by 2313the libgccjit API. 2314 2315How should we handle the stack? In theory we could calculate what the 2316stack depth will be at each opcode, and optimize away the stack 2317manipulation "by hand". We'll see below that libgccjit is able to do 2318this for us, so we'll implement stack manipulation 2319in a direct way, by creating a @code{stack} array and @code{stack_depth} 2320variables, local within the generated function, equivalent to this C code: 2321 2322@example 2323int stack_depth; 2324int stack[MAX_STACK_DEPTH]; 2325@end example 2326 2327@noindent 2328 2329We'll also have local variables @code{x} and @code{y} for use when implementing 2330the opcodes, equivalent to this: 2331 2332@example 2333int x; 2334int y; 2335@end example 2336 2337@noindent 2338 2339This means our compiler has the following state: 2340 2341@quotation 2342 2343@example 2344 2345struct compilation_state 2346@{ 2347 gcc_jit_context *ctxt; 2348 2349 gcc_jit_type *int_type; 2350 gcc_jit_type *bool_type; 2351 gcc_jit_type *stack_type; /* int[MAX_STACK_DEPTH] */ 2352 2353 gcc_jit_rvalue *const_one; 2354 2355 gcc_jit_function *fn; 2356 gcc_jit_param *param_arg; 2357 gcc_jit_lvalue *stack; 2358 gcc_jit_lvalue *stack_depth; 2359 gcc_jit_lvalue *x; 2360 gcc_jit_lvalue *y; 2361 2362 gcc_jit_location *op_locs[MAX_OPS]; 2363 gcc_jit_block *initial_block; 2364 gcc_jit_block *op_blocks[MAX_OPS]; 2365 2366@}; 2367 2368 2369@end example 2370 2371@noindent 2372@end quotation 2373 2374@node Setting things up,Populating the function,Compiling to machine code,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2375@anchor{intro/tutorial04 setting-things-up}@anchor{3a} 2376@subsection Setting things up 2377 2378 2379First we create our types: 2380 2381@quotation 2382 2383@example 2384 state.int_type = 2385 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_INT); 2386 state.bool_type = 2387 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_BOOL); 2388 state.stack_type = 2389 gcc_jit_context_new_array_type (state.ctxt, NULL, 2390 state.int_type, MAX_STACK_DEPTH); 2391 2392 2393@end example 2394 2395@noindent 2396@end quotation 2397 2398along with extracting a useful @cite{int} constant: 2399 2400@quotation 2401 2402@example 2403 state.const_one = gcc_jit_context_one (state.ctxt, state.int_type); 2404 2405 2406@end example 2407 2408@noindent 2409@end quotation 2410 2411We'll implement push and pop in terms of the @code{stack} array and 2412@code{stack_depth}. Here are helper functions for adding statements to 2413a block, implementing pushing and popping values: 2414 2415@quotation 2416 2417@example 2418 2419static void 2420add_push (compilation_state *state, 2421 gcc_jit_block *block, 2422 gcc_jit_rvalue *rvalue, 2423 gcc_jit_location *loc) 2424@{ 2425 /* stack[stack_depth] = RVALUE */ 2426 gcc_jit_block_add_assignment ( 2427 block, 2428 loc, 2429 /* stack[stack_depth] */ 2430 gcc_jit_context_new_array_access ( 2431 state->ctxt, 2432 loc, 2433 gcc_jit_lvalue_as_rvalue (state->stack), 2434 gcc_jit_lvalue_as_rvalue (state->stack_depth)), 2435 rvalue); 2436 2437 /* "stack_depth++;". */ 2438 gcc_jit_block_add_assignment_op ( 2439 block, 2440 loc, 2441 state->stack_depth, 2442 GCC_JIT_BINARY_OP_PLUS, 2443 state->const_one); 2444@} 2445 2446static void 2447add_pop (compilation_state *state, 2448 gcc_jit_block *block, 2449 gcc_jit_lvalue *lvalue, 2450 gcc_jit_location *loc) 2451@{ 2452 /* "--stack_depth;". */ 2453 gcc_jit_block_add_assignment_op ( 2454 block, 2455 loc, 2456 state->stack_depth, 2457 GCC_JIT_BINARY_OP_MINUS, 2458 state->const_one); 2459 2460 /* "LVALUE = stack[stack_depth];". */ 2461 gcc_jit_block_add_assignment ( 2462 block, 2463 loc, 2464 lvalue, 2465 /* stack[stack_depth] */ 2466 gcc_jit_lvalue_as_rvalue ( 2467 gcc_jit_context_new_array_access ( 2468 state->ctxt, 2469 loc, 2470 gcc_jit_lvalue_as_rvalue (state->stack), 2471 gcc_jit_lvalue_as_rvalue (state->stack_depth)))); 2472@} 2473 2474 2475@end example 2476 2477@noindent 2478@end quotation 2479 2480We will support single-stepping through the generated code in the 2481debugger, so we need to create @pxref{3b,,gcc_jit_location} instances, one 2482per operation in the source code. These will reference the lines of 2483e.g. @code{factorial.toy}. 2484 2485@quotation 2486 2487@example 2488 for (pc = 0; pc < fn->fn_num_ops; pc++) 2489 @{ 2490 toyvm_op *op = &fn->fn_ops[pc]; 2491 2492 state.op_locs[pc] = gcc_jit_context_new_location (state.ctxt, 2493 fn->fn_filename, 2494 op->op_linenum, 2495 0); /* column */ 2496 @} 2497 2498 2499@end example 2500 2501@noindent 2502@end quotation 2503 2504Let's create the function itself. As usual, we create its parameter 2505first, then use the parameter to create the function: 2506 2507@quotation 2508 2509@example 2510 state.param_arg = 2511 gcc_jit_context_new_param (state.ctxt, state.op_locs[0], 2512 state.int_type, "arg"); 2513 state.fn = 2514 gcc_jit_context_new_function (state.ctxt, 2515 state.op_locs[0], 2516 GCC_JIT_FUNCTION_EXPORTED, 2517 state.int_type, 2518 funcname, 2519 1, &state.param_arg, 0); 2520 2521 2522@end example 2523 2524@noindent 2525@end quotation 2526 2527We create the locals within the function. 2528 2529@quotation 2530 2531@example 2532 state.stack = 2533 gcc_jit_function_new_local (state.fn, NULL, 2534 state.stack_type, "stack"); 2535 state.stack_depth = 2536 gcc_jit_function_new_local (state.fn, NULL, 2537 state.int_type, "stack_depth"); 2538 state.x = 2539 gcc_jit_function_new_local (state.fn, NULL, 2540 state.int_type, "x"); 2541 state.y = 2542 gcc_jit_function_new_local (state.fn, NULL, 2543 state.int_type, "y"); 2544 2545 2546@end example 2547 2548@noindent 2549@end quotation 2550 2551@node Populating the function,Verifying the control flow graph,Setting things up,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2552@anchor{intro/tutorial04 populating-the-function}@anchor{3c} 2553@subsection Populating the function 2554 2555 2556There's some one-time initialization, and the API treats the first block 2557you create as the entrypoint of the function, so we need to create that 2558block first: 2559 2560@quotation 2561 2562@example 2563 state.initial_block = gcc_jit_function_new_block (state.fn, "initial"); 2564 2565 2566@end example 2567 2568@noindent 2569@end quotation 2570 2571We can now create blocks for each of the operations. Most of these will 2572be consolidated into larger blocks when the optimizer runs. 2573 2574@quotation 2575 2576@example 2577 for (pc = 0; pc < fn->fn_num_ops; pc++) 2578 @{ 2579 char buf[16]; 2580 sprintf (buf, "instr%i", pc); 2581 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); 2582 @} 2583 2584 2585@end example 2586 2587@noindent 2588@end quotation 2589 2590Now that we have a block it can jump to when it's done, we can populate 2591the initial block: 2592 2593@quotation 2594 2595@example 2596 2597 /* "stack_depth = 0;". */ 2598 gcc_jit_block_add_assignment ( 2599 state.initial_block, 2600 state.op_locs[0], 2601 state.stack_depth, 2602 gcc_jit_context_zero (state.ctxt, state.int_type)); 2603 2604 /* "PUSH (arg);". */ 2605 add_push (&state, 2606 state.initial_block, 2607 gcc_jit_param_as_rvalue (state.param_arg), 2608 state.op_locs[0]); 2609 2610 /* ...and jump to insn 0. */ 2611 gcc_jit_block_end_with_jump (state.initial_block, 2612 state.op_locs[0], 2613 state.op_blocks[0]); 2614 2615 2616@end example 2617 2618@noindent 2619@end quotation 2620 2621We can now populate the blocks for the individual operations. We loop 2622through them, adding instructions to their blocks: 2623 2624@quotation 2625 2626@example 2627 for (pc = 0; pc < fn->fn_num_ops; pc++) 2628 @{ 2629 gcc_jit_location *loc = state.op_locs[pc]; 2630 2631 gcc_jit_block *block = state.op_blocks[pc]; 2632 gcc_jit_block *next_block = (pc < fn->fn_num_ops 2633 ? state.op_blocks[pc + 1] 2634 : NULL); 2635 2636 toyvm_op *op; 2637 op = &fn->fn_ops[pc]; 2638 2639 2640@end example 2641 2642@noindent 2643@end quotation 2644 2645We're going to have another big @code{switch} statement for implementing 2646the opcodes, this time for compiling them, rather than interpreting 2647them. It's helpful to have macros for implementing push and pop, so that 2648we can make the @code{switch} statement that's coming up look as much as 2649possible like the one above within the interpreter: 2650 2651@example 2652 2653#define X_EQUALS_POP()\ 2654 add_pop (&state, block, state.x, loc) 2655#define Y_EQUALS_POP()\ 2656 add_pop (&state, block, state.y, loc) 2657#define PUSH_RVALUE(RVALUE)\ 2658 add_push (&state, block, (RVALUE), loc) 2659#define PUSH_X()\ 2660 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.x)) 2661#define PUSH_Y() \ 2662 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.y)) 2663 2664 2665@end example 2666 2667@noindent 2668 2669@cartouche 2670@quotation Note 2671A particularly clever implementation would have an @emph{identical} 2672@code{switch} statement shared by the interpreter and the compiler, with 2673some preprocessor "magic". We're not doing that here, for the sake 2674of simplicity. 2675@end quotation 2676@end cartouche 2677 2678When I first implemented this compiler, I accidentally missed an edit 2679when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the 2680stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y} 2681uninitialized. 2682 2683To track this kind of thing down, we can use 2684@pxref{3d,,gcc_jit_block_add_comment()} to add descriptive comments 2685to the internal representation. This is invaluable when looking through 2686the generated IR for, say @code{factorial}: 2687 2688@quotation 2689 2690@example 2691 2692 gcc_jit_block_add_comment (block, loc, opcode_names[op->op_opcode]); 2693 2694 2695@end example 2696 2697@noindent 2698@end quotation 2699 2700We can now write the big @code{switch} statement that implements the 2701individual opcodes, populating the relevant block with statements: 2702 2703@quotation 2704 2705@example 2706 2707 switch (op->op_opcode) 2708 @{ 2709 case DUP: 2710 X_EQUALS_POP (); 2711 PUSH_X (); 2712 PUSH_X (); 2713 break; 2714 2715 case ROT: 2716 Y_EQUALS_POP (); 2717 X_EQUALS_POP (); 2718 PUSH_Y (); 2719 PUSH_X (); 2720 break; 2721 2722 case BINARY_ADD: 2723 Y_EQUALS_POP (); 2724 X_EQUALS_POP (); 2725 PUSH_RVALUE ( 2726 gcc_jit_context_new_binary_op ( 2727 state.ctxt, 2728 loc, 2729 GCC_JIT_BINARY_OP_PLUS, 2730 state.int_type, 2731 gcc_jit_lvalue_as_rvalue (state.x), 2732 gcc_jit_lvalue_as_rvalue (state.y))); 2733 break; 2734 2735 case BINARY_SUBTRACT: 2736 Y_EQUALS_POP (); 2737 X_EQUALS_POP (); 2738 PUSH_RVALUE ( 2739 gcc_jit_context_new_binary_op ( 2740 state.ctxt, 2741 loc, 2742 GCC_JIT_BINARY_OP_MINUS, 2743 state.int_type, 2744 gcc_jit_lvalue_as_rvalue (state.x), 2745 gcc_jit_lvalue_as_rvalue (state.y))); 2746 break; 2747 2748 case BINARY_MULT: 2749 Y_EQUALS_POP (); 2750 X_EQUALS_POP (); 2751 PUSH_RVALUE ( 2752 gcc_jit_context_new_binary_op ( 2753 state.ctxt, 2754 loc, 2755 GCC_JIT_BINARY_OP_MULT, 2756 state.int_type, 2757 gcc_jit_lvalue_as_rvalue (state.x), 2758 gcc_jit_lvalue_as_rvalue (state.y))); 2759 break; 2760 2761 case BINARY_COMPARE_LT: 2762 Y_EQUALS_POP (); 2763 X_EQUALS_POP (); 2764 PUSH_RVALUE ( 2765 /* cast of bool to int */ 2766 gcc_jit_context_new_cast ( 2767 state.ctxt, 2768 loc, 2769 /* (x < y) as a bool */ 2770 gcc_jit_context_new_comparison ( 2771 state.ctxt, 2772 loc, 2773 GCC_JIT_COMPARISON_LT, 2774 gcc_jit_lvalue_as_rvalue (state.x), 2775 gcc_jit_lvalue_as_rvalue (state.y)), 2776 state.int_type)); 2777 break; 2778 2779 case RECURSE: 2780 @{ 2781 X_EQUALS_POP (); 2782 gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (state.x); 2783 PUSH_RVALUE ( 2784 gcc_jit_context_new_call ( 2785 state.ctxt, 2786 loc, 2787 state.fn, 2788 1, &arg)); 2789 break; 2790 @} 2791 2792 case RETURN: 2793 X_EQUALS_POP (); 2794 gcc_jit_block_end_with_return ( 2795 block, 2796 loc, 2797 gcc_jit_lvalue_as_rvalue (state.x)); 2798 break; 2799 2800 /* Ops taking an operand. */ 2801 case PUSH_CONST: 2802 PUSH_RVALUE ( 2803 gcc_jit_context_new_rvalue_from_int ( 2804 state.ctxt, 2805 state.int_type, 2806 op->op_operand)); 2807 break; 2808 2809 case JUMP_ABS_IF_TRUE: 2810 X_EQUALS_POP (); 2811 gcc_jit_block_end_with_conditional ( 2812 block, 2813 loc, 2814 /* "(bool)x". */ 2815 gcc_jit_context_new_cast ( 2816 state.ctxt, 2817 loc, 2818 gcc_jit_lvalue_as_rvalue (state.x), 2819 state.bool_type), 2820 state.op_blocks[op->op_operand], /* on_true */ 2821 next_block); /* on_false */ 2822 break; 2823 2824 default: 2825 assert(0); 2826 @} /* end of switch on opcode */ 2827 2828 2829@end example 2830 2831@noindent 2832@end quotation 2833 2834Every block must be terminated, via a call to one of the 2835@code{gcc_jit_block_end_with_} entrypoints. This has been done for two 2836of the opcodes, but we need to do it for the other ones, by jumping 2837to the next block. 2838 2839@quotation 2840 2841@example 2842 if (op->op_opcode != JUMP_ABS_IF_TRUE 2843 && op->op_opcode != RETURN) 2844 gcc_jit_block_end_with_jump ( 2845 block, 2846 loc, 2847 next_block); 2848 2849 2850@end example 2851 2852@noindent 2853@end quotation 2854 2855This is analogous to simply incrementing the program counter. 2856 2857@node Verifying the control flow graph,Compiling the context,Populating the function,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2858@anchor{intro/tutorial04 verifying-the-control-flow-graph}@anchor{3e} 2859@subsection Verifying the control flow graph 2860 2861 2862Having finished looping over the blocks, the context is complete. 2863 2864As before, we can verify that the control flow and statements are sane by 2865using @pxref{33,,gcc_jit_function_dump_to_dot()}: 2866 2867@example 2868gcc_jit_function_dump_to_dot (state.fn, "/tmp/factorial.dot"); 2869@end example 2870 2871@noindent 2872 2873and viewing the result. Note how the label names, comments, and 2874variable names show up in the dump, to make it easier to spot 2875errors in our compiler. 2876 2877@quotation 2878 2879 2880@float Figure 2881 2882@image{factorial1,,,image of a control flow graph,png} 2883 2884@end float 2885 2886@end quotation 2887 2888@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 2889@anchor{intro/tutorial04 compiling-the-context}@anchor{3f} 2890@subsection Compiling the context 2891 2892 2893Having finished looping over the blocks and populating them with 2894statements, the context is complete. 2895 2896We can now compile it, and extract machine code from the result: 2897 2898@quotation 2899 2900@example 2901 gcc_jit_result *jit_result = gcc_jit_context_compile (state.ctxt); 2902 gcc_jit_context_release (state.ctxt); 2903 2904 toyvm_compiled_function *toyvm_result = 2905 (toyvm_compiled_function *)calloc (1, sizeof (toyvm_compiled_function)); 2906 if (!toyvm_result) 2907 @{ 2908 fprintf (stderr, "out of memory allocating toyvm_compiled_function\n"); 2909 gcc_jit_result_release (jit_result); 2910 return NULL; 2911 @} 2912 2913 toyvm_result->cf_jit_result = jit_result; 2914 toyvm_result->cf_code = 2915 (toyvm_compiled_code)gcc_jit_result_get_code (jit_result, 2916 funcname); 2917 2918 free (funcname); 2919 2920 return toyvm_result; 2921@} 2922 2923char test[1024]; 2924 2925#define CHECK_NON_NULL(PTR) \ 2926 do @{ \ 2927 if ((PTR) != NULL) \ 2928 @{ \ 2929 pass ("%s: %s is non-null", test, #PTR); \ 2930 @} \ 2931 else \ 2932 @{ \ 2933 fail ("%s: %s is NULL", test, #PTR); \ 2934 abort (); \ 2935 @} \ 2936 @} while (0) 2937 2938#define CHECK_VALUE(ACTUAL, EXPECTED) \ 2939 do @{ \ 2940 if ((ACTUAL) == (EXPECTED)) \ 2941 @{ \ 2942 pass ("%s: actual: %s == expected: %s", test, #ACTUAL, #EXPECTED); \ 2943 @} \ 2944 else \ 2945 @{ \ 2946 fail ("%s: actual: %s != expected: %s", test, #ACTUAL, #EXPECTED); \ 2947 fprintf (stderr, "incorrect value\n"); \ 2948 abort (); \ 2949 @} \ 2950 @} while (0) 2951 2952static void 2953test_script (const char *scripts_dir, const char *script_name, int input, 2954 int expected_result) 2955@{ 2956 char *script_path; 2957 toyvm_function *fn; 2958 int interpreted_result; 2959 toyvm_compiled_function *compiled_fn; 2960 toyvm_compiled_code code; 2961 int compiled_result; 2962 2963 snprintf (test, sizeof (test), "toyvm.c: %s", script_name); 2964 2965 script_path = (char *)malloc (strlen (scripts_dir) 2966 + strlen (script_name) + 1); 2967 CHECK_NON_NULL (script_path); 2968 sprintf (script_path, "%s%s", scripts_dir, script_name); 2969 2970 fn = toyvm_function_parse (script_path, script_name); 2971 CHECK_NON_NULL (fn); 2972 2973 interpreted_result = toyvm_function_interpret (fn, input, NULL); 2974 CHECK_VALUE (interpreted_result, expected_result); 2975 2976 compiled_fn = toyvm_function_compile (fn); 2977 CHECK_NON_NULL (compiled_fn); 2978 2979 code = (toyvm_compiled_code)compiled_fn->cf_code; 2980 CHECK_NON_NULL (code); 2981 2982 compiled_result = code (input); 2983 CHECK_VALUE (compiled_result, expected_result); 2984 2985 gcc_jit_result_release (compiled_fn->cf_jit_result); 2986 free (compiled_fn); 2987 free (fn); 2988 free (script_path); 2989@} 2990 2991#define PATH_TO_SCRIPTS ("/jit/docs/examples/tut04-toyvm/") 2992 2993static void 2994test_suite (void) 2995@{ 2996 const char *srcdir; 2997 char *scripts_dir; 2998 2999 snprintf (test, sizeof (test), "toyvm.c"); 3000 3001 /* We need to locate the test scripts. 3002 Rely on "srcdir" being set in the environment. */ 3003 3004 srcdir = getenv ("srcdir"); 3005 CHECK_NON_NULL (srcdir); 3006 3007 scripts_dir = (char *)malloc (strlen (srcdir) + strlen(PATH_TO_SCRIPTS) 3008 + 1); 3009 CHECK_NON_NULL (scripts_dir); 3010 sprintf (scripts_dir, "%s%s", srcdir, PATH_TO_SCRIPTS); 3011 3012 test_script (scripts_dir, "factorial.toy", 10, 3628800); 3013 test_script (scripts_dir, "fibonacci.toy", 10, 55); 3014 3015 free (scripts_dir); 3016@} 3017 3018int 3019main (int argc, char **argv) 3020@{ 3021 const char *filename = NULL; 3022 toyvm_function *fn = NULL; 3023 3024 /* If called with no args, assume we're being run by the test suite. */ 3025 if (argc < 3) 3026 @{ 3027 test_suite (); 3028 return 0; 3029 @} 3030 3031 if (argc != 3) 3032 @{ 3033 fprintf (stdout, 3034 "%s FILENAME INPUT: Parse and run a .toy file\n", 3035 argv[0]); 3036 exit (1); 3037 @} 3038 3039 filename = argv[1]; 3040 fn = toyvm_function_parse (filename, filename); 3041 if (!fn) 3042 exit (1); 3043 3044 if (0) 3045 toyvm_function_disassemble (fn, stdout); 3046 3047 printf ("interpreter result: %d\n", 3048 toyvm_function_interpret (fn, atoi (argv[2]), NULL)); 3049 3050 /* JIT-compilation. */ 3051 toyvm_compiled_function *compiled_fn 3052 = toyvm_function_compile (fn); 3053 3054 toyvm_compiled_code code = compiled_fn->cf_code; 3055 printf ("compiler result: %d\n", 3056 code (atoi (argv[2]))); 3057 3058 gcc_jit_result_release (compiled_fn->cf_jit_result); 3059 free (compiled_fn); 3060 3061 return 0; 3062@} 3063 3064@end example 3065 3066@noindent 3067@end quotation 3068 3069We can now run the result: 3070 3071@quotation 3072 3073@example 3074 toyvm_compiled_function *compiled_fn 3075 = toyvm_function_compile (fn); 3076 3077 toyvm_compiled_code code = compiled_fn->cf_code; 3078 printf ("compiler result: %d\n", 3079 code (atoi (argv[2]))); 3080 3081 gcc_jit_result_release (compiled_fn->cf_jit_result); 3082 free (compiled_fn); 3083 3084 3085@end example 3086 3087@noindent 3088@end quotation 3089 3090@node Single-stepping through the generated code,Examining the generated code,Compiling the context,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3091@anchor{intro/tutorial04 single-stepping-through-the-generated-code}@anchor{40} 3092@subsection Single-stepping through the generated code 3093 3094 3095It's possible to debug the generated code. To do this we need to both: 3096 3097@quotation 3098 3099 3100@itemize * 3101 3102@item 3103Set up source code locations for our statements, so that we can 3104meaningfully step through the code. We did this above by 3105calling @pxref{41,,gcc_jit_context_new_location()} and using the 3106results. 3107 3108@item 3109Enable the generation of debugging information, by setting 3110@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 3111@pxref{8,,gcc_jit_context} via 3112@pxref{1b,,gcc_jit_context_set_bool_option()}: 3113 3114@example 3115gcc_jit_context_set_bool_option ( 3116 ctxt, 3117 GCC_JIT_BOOL_OPTION_DEBUGINFO, 3118 1); 3119@end example 3120 3121@noindent 3122@end itemize 3123@end quotation 3124 3125Having done this, we can put a breakpoint on the generated function: 3126 3127@example 3128$ gdb --args ./toyvm factorial.toy 10 3129(gdb) break factorial 3130Function "factorial" not defined. 3131Make breakpoint pending on future shared library load? (y or [n]) y 3132Breakpoint 1 (factorial) pending. 3133(gdb) run 3134Breakpoint 1, factorial (arg=10) at factorial.toy:14 313514 DUP 3136@end example 3137 3138@noindent 3139 3140We've set up location information, which references @code{factorial.toy}. 3141This allows us to use e.g. @code{list} to see where we are in the script: 3142 3143@example 3144(gdb) list 31459 314610 # Initial state: 314711 # stack: [arg] 314812 314913 # 0: 315014 DUP 315115 # stack: [arg, arg] 315216 315317 # 1: 315418 PUSH_CONST 2 3155@end example 3156 3157@noindent 3158 3159and to step through the function, examining the data: 3160 3161@example 3162(gdb) n 316318 PUSH_CONST 2 3164(gdb) n 316522 BINARY_COMPARE_LT 3166(gdb) print stack 3167$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@} 3168(gdb) print stack_depth 3169$6 = 3 3170@end example 3171 3172@noindent 3173 3174You'll see that the parts of the @code{stack} array that haven't been 3175touched yet are uninitialized. 3176 3177@cartouche 3178@quotation Note 3179Turning on optimizations may lead to unpredictable results when 3180stepping through the generated code: the execution may appear to 3181"jump around" the source code. This is analogous to turning up the 3182optimization level in a regular compiler. 3183@end quotation 3184@end cartouche 3185 3186@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 3187@anchor{intro/tutorial04 examining-the-generated-code}@anchor{43} 3188@subsection Examining the generated code 3189 3190 3191How good is the optimized code? 3192 3193We can turn up optimizations, by calling 3194@pxref{1e,,gcc_jit_context_set_int_option()} with 3195@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 3196 3197@example 3198gcc_jit_context_set_int_option ( 3199 ctxt, 3200 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3201 3); 3202@end example 3203 3204@noindent 3205 3206One of GCC's internal representations is called "gimple". A dump of the 3207initial gimple representation of the code can be seen by setting: 3208 3209@example 3210gcc_jit_context_set_bool_option (ctxt, 3211 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 3212 1); 3213@end example 3214 3215@noindent 3216 3217With optimization on and source locations displayed, this gives: 3218 3219@c We'll use "c" for gimple dumps 3220 3221@example 3222factorial (signed int arg) 3223@{ 3224 <unnamed type> D.80; 3225 signed int D.81; 3226 signed int D.82; 3227 signed int D.83; 3228 signed int D.84; 3229 signed int D.85; 3230 signed int y; 3231 signed int x; 3232 signed int stack_depth; 3233 signed int stack[8]; 3234 3235 try 3236 @{ 3237 initial: 3238 stack_depth = 0; 3239 stack[stack_depth] = arg; 3240 stack_depth = stack_depth + 1; 3241 goto instr0; 3242 instr0: 3243 /* DUP */: 3244 stack_depth = stack_depth + -1; 3245 x = stack[stack_depth]; 3246 stack[stack_depth] = x; 3247 stack_depth = stack_depth + 1; 3248 stack[stack_depth] = x; 3249 stack_depth = stack_depth + 1; 3250 goto instr1; 3251 instr1: 3252 /* PUSH_CONST */: 3253 stack[stack_depth] = 2; 3254 stack_depth = stack_depth + 1; 3255 goto instr2; 3256 3257 /* etc */ 3258@end example 3259 3260@noindent 3261 3262You can see the generated machine code in assembly form via: 3263 3264@example 3265gcc_jit_context_set_bool_option ( 3266 ctxt, 3267 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 3268 1); 3269result = gcc_jit_context_compile (ctxt); 3270@end example 3271 3272@noindent 3273 3274which shows that (on this x86_64 box) the compiler has unrolled the loop 3275and is using MMX instructions to perform several multiplications 3276simultaneously: 3277 3278@example 3279 .file "fake.c" 3280 .text 3281.Ltext0: 3282 .p2align 4,,15 3283 .globl factorial 3284 .type factorial, @@function 3285factorial: 3286.LFB0: 3287 .file 1 "factorial.toy" 3288 .loc 1 14 0 3289 .cfi_startproc 3290.LVL0: 3291.L2: 3292 .loc 1 26 0 3293 cmpl $1, %edi 3294 jle .L13 3295 leal -1(%rdi), %edx 3296 movl %edx, %ecx 3297 shrl $2, %ecx 3298 leal 0(,%rcx,4), %esi 3299 testl %esi, %esi 3300 je .L14 3301 cmpl $9, %edx 3302 jbe .L14 3303 leal -2(%rdi), %eax 3304 movl %eax, -16(%rsp) 3305 leal -3(%rdi), %eax 3306 movd -16(%rsp), %xmm0 3307 movl %edi, -16(%rsp) 3308 movl %eax, -12(%rsp) 3309 movd -16(%rsp), %xmm1 3310 xorl %eax, %eax 3311 movl %edx, -16(%rsp) 3312 movd -12(%rsp), %xmm4 3313 movd -16(%rsp), %xmm6 3314 punpckldq %xmm4, %xmm0 3315 movdqa .LC1(%rip), %xmm4 3316 punpckldq %xmm6, %xmm1 3317 punpcklqdq %xmm0, %xmm1 3318 movdqa .LC0(%rip), %xmm0 3319 jmp .L5 3320 # etc - edited for brevity 3321@end example 3322 3323@noindent 3324 3325This is clearly overkill for a function that will likely overflow the 3326@code{int} type before the vectorization is worthwhile - but then again, this 3327is a toy example. 3328 3329Turning down the optimization level to 2: 3330 3331@example 3332gcc_jit_context_set_int_option ( 3333 ctxt, 3334 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3335 3); 3336@end example 3337 3338@noindent 3339 3340yields this code, which is simple enough to quote in its entirety: 3341 3342@example 3343 .file "fake.c" 3344 .text 3345 .p2align 4,,15 3346 .globl factorial 3347 .type factorial, @@function 3348factorial: 3349.LFB0: 3350 .cfi_startproc 3351.L2: 3352 cmpl $1, %edi 3353 jle .L8 3354 movl $1, %edx 3355 jmp .L4 3356 .p2align 4,,10 3357 .p2align 3 3358.L6: 3359 movl %eax, %edi 3360.L4: 3361.L5: 3362 leal -1(%rdi), %eax 3363 imull %edi, %edx 3364 cmpl $1, %eax 3365 jne .L6 3366.L3: 3367.L7: 3368 imull %edx, %eax 3369 ret 3370.L8: 3371 movl %edi, %eax 3372 movl $1, %edx 3373 jmp .L7 3374 .cfi_endproc 3375.LFE0: 3376 .size factorial, .-factorial 3377 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})" 3378 .section .note.GNU-stack,"",@@progbits 3379@end example 3380 3381@noindent 3382 3383Note that the stack pushing and popping have been eliminated, as has the 3384recursive call (in favor of an iteration). 3385 3386@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 3387@anchor{intro/tutorial04 putting-it-all-together}@anchor{44} 3388@subsection Putting it all together 3389 3390 3391The complete example can be seen in the source tree at 3392@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.c} 3393 3394along with a Makefile and a couple of sample .toy scripts: 3395 3396@example 3397$ ls -al 3398drwxrwxr-x. 2 david david 4096 Sep 19 17:46 . 3399drwxrwxr-x. 3 david david 4096 Sep 19 15:26 .. 3400-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy 3401-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy 3402-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile 3403-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.c 3404 3405$ make toyvm 3406g++ -Wall -g -o toyvm toyvm.c -lgccjit 3407 3408$ ./toyvm factorial.toy 10 3409interpreter result: 3628800 3410compiler result: 3628800 3411 3412$ ./toyvm fibonacci.toy 10 3413interpreter result: 55 3414compiler result: 55 3415@end example 3416 3417@noindent 3418 3419@node Behind the curtain How does our code get optimized?,,Putting it all together,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3420@anchor{intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{45} 3421@subsection Behind the curtain: How does our code get optimized? 3422 3423 3424Our example is done, but you may be wondering about exactly how the 3425compiler turned what we gave it into the machine code seen above. 3426 3427We can examine what the compiler is doing in detail by setting: 3428 3429@example 3430gcc_jit_context_set_bool_option (state.ctxt, 3431 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 3432 1); 3433gcc_jit_context_set_bool_option (state.ctxt, 3434 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 3435 1); 3436@end example 3437 3438@noindent 3439 3440This will dump detailed information about the compiler's state to a 3441directory under @code{/tmp}, and keep it from being cleaned up. 3442 3443The precise names and their formats of these files is subject to change. 3444Higher optimization levels lead to more files. 3445Here's what I saw (edited for brevity; there were almost 200 files): 3446 3447@example 3448intermediate files written to /tmp/libgccjit-KPQbGw 3449$ ls /tmp/libgccjit-KPQbGw/ 3450fake.c.000i.cgraph 3451fake.c.000i.type-inheritance 3452fake.c.004t.gimple 3453fake.c.007t.omplower 3454fake.c.008t.lower 3455fake.c.011t.eh 3456fake.c.012t.cfg 3457fake.c.014i.visibility 3458fake.c.015i.early_local_cleanups 3459fake.c.016t.ssa 3460# etc 3461@end example 3462 3463@noindent 3464 3465The gimple code is converted into Static Single Assignment form, 3466with annotations for use when generating the debuginfo: 3467 3468@example 3469$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa 3470@end example 3471 3472@noindent 3473 3474@example 3475;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3476 3477factorial (signed int arg) 3478@{ 3479 signed int stack[8]; 3480 signed int stack_depth; 3481 signed int x; 3482 signed int y; 3483 <unnamed type> _20; 3484 signed int _21; 3485 signed int _38; 3486 signed int _44; 3487 signed int _51; 3488 signed int _56; 3489 3490initial: 3491 stack_depth_3 = 0; 3492 # DEBUG stack_depth => stack_depth_3 3493 stack[stack_depth_3] = arg_5(D); 3494 stack_depth_7 = stack_depth_3 + 1; 3495 # DEBUG stack_depth => stack_depth_7 3496 # DEBUG instr0 => NULL 3497 # DEBUG /* DUP */ => NULL 3498 stack_depth_8 = stack_depth_7 + -1; 3499 # DEBUG stack_depth => stack_depth_8 3500 x_9 = stack[stack_depth_8]; 3501 # DEBUG x => x_9 3502 stack[stack_depth_8] = x_9; 3503 stack_depth_11 = stack_depth_8 + 1; 3504 # DEBUG stack_depth => stack_depth_11 3505 stack[stack_depth_11] = x_9; 3506 stack_depth_13 = stack_depth_11 + 1; 3507 # DEBUG stack_depth => stack_depth_13 3508 # DEBUG instr1 => NULL 3509 # DEBUG /* PUSH_CONST */ => NULL 3510 stack[stack_depth_13] = 2; 3511 3512 /* etc; edited for brevity */ 3513@end example 3514 3515@noindent 3516 3517We can perhaps better see the code by turning off 3518@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG} 3519statements, giving: 3520 3521@example 3522$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa 3523@end example 3524 3525@noindent 3526 3527@example 3528;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3529 3530factorial (signed int arg) 3531@{ 3532 signed int stack[8]; 3533 signed int stack_depth; 3534 signed int x; 3535 signed int y; 3536 <unnamed type> _20; 3537 signed int _21; 3538 signed int _38; 3539 signed int _44; 3540 signed int _51; 3541 signed int _56; 3542 3543initial: 3544 stack_depth_3 = 0; 3545 stack[stack_depth_3] = arg_5(D); 3546 stack_depth_7 = stack_depth_3 + 1; 3547 stack_depth_8 = stack_depth_7 + -1; 3548 x_9 = stack[stack_depth_8]; 3549 stack[stack_depth_8] = x_9; 3550 stack_depth_11 = stack_depth_8 + 1; 3551 stack[stack_depth_11] = x_9; 3552 stack_depth_13 = stack_depth_11 + 1; 3553 stack[stack_depth_13] = 2; 3554 stack_depth_15 = stack_depth_13 + 1; 3555 stack_depth_16 = stack_depth_15 + -1; 3556 y_17 = stack[stack_depth_16]; 3557 stack_depth_18 = stack_depth_16 + -1; 3558 x_19 = stack[stack_depth_18]; 3559 _20 = x_19 < y_17; 3560 _21 = (signed int) _20; 3561 stack[stack_depth_18] = _21; 3562 stack_depth_23 = stack_depth_18 + 1; 3563 stack_depth_24 = stack_depth_23 + -1; 3564 x_25 = stack[stack_depth_24]; 3565 if (x_25 != 0) 3566 goto <bb 4> (instr9); 3567 else 3568 goto <bb 3> (instr4); 3569 3570instr4: 3571/* DUP */: 3572 stack_depth_26 = stack_depth_24 + -1; 3573 x_27 = stack[stack_depth_26]; 3574 stack[stack_depth_26] = x_27; 3575 stack_depth_29 = stack_depth_26 + 1; 3576 stack[stack_depth_29] = x_27; 3577 stack_depth_31 = stack_depth_29 + 1; 3578 stack[stack_depth_31] = 1; 3579 stack_depth_33 = stack_depth_31 + 1; 3580 stack_depth_34 = stack_depth_33 + -1; 3581 y_35 = stack[stack_depth_34]; 3582 stack_depth_36 = stack_depth_34 + -1; 3583 x_37 = stack[stack_depth_36]; 3584 _38 = x_37 - y_35; 3585 stack[stack_depth_36] = _38; 3586 stack_depth_40 = stack_depth_36 + 1; 3587 stack_depth_41 = stack_depth_40 + -1; 3588 x_42 = stack[stack_depth_41]; 3589 _44 = factorial (x_42); 3590 stack[stack_depth_41] = _44; 3591 stack_depth_46 = stack_depth_41 + 1; 3592 stack_depth_47 = stack_depth_46 + -1; 3593 y_48 = stack[stack_depth_47]; 3594 stack_depth_49 = stack_depth_47 + -1; 3595 x_50 = stack[stack_depth_49]; 3596 _51 = x_50 * y_48; 3597 stack[stack_depth_49] = _51; 3598 stack_depth_53 = stack_depth_49 + 1; 3599 3600 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)> 3601instr9: 3602/* RETURN */: 3603 stack_depth_54 = stack_depth_1 + -1; 3604 x_55 = stack[stack_depth_54]; 3605 _56 = x_55; 3606 stack =@{v@} @{CLOBBER@}; 3607 return _56; 3608 3609@} 3610@end example 3611 3612@noindent 3613 3614Note in the above how all the @pxref{28,,gcc_jit_block} instances we 3615created have been consolidated into just 3 blocks in GCC's internal 3616representation: @code{initial}, @code{instr4} and @code{instr9}. 3617 3618@menu 3619* Optimizing away stack manipulation:: 3620* Elimination of tail recursion:: 3621 3622@end menu 3623 3624@node Optimizing away stack manipulation,Elimination of tail recursion,,Behind the curtain How does our code get optimized? 3625@anchor{intro/tutorial04 optimizing-away-stack-manipulation}@anchor{46} 3626@subsubsection Optimizing away stack manipulation 3627 3628 3629Recall our simple implementation of stack operations. Let's examine 3630how the stack operations are optimized away. 3631 3632After a pass of constant-propagation, the depth of the stack at each 3633opcode can be determined at compile-time: 3634 3635@example 3636$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1 3637@end example 3638 3639@noindent 3640 3641@example 3642;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3643 3644factorial (signed int arg) 3645@{ 3646 signed int stack[8]; 3647 signed int stack_depth; 3648 signed int x; 3649 signed int y; 3650 <unnamed type> _20; 3651 signed int _21; 3652 signed int _38; 3653 signed int _44; 3654 signed int _51; 3655 3656initial: 3657 stack[0] = arg_5(D); 3658 x_9 = stack[0]; 3659 stack[0] = x_9; 3660 stack[1] = x_9; 3661 stack[2] = 2; 3662 y_17 = stack[2]; 3663 x_19 = stack[1]; 3664 _20 = x_19 < y_17; 3665 _21 = (signed int) _20; 3666 stack[1] = _21; 3667 x_25 = stack[1]; 3668 if (x_25 != 0) 3669 goto <bb 4> (instr9); 3670 else 3671 goto <bb 3> (instr4); 3672 3673instr4: 3674/* DUP */: 3675 x_27 = stack[0]; 3676 stack[0] = x_27; 3677 stack[1] = x_27; 3678 stack[2] = 1; 3679 y_35 = stack[2]; 3680 x_37 = stack[1]; 3681 _38 = x_37 - y_35; 3682 stack[1] = _38; 3683 x_42 = stack[1]; 3684 _44 = factorial (x_42); 3685 stack[1] = _44; 3686 y_48 = stack[1]; 3687 x_50 = stack[0]; 3688 _51 = x_50 * y_48; 3689 stack[0] = _51; 3690 3691instr9: 3692/* RETURN */: 3693 x_55 = stack[0]; 3694 x_56 = x_55; 3695 stack =@{v@} @{CLOBBER@}; 3696 return x_56; 3697 3698@} 3699@end example 3700 3701@noindent 3702 3703Note how, in the above, all those @code{stack_depth} values are now just 3704constants: we're accessing specific stack locations at each opcode. 3705 3706The "esra" pass ("Early Scalar Replacement of Aggregates") breaks 3707out our "stack" array into individual elements: 3708 3709@example 3710$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra 3711@end example 3712 3713@noindent 3714 3715@example 3716;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3717 3718Created a replacement for stack offset: 0, size: 32: stack$0 3719Created a replacement for stack offset: 32, size: 32: stack$1 3720Created a replacement for stack offset: 64, size: 32: stack$2 3721 3722Symbols to be put in SSA form 3723@{ D.89 D.90 D.91 @} 3724Incremental SSA update started at block: 0 3725Number of blocks in CFG: 5 3726Number of blocks to update: 4 ( 80%) 3727 3728 3729factorial (signed int arg) 3730@{ 3731 signed int stack$2; 3732 signed int stack$1; 3733 signed int stack$0; 3734 signed int stack[8]; 3735 signed int stack_depth; 3736 signed int x; 3737 signed int y; 3738 <unnamed type> _20; 3739 signed int _21; 3740 signed int _38; 3741 signed int _44; 3742 signed int _51; 3743 3744initial: 3745 stack$0_45 = arg_5(D); 3746 x_9 = stack$0_45; 3747 stack$0_39 = x_9; 3748 stack$1_32 = x_9; 3749 stack$2_30 = 2; 3750 y_17 = stack$2_30; 3751 x_19 = stack$1_32; 3752 _20 = x_19 < y_17; 3753 _21 = (signed int) _20; 3754 stack$1_28 = _21; 3755 x_25 = stack$1_28; 3756 if (x_25 != 0) 3757 goto <bb 4> (instr9); 3758 else 3759 goto <bb 3> (instr4); 3760 3761instr4: 3762/* DUP */: 3763 x_27 = stack$0_39; 3764 stack$0_22 = x_27; 3765 stack$1_14 = x_27; 3766 stack$2_12 = 1; 3767 y_35 = stack$2_12; 3768 x_37 = stack$1_14; 3769 _38 = x_37 - y_35; 3770 stack$1_10 = _38; 3771 x_42 = stack$1_10; 3772 _44 = factorial (x_42); 3773 stack$1_6 = _44; 3774 y_48 = stack$1_6; 3775 x_50 = stack$0_22; 3776 _51 = x_50 * y_48; 3777 stack$0_1 = _51; 3778 3779 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)> 3780instr9: 3781/* RETURN */: 3782 x_55 = stack$0_52; 3783 x_56 = x_55; 3784 stack =@{v@} @{CLOBBER@}; 3785 return x_56; 3786 3787@} 3788@end example 3789 3790@noindent 3791 3792Hence at this point, all those pushes and pops of the stack are now 3793simply assignments to specific temporary variables. 3794 3795After some copy propagation, the stack manipulation has been completely 3796optimized away: 3797 3798@example 3799$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1 3800@end example 3801 3802@noindent 3803 3804@example 3805;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3806 3807factorial (signed int arg) 3808@{ 3809 signed int stack$2; 3810 signed int stack$1; 3811 signed int stack$0; 3812 signed int stack[8]; 3813 signed int stack_depth; 3814 signed int x; 3815 signed int y; 3816 <unnamed type> _20; 3817 signed int _21; 3818 signed int _38; 3819 signed int _44; 3820 signed int _51; 3821 3822initial: 3823 stack$0_39 = arg_5(D); 3824 _20 = arg_5(D) <= 1; 3825 _21 = (signed int) _20; 3826 if (_21 != 0) 3827 goto <bb 4> (instr9); 3828 else 3829 goto <bb 3> (instr4); 3830 3831instr4: 3832/* DUP */: 3833 _38 = arg_5(D) + -1; 3834 _44 = factorial (_38); 3835 _51 = arg_5(D) * _44; 3836 stack$0_1 = _51; 3837 3838 # stack$0_52 = PHI <arg_5(D)(2), _51(3)> 3839instr9: 3840/* RETURN */: 3841 stack =@{v@} @{CLOBBER@}; 3842 return stack$0_52; 3843 3844@} 3845@end example 3846 3847@noindent 3848 3849Later on, another pass finally eliminated @code{stack_depth} local and the 3850unused parts of the @cite{stack`} array altogether: 3851 3852@example 3853$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa 3854@end example 3855 3856@noindent 3857 3858@example 3859;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3860 3861Released 44 names, 314.29%, removed 44 holes 3862factorial (signed int arg) 3863@{ 3864 signed int stack$0; 3865 signed int mult_acc_1; 3866 <unnamed type> _5; 3867 signed int _6; 3868 signed int _7; 3869 signed int mul_tmp_10; 3870 signed int mult_acc_11; 3871 signed int mult_acc_13; 3872 3873 # arg_9 = PHI <arg_8(D)(0)> 3874 # mult_acc_13 = PHI <1(0)> 3875initial: 3876 3877 <bb 5>: 3878 # arg_4 = PHI <arg_9(2), _7(3)> 3879 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)> 3880 _5 = arg_4 <= 1; 3881 _6 = (signed int) _5; 3882 if (_6 != 0) 3883 goto <bb 4> (instr9); 3884 else 3885 goto <bb 3> (instr4); 3886 3887instr4: 3888/* DUP */: 3889 _7 = arg_4 + -1; 3890 mult_acc_11 = mult_acc_1 * arg_4; 3891 goto <bb 5>; 3892 3893 # stack$0_12 = PHI <arg_4(5)> 3894instr9: 3895/* RETURN */: 3896 mul_tmp_10 = mult_acc_1 * stack$0_12; 3897 return mul_tmp_10; 3898 3899@} 3900@end example 3901 3902@noindent 3903 3904@node Elimination of tail recursion,,Optimizing away stack manipulation,Behind the curtain How does our code get optimized? 3905@anchor{intro/tutorial04 elimination-of-tail-recursion}@anchor{47} 3906@subsubsection Elimination of tail recursion 3907 3908 3909Another significant optimization is the detection that the call to 3910@code{factorial} is tail recursion, which can be eliminated in favor of 3911an iteration: 3912 3913@example 3914$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1 3915@end example 3916 3917@noindent 3918 3919@example 3920;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3921 3922 3923Symbols to be put in SSA form 3924@{ D.88 @} 3925Incremental SSA update started at block: 0 3926Number of blocks in CFG: 5 3927Number of blocks to update: 4 ( 80%) 3928 3929 3930factorial (signed int arg) 3931@{ 3932 signed int stack$2; 3933 signed int stack$1; 3934 signed int stack$0; 3935 signed int stack[8]; 3936 signed int stack_depth; 3937 signed int x; 3938 signed int y; 3939 signed int mult_acc_1; 3940 <unnamed type> _20; 3941 signed int _21; 3942 signed int _38; 3943 signed int mul_tmp_44; 3944 signed int mult_acc_51; 3945 3946 # arg_5 = PHI <arg_39(D)(0), _38(3)> 3947 # mult_acc_1 = PHI <1(0), mult_acc_51(3)> 3948initial: 3949 _20 = arg_5 <= 1; 3950 _21 = (signed int) _20; 3951 if (_21 != 0) 3952 goto <bb 4> (instr9); 3953 else 3954 goto <bb 3> (instr4); 3955 3956instr4: 3957/* DUP */: 3958 _38 = arg_5 + -1; 3959 mult_acc_51 = mult_acc_1 * arg_5; 3960 goto <bb 2> (initial); 3961 3962 # stack$0_52 = PHI <arg_5(2)> 3963instr9: 3964/* RETURN */: 3965 stack =@{v@} @{CLOBBER@}; 3966 mul_tmp_44 = mult_acc_1 * stack$0_52; 3967 return mul_tmp_44; 3968 3969@} 3970@end example 3971 3972@noindent 3973 3974@c Copyright (C) 2015 Free Software Foundation, Inc. 3975@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 3976@c 3977@c This is free software: you can redistribute it and/or modify it 3978@c under the terms of the GNU General Public License as published by 3979@c the Free Software Foundation, either version 3 of the License, or 3980@c (at your option) any later version. 3981@c 3982@c This program is distributed in the hope that it will be useful, but 3983@c WITHOUT ANY WARRANTY; without even the implied warranty of 3984@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 3985@c General Public License for more details. 3986@c 3987@c You should have received a copy of the GNU General Public License 3988@c along with this program. If not, see 3989@c <http://www.gnu.org/licenses/>. 3990 3991@node Tutorial part 5 Implementing an Ahead-of-Time compiler,,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial 3992@anchor{intro/tutorial05 doc}@anchor{48}@anchor{intro/tutorial05 tutorial-part-5-implementing-an-ahead-of-time-compiler}@anchor{49} 3993@section Tutorial part 5: Implementing an Ahead-of-Time compiler 3994 3995 3996If you have a pre-existing language frontend that's compatible with 3997libgccjit's license, it's possible to hook it up to libgccjit as a 3998backend. In the previous example we showed 3999how to do that for in-memory JIT-compilation, but libgccjit can also 4000compile code directly to a file, allowing you to implement a more 4001traditional ahead-of-time compiler ("JIT" is something of a misnomer 4002for this use-case). 4003 4004The essential difference is to compile the context using 4005@pxref{4a,,gcc_jit_context_compile_to_file()} rather than 4006@pxref{15,,gcc_jit_context_compile()}. 4007 4008@menu 4009* The "brainf" language:: 4010* Converting a brainf script to libgccjit IR:: 4011* Compiling a context to a file:: 4012* Other forms of ahead-of-time-compilation:: 4013 4014@end menu 4015 4016@node The "brainf" language,Converting a brainf script to libgccjit IR,,Tutorial part 5 Implementing an Ahead-of-Time compiler 4017@anchor{intro/tutorial05 the-brainf-language}@anchor{4b} 4018@subsection The "brainf" language 4019 4020 4021In this example we use libgccjit to construct an ahead-of-time compiler 4022for an esoteric programming language that we shall refer to as "brainf". 4023 4024brainf scripts operate on an array of bytes, with a notional data pointer 4025within the array. 4026 4027brainf is hard for humans to read, but it's trivial to write a parser for 4028it, as there is no lexing; just a stream of bytes. The operations are: 4029 4030 4031@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 4032@headitem 4033 4034Character 4035 4036@tab 4037 4038Meaning 4039 4040@item 4041 4042@code{>} 4043 4044@tab 4045 4046@code{idx += 1} 4047 4048@item 4049 4050@code{<} 4051 4052@tab 4053 4054@code{idx -= 1} 4055 4056@item 4057 4058@code{+} 4059 4060@tab 4061 4062@code{data[idx] += 1} 4063 4064@item 4065 4066@code{-} 4067 4068@tab 4069 4070@code{data[idx] -= 1} 4071 4072@item 4073 4074@code{.} 4075 4076@tab 4077 4078@code{output (data[idx])} 4079 4080@item 4081 4082@code{,} 4083 4084@tab 4085 4086@code{data[idx] = input ()} 4087 4088@item 4089 4090@code{[} 4091 4092@tab 4093 4094loop until @code{data[idx] == 0} 4095 4096@item 4097 4098@code{]} 4099 4100@tab 4101 4102end of loop 4103 4104@item 4105 4106Anything else 4107 4108@tab 4109 4110ignored 4111 4112@end multitable 4113 4114 4115Unlike the previous example, we'll implement an ahead-of-time compiler, 4116which reads @code{.bf} scripts and outputs executables (though it would 4117be trivial to have it run them JIT-compiled in-process). 4118 4119Here's what a simple @code{.bf} script looks like: 4120 4121@quotation 4122 4123@example 4124[ 4125 Emit the uppercase alphabet 4126] 4127 4128cell 0 = 26 4129++++++++++++++++++++++++++ 4130 4131cell 1 = 65 4132>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4133 4134while cell#0 != 0 4135[ 4136 > 4137 . emit cell#1 4138 + increment cell@@1 4139 <- decrement cell@@0 4140] 4141 4142@end example 4143 4144@noindent 4145@end quotation 4146 4147@cartouche 4148@quotation Note 4149This example makes use of whitespace and comments for legibility, but 4150could have been written as: 4151 4152@example 4153++++++++++++++++++++++++++ 4154>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4155[>.+<-] 4156@end example 4157 4158@noindent 4159 4160It's not a particularly useful language, except for providing 4161compiler-writers with a test case that's easy to parse. The point 4162is that you can use @pxref{4a,,gcc_jit_context_compile_to_file()} 4163to use libgccjit as a backend for a pre-existing language frontend 4164(provided that the pre-existing frontend is compatible with libgccjit's 4165license). 4166@end quotation 4167@end cartouche 4168 4169@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 4170@anchor{intro/tutorial05 converting-a-brainf-script-to-libgccjit-ir}@anchor{4c} 4171@subsection Converting a brainf script to libgccjit IR 4172 4173 4174As before we write simple code to populate a @pxref{8,,gcc_jit_context *}. 4175 4176@quotation 4177 4178@example 4179 4180typedef struct bf_compiler 4181@{ 4182 const char *filename; 4183 int line; 4184 int column; 4185 4186 gcc_jit_context *ctxt; 4187 4188 gcc_jit_type *void_type; 4189 gcc_jit_type *int_type; 4190 gcc_jit_type *byte_type; 4191 gcc_jit_type *array_type; 4192 4193 gcc_jit_function *func_getchar; 4194 gcc_jit_function *func_putchar; 4195 4196 gcc_jit_function *func; 4197 gcc_jit_block *curblock; 4198 4199 gcc_jit_rvalue *int_zero; 4200 gcc_jit_rvalue *int_one; 4201 gcc_jit_rvalue *byte_zero; 4202 gcc_jit_rvalue *byte_one; 4203 gcc_jit_lvalue *data_cells; 4204 gcc_jit_lvalue *idx; 4205 4206 int num_open_parens; 4207 gcc_jit_block *paren_test[MAX_OPEN_PARENS]; 4208 gcc_jit_block *paren_body[MAX_OPEN_PARENS]; 4209 gcc_jit_block *paren_after[MAX_OPEN_PARENS]; 4210 4211@} bf_compiler; 4212 4213/* Bail out, with a message on stderr. */ 4214 4215static void 4216fatal_error (bf_compiler *bfc, const char *msg) 4217@{ 4218 fprintf (stderr, 4219 "%s:%i:%i: %s", 4220 bfc->filename, bfc->line, bfc->column, msg); 4221 abort (); 4222@} 4223 4224/* Get "data_cells[idx]" as an lvalue. */ 4225 4226static gcc_jit_lvalue * 4227bf_get_current_data (bf_compiler *bfc, gcc_jit_location *loc) 4228@{ 4229 return gcc_jit_context_new_array_access ( 4230 bfc->ctxt, 4231 loc, 4232 gcc_jit_lvalue_as_rvalue (bfc->data_cells), 4233 gcc_jit_lvalue_as_rvalue (bfc->idx)); 4234@} 4235 4236/* Get "data_cells[idx] == 0" as a boolean rvalue. */ 4237 4238static gcc_jit_rvalue * 4239bf_current_data_is_zero (bf_compiler *bfc, gcc_jit_location *loc) 4240@{ 4241 return gcc_jit_context_new_comparison ( 4242 bfc->ctxt, 4243 loc, 4244 GCC_JIT_COMPARISON_EQ, 4245 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)), 4246 bfc->byte_zero); 4247@} 4248 4249/* Compile one bf character. */ 4250 4251static void 4252bf_compile_char (bf_compiler *bfc, 4253 unsigned char ch) 4254@{ 4255 gcc_jit_location *loc = 4256 gcc_jit_context_new_location (bfc->ctxt, 4257 bfc->filename, 4258 bfc->line, 4259 bfc->column); 4260 4261 /* Turn this on to trace execution, by injecting putchar () 4262 of each source char. */ 4263 if (0) 4264 @{ 4265 gcc_jit_rvalue *arg = 4266 gcc_jit_context_new_rvalue_from_int ( 4267 bfc->ctxt, 4268 bfc->int_type, 4269 ch); 4270 gcc_jit_rvalue *call = 4271 gcc_jit_context_new_call (bfc->ctxt, 4272 loc, 4273 bfc->func_putchar, 4274 1, &arg); 4275 gcc_jit_block_add_eval (bfc->curblock, 4276 loc, 4277 call); 4278 @} 4279 4280 switch (ch) 4281 @{ 4282 case '>': 4283 gcc_jit_block_add_comment (bfc->curblock, 4284 loc, 4285 "'>': idx += 1;"); 4286 gcc_jit_block_add_assignment_op (bfc->curblock, 4287 loc, 4288 bfc->idx, 4289 GCC_JIT_BINARY_OP_PLUS, 4290 bfc->int_one); 4291 break; 4292 4293 case '<': 4294 gcc_jit_block_add_comment (bfc->curblock, 4295 loc, 4296 "'<': idx -= 1;"); 4297 gcc_jit_block_add_assignment_op (bfc->curblock, 4298 loc, 4299 bfc->idx, 4300 GCC_JIT_BINARY_OP_MINUS, 4301 bfc->int_one); 4302 break; 4303 4304 case '+': 4305 gcc_jit_block_add_comment (bfc->curblock, 4306 loc, 4307 "'+': data[idx] += 1;"); 4308 gcc_jit_block_add_assignment_op (bfc->curblock, 4309 loc, 4310 bf_get_current_data (bfc, loc), 4311 GCC_JIT_BINARY_OP_PLUS, 4312 bfc->byte_one); 4313 break; 4314 4315 case '-': 4316 gcc_jit_block_add_comment (bfc->curblock, 4317 loc, 4318 "'-': data[idx] -= 1;"); 4319 gcc_jit_block_add_assignment_op (bfc->curblock, 4320 loc, 4321 bf_get_current_data (bfc, loc), 4322 GCC_JIT_BINARY_OP_MINUS, 4323 bfc->byte_one); 4324 break; 4325 4326 case '.': 4327 @{ 4328 gcc_jit_rvalue *arg = 4329 gcc_jit_context_new_cast ( 4330 bfc->ctxt, 4331 loc, 4332 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)), 4333 bfc->int_type); 4334 gcc_jit_rvalue *call = 4335 gcc_jit_context_new_call (bfc->ctxt, 4336 loc, 4337 bfc->func_putchar, 4338 1, &arg); 4339 gcc_jit_block_add_comment (bfc->curblock, 4340 loc, 4341 "'.': putchar ((int)data[idx]);"); 4342 gcc_jit_block_add_eval (bfc->curblock, 4343 loc, 4344 call); 4345 @} 4346 break; 4347 4348 case ',': 4349 @{ 4350 gcc_jit_rvalue *call = 4351 gcc_jit_context_new_call (bfc->ctxt, 4352 loc, 4353 bfc->func_getchar, 4354 0, NULL); 4355 gcc_jit_block_add_comment ( 4356 bfc->curblock, 4357 loc, 4358 "',': data[idx] = (unsigned char)getchar ();"); 4359 gcc_jit_block_add_assignment (bfc->curblock, 4360 loc, 4361 bf_get_current_data (bfc, loc), 4362 gcc_jit_context_new_cast ( 4363 bfc->ctxt, 4364 loc, 4365 call, 4366 bfc->byte_type)); 4367 @} 4368 break; 4369 4370 case '[': 4371 @{ 4372 gcc_jit_block *loop_test = 4373 gcc_jit_function_new_block (bfc->func, NULL); 4374 gcc_jit_block *on_zero = 4375 gcc_jit_function_new_block (bfc->func, NULL); 4376 gcc_jit_block *on_non_zero = 4377 gcc_jit_function_new_block (bfc->func, NULL); 4378 4379 if (bfc->num_open_parens == MAX_OPEN_PARENS) 4380 fatal_error (bfc, "too many open parens"); 4381 4382 gcc_jit_block_end_with_jump ( 4383 bfc->curblock, 4384 loc, 4385 loop_test); 4386 4387 gcc_jit_block_add_comment ( 4388 loop_test, 4389 loc, 4390 "'['"); 4391 gcc_jit_block_end_with_conditional ( 4392 loop_test, 4393 loc, 4394 bf_current_data_is_zero (bfc, loc), 4395 on_zero, 4396 on_non_zero); 4397 bfc->paren_test[bfc->num_open_parens] = loop_test; 4398 bfc->paren_body[bfc->num_open_parens] = on_non_zero; 4399 bfc->paren_after[bfc->num_open_parens] = on_zero; 4400 bfc->num_open_parens += 1; 4401 bfc->curblock = on_non_zero; 4402 @} 4403 break; 4404 4405 case ']': 4406 @{ 4407 gcc_jit_block_add_comment ( 4408 bfc->curblock, 4409 loc, 4410 "']'"); 4411 4412 if (bfc->num_open_parens == 0) 4413 fatal_error (bfc, "mismatching parens"); 4414 bfc->num_open_parens -= 1; 4415 gcc_jit_block_end_with_jump ( 4416 bfc->curblock, 4417 loc, 4418 bfc->paren_test[bfc->num_open_parens]); 4419 bfc->curblock = bfc->paren_after[bfc->num_open_parens]; 4420 @} 4421 break; 4422 4423 case '\n': 4424 bfc->line +=1; 4425 bfc->column = 0; 4426 break; 4427 @} 4428 4429 if (ch != '\n') 4430 bfc->column += 1; 4431@} 4432 4433/* Compile the given .bf file into a gcc_jit_context, containing a 4434 single "main" function suitable for compiling into an executable. */ 4435 4436gcc_jit_context * 4437bf_compile (const char *filename) 4438@{ 4439 bf_compiler bfc; 4440 FILE *f_in; 4441 int ch; 4442 4443 memset (&bfc, 0, sizeof (bfc)); 4444 4445 bfc.filename = filename; 4446 f_in = fopen (filename, "r"); 4447 if (!f_in) 4448 fatal_error (&bfc, "unable to open file"); 4449 bfc.line = 1; 4450 4451 bfc.ctxt = gcc_jit_context_acquire (); 4452 4453 gcc_jit_context_set_int_option ( 4454 bfc.ctxt, 4455 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 4456 3); 4457 gcc_jit_context_set_bool_option ( 4458 bfc.ctxt, 4459 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 4460 0); 4461 gcc_jit_context_set_bool_option ( 4462 bfc.ctxt, 4463 GCC_JIT_BOOL_OPTION_DEBUGINFO, 4464 1); 4465 gcc_jit_context_set_bool_option ( 4466 bfc.ctxt, 4467 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 4468 0); 4469 gcc_jit_context_set_bool_option ( 4470 bfc.ctxt, 4471 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 4472 0); 4473 4474 bfc.void_type = 4475 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_VOID); 4476 bfc.int_type = 4477 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_INT); 4478 bfc.byte_type = 4479 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR); 4480 bfc.array_type = 4481 gcc_jit_context_new_array_type (bfc.ctxt, 4482 NULL, 4483 bfc.byte_type, 4484 30000); 4485 4486 bfc.func_getchar = 4487 gcc_jit_context_new_function (bfc.ctxt, NULL, 4488 GCC_JIT_FUNCTION_IMPORTED, 4489 bfc.int_type, 4490 "getchar", 4491 0, NULL, 4492 0); 4493 4494 gcc_jit_param *param_c = 4495 gcc_jit_context_new_param (bfc.ctxt, NULL, bfc.int_type, "c"); 4496 bfc.func_putchar = 4497 gcc_jit_context_new_function (bfc.ctxt, NULL, 4498 GCC_JIT_FUNCTION_IMPORTED, 4499 bfc.void_type, 4500 "putchar", 4501 1, ¶m_c, 4502 0); 4503 4504 bfc.func = make_main (bfc.ctxt); 4505 bfc.curblock = 4506 gcc_jit_function_new_block (bfc.func, "initial"); 4507 bfc.int_zero = gcc_jit_context_zero (bfc.ctxt, bfc.int_type); 4508 bfc.int_one = gcc_jit_context_one (bfc.ctxt, bfc.int_type); 4509 bfc.byte_zero = gcc_jit_context_zero (bfc.ctxt, bfc.byte_type); 4510 bfc.byte_one = gcc_jit_context_one (bfc.ctxt, bfc.byte_type); 4511 4512 bfc.data_cells = 4513 gcc_jit_context_new_global (bfc.ctxt, NULL, 4514 GCC_JIT_GLOBAL_INTERNAL, 4515 bfc.array_type, 4516 "data_cells"); 4517 bfc.idx = 4518 gcc_jit_function_new_local (bfc.func, NULL, 4519 bfc.int_type, 4520 "idx"); 4521 4522 gcc_jit_block_add_comment (bfc.curblock, 4523 NULL, 4524 "idx = 0;"); 4525 gcc_jit_block_add_assignment (bfc.curblock, 4526 NULL, 4527 bfc.idx, 4528 bfc.int_zero); 4529 4530 bfc.num_open_parens = 0; 4531 4532 while ( EOF != (ch = fgetc (f_in))) 4533 bf_compile_char (&bfc, (unsigned char)ch); 4534 4535 gcc_jit_block_end_with_return (bfc.curblock, NULL, bfc.int_zero); 4536 4537 fclose (f_in); 4538 4539 return bfc.ctxt; 4540@} 4541 4542 4543@end example 4544 4545@noindent 4546@end quotation 4547 4548@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 4549@anchor{intro/tutorial05 compiling-a-context-to-a-file}@anchor{4d} 4550@subsection Compiling a context to a file 4551 4552 4553Unlike the previous tutorial, this time we'll compile the context 4554directly to an executable, using @pxref{4a,,gcc_jit_context_compile_to_file()}: 4555 4556@example 4557gcc_jit_context_compile_to_file (ctxt, 4558 GCC_JIT_OUTPUT_KIND_EXECUTABLE, 4559 output_file); 4560@end example 4561 4562@noindent 4563 4564Here's the top-level of the compiler, which is what actually calls into 4565@pxref{4a,,gcc_jit_context_compile_to_file()}: 4566 4567@quotation 4568 4569@example 4570 4571int 4572main (int argc, char **argv) 4573@{ 4574 const char *input_file; 4575 const char *output_file; 4576 gcc_jit_context *ctxt; 4577 const char *err; 4578 4579 if (argc != 3) 4580 @{ 4581 fprintf (stderr, "%s: INPUT_FILE OUTPUT_FILE\n", argv[0]); 4582 return 1; 4583 @} 4584 4585 input_file = argv[1]; 4586 output_file = argv[2]; 4587 ctxt = bf_compile (input_file); 4588 4589 gcc_jit_context_compile_to_file (ctxt, 4590 GCC_JIT_OUTPUT_KIND_EXECUTABLE, 4591 output_file); 4592 4593 err = gcc_jit_context_get_first_error (ctxt); 4594 4595 if (err) 4596 @{ 4597 gcc_jit_context_release (ctxt); 4598 return 1; 4599 @} 4600 4601 gcc_jit_context_release (ctxt); 4602 return 0; 4603@} 4604 4605 4606@end example 4607 4608@noindent 4609@end quotation 4610 4611Note how once the context is populated you could trivially instead compile 4612it to memory using @pxref{15,,gcc_jit_context_compile()} and run it in-process 4613as in the previous tutorial. 4614 4615To create an executable, we need to export a @code{main} function. Here's 4616how to create one from the JIT API: 4617 4618@quotation 4619 4620@example 4621 4622/* Make "main" function: 4623 int 4624 main (int argc, char **argv) 4625 @{ 4626 ... 4627 @} 4628*/ 4629static gcc_jit_function * 4630make_main (gcc_jit_context *ctxt) 4631@{ 4632 gcc_jit_type *int_type = 4633 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 4634 gcc_jit_param *param_argc = 4635 gcc_jit_context_new_param (ctxt, NULL, int_type, "argc"); 4636 gcc_jit_type *char_ptr_ptr_type = 4637 gcc_jit_type_get_pointer ( 4638 gcc_jit_type_get_pointer ( 4639 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR))); 4640 gcc_jit_param *param_argv = 4641 gcc_jit_context_new_param (ctxt, NULL, char_ptr_ptr_type, "argv"); 4642 gcc_jit_param *params[2] = @{param_argc, param_argv@}; 4643 gcc_jit_function *func_main = 4644 gcc_jit_context_new_function (ctxt, NULL, 4645 GCC_JIT_FUNCTION_EXPORTED, 4646 int_type, 4647 "main", 4648 2, params, 4649 0); 4650 return func_main; 4651@} 4652 4653 4654@end example 4655 4656@noindent 4657@end quotation 4658 4659@cartouche 4660@quotation Note 4661The above implementation ignores @code{argc} and @code{argv}, but you could 4662make use of them by exposing @code{param_argc} and @code{param_argv} to the 4663caller. 4664@end quotation 4665@end cartouche 4666 4667Upon compiling this C code, we obtain a bf-to-machine-code compiler; 4668let's call it @code{bfc}: 4669 4670@example 4671$ gcc \ 4672 tut05-bf.c \ 4673 -o bfc \ 4674 -lgccjit 4675@end example 4676 4677@noindent 4678 4679We can now use @code{bfc} to compile .bf files into machine code executables: 4680 4681@example 4682$ ./bfc \ 4683 emit-alphabet.bf \ 4684 a.out 4685@end example 4686 4687@noindent 4688 4689which we can run directly: 4690 4691@example 4692$ ./a.out 4693ABCDEFGHIJKLMNOPQRSTUVWXYZ 4694@end example 4695 4696@noindent 4697 4698Success! 4699 4700We can also inspect the generated executable using standard tools: 4701 4702@example 4703$ objdump -d a.out |less 4704@end example 4705 4706@noindent 4707 4708which shows that libgccjit has managed to optimize the function 4709somewhat (for example, the runs of 26 and 65 increment operations 4710have become integer constants 0x1a and 0x41): 4711 4712@example 47130000000000400620 <main>: 4714 400620: 80 3d 39 0a 20 00 00 cmpb $0x0,0x200a39(%rip) # 601060 <data 4715 400627: 74 07 je 400630 <main 4716 400629: eb fe jmp 400629 <main+0x9> 4717 40062b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 4718 400630: 48 83 ec 08 sub $0x8,%rsp 4719 400634: 0f b6 05 26 0a 20 00 movzbl 0x200a26(%rip),%eax # 601061 <data_cells+0x1> 4720 40063b: c6 05 1e 0a 20 00 1a movb $0x1a,0x200a1e(%rip) # 601060 <data_cells> 4721 400642: 8d 78 41 lea 0x41(%rax),%edi 4722 400645: 40 88 3d 15 0a 20 00 mov %dil,0x200a15(%rip) # 601061 <data_cells+0x1> 4723 40064c: 0f 1f 40 00 nopl 0x0(%rax) 4724 400650: 40 0f b6 ff movzbl %dil,%edi 4725 400654: e8 87 fe ff ff callq 4004e0 <putchar@@plt> 4726 400659: 0f b6 05 01 0a 20 00 movzbl 0x200a01(%rip),%eax # 601061 <data_cells+0x1> 4727 400660: 80 2d f9 09 20 00 01 subb $0x1,0x2009f9(%rip) # 601060 <data_cells> 4728 400667: 8d 78 01 lea 0x1(%rax),%edi 4729 40066a: 40 88 3d f0 09 20 00 mov %dil,0x2009f0(%rip) # 601061 <data_cells+0x1> 4730 400671: 75 dd jne 400650 <main+0x30> 4731 400673: 31 c0 xor %eax,%eax 4732 400675: 48 83 c4 08 add $0x8,%rsp 4733 400679: c3 retq 4734 40067a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 4735@end example 4736 4737@noindent 4738 4739We also set up debugging information (via 4740@pxref{41,,gcc_jit_context_new_location()} and 4741@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO}), so it's possible to use @code{gdb} 4742to singlestep through the generated binary and inspect the internal 4743state @code{idx} and @code{data_cells}: 4744 4745@example 4746(gdb) break main 4747Breakpoint 1 at 0x400790 4748(gdb) run 4749Starting program: a.out 4750 4751Breakpoint 1, 0x0000000000400790 in main (argc=1, argv=0x7fffffffe448) 4752(gdb) stepi 47530x0000000000400797 in main (argc=1, argv=0x7fffffffe448) 4754(gdb) stepi 47550x00000000004007a0 in main (argc=1, argv=0x7fffffffe448) 4756(gdb) stepi 47579 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4758(gdb) list 47594 47605 cell 0 = 26 47616 ++++++++++++++++++++++++++ 47627 47638 cell 1 = 65 47649 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 476510 476611 while cell#0 != 0 476712 [ 476813 > 4769(gdb) n 47706 ++++++++++++++++++++++++++ 4771(gdb) n 47729 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4773(gdb) p idx 4774$1 = 1 4775(gdb) p data_cells 4776$2 = "\032", '\000' <repeats 29998 times> 4777(gdb) p data_cells[0] 4778$3 = 26 '\032' 4779(gdb) p data_cells[1] 4780$4 = 0 '\000' 4781(gdb) list 47824 47835 cell 0 = 26 47846 ++++++++++++++++++++++++++ 47857 47868 cell 1 = 65 47879 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 478810 478911 while cell#0 != 0 479012 [ 479113 > 4792@end example 4793 4794@noindent 4795 4796@node Other forms of ahead-of-time-compilation,,Compiling a context to a file,Tutorial part 5 Implementing an Ahead-of-Time compiler 4797@anchor{intro/tutorial05 other-forms-of-ahead-of-time-compilation}@anchor{4e} 4798@subsection Other forms of ahead-of-time-compilation 4799 4800 4801The above demonstrates compiling a @pxref{8,,gcc_jit_context *} directly 4802to an executable. It's also possible to compile it to an object file, 4803and to a dynamic library. See the documentation of 4804@pxref{4a,,gcc_jit_context_compile_to_file()} for more information. 4805 4806@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 4807@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 4808@c 4809@c This is free software: you can redistribute it and/or modify it 4810@c under the terms of the GNU General Public License as published by 4811@c the Free Software Foundation, either version 3 of the License, or 4812@c (at your option) any later version. 4813@c 4814@c This program is distributed in the hope that it will be useful, but 4815@c WITHOUT ANY WARRANTY; without even the implied warranty of 4816@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4817@c General Public License for more details. 4818@c 4819@c You should have received a copy of the GNU General Public License 4820@c along with this program. If not, see 4821@c <http://www.gnu.org/licenses/>. 4822 4823@node Topic Reference,C++ bindings for libgccjit,Tutorial,Top 4824@anchor{topics/index doc}@anchor{4f}@anchor{topics/index topic-reference}@anchor{50} 4825@chapter Topic Reference 4826 4827 4828@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 4829@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 4830@c 4831@c This is free software: you can redistribute it and/or modify it 4832@c under the terms of the GNU General Public License as published by 4833@c the Free Software Foundation, either version 3 of the License, or 4834@c (at your option) any later version. 4835@c 4836@c This program is distributed in the hope that it will be useful, but 4837@c WITHOUT ANY WARRANTY; without even the implied warranty of 4838@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4839@c General Public License for more details. 4840@c 4841@c You should have received a copy of the GNU General Public License 4842@c along with this program. If not, see 4843@c <http://www.gnu.org/licenses/>. 4844 4845@menu 4846* Compilation contexts:: 4847* Objects:: 4848* Types:: 4849* Expressions:: 4850* Creating and using functions:: 4851* Source Locations:: 4852* Compiling a context:: 4853* ABI and API compatibility:: 4854 4855Compilation contexts 4856 4857* Lifetime-management:: 4858* Thread-safety:: 4859* Error-handling: Error-handling<2>. 4860* Debugging:: 4861* Options: Options<2>. 4862 4863Options 4864 4865* String Options:: 4866* Boolean options:: 4867* Integer options:: 4868* Additional command-line options:: 4869 4870Types 4871 4872* Standard types:: 4873* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 4874* Structures and unions:: 4875 4876Expressions 4877 4878* Rvalues:: 4879* Lvalues:: 4880* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 4881 4882Rvalues 4883 4884* Simple expressions:: 4885* Unary Operations:: 4886* Binary Operations:: 4887* Comparisons:: 4888* Function calls:: 4889* Type-coercion:: 4890 4891Lvalues 4892 4893* Global variables:: 4894 4895Creating and using functions 4896 4897* Params:: 4898* Functions:: 4899* Blocks:: 4900* Statements:: 4901 4902Source Locations 4903 4904* Faking it:: 4905 4906Compiling a context 4907 4908* In-memory compilation:: 4909* Ahead-of-time compilation:: 4910 4911ABI and API compatibility 4912 4913* ABI symbol tags:: 4914 4915ABI symbol tags 4916 4917* LIBGCCJIT_ABI_0:: 4918* LIBGCCJIT_ABI_1:: 4919* LIBGCCJIT_ABI_2:: 4920* LIBGCCJIT_ABI_3:: 4921 4922@end menu 4923 4924 4925@node Compilation contexts,Objects,,Topic Reference 4926@anchor{topics/contexts compilation-contexts}@anchor{51}@anchor{topics/contexts doc}@anchor{52} 4927@section Compilation contexts 4928 4929 4930@geindex gcc_jit_context (C type) 4931@anchor{topics/contexts gcc_jit_context}@anchor{8} 4932@deffn {C Type} gcc_jit_context 4933@end deffn 4934 4935The top-level of the API is the @pxref{8,,gcc_jit_context} type. 4936 4937A @pxref{8,,gcc_jit_context} instance encapsulates the state of a 4938compilation. 4939 4940You can set up options on it, and add types, functions and code. 4941Invoking @pxref{15,,gcc_jit_context_compile()} on it gives you a 4942@pxref{16,,gcc_jit_result}. 4943 4944@menu 4945* Lifetime-management:: 4946* Thread-safety:: 4947* Error-handling: Error-handling<2>. 4948* Debugging:: 4949* Options: Options<2>. 4950 4951@end menu 4952 4953@node Lifetime-management,Thread-safety,,Compilation contexts 4954@anchor{topics/contexts lifetime-management}@anchor{53} 4955@subsection Lifetime-management 4956 4957 4958Contexts are the unit of lifetime-management within the API: objects 4959have their lifetime bounded by the context they are created within, and 4960cleanup of such objects is done for you when the context is released. 4961 4962@geindex gcc_jit_context_acquire (C function) 4963@anchor{topics/contexts gcc_jit_context_acquire}@anchor{9} 4964@deffn {C Function} gcc_jit_context *gcc_jit_context_acquire (void) 4965 4966This function acquires a new @pxref{8,,gcc_jit_context *} instance, 4967which is independent of any others that may be present within this 4968process. 4969@end deffn 4970 4971@geindex gcc_jit_context_release (C function) 4972@anchor{topics/contexts gcc_jit_context_release}@anchor{c} 4973@deffn {C Function} void gcc_jit_context_release (gcc_jit_context@w{ }*ctxt) 4974 4975This function releases all resources associated with the given context. 4976Both the context itself and all of its @pxref{e,,gcc_jit_object *} 4977instances are cleaned up. It should be called exactly once on a given 4978context. 4979 4980It is invalid to use the context or any of its "contextual" objects 4981after calling this. 4982 4983@example 4984gcc_jit_context_release (ctxt); 4985@end example 4986 4987@noindent 4988@end deffn 4989 4990@geindex gcc_jit_context_new_child_context (C function) 4991@anchor{topics/contexts gcc_jit_context_new_child_context}@anchor{54} 4992@deffn {C Function} gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context@w{ }*parent_ctxt) 4993 4994Given an existing JIT context, create a child context. 4995 4996The child inherits a copy of all option-settings from the parent. 4997 4998The child can reference objects created within the parent, but not 4999vice-versa. 5000 5001The lifetime of the child context must be bounded by that of the 5002parent: you should release a child context before releasing the parent 5003context. 5004 5005If you use a function from a parent context within a child context, 5006you have to compile the parent context before you can compile the 5007child context, and the gcc_jit_result of the parent context must 5008outlive the gcc_jit_result of the child context. 5009 5010This allows caching of shared initializations. For example, you could 5011create types and declarations of global functions in a parent context 5012once within a process, and then create child contexts whenever a 5013function or loop becomes hot. Each such child context can be used for 5014JIT-compiling just one function or loop, but can reference types 5015and helper functions created within the parent context. 5016 5017Contexts can be arbitrarily nested, provided the above rules are 5018followed, but it's probably not worth going above 2 or 3 levels, and 5019there will likely be a performance hit for such nesting. 5020@end deffn 5021 5022@node Thread-safety,Error-handling<2>,Lifetime-management,Compilation contexts 5023@anchor{topics/contexts thread-safety}@anchor{55} 5024@subsection Thread-safety 5025 5026 5027Instances of @pxref{8,,gcc_jit_context *} created via 5028@pxref{9,,gcc_jit_context_acquire()} are independent from each other: 5029only one thread may use a given context at once, but multiple threads 5030could each have their own contexts without needing locks. 5031 5032Contexts created via @pxref{54,,gcc_jit_context_new_child_context()} are 5033related to their parent context. They can be partitioned by their 5034ultimate ancestor into independent "family trees". Only one thread 5035within a process may use a given "family tree" of such contexts at once, 5036and if you're using multiple threads you should provide your own locking 5037around entire such context partitions. 5038 5039@node Error-handling<2>,Debugging,Thread-safety,Compilation contexts 5040@anchor{topics/contexts error-handling}@anchor{19}@anchor{topics/contexts id1}@anchor{56} 5041@subsection Error-handling 5042 5043 5044Various kinds of errors are possible when using the API, such as 5045mismatched types in an assignment. You can only compile and get code from 5046a context if no errors occur. 5047 5048Errors are printed on stderr and can be queried using 5049@pxref{57,,gcc_jit_context_get_first_error()}. 5050 5051They typically contain the name of the API entrypoint where the error 5052occurred, and pertinent information on the problem: 5053 5054@example 5055./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *) 5056@end example 5057 5058@noindent 5059 5060In general, if an error occurs when using an API entrypoint, the 5061entrypoint returns NULL. You don't have to check everywhere for NULL 5062results, since the API handles a NULL being passed in for any 5063argument by issuing another error. This typically leads to a cascade of 5064followup error messages, but is safe (albeit verbose). The first error 5065message is usually the one to pay attention to, since it is likely to 5066be responsible for all of the rest: 5067 5068@geindex gcc_jit_context_get_first_error (C function) 5069@anchor{topics/contexts gcc_jit_context_get_first_error}@anchor{57} 5070@deffn {C Function} const char * gcc_jit_context_get_first_error (gcc_jit_context@w{ }*ctxt) 5071 5072Returns the first error message that occurred on the context. 5073 5074The returned string is valid for the rest of the lifetime of the 5075context. 5076 5077If no errors occurred, this will be NULL. 5078@end deffn 5079 5080If you are wrapping the C API for a higher-level language that supports 5081exception-handling, you may instead be interested in the last error that 5082occurred on the context, so that you can embed this in an exception: 5083 5084@geindex gcc_jit_context_get_last_error (C function) 5085@anchor{topics/contexts gcc_jit_context_get_last_error}@anchor{58} 5086@deffn {C Function} const char * gcc_jit_context_get_last_error (gcc_jit_context@w{ }*ctxt) 5087 5088Returns the last error message that occurred on the context. 5089 5090If no errors occurred, this will be NULL. 5091 5092If non-NULL, the returned string is only guaranteed to be valid until 5093the next call to libgccjit relating to this context. 5094@end deffn 5095 5096@node Debugging,Options<2>,Error-handling<2>,Compilation contexts 5097@anchor{topics/contexts debugging}@anchor{59} 5098@subsection Debugging 5099 5100 5101@geindex gcc_jit_context_dump_to_file (C function) 5102@anchor{topics/contexts gcc_jit_context_dump_to_file}@anchor{5a} 5103@deffn {C Function} void gcc_jit_context_dump_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path, int@w{ }update_locations) 5104 5105To help with debugging: dump a C-like representation to the given path, 5106describing what's been set up on the context. 5107 5108If "update_locations" is true, then also set up @pxref{3b,,gcc_jit_location} 5109information throughout the context, pointing at the dump file as if it 5110were a source file. This may be of use in conjunction with 5111@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to allow stepping through the 5112code in a debugger. 5113@end deffn 5114 5115@geindex gcc_jit_context_set_logfile (C function) 5116@anchor{topics/contexts gcc_jit_context_set_logfile}@anchor{5b} 5117@deffn {C Function} void gcc_jit_context_set_logfile (gcc_jit_context@w{ }*ctxt, FILE@w{ }*logfile, int@w{ }flags, int@w{ }verbosity) 5118 5119To help with debugging; enable ongoing logging of the context's 5120activity to the given file. 5121 5122For example, the following will enable logging to stderr. 5123 5124@example 5125gcc_jit_context_set_logfile (ctxt, stderr, 0, 0); 5126@end example 5127 5128@noindent 5129 5130Examples of information logged include: 5131 5132 5133@itemize * 5134 5135@item 5136API calls 5137 5138@item 5139the various steps involved within compilation 5140 5141@item 5142activity on any @pxref{16,,gcc_jit_result} instances created by 5143the context 5144 5145@item 5146activity within any child contexts 5147@end itemize 5148 5149An example of a log can be seen @pxref{5c,,here}, 5150though the precise format and kinds of information logged is subject 5151to change. 5152 5153The caller remains responsible for closing @cite{logfile}, and it must not 5154be closed until all users are released. In particular, note that 5155child contexts and @pxref{16,,gcc_jit_result} instances created by 5156the context will use the logfile. 5157 5158There may a performance cost for logging. 5159 5160You can turn off logging on @cite{ctxt} by passing @cite{NULL} for @cite{logfile}. 5161Doing so only affects the context; it does not affect child contexts 5162or @pxref{16,,gcc_jit_result} instances already created by 5163the context. 5164 5165The parameters "flags" and "verbosity" are reserved for future 5166expansion, and must be zero for now. 5167@end deffn 5168 5169To contrast the above: @pxref{5a,,gcc_jit_context_dump_to_file()} dumps the 5170current state of a context to the given path, whereas 5171@pxref{5b,,gcc_jit_context_set_logfile()} enables on-going logging of 5172future activies on a context to the given @cite{FILE *}. 5173 5174@geindex gcc_jit_context_dump_reproducer_to_file (C function) 5175@anchor{topics/contexts gcc_jit_context_dump_reproducer_to_file}@anchor{5d} 5176@deffn {C Function} void gcc_jit_context_dump_reproducer_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path) 5177 5178Write C source code into @cite{path} that can be compiled into a 5179self-contained executable (i.e. with libgccjit as the only dependency). 5180The generated code will attempt to replay the API calls that have been 5181made into the given context. 5182 5183This may be useful when debugging the library or client code, for 5184reducing a complicated recipe for reproducing a bug into a simpler 5185form. For example, consider client code that parses some source file 5186into some internal representation, and then walks this IR, calling into 5187libgccjit. If this encounters a bug, a call to 5188@cite{gcc_jit_context_dump_reproducer_to_file} will write out C code for 5189a much simpler executable that performs the equivalent calls into 5190libgccjit, without needing the client code and its data. 5191 5192Typically you need to supply @code{-Wno-unused-variable} when 5193compiling the generated file (since the result of each API call is 5194assigned to a unique variable within the generated C source, and not 5195all are necessarily then used). 5196@end deffn 5197 5198@geindex gcc_jit_context_enable_dump (C function) 5199@anchor{topics/contexts gcc_jit_context_enable_dump}@anchor{5e} 5200@deffn {C Function} void gcc_jit_context_enable_dump (gcc_jit_context@w{ }*ctxt, const char@w{ }*dumpname, char@w{ }**out_ptr) 5201 5202Enable the dumping of a specific set of internal state from the 5203compilation, capturing the result in-memory as a buffer. 5204 5205Parameter "dumpname" corresponds to the equivalent gcc command-line 5206option, without the "-fdump-" prefix. 5207For example, to get the equivalent of @code{-fdump-tree-vrp1}, 5208supply @code{"tree-vrp1"}: 5209 5210@example 5211static char *dump_vrp1; 5212 5213void 5214create_code (gcc_jit_context *ctxt) 5215@{ 5216 gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1); 5217 /* (other API calls omitted for brevity) */ 5218@} 5219@end example 5220 5221@noindent 5222 5223The context directly stores the dumpname as a @code{(const char *)}, so 5224the passed string must outlive the context. 5225 5226@pxref{15,,gcc_jit_context_compile()} will capture the dump as a 5227dynamically-allocated buffer, writing it to @code{*out_ptr}. 5228 5229The caller becomes responsible for calling: 5230 5231@example 5232free (*out_ptr) 5233@end example 5234 5235@noindent 5236 5237each time that @pxref{15,,gcc_jit_context_compile()} is called. 5238@code{*out_ptr} will be written to, either with the address of a buffer, 5239or with @code{NULL} if an error occurred. 5240 5241@cartouche 5242@quotation Warning 5243This API entrypoint is likely to be less stable than the others. 5244In particular, both the precise dumpnames, and the format and content 5245of the dumps are subject to change. 5246 5247It exists primarily for writing the library's own test suite. 5248@end quotation 5249@end cartouche 5250@end deffn 5251 5252@node Options<2>,,Debugging,Compilation contexts 5253@anchor{topics/contexts options}@anchor{5f} 5254@subsection Options 5255 5256 5257Options present in the initial release of libgccjit were handled using 5258enums, whereas those added subsequently have their own per-option API 5259entrypoints. 5260 5261Adding entrypoints for each new option means that client code that use 5262the new options can be identified directly from binary metadata, which 5263would not be possible if we instead extended the various 5264@code{enum gcc_jit_*_option}. 5265 5266@menu 5267* String Options:: 5268* Boolean options:: 5269* Integer options:: 5270* Additional command-line options:: 5271 5272@end menu 5273 5274@node String Options,Boolean options,,Options<2> 5275@anchor{topics/contexts string-options}@anchor{60} 5276@subsubsection String Options 5277 5278 5279@geindex gcc_jit_context_set_str_option (C function) 5280@anchor{topics/contexts gcc_jit_context_set_str_option}@anchor{61} 5281@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) 5282 5283Set a string option of the context. 5284 5285@geindex gcc_jit_str_option (C type) 5286@anchor{topics/contexts gcc_jit_str_option}@anchor{62} 5287@deffn {C Type} enum gcc_jit_str_option 5288@end deffn 5289 5290The parameter @code{value} can be NULL. If non-NULL, the call takes a 5291copy of the underlying string, so it is valid to pass in a pointer to 5292an on-stack buffer. 5293 5294There is just one string option specified this way: 5295 5296@geindex GCC_JIT_STR_OPTION_PROGNAME (C macro) 5297@anchor{topics/contexts GCC_JIT_STR_OPTION_PROGNAME}@anchor{63} 5298@deffn {C Macro} GCC_JIT_STR_OPTION_PROGNAME 5299 5300The name of the program, for use as a prefix when printing error 5301messages to stderr. If @cite{NULL}, or default, "libgccjit.so" is used. 5302@end deffn 5303@end deffn 5304 5305@node Boolean options,Integer options,String Options,Options<2> 5306@anchor{topics/contexts boolean-options}@anchor{64} 5307@subsubsection Boolean options 5308 5309 5310@geindex gcc_jit_context_set_bool_option (C function) 5311@anchor{topics/contexts gcc_jit_context_set_bool_option}@anchor{1b} 5312@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) 5313 5314Set a boolean option of the context. 5315Zero is "false" (the default), non-zero is "true". 5316 5317@geindex gcc_jit_bool_option (C type) 5318@anchor{topics/contexts gcc_jit_bool_option}@anchor{65} 5319@deffn {C Type} enum gcc_jit_bool_option 5320@end deffn 5321 5322@geindex GCC_JIT_BOOL_OPTION_DEBUGINFO (C macro) 5323@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DEBUGINFO}@anchor{42} 5324@deffn {C Macro} GCC_JIT_BOOL_OPTION_DEBUGINFO 5325 5326If true, @pxref{15,,gcc_jit_context_compile()} will attempt to do the right 5327thing so that if you attach a debugger to the process, it will 5328be able to inspect variables and step through your code. 5329 5330Note that you can't step through code unless you set up source 5331location information for the code (by creating and passing in 5332@pxref{3b,,gcc_jit_location} instances). 5333@end deffn 5334 5335@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE (C macro) 5336@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}@anchor{66} 5337@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE 5338 5339If true, @pxref{15,,gcc_jit_context_compile()} will dump its initial 5340"tree" representation of your code to stderr (before any 5341optimizations). 5342 5343Here's some sample output (from the @cite{square} example): 5344 5345@example 5346<statement_list 0x7f4875a62cc0 5347 type <void_type 0x7f4875a64bd0 VOID 5348 align 8 symtab 0 alias set -1 canonical type 0x7f4875a64bd0 5349 pointer_to_this <pointer_type 0x7f4875a64c78>> 5350 side-effects head 0x7f4875a761e0 tail 0x7f4875a761f8 stmts 0x7f4875a62d20 0x7f4875a62d00 5351 5352 stmt <label_expr 0x7f4875a62d20 type <void_type 0x7f4875a64bd0> 5353 side-effects 5354 arg 0 <label_decl 0x7f4875a79080 entry type <void_type 0x7f4875a64bd0> 5355 VOID file (null) line 0 col 0 5356 align 1 context <function_decl 0x7f4875a77500 square>>> 5357 stmt <return_expr 0x7f4875a62d00 5358 type <integer_type 0x7f4875a645e8 public SI 5359 size <integer_cst 0x7f4875a623a0 constant 32> 5360 unit size <integer_cst 0x7f4875a623c0 constant 4> 5361 align 32 symtab 0 alias set -1 canonical type 0x7f4875a645e8 precision 32 min <integer_cst 0x7f4875a62340 -2147483648> max <integer_cst 0x7f4875a62360 2147483647> 5362 pointer_to_this <pointer_type 0x7f4875a6b348>> 5363 side-effects 5364 arg 0 <modify_expr 0x7f4875a72a78 type <integer_type 0x7f4875a645e8> 5365 side-effects arg 0 <result_decl 0x7f4875a7a000 D.54> 5366 arg 1 <mult_expr 0x7f4875a72a50 type <integer_type 0x7f4875a645e8> 5367 arg 0 <parm_decl 0x7f4875a79000 i> arg 1 <parm_decl 0x7f4875a79000 i>>>>> 5368@end example 5369 5370@noindent 5371@end deffn 5372 5373@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE (C macro) 5374@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}@anchor{1c} 5375@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE 5376 5377If true, @pxref{15,,gcc_jit_context_compile()} will dump the "gimple" 5378representation of your code to stderr, before any optimizations 5379are performed. The dump resembles C code: 5380 5381@example 5382square (signed int i) 5383@{ 5384 signed int D.56; 5385 5386 entry: 5387 D.56 = i * i; 5388 return D.56; 5389@} 5390@end example 5391 5392@noindent 5393@end deffn 5394 5395@geindex GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE (C macro) 5396@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE}@anchor{1d} 5397@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE 5398 5399If true, @pxref{15,,gcc_jit_context_compile()} will dump the final 5400generated code to stderr, in the form of assembly language: 5401 5402@example 5403 .file "fake.c" 5404 .text 5405 .globl square 5406 .type square, @@function 5407square: 5408.LFB0: 5409 .cfi_startproc 5410 pushq %rbp 5411 .cfi_def_cfa_offset 16 5412 .cfi_offset 6, -16 5413 movq %rsp, %rbp 5414 .cfi_def_cfa_register 6 5415 movl %edi, -4(%rbp) 5416.L2: 5417 movl -4(%rbp), %eax 5418 imull -4(%rbp), %eax 5419 popq %rbp 5420 .cfi_def_cfa 7, 8 5421 ret 5422 .cfi_endproc 5423.LFE0: 5424 .size square, .-square 5425 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.1-%@{gcc_release@})" 5426 .section .note.GNU-stack,"",@@progbits 5427@end example 5428 5429@noindent 5430@end deffn 5431 5432@geindex GCC_JIT_BOOL_OPTION_DUMP_SUMMARY (C macro) 5433@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_SUMMARY}@anchor{67} 5434@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_SUMMARY 5435 5436If true, @pxref{15,,gcc_jit_context_compile()} will print information to stderr 5437on the actions it is performing, followed by a profile showing 5438the time taken and memory usage of each phase. 5439@end deffn 5440 5441@geindex GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING (C macro) 5442@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING}@anchor{68} 5443@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING 5444 5445If true, @pxref{15,,gcc_jit_context_compile()} will dump copious 5446amount of information on what it's doing to various 5447files within a temporary directory. Use 5448@pxref{69,,GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES} (see below) to 5449see the results. The files are intended to be human-readable, 5450but the exact files and their formats are subject to change. 5451@end deffn 5452 5453@geindex GCC_JIT_BOOL_OPTION_SELFCHECK_GC (C macro) 5454@anchor{topics/contexts GCC_JIT_BOOL_OPTION_SELFCHECK_GC}@anchor{6a} 5455@deffn {C Macro} GCC_JIT_BOOL_OPTION_SELFCHECK_GC 5456 5457If true, libgccjit will aggressively run its garbage collector, to 5458shake out bugs (greatly slowing down the compile). This is likely 5459to only be of interest to developers @emph{of} the library. It is 5460used when running the selftest suite. 5461@end deffn 5462 5463@geindex GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES (C macro) 5464@anchor{topics/contexts GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES}@anchor{69} 5465@deffn {C Macro} GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES 5466 5467If true, the @pxref{8,,gcc_jit_context} will not clean up intermediate files 5468written to the filesystem, and will display their location on stderr. 5469@end deffn 5470@end deffn 5471 5472@geindex gcc_jit_context_set_bool_allow_unreachable_blocks (C function) 5473@anchor{topics/contexts gcc_jit_context_set_bool_allow_unreachable_blocks}@anchor{6b} 5474@deffn {C Function} void gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value) 5475 5476By default, libgccjit will issue an error about unreachable blocks 5477within a function. 5478 5479This entrypoint can be used to disable that error. 5480 5481This entrypoint was added in @pxref{6c,,LIBGCCJIT_ABI_2}; you can test for 5482its presence using 5483 5484@example 5485#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 5486@end example 5487 5488@noindent 5489@end deffn 5490 5491@node Integer options,Additional command-line options,Boolean options,Options<2> 5492@anchor{topics/contexts integer-options}@anchor{6d} 5493@subsubsection Integer options 5494 5495 5496@geindex gcc_jit_context_set_int_option (C function) 5497@anchor{topics/contexts gcc_jit_context_set_int_option}@anchor{1e} 5498@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) 5499 5500Set an integer option of the context. 5501 5502@geindex gcc_jit_int_option (C type) 5503@anchor{topics/contexts gcc_jit_int_option}@anchor{6e} 5504@deffn {C Type} enum gcc_jit_int_option 5505@end deffn 5506 5507There is just one integer option specified this way: 5508 5509@geindex GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL (C macro) 5510@anchor{topics/contexts GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}@anchor{1f} 5511@deffn {C Macro} GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL 5512 5513How much to optimize the code. 5514 5515Valid values are 0-3, corresponding to GCC's command-line options 5516-O0 through -O3. 5517 5518The default value is 0 (unoptimized). 5519@end deffn 5520@end deffn 5521 5522@node Additional command-line options,,Integer options,Options<2> 5523@anchor{topics/contexts additional-command-line-options}@anchor{6f} 5524@subsubsection Additional command-line options 5525 5526 5527@geindex gcc_jit_context_add_command_line_option (C function) 5528@anchor{topics/contexts gcc_jit_context_add_command_line_option}@anchor{70} 5529@deffn {C Function} void gcc_jit_context_add_command_line_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname) 5530 5531Add an arbitrary gcc command-line option to the context, for use 5532by @pxref{15,,gcc_jit_context_compile()} and 5533@pxref{4a,,gcc_jit_context_compile_to_file()}. 5534 5535The parameter @code{optname} must be non-NULL. The underlying buffer is 5536copied, so that it does not need to outlive the call. 5537 5538Extra options added by @cite{gcc_jit_context_add_command_line_option} are 5539applied @emph{after} the regular options above, potentially overriding them. 5540Options from parent contexts are inherited by child contexts; options 5541from the parent are applied @emph{before} those from the child. 5542 5543For example: 5544 5545@example 5546gcc_jit_context_add_command_line_option (ctxt, "-ffast-math"); 5547gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm"); 5548@end example 5549 5550@noindent 5551 5552Note that only some options are likely to be meaningful; there is no 5553"frontend" within libgccjit, so typically only those affecting 5554optimization and code-generation are likely to be useful. 5555 5556This entrypoint was added in @pxref{71,,LIBGCCJIT_ABI_1}; you can test for 5557its presence using 5558 5559@example 5560#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 5561@end example 5562 5563@noindent 5564@end deffn 5565 5566@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 5567@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 5568@c 5569@c This is free software: you can redistribute it and/or modify it 5570@c under the terms of the GNU General Public License as published by 5571@c the Free Software Foundation, either version 3 of the License, or 5572@c (at your option) any later version. 5573@c 5574@c This program is distributed in the hope that it will be useful, but 5575@c WITHOUT ANY WARRANTY; without even the implied warranty of 5576@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5577@c General Public License for more details. 5578@c 5579@c You should have received a copy of the GNU General Public License 5580@c along with this program. If not, see 5581@c <http://www.gnu.org/licenses/>. 5582 5583@node Objects,Types,Compilation contexts,Topic Reference 5584@anchor{topics/objects objects}@anchor{72}@anchor{topics/objects doc}@anchor{73} 5585@section Objects 5586 5587 5588@geindex gcc_jit_object (C type) 5589@anchor{topics/objects gcc_jit_object}@anchor{e} 5590@deffn {C Type} gcc_jit_object 5591@end deffn 5592 5593Almost every entity in the API (with the exception of 5594@pxref{8,,gcc_jit_context *} and @pxref{16,,gcc_jit_result *}) is a 5595"contextual" object, a @pxref{e,,gcc_jit_object *} 5596 5597A JIT object: 5598 5599@quotation 5600 5601 5602@itemize * 5603 5604@item 5605is associated with a @pxref{8,,gcc_jit_context *}. 5606 5607@item 5608is automatically cleaned up for you when its context is released so 5609you don't need to manually track and cleanup all objects, just the 5610contexts. 5611@end itemize 5612@end quotation 5613 5614Although the API is C-based, there is a form of class hierarchy, which 5615looks like this: 5616 5617@example 5618+- gcc_jit_object 5619 +- gcc_jit_location 5620 +- gcc_jit_type 5621 +- gcc_jit_struct 5622 +- gcc_jit_field 5623 +- gcc_jit_function 5624 +- gcc_jit_block 5625 +- gcc_jit_rvalue 5626 +- gcc_jit_lvalue 5627 +- gcc_jit_param 5628 +- gcc_jit_case 5629@end example 5630 5631@noindent 5632 5633There are casting methods for upcasting from subclasses to parent classes. 5634For example, @pxref{d,,gcc_jit_type_as_object()}: 5635 5636@example 5637gcc_jit_object *obj = gcc_jit_type_as_object (int_type); 5638@end example 5639 5640@noindent 5641 5642The object "base class" has the following operations: 5643 5644@geindex gcc_jit_object_get_context (C function) 5645@anchor{topics/objects gcc_jit_object_get_context}@anchor{74} 5646@deffn {C Function} gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object@w{ }*obj) 5647 5648Which context is "obj" within? 5649@end deffn 5650 5651@geindex gcc_jit_object_get_debug_string (C function) 5652@anchor{topics/objects gcc_jit_object_get_debug_string}@anchor{f} 5653@deffn {C Function} const char *gcc_jit_object_get_debug_string (gcc_jit_object@w{ }*obj) 5654 5655Generate a human-readable description for the given object. 5656 5657For example, 5658 5659@example 5660printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); 5661@end example 5662 5663@noindent 5664 5665might give this text on stdout: 5666 5667@example 5668obj: 4.0 * (float)i 5669@end example 5670 5671@noindent 5672 5673@cartouche 5674@quotation Note 5675If you call this on an object, the @cite{const char *} buffer is allocated 5676and generated on the first call for that object, and the buffer will 5677have the same lifetime as the object i.e. it will exist until the 5678object's context is released. 5679@end quotation 5680@end cartouche 5681@end deffn 5682 5683@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 5684@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 5685@c 5686@c This is free software: you can redistribute it and/or modify it 5687@c under the terms of the GNU General Public License as published by 5688@c the Free Software Foundation, either version 3 of the License, or 5689@c (at your option) any later version. 5690@c 5691@c This program is distributed in the hope that it will be useful, but 5692@c WITHOUT ANY WARRANTY; without even the implied warranty of 5693@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5694@c General Public License for more details. 5695@c 5696@c You should have received a copy of the GNU General Public License 5697@c along with this program. If not, see 5698@c <http://www.gnu.org/licenses/>. 5699 5700@node Types,Expressions,Objects,Topic Reference 5701@anchor{topics/types doc}@anchor{75}@anchor{topics/types types}@anchor{76} 5702@section Types 5703 5704 5705@geindex gcc_jit_type (C type) 5706@anchor{topics/types gcc_jit_type}@anchor{a} 5707@deffn {C Type} gcc_jit_type 5708 5709gcc_jit_type represents a type within the library. 5710@end deffn 5711 5712@geindex gcc_jit_type_as_object (C function) 5713@anchor{topics/types gcc_jit_type_as_object}@anchor{d} 5714@deffn {C Function} gcc_jit_object *gcc_jit_type_as_object (gcc_jit_type@w{ }*type) 5715 5716Upcast a type to an object. 5717@end deffn 5718 5719Types can be created in several ways: 5720 5721 5722@itemize * 5723 5724@item 5725fundamental types can be accessed using 5726@pxref{b,,gcc_jit_context_get_type()}: 5727 5728@example 5729gcc_jit_type *int_type = gcc_jit_context_get_type (GCC_JIT_TYPE_INT); 5730@end example 5731 5732@noindent 5733 5734See @pxref{b,,gcc_jit_context_get_type()} for the available types. 5735 5736@item 5737derived types can be accessed by using functions such as 5738@pxref{77,,gcc_jit_type_get_pointer()} and @pxref{78,,gcc_jit_type_get_const()}: 5739 5740@example 5741gcc_jit_type *const_int_star = gcc_jit_type_get_pointer (gcc_jit_type_get_const (int_type)); 5742gcc_jit_type *int_const_star = gcc_jit_type_get_const (gcc_jit_type_get_pointer (int_type)); 5743@end example 5744 5745@noindent 5746 5747@item 5748by creating structures (see below). 5749@end itemize 5750 5751@menu 5752* Standard types:: 5753* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 5754* Structures and unions:: 5755 5756@end menu 5757 5758@node Standard types,Pointers const and volatile,,Types 5759@anchor{topics/types standard-types}@anchor{79} 5760@subsection Standard types 5761 5762 5763@geindex gcc_jit_context_get_type (C function) 5764@anchor{topics/types gcc_jit_context_get_type}@anchor{b} 5765@deffn {C Function} gcc_jit_type *gcc_jit_context_get_type (gcc_jit_context@w{ }*ctxt, enum gcc_jit_types@w{ }type_) 5766 5767Access a specific type. The available types are: 5768 5769 5770@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 5771@headitem 5772 5773@cite{enum gcc_jit_types} value 5774 5775@tab 5776 5777Meaning 5778 5779@item 5780 5781@code{GCC_JIT_TYPE_VOID} 5782 5783@tab 5784 5785C's @code{void} type. 5786 5787@item 5788 5789@code{GCC_JIT_TYPE_VOID_PTR} 5790 5791@tab 5792 5793C's @code{void *}. 5794 5795@item 5796 5797@code{GCC_JIT_TYPE_BOOL} 5798 5799@tab 5800 5801C++'s @code{bool} type; also C99's 5802@code{_Bool} type, aka @code{bool} if 5803using stdbool.h. 5804 5805@item 5806 5807@code{GCC_JIT_TYPE_CHAR} 5808 5809@tab 5810 5811C's @code{char} (of some signedness) 5812 5813@item 5814 5815@code{GCC_JIT_TYPE_SIGNED_CHAR} 5816 5817@tab 5818 5819C's @code{signed char} 5820 5821@item 5822 5823@code{GCC_JIT_TYPE_UNSIGNED_CHAR} 5824 5825@tab 5826 5827C's @code{unsigned char} 5828 5829@item 5830 5831@code{GCC_JIT_TYPE_SHORT} 5832 5833@tab 5834 5835C's @code{short} (signed) 5836 5837@item 5838 5839@code{GCC_JIT_TYPE_UNSIGNED_SHORT} 5840 5841@tab 5842 5843C's @code{unsigned short} 5844 5845@item 5846 5847@code{GCC_JIT_TYPE_INT} 5848 5849@tab 5850 5851C's @code{int} (signed) 5852 5853@item 5854 5855@code{GCC_JIT_TYPE_UNSIGNED_INT} 5856 5857@tab 5858 5859C's @code{unsigned int} 5860 5861@item 5862 5863@code{GCC_JIT_TYPE_LONG} 5864 5865@tab 5866 5867C's @code{long} (signed) 5868 5869@item 5870 5871@code{GCC_JIT_TYPE_UNSIGNED_LONG} 5872 5873@tab 5874 5875C's @code{unsigned long} 5876 5877@item 5878 5879@code{GCC_JIT_TYPE_LONG_LONG} 5880 5881@tab 5882 5883C99's @code{long long} (signed) 5884 5885@item 5886 5887@code{GCC_JIT_TYPE_UNSIGNED_LONG_LONG} 5888 5889@tab 5890 5891C99's @code{unsigned long long} 5892 5893@item 5894 5895@code{GCC_JIT_TYPE_FLOAT} 5896 5897@tab 5898 5899@item 5900 5901@code{GCC_JIT_TYPE_DOUBLE} 5902 5903@tab 5904 5905@item 5906 5907@code{GCC_JIT_TYPE_LONG_DOUBLE} 5908 5909@tab 5910 5911@item 5912 5913@code{GCC_JIT_TYPE_CONST_CHAR_PTR} 5914 5915@tab 5916 5917C type: @code{(const char *)} 5918 5919@item 5920 5921@code{GCC_JIT_TYPE_SIZE_T} 5922 5923@tab 5924 5925C's @code{size_t} type 5926 5927@item 5928 5929@code{GCC_JIT_TYPE_FILE_PTR} 5930 5931@tab 5932 5933C type: @code{(FILE *)} 5934 5935@item 5936 5937@code{GCC_JIT_TYPE_COMPLEX_FLOAT} 5938 5939@tab 5940 5941C99's @code{_Complex float} 5942 5943@item 5944 5945@code{GCC_JIT_TYPE_COMPLEX_DOUBLE} 5946 5947@tab 5948 5949C99's @code{_Complex double} 5950 5951@item 5952 5953@code{GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE} 5954 5955@tab 5956 5957C99's @code{_Complex long double} 5958 5959@end multitable 5960 5961@end deffn 5962 5963@geindex gcc_jit_context_get_int_type (C function) 5964@anchor{topics/types gcc_jit_context_get_int_type}@anchor{7a} 5965@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) 5966 5967Access the integer type of the given size. 5968@end deffn 5969 5970@node Pointers const and volatile,Structures and unions,Standard types,Types 5971@anchor{topics/types pointers-const-and-volatile}@anchor{7b} 5972@subsection Pointers, @cite{const}, and @cite{volatile} 5973 5974 5975@geindex gcc_jit_type_get_pointer (C function) 5976@anchor{topics/types gcc_jit_type_get_pointer}@anchor{77} 5977@deffn {C Function} gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type@w{ }*type) 5978 5979Given type "T", get type "T*". 5980@end deffn 5981 5982@geindex gcc_jit_type_get_const (C function) 5983@anchor{topics/types gcc_jit_type_get_const}@anchor{78} 5984@deffn {C Function} gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type@w{ }*type) 5985 5986Given type "T", get type "const T". 5987@end deffn 5988 5989@geindex gcc_jit_type_get_volatile (C function) 5990@anchor{topics/types gcc_jit_type_get_volatile}@anchor{7c} 5991@deffn {C Function} gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type@w{ }*type) 5992 5993Given type "T", get type "volatile T". 5994@end deffn 5995 5996@geindex gcc_jit_context_new_array_type (C function) 5997@anchor{topics/types gcc_jit_context_new_array_type}@anchor{7d} 5998@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) 5999 6000Given type "T", get type "T[N]" (for a constant N). 6001@end deffn 6002 6003@node Structures and unions,,Pointers const and volatile,Types 6004@anchor{topics/types structures-and-unions}@anchor{7e} 6005@subsection Structures and unions 6006 6007 6008@geindex gcc_jit_struct (C type) 6009@anchor{topics/types gcc_jit_struct}@anchor{7f} 6010@deffn {C Type} gcc_jit_struct 6011@end deffn 6012 6013A compound type analagous to a C @cite{struct}. 6014 6015@geindex gcc_jit_field (C type) 6016@anchor{topics/types gcc_jit_field}@anchor{80} 6017@deffn {C Type} gcc_jit_field 6018@end deffn 6019 6020A field within a @pxref{7f,,gcc_jit_struct}. 6021 6022You can model C @cite{struct} types by creating @pxref{7f,,gcc_jit_struct *} and 6023@pxref{80,,gcc_jit_field} instances, in either order: 6024 6025 6026@itemize * 6027 6028@item 6029by creating the fields, then the structure. For example, to model: 6030 6031@example 6032struct coord @{double x; double y; @}; 6033@end example 6034 6035@noindent 6036 6037you could call: 6038 6039@example 6040gcc_jit_field *field_x = 6041 gcc_jit_context_new_field (ctxt, NULL, double_type, "x"); 6042gcc_jit_field *field_y = 6043 gcc_jit_context_new_field (ctxt, NULL, double_type, "y"); 6044gcc_jit_field *fields[2] = @{field_x, field_y@}; 6045gcc_jit_struct *coord = 6046 gcc_jit_context_new_struct_type (ctxt, NULL, "coord", 2, fields); 6047@end example 6048 6049@noindent 6050 6051@item 6052by creating the structure, then populating it with fields, typically 6053to allow modelling self-referential structs such as: 6054 6055@example 6056struct node @{ int m_hash; struct node *m_next; @}; 6057@end example 6058 6059@noindent 6060 6061like this: 6062 6063@example 6064gcc_jit_type *node = 6065 gcc_jit_context_new_opaque_struct (ctxt, NULL, "node"); 6066gcc_jit_type *node_ptr = 6067 gcc_jit_type_get_pointer (node); 6068gcc_jit_field *field_hash = 6069 gcc_jit_context_new_field (ctxt, NULL, int_type, "m_hash"); 6070gcc_jit_field *field_next = 6071 gcc_jit_context_new_field (ctxt, NULL, node_ptr, "m_next"); 6072gcc_jit_field *fields[2] = @{field_hash, field_next@}; 6073gcc_jit_struct_set_fields (node, NULL, 2, fields); 6074@end example 6075 6076@noindent 6077@end itemize 6078 6079@geindex gcc_jit_context_new_field (C function) 6080@anchor{topics/types gcc_jit_context_new_field}@anchor{81} 6081@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) 6082 6083Construct a new field, with the given type and name. 6084 6085The parameter @code{name} must be non-NULL. The call takes a copy of the 6086underlying string, so it is valid to pass in a pointer to an on-stack 6087buffer. 6088@end deffn 6089 6090@geindex gcc_jit_field_as_object (C function) 6091@anchor{topics/types gcc_jit_field_as_object}@anchor{82} 6092@deffn {C Function} gcc_jit_object * gcc_jit_field_as_object (gcc_jit_field@w{ }*field) 6093 6094Upcast from field to object. 6095@end deffn 6096 6097@geindex gcc_jit_context_new_struct_type (C function) 6098@anchor{topics/types gcc_jit_context_new_struct_type}@anchor{83} 6099@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) 6100 6101@quotation 6102 6103Construct a new struct type, with the given name and fields. 6104 6105The parameter @code{name} must be non-NULL. The call takes a copy of 6106the underlying string, so it is valid to pass in a pointer to an 6107on-stack buffer. 6108@end quotation 6109@end deffn 6110 6111@geindex gcc_jit_context_new_opaque_struct (C function) 6112@anchor{topics/types gcc_jit_context_new_opaque_struct}@anchor{84} 6113@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) 6114 6115Construct a new struct type, with the given name, but without 6116specifying the fields. The fields can be omitted (in which case the 6117size of the struct is not known), or later specified using 6118@pxref{85,,gcc_jit_struct_set_fields()}. 6119 6120The parameter @code{name} must be non-NULL. The call takes a copy of 6121the underlying string, so it is valid to pass in a pointer to an 6122on-stack buffer. 6123@end deffn 6124 6125@geindex gcc_jit_struct_as_type (C function) 6126@anchor{topics/types gcc_jit_struct_as_type}@anchor{86} 6127@deffn {C Function} gcc_jit_type * gcc_jit_struct_as_type (gcc_jit_struct@w{ }*struct_type) 6128 6129Upcast from struct to type. 6130@end deffn 6131 6132@geindex gcc_jit_struct_set_fields (C function) 6133@anchor{topics/types gcc_jit_struct_set_fields}@anchor{85} 6134@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) 6135 6136Populate the fields of a formerly-opaque struct type. 6137 6138This can only be called once on a given struct type. 6139@end deffn 6140 6141@geindex gcc_jit_context_new_union_type (C function) 6142@anchor{topics/types gcc_jit_context_new_union_type}@anchor{87} 6143@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) 6144 6145Construct a new union type, with the given name and fields. 6146 6147The parameter @code{name} must be non-NULL. It is copied, so the input 6148buffer does not need to outlive the call. 6149 6150Example of use: 6151 6152@example 6153 6154union int_or_float 6155@{ 6156 int as_int; 6157 float as_float; 6158@}; 6159 6160void 6161create_code (gcc_jit_context *ctxt, void *user_data) 6162@{ 6163 /* Let's try to inject the equivalent of: 6164 float 6165 test_union (int i) 6166 @{ 6167 union int_or_float u; 6168 u.as_int = i; 6169 return u.as_float; 6170 @} 6171 */ 6172 gcc_jit_type *int_type = 6173 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 6174 gcc_jit_type *float_type = 6175 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); 6176 gcc_jit_field *as_int = 6177 gcc_jit_context_new_field (ctxt, 6178 NULL, 6179 int_type, 6180 "as_int"); 6181 gcc_jit_field *as_float = 6182 gcc_jit_context_new_field (ctxt, 6183 NULL, 6184 float_type, 6185 "as_float"); 6186 gcc_jit_field *fields[] = @{as_int, as_float@}; 6187 gcc_jit_type *union_type = 6188 gcc_jit_context_new_union_type (ctxt, NULL, 6189 "int_or_float", 2, fields); 6190 6191 /* Build the test function. */ 6192 gcc_jit_param *param_i = 6193 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 6194 gcc_jit_function *test_fn = 6195 gcc_jit_context_new_function (ctxt, NULL, 6196 GCC_JIT_FUNCTION_EXPORTED, 6197 float_type, 6198 "test_union", 6199 1, ¶m_i, 6200 0); 6201 6202 gcc_jit_lvalue *u = 6203 gcc_jit_function_new_local (test_fn, NULL, 6204 union_type, "u"); 6205 6206 gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); 6207 6208 /* u.as_int = i; */ 6209 gcc_jit_block_add_assignment ( 6210 block, 6211 NULL, 6212 /* "u.as_int = ..." */ 6213 gcc_jit_lvalue_access_field (u, 6214 NULL, 6215 as_int), 6216 gcc_jit_param_as_rvalue (param_i)); 6217 6218 /* return u.as_float; */ 6219 gcc_jit_block_end_with_return ( 6220 block, NULL, 6221 gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (u), 6222 NULL, 6223 as_float)); 6224@} 6225 6226 6227@end example 6228 6229@noindent 6230@end deffn 6231 6232@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 6233@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 6234@c 6235@c This is free software: you can redistribute it and/or modify it 6236@c under the terms of the GNU General Public License as published by 6237@c the Free Software Foundation, either version 3 of the License, or 6238@c (at your option) any later version. 6239@c 6240@c This program is distributed in the hope that it will be useful, but 6241@c WITHOUT ANY WARRANTY; without even the implied warranty of 6242@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 6243@c General Public License for more details. 6244@c 6245@c You should have received a copy of the GNU General Public License 6246@c along with this program. If not, see 6247@c <http://www.gnu.org/licenses/>. 6248 6249@node Expressions,Creating and using functions,Types,Topic Reference 6250@anchor{topics/expressions expressions}@anchor{88}@anchor{topics/expressions doc}@anchor{89} 6251@section Expressions 6252 6253 6254@menu 6255* Rvalues:: 6256* Lvalues:: 6257* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 6258 6259Rvalues 6260 6261* Simple expressions:: 6262* Unary Operations:: 6263* Binary Operations:: 6264* Comparisons:: 6265* Function calls:: 6266* Type-coercion:: 6267 6268Lvalues 6269 6270* Global variables:: 6271 6272@end menu 6273 6274 6275@node Rvalues,Lvalues,,Expressions 6276@anchor{topics/expressions rvalues}@anchor{8a} 6277@subsection Rvalues 6278 6279 6280@geindex gcc_jit_rvalue (C type) 6281@anchor{topics/expressions gcc_jit_rvalue}@anchor{13} 6282@deffn {C Type} gcc_jit_rvalue 6283@end deffn 6284 6285A @pxref{13,,gcc_jit_rvalue *} is an expression that can be computed. 6286 6287It can be simple, e.g.: 6288 6289@quotation 6290 6291 6292@itemize * 6293 6294@item 6295an integer value e.g. @cite{0} or @cite{42} 6296 6297@item 6298a string literal e.g. @cite{"Hello world"} 6299 6300@item 6301a variable e.g. @cite{i}. These are also lvalues (see below). 6302@end itemize 6303@end quotation 6304 6305or compound e.g.: 6306 6307@quotation 6308 6309 6310@itemize * 6311 6312@item 6313a unary expression e.g. @cite{!cond} 6314 6315@item 6316a binary expression e.g. @cite{(a + b)} 6317 6318@item 6319a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} 6320 6321@item 6322etc. 6323@end itemize 6324@end quotation 6325 6326Every rvalue has an associated type, and the API will check to ensure 6327that types match up correctly (otherwise the context will emit an error). 6328 6329@geindex gcc_jit_rvalue_get_type (C function) 6330@anchor{topics/expressions gcc_jit_rvalue_get_type}@anchor{8b} 6331@deffn {C Function} gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue@w{ }*rvalue) 6332 6333Get the type of this rvalue. 6334@end deffn 6335 6336@geindex gcc_jit_rvalue_as_object (C function) 6337@anchor{topics/expressions gcc_jit_rvalue_as_object}@anchor{14} 6338@deffn {C Function} gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue@w{ }*rvalue) 6339 6340Upcast the given rvalue to be an object. 6341@end deffn 6342 6343@menu 6344* Simple expressions:: 6345* Unary Operations:: 6346* Binary Operations:: 6347* Comparisons:: 6348* Function calls:: 6349* Type-coercion:: 6350 6351@end menu 6352 6353@node Simple expressions,Unary Operations,,Rvalues 6354@anchor{topics/expressions simple-expressions}@anchor{8c} 6355@subsubsection Simple expressions 6356 6357 6358@geindex gcc_jit_context_new_rvalue_from_int (C function) 6359@anchor{topics/expressions gcc_jit_context_new_rvalue_from_int}@anchor{30} 6360@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) 6361 6362Given a numeric type (integer or floating point), build an rvalue for 6363the given constant @code{int} value. 6364@end deffn 6365 6366@geindex gcc_jit_context_new_rvalue_from_long (C function) 6367@anchor{topics/expressions gcc_jit_context_new_rvalue_from_long}@anchor{8d} 6368@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) 6369 6370Given a numeric type (integer or floating point), build an rvalue for 6371the given constant @code{long} value. 6372@end deffn 6373 6374@geindex gcc_jit_context_zero (C function) 6375@anchor{topics/expressions gcc_jit_context_zero}@anchor{2b} 6376@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) 6377 6378Given a numeric type (integer or floating point), get the rvalue for 6379zero. Essentially this is just a shortcut for: 6380 6381@example 6382gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0) 6383@end example 6384 6385@noindent 6386@end deffn 6387 6388@geindex gcc_jit_context_one (C function) 6389@anchor{topics/expressions gcc_jit_context_one}@anchor{2f} 6390@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_one (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) 6391 6392Given a numeric type (integer or floating point), get the rvalue for 6393one. Essentially this is just a shortcut for: 6394 6395@example 6396gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1) 6397@end example 6398 6399@noindent 6400@end deffn 6401 6402@geindex gcc_jit_context_new_rvalue_from_double (C function) 6403@anchor{topics/expressions gcc_jit_context_new_rvalue_from_double}@anchor{31} 6404@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) 6405 6406Given a numeric type (integer or floating point), build an rvalue for 6407the given constant @code{double} value. 6408@end deffn 6409 6410@geindex gcc_jit_context_new_rvalue_from_ptr (C function) 6411@anchor{topics/expressions gcc_jit_context_new_rvalue_from_ptr}@anchor{8e} 6412@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) 6413 6414Given a pointer type, build an rvalue for the given address. 6415@end deffn 6416 6417@geindex gcc_jit_context_null (C function) 6418@anchor{topics/expressions gcc_jit_context_null}@anchor{8f} 6419@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type) 6420 6421Given a pointer type, build an rvalue for @code{NULL}. Essentially this 6422is just a shortcut for: 6423 6424@example 6425gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL) 6426@end example 6427 6428@noindent 6429@end deffn 6430 6431@geindex gcc_jit_context_new_string_literal (C function) 6432@anchor{topics/expressions gcc_jit_context_new_string_literal}@anchor{90} 6433@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_string_literal (gcc_jit_context@w{ }*ctxt, const char@w{ }*value) 6434 6435Generate an rvalue for the given NIL-terminated string, of type 6436@code{GCC_JIT_TYPE_CONST_CHAR_PTR}. 6437 6438The parameter @code{value} must be non-NULL. The call takes a copy of the 6439underlying string, so it is valid to pass in a pointer to an on-stack 6440buffer. 6441@end deffn 6442 6443@node Unary Operations,Binary Operations,Simple expressions,Rvalues 6444@anchor{topics/expressions unary-operations}@anchor{91} 6445@subsubsection Unary Operations 6446 6447 6448@geindex gcc_jit_context_new_unary_op (C function) 6449@anchor{topics/expressions gcc_jit_context_new_unary_op}@anchor{92} 6450@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) 6451 6452Build a unary operation out of an input rvalue. 6453@end deffn 6454 6455@geindex gcc_jit_unary_op (C type) 6456@anchor{topics/expressions gcc_jit_unary_op}@anchor{93} 6457@deffn {C Type} enum gcc_jit_unary_op 6458@end deffn 6459 6460The available unary operations are: 6461 6462 6463@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6464@headitem 6465 6466Unary Operation 6467 6468@tab 6469 6470C equivalent 6471 6472@item 6473 6474@pxref{94,,GCC_JIT_UNARY_OP_MINUS} 6475 6476@tab 6477 6478@cite{-(EXPR)} 6479 6480@item 6481 6482@pxref{95,,GCC_JIT_UNARY_OP_BITWISE_NEGATE} 6483 6484@tab 6485 6486@cite{~(EXPR)} 6487 6488@item 6489 6490@pxref{96,,GCC_JIT_UNARY_OP_LOGICAL_NEGATE} 6491 6492@tab 6493 6494@cite{!(EXPR)} 6495 6496@item 6497 6498@pxref{97,,GCC_JIT_UNARY_OP_ABS} 6499 6500@tab 6501 6502@cite{abs (EXPR)} 6503 6504@end multitable 6505 6506 6507@geindex GCC_JIT_UNARY_OP_MINUS (C macro) 6508@anchor{topics/expressions GCC_JIT_UNARY_OP_MINUS}@anchor{94} 6509@deffn {C Macro} GCC_JIT_UNARY_OP_MINUS 6510 6511Negate an arithmetic value; analogous to: 6512 6513@example 6514-(EXPR) 6515@end example 6516 6517@noindent 6518 6519in C. 6520@end deffn 6521 6522@geindex GCC_JIT_UNARY_OP_BITWISE_NEGATE (C macro) 6523@anchor{topics/expressions GCC_JIT_UNARY_OP_BITWISE_NEGATE}@anchor{95} 6524@deffn {C Macro} GCC_JIT_UNARY_OP_BITWISE_NEGATE 6525 6526Bitwise negation of an integer value (one's complement); analogous 6527to: 6528 6529@example 6530~(EXPR) 6531@end example 6532 6533@noindent 6534 6535in C. 6536@end deffn 6537 6538@geindex GCC_JIT_UNARY_OP_LOGICAL_NEGATE (C macro) 6539@anchor{topics/expressions GCC_JIT_UNARY_OP_LOGICAL_NEGATE}@anchor{96} 6540@deffn {C Macro} GCC_JIT_UNARY_OP_LOGICAL_NEGATE 6541 6542Logical negation of an arithmetic or pointer value; analogous to: 6543 6544@example 6545!(EXPR) 6546@end example 6547 6548@noindent 6549 6550in C. 6551@end deffn 6552 6553@geindex GCC_JIT_UNARY_OP_ABS (C macro) 6554@anchor{topics/expressions GCC_JIT_UNARY_OP_ABS}@anchor{97} 6555@deffn {C Macro} GCC_JIT_UNARY_OP_ABS 6556 6557Absolute value of an arithmetic expression; analogous to: 6558 6559@example 6560abs (EXPR) 6561@end example 6562 6563@noindent 6564 6565in C. 6566@end deffn 6567 6568@node Binary Operations,Comparisons,Unary Operations,Rvalues 6569@anchor{topics/expressions binary-operations}@anchor{98} 6570@subsubsection Binary Operations 6571 6572 6573@geindex gcc_jit_context_new_binary_op (C function) 6574@anchor{topics/expressions gcc_jit_context_new_binary_op}@anchor{12} 6575@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) 6576 6577Build a binary operation out of two constituent rvalues. 6578@end deffn 6579 6580@geindex gcc_jit_binary_op (C type) 6581@anchor{topics/expressions gcc_jit_binary_op}@anchor{99} 6582@deffn {C Type} enum gcc_jit_binary_op 6583@end deffn 6584 6585The available binary operations are: 6586 6587 6588@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6589@headitem 6590 6591Binary Operation 6592 6593@tab 6594 6595C equivalent 6596 6597@item 6598 6599@pxref{9a,,GCC_JIT_BINARY_OP_PLUS} 6600 6601@tab 6602 6603@cite{x + y} 6604 6605@item 6606 6607@pxref{9b,,GCC_JIT_BINARY_OP_MINUS} 6608 6609@tab 6610 6611@cite{x - y} 6612 6613@item 6614 6615@pxref{9c,,GCC_JIT_BINARY_OP_MULT} 6616 6617@tab 6618 6619@cite{x * y} 6620 6621@item 6622 6623@pxref{9d,,GCC_JIT_BINARY_OP_DIVIDE} 6624 6625@tab 6626 6627@cite{x / y} 6628 6629@item 6630 6631@pxref{9e,,GCC_JIT_BINARY_OP_MODULO} 6632 6633@tab 6634 6635@cite{x % y} 6636 6637@item 6638 6639@pxref{9f,,GCC_JIT_BINARY_OP_BITWISE_AND} 6640 6641@tab 6642 6643@cite{x & y} 6644 6645@item 6646 6647@pxref{a0,,GCC_JIT_BINARY_OP_BITWISE_XOR} 6648 6649@tab 6650 6651@cite{x ^ y} 6652 6653@item 6654 6655@pxref{a1,,GCC_JIT_BINARY_OP_BITWISE_OR} 6656 6657@tab 6658 6659@cite{x | y} 6660 6661@item 6662 6663@pxref{a2,,GCC_JIT_BINARY_OP_LOGICAL_AND} 6664 6665@tab 6666 6667@cite{x && y} 6668 6669@item 6670 6671@pxref{a3,,GCC_JIT_BINARY_OP_LOGICAL_OR} 6672 6673@tab 6674 6675@cite{x || y} 6676 6677@item 6678 6679@pxref{a4,,GCC_JIT_BINARY_OP_LSHIFT} 6680 6681@tab 6682 6683@cite{x << y} 6684 6685@item 6686 6687@pxref{a5,,GCC_JIT_BINARY_OP_RSHIFT} 6688 6689@tab 6690 6691@cite{x >> y} 6692 6693@end multitable 6694 6695 6696@geindex GCC_JIT_BINARY_OP_PLUS (C macro) 6697@anchor{topics/expressions GCC_JIT_BINARY_OP_PLUS}@anchor{9a} 6698@deffn {C Macro} GCC_JIT_BINARY_OP_PLUS 6699 6700Addition of arithmetic values; analogous to: 6701 6702@example 6703(EXPR_A) + (EXPR_B) 6704@end example 6705 6706@noindent 6707 6708in C. 6709 6710For pointer addition, use @pxref{a6,,gcc_jit_context_new_array_access()}. 6711@end deffn 6712 6713@geindex GCC_JIT_BINARY_OP_MINUS (C macro) 6714@anchor{topics/expressions GCC_JIT_BINARY_OP_MINUS}@anchor{9b} 6715@deffn {C Macro} GCC_JIT_BINARY_OP_MINUS 6716 6717Subtraction of arithmetic values; analogous to: 6718 6719@example 6720(EXPR_A) - (EXPR_B) 6721@end example 6722 6723@noindent 6724 6725in C. 6726@end deffn 6727 6728@geindex GCC_JIT_BINARY_OP_MULT (C macro) 6729@anchor{topics/expressions GCC_JIT_BINARY_OP_MULT}@anchor{9c} 6730@deffn {C Macro} GCC_JIT_BINARY_OP_MULT 6731 6732Multiplication of a pair of arithmetic values; analogous to: 6733 6734@example 6735(EXPR_A) * (EXPR_B) 6736@end example 6737 6738@noindent 6739 6740in C. 6741@end deffn 6742 6743@geindex GCC_JIT_BINARY_OP_DIVIDE (C macro) 6744@anchor{topics/expressions GCC_JIT_BINARY_OP_DIVIDE}@anchor{9d} 6745@deffn {C Macro} GCC_JIT_BINARY_OP_DIVIDE 6746 6747Quotient of division of arithmetic values; analogous to: 6748 6749@example 6750(EXPR_A) / (EXPR_B) 6751@end example 6752 6753@noindent 6754 6755in C. 6756 6757The result type affects the kind of division: if the result type is 6758integer-based, then the result is truncated towards zero, whereas 6759a floating-point result type indicates floating-point division. 6760@end deffn 6761 6762@geindex GCC_JIT_BINARY_OP_MODULO (C macro) 6763@anchor{topics/expressions GCC_JIT_BINARY_OP_MODULO}@anchor{9e} 6764@deffn {C Macro} GCC_JIT_BINARY_OP_MODULO 6765 6766Remainder of division of arithmetic values; analogous to: 6767 6768@example 6769(EXPR_A) % (EXPR_B) 6770@end example 6771 6772@noindent 6773 6774in C. 6775@end deffn 6776 6777@geindex GCC_JIT_BINARY_OP_BITWISE_AND (C macro) 6778@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_AND}@anchor{9f} 6779@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_AND 6780 6781Bitwise AND; analogous to: 6782 6783@example 6784(EXPR_A) & (EXPR_B) 6785@end example 6786 6787@noindent 6788 6789in C. 6790@end deffn 6791 6792@geindex GCC_JIT_BINARY_OP_BITWISE_XOR (C macro) 6793@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_XOR}@anchor{a0} 6794@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_XOR 6795 6796Bitwise exclusive OR; analogous to: 6797 6798@example 6799(EXPR_A) ^ (EXPR_B) 6800@end example 6801 6802@noindent 6803 6804in C. 6805@end deffn 6806 6807@geindex GCC_JIT_BINARY_OP_BITWISE_OR (C macro) 6808@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_OR}@anchor{a1} 6809@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_OR 6810 6811Bitwise inclusive OR; analogous to: 6812 6813@example 6814(EXPR_A) | (EXPR_B) 6815@end example 6816 6817@noindent 6818 6819in C. 6820@end deffn 6821 6822@geindex GCC_JIT_BINARY_OP_LOGICAL_AND (C macro) 6823@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_AND}@anchor{a2} 6824@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_AND 6825 6826Logical AND; analogous to: 6827 6828@example 6829(EXPR_A) && (EXPR_B) 6830@end example 6831 6832@noindent 6833 6834in C. 6835@end deffn 6836 6837@geindex GCC_JIT_BINARY_OP_LOGICAL_OR (C macro) 6838@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_OR}@anchor{a3} 6839@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_OR 6840 6841Logical OR; analogous to: 6842 6843@example 6844(EXPR_A) || (EXPR_B) 6845@end example 6846 6847@noindent 6848 6849in C. 6850@end deffn 6851 6852@geindex GCC_JIT_BINARY_OP_LSHIFT (C macro) 6853@anchor{topics/expressions GCC_JIT_BINARY_OP_LSHIFT}@anchor{a4} 6854@deffn {C Macro} GCC_JIT_BINARY_OP_LSHIFT 6855 6856Left shift; analogous to: 6857 6858@example 6859(EXPR_A) << (EXPR_B) 6860@end example 6861 6862@noindent 6863 6864in C. 6865@end deffn 6866 6867@geindex GCC_JIT_BINARY_OP_RSHIFT (C macro) 6868@anchor{topics/expressions GCC_JIT_BINARY_OP_RSHIFT}@anchor{a5} 6869@deffn {C Macro} GCC_JIT_BINARY_OP_RSHIFT 6870 6871Right shift; analogous to: 6872 6873@example 6874(EXPR_A) >> (EXPR_B) 6875@end example 6876 6877@noindent 6878 6879in C. 6880@end deffn 6881 6882@node Comparisons,Function calls,Binary Operations,Rvalues 6883@anchor{topics/expressions comparisons}@anchor{a7} 6884@subsubsection Comparisons 6885 6886 6887@geindex gcc_jit_context_new_comparison (C function) 6888@anchor{topics/expressions gcc_jit_context_new_comparison}@anchor{2c} 6889@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) 6890 6891Build a boolean rvalue out of the comparison of two other rvalues. 6892@end deffn 6893 6894@geindex gcc_jit_comparison (C type) 6895@anchor{topics/expressions gcc_jit_comparison}@anchor{a8} 6896@deffn {C Type} enum gcc_jit_comparison 6897@end deffn 6898 6899 6900@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6901@headitem 6902 6903Comparison 6904 6905@tab 6906 6907C equivalent 6908 6909@item 6910 6911@code{GCC_JIT_COMPARISON_EQ} 6912 6913@tab 6914 6915@cite{x == y} 6916 6917@item 6918 6919@code{GCC_JIT_COMPARISON_NE} 6920 6921@tab 6922 6923@cite{x != y} 6924 6925@item 6926 6927@code{GCC_JIT_COMPARISON_LT} 6928 6929@tab 6930 6931@cite{x < y} 6932 6933@item 6934 6935@code{GCC_JIT_COMPARISON_LE} 6936 6937@tab 6938 6939@cite{x <= y} 6940 6941@item 6942 6943@code{GCC_JIT_COMPARISON_GT} 6944 6945@tab 6946 6947@cite{x > y} 6948 6949@item 6950 6951@code{GCC_JIT_COMPARISON_GE} 6952 6953@tab 6954 6955@cite{x >= y} 6956 6957@end multitable 6958 6959 6960@node Function calls,Type-coercion,Comparisons,Rvalues 6961@anchor{topics/expressions function-calls}@anchor{a9} 6962@subsubsection Function calls 6963 6964 6965@geindex gcc_jit_context_new_call (C function) 6966@anchor{topics/expressions gcc_jit_context_new_call}@anchor{aa} 6967@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) 6968 6969Given a function and the given table of argument rvalues, construct a 6970call to the function, with the result as an rvalue. 6971 6972@cartouche 6973@quotation Note 6974@pxref{aa,,gcc_jit_context_new_call()} merely builds a 6975@pxref{13,,gcc_jit_rvalue} i.e. an expression that can be evaluated, 6976perhaps as part of a more complicated expression. 6977The call @emph{won't} happen unless you add a statement to a function 6978that evaluates the expression. 6979 6980For example, if you want to call a function and discard the result 6981(or to call a function with @code{void} return type), use 6982@pxref{ab,,gcc_jit_block_add_eval()}: 6983 6984@example 6985/* Add "(void)printf (arg0, arg1);". */ 6986gcc_jit_block_add_eval ( 6987 block, NULL, 6988 gcc_jit_context_new_call ( 6989 ctxt, 6990 NULL, 6991 printf_func, 6992 2, args)); 6993@end example 6994 6995@noindent 6996@end quotation 6997@end cartouche 6998@end deffn 6999 7000@node Type-coercion,,Function calls,Rvalues 7001@anchor{topics/expressions type-coercion}@anchor{ac} 7002@subsubsection Type-coercion 7003 7004 7005@geindex gcc_jit_context_new_cast (C function) 7006@anchor{topics/expressions gcc_jit_context_new_cast}@anchor{ad} 7007@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) 7008 7009Given an rvalue of T, construct another rvalue of another type. 7010 7011Currently only a limited set of conversions are possible: 7012 7013@quotation 7014 7015 7016@itemize * 7017 7018@item 7019int <-> float 7020 7021@item 7022int <-> bool 7023 7024@item 7025P* <-> Q*, for pointer types P and Q 7026@end itemize 7027@end quotation 7028@end deffn 7029 7030@node Lvalues,Working with pointers structs and unions,Rvalues,Expressions 7031@anchor{topics/expressions lvalues}@anchor{ae} 7032@subsection Lvalues 7033 7034 7035@geindex gcc_jit_lvalue (C type) 7036@anchor{topics/expressions gcc_jit_lvalue}@anchor{24} 7037@deffn {C Type} gcc_jit_lvalue 7038@end deffn 7039 7040An lvalue is something that can of the @emph{left}-hand side of an assignment: 7041a storage area (such as a variable). It is also usable as an rvalue, 7042where the rvalue is computed by reading from the storage area. 7043 7044@geindex gcc_jit_lvalue_as_object (C function) 7045@anchor{topics/expressions gcc_jit_lvalue_as_object}@anchor{af} 7046@deffn {C Function} gcc_jit_object * gcc_jit_lvalue_as_object (gcc_jit_lvalue@w{ }*lvalue) 7047 7048Upcast an lvalue to be an object. 7049@end deffn 7050 7051@geindex gcc_jit_lvalue_as_rvalue (C function) 7052@anchor{topics/expressions gcc_jit_lvalue_as_rvalue}@anchor{b0} 7053@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue@w{ }*lvalue) 7054 7055Upcast an lvalue to be an rvalue. 7056@end deffn 7057 7058@geindex gcc_jit_lvalue_get_address (C function) 7059@anchor{topics/expressions gcc_jit_lvalue_get_address}@anchor{b1} 7060@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_get_address (gcc_jit_lvalue@w{ }*lvalue, gcc_jit_location@w{ }*loc) 7061 7062Take the address of an lvalue; analogous to: 7063 7064@example 7065&(EXPR) 7066@end example 7067 7068@noindent 7069 7070in C. 7071@end deffn 7072 7073@menu 7074* Global variables:: 7075 7076@end menu 7077 7078@node Global variables,,,Lvalues 7079@anchor{topics/expressions global-variables}@anchor{b2} 7080@subsubsection Global variables 7081 7082 7083@geindex gcc_jit_context_new_global (C function) 7084@anchor{topics/expressions gcc_jit_context_new_global}@anchor{b3} 7085@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) 7086 7087Add a new global variable of the given type and name to the context. 7088 7089The parameter @code{name} must be non-NULL. The call takes a copy of the 7090underlying string, so it is valid to pass in a pointer to an on-stack 7091buffer. 7092 7093The "kind" parameter determines the visibility of the "global" outside 7094of the @pxref{16,,gcc_jit_result}: 7095 7096@geindex gcc_jit_global_kind (C type) 7097@anchor{topics/expressions gcc_jit_global_kind}@anchor{b4} 7098@deffn {C Type} enum gcc_jit_global_kind 7099@end deffn 7100 7101@geindex GCC_JIT_GLOBAL_EXPORTED (C macro) 7102@anchor{topics/expressions GCC_JIT_GLOBAL_EXPORTED}@anchor{b5} 7103@deffn {C Macro} GCC_JIT_GLOBAL_EXPORTED 7104 7105Global is defined by the client code and is visible 7106by name outside of this JIT context via 7107@pxref{b6,,gcc_jit_result_get_global()} (and this value is required for 7108the global to be accessible via that entrypoint). 7109@end deffn 7110 7111@geindex GCC_JIT_GLOBAL_INTERNAL (C macro) 7112@anchor{topics/expressions GCC_JIT_GLOBAL_INTERNAL}@anchor{b7} 7113@deffn {C Macro} GCC_JIT_GLOBAL_INTERNAL 7114 7115Global is defined by the client code, but is invisible 7116outside of it. Analogous to a "static" global within a .c file. 7117Specifically, the variable will only be visible within this 7118context and within child contexts. 7119@end deffn 7120 7121@geindex GCC_JIT_GLOBAL_IMPORTED (C macro) 7122@anchor{topics/expressions GCC_JIT_GLOBAL_IMPORTED}@anchor{b8} 7123@deffn {C Macro} GCC_JIT_GLOBAL_IMPORTED 7124 7125Global is not defined by the client code; we're merely 7126referring to it. Analogous to using an "extern" global from a 7127header file. 7128@end deffn 7129@end deffn 7130 7131@node Working with pointers structs and unions,,Lvalues,Expressions 7132@anchor{topics/expressions working-with-pointers-structs-and-unions}@anchor{b9} 7133@subsection Working with pointers, structs and unions 7134 7135 7136@geindex gcc_jit_rvalue_dereference (C function) 7137@anchor{topics/expressions gcc_jit_rvalue_dereference}@anchor{ba} 7138@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference (gcc_jit_rvalue@w{ }*rvalue, gcc_jit_location@w{ }*loc) 7139 7140Given an rvalue of pointer type @code{T *}, dereferencing the pointer, 7141getting an lvalue of type @code{T}. Analogous to: 7142 7143@example 7144*(EXPR) 7145@end example 7146 7147@noindent 7148 7149in C. 7150@end deffn 7151 7152Field access is provided separately for both lvalues and rvalues. 7153 7154@geindex gcc_jit_lvalue_access_field (C function) 7155@anchor{topics/expressions gcc_jit_lvalue_access_field}@anchor{bb} 7156@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) 7157 7158Given an lvalue of struct or union type, access the given field, 7159getting an lvalue of the field's type. Analogous to: 7160 7161@example 7162(EXPR).field = ...; 7163@end example 7164 7165@noindent 7166 7167in C. 7168@end deffn 7169 7170@geindex gcc_jit_rvalue_access_field (C function) 7171@anchor{topics/expressions gcc_jit_rvalue_access_field}@anchor{bc} 7172@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) 7173 7174Given an rvalue of struct or union type, access the given field 7175as an rvalue. Analogous to: 7176 7177@example 7178(EXPR).field 7179@end example 7180 7181@noindent 7182 7183in C. 7184@end deffn 7185 7186@geindex gcc_jit_rvalue_dereference_field (C function) 7187@anchor{topics/expressions gcc_jit_rvalue_dereference_field}@anchor{bd} 7188@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) 7189 7190Given an rvalue of pointer type @code{T *} where T is of struct or union 7191type, access the given field as an lvalue. Analogous to: 7192 7193@example 7194(EXPR)->field 7195@end example 7196 7197@noindent 7198 7199in C, itself equivalent to @code{(*EXPR).FIELD}. 7200@end deffn 7201 7202@geindex gcc_jit_context_new_array_access (C function) 7203@anchor{topics/expressions gcc_jit_context_new_array_access}@anchor{a6} 7204@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) 7205 7206Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at 7207the given index, using standard C array indexing rules i.e. each 7208increment of @code{index} corresponds to @code{sizeof(T)} bytes. 7209Analogous to: 7210 7211@example 7212PTR[INDEX] 7213@end example 7214 7215@noindent 7216 7217in C (or, indeed, to @code{PTR + INDEX}). 7218@end deffn 7219 7220@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 7221@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7222@c 7223@c This is free software: you can redistribute it and/or modify it 7224@c under the terms of the GNU General Public License as published by 7225@c the Free Software Foundation, either version 3 of the License, or 7226@c (at your option) any later version. 7227@c 7228@c This program is distributed in the hope that it will be useful, but 7229@c WITHOUT ANY WARRANTY; without even the implied warranty of 7230@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7231@c General Public License for more details. 7232@c 7233@c You should have received a copy of the GNU General Public License 7234@c along with this program. If not, see 7235@c <http://www.gnu.org/licenses/>. 7236 7237@node Creating and using functions,Source Locations,Expressions,Topic Reference 7238@anchor{topics/functions doc}@anchor{be}@anchor{topics/functions creating-and-using-functions}@anchor{bf} 7239@section Creating and using functions 7240 7241 7242@menu 7243* Params:: 7244* Functions:: 7245* Blocks:: 7246* Statements:: 7247 7248@end menu 7249 7250@node Params,Functions,,Creating and using functions 7251@anchor{topics/functions params}@anchor{c0} 7252@subsection Params 7253 7254 7255@geindex gcc_jit_param (C type) 7256@anchor{topics/functions gcc_jit_param}@anchor{25} 7257@deffn {C Type} gcc_jit_param 7258 7259A @cite{gcc_jit_param} represents a parameter to a function. 7260@end deffn 7261 7262@geindex gcc_jit_context_new_param (C function) 7263@anchor{topics/functions gcc_jit_context_new_param}@anchor{10} 7264@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) 7265 7266In preparation for creating a function, create a new parameter of the 7267given type and name. 7268 7269The parameter @code{name} must be non-NULL. The call takes a copy of the 7270underlying string, so it is valid to pass in a pointer to an on-stack 7271buffer. 7272@end deffn 7273 7274Parameters are lvalues, and thus are also rvalues (and objects), so the 7275following upcasts are available: 7276 7277@geindex gcc_jit_param_as_lvalue (C function) 7278@anchor{topics/functions gcc_jit_param_as_lvalue}@anchor{c1} 7279@deffn {C Function} gcc_jit_lvalue * gcc_jit_param_as_lvalue (gcc_jit_param@w{ }*param) 7280 7281Upcasting from param to lvalue. 7282@end deffn 7283 7284@geindex gcc_jit_param_as_rvalue (C function) 7285@anchor{topics/functions gcc_jit_param_as_rvalue}@anchor{c2} 7286@deffn {C Function} gcc_jit_rvalue * gcc_jit_param_as_rvalue (gcc_jit_param@w{ }*param) 7287 7288Upcasting from param to rvalue. 7289@end deffn 7290 7291@geindex gcc_jit_param_as_object (C function) 7292@anchor{topics/functions gcc_jit_param_as_object}@anchor{c3} 7293@deffn {C Function} gcc_jit_object * gcc_jit_param_as_object (gcc_jit_param@w{ }*param) 7294 7295Upcasting from param to object. 7296@end deffn 7297 7298@node Functions,Blocks,Params,Creating and using functions 7299@anchor{topics/functions functions}@anchor{c4} 7300@subsection Functions 7301 7302 7303@geindex gcc_jit_function (C type) 7304@anchor{topics/functions gcc_jit_function}@anchor{29} 7305@deffn {C Type} gcc_jit_function 7306 7307A @cite{gcc_jit_function} represents a function - either one that we're 7308creating ourselves, or one that we're referencing. 7309@end deffn 7310 7311@geindex gcc_jit_context_new_function (C function) 7312@anchor{topics/functions gcc_jit_context_new_function}@anchor{11} 7313@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) 7314 7315Create a gcc_jit_function with the given name and parameters. 7316 7317@geindex gcc_jit_function_kind (C type) 7318@anchor{topics/functions gcc_jit_function_kind}@anchor{c5} 7319@deffn {C Type} enum gcc_jit_function_kind 7320@end deffn 7321 7322This enum controls the kind of function created, and has the following 7323values: 7324 7325@quotation 7326 7327@geindex GCC_JIT_FUNCTION_EXPORTED (C macro) 7328@anchor{topics/functions GCC_JIT_FUNCTION_EXPORTED}@anchor{c6} 7329@deffn {C Macro} GCC_JIT_FUNCTION_EXPORTED 7330 7331Function is defined by the client code and visible 7332by name outside of the JIT. 7333 7334This value is required if you want to extract machine code 7335for this function from a @pxref{16,,gcc_jit_result} via 7336@pxref{17,,gcc_jit_result_get_code()}. 7337@end deffn 7338 7339@geindex GCC_JIT_FUNCTION_INTERNAL (C macro) 7340@anchor{topics/functions GCC_JIT_FUNCTION_INTERNAL}@anchor{c7} 7341@deffn {C Macro} GCC_JIT_FUNCTION_INTERNAL 7342 7343Function is defined by the client code, but is invisible 7344outside of the JIT. Analogous to a "static" function. 7345@end deffn 7346 7347@geindex GCC_JIT_FUNCTION_IMPORTED (C macro) 7348@anchor{topics/functions GCC_JIT_FUNCTION_IMPORTED}@anchor{c8} 7349@deffn {C Macro} GCC_JIT_FUNCTION_IMPORTED 7350 7351Function is not defined by the client code; we're merely 7352referring to it. Analogous to using an "extern" function from a 7353header file. 7354@end deffn 7355 7356@geindex GCC_JIT_FUNCTION_ALWAYS_INLINE (C macro) 7357@anchor{topics/functions GCC_JIT_FUNCTION_ALWAYS_INLINE}@anchor{c9} 7358@deffn {C Macro} GCC_JIT_FUNCTION_ALWAYS_INLINE 7359 7360Function is only ever inlined into other functions, and is 7361invisible outside of the JIT. 7362 7363Analogous to prefixing with @code{inline} and adding 7364@code{__attribute__((always_inline))} 7365 7366Inlining will only occur when the optimization level is 7367above 0; when optimization is off, this is essentially the 7368same as GCC_JIT_FUNCTION_INTERNAL. 7369@end deffn 7370@end quotation 7371 7372The parameter @code{name} must be non-NULL. The call takes a copy of the 7373underlying string, so it is valid to pass in a pointer to an on-stack 7374buffer. 7375@end deffn 7376 7377@geindex gcc_jit_context_get_builtin_function (C function) 7378@anchor{topics/functions gcc_jit_context_get_builtin_function}@anchor{ca} 7379@deffn {C Function} gcc_jit_function *gcc_jit_context_get_builtin_function (gcc_jit_context@w{ }*ctxt, const char@w{ }*name) 7380@end deffn 7381 7382@geindex gcc_jit_function_as_object (C function) 7383@anchor{topics/functions gcc_jit_function_as_object}@anchor{cb} 7384@deffn {C Function} gcc_jit_object * gcc_jit_function_as_object (gcc_jit_function@w{ }*func) 7385 7386Upcasting from function to object. 7387@end deffn 7388 7389@geindex gcc_jit_function_get_param (C function) 7390@anchor{topics/functions gcc_jit_function_get_param}@anchor{cc} 7391@deffn {C Function} gcc_jit_param * gcc_jit_function_get_param (gcc_jit_function@w{ }*func, int@w{ }index) 7392 7393Get the param of the given index (0-based). 7394@end deffn 7395 7396@geindex gcc_jit_function_dump_to_dot (C function) 7397@anchor{topics/functions gcc_jit_function_dump_to_dot}@anchor{33} 7398@deffn {C Function} void gcc_jit_function_dump_to_dot (gcc_jit_function@w{ }*func, const char@w{ }*path) 7399 7400Emit the function in graphviz format to the given path. 7401@end deffn 7402 7403@geindex gcc_jit_function_new_local (C function) 7404@anchor{topics/functions gcc_jit_function_new_local}@anchor{26} 7405@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) 7406 7407Create a new local variable within the function, of the given type and 7408name. 7409 7410The parameter @code{name} must be non-NULL. The call takes a copy of the 7411underlying string, so it is valid to pass in a pointer to an on-stack 7412buffer. 7413@end deffn 7414 7415@node Blocks,Statements,Functions,Creating and using functions 7416@anchor{topics/functions blocks}@anchor{cd} 7417@subsection Blocks 7418 7419 7420@geindex gcc_jit_block (C type) 7421@anchor{topics/functions gcc_jit_block}@anchor{28} 7422@deffn {C Type} gcc_jit_block 7423 7424A @cite{gcc_jit_block} represents a basic block within a function i.e. a 7425sequence of statements with a single entry point and a single exit 7426point. 7427 7428The first basic block that you create within a function will 7429be the entrypoint. 7430 7431Each basic block that you create within a function must be 7432terminated, either with a conditional, a jump, a return, or a 7433switch. 7434 7435It's legal to have multiple basic blocks that return within 7436one function. 7437@end deffn 7438 7439@geindex gcc_jit_function_new_block (C function) 7440@anchor{topics/functions gcc_jit_function_new_block}@anchor{ce} 7441@deffn {C Function} gcc_jit_block * gcc_jit_function_new_block (gcc_jit_function@w{ }*func, const char@w{ }*name) 7442 7443Create a basic block of the given name. The name may be NULL, but 7444providing meaningful names is often helpful when debugging: it may 7445show up in dumps of the internal representation, and in error 7446messages. It is copied, so the input buffer does not need to outlive 7447the call; you can pass in a pointer to an on-stack buffer, e.g.: 7448 7449@example 7450for (pc = 0; pc < fn->fn_num_ops; pc++) 7451 @{ 7452 char buf[16]; 7453 sprintf (buf, "instr%i", pc); 7454 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); 7455 @} 7456@end example 7457 7458@noindent 7459@end deffn 7460 7461@geindex gcc_jit_block_as_object (C function) 7462@anchor{topics/functions gcc_jit_block_as_object}@anchor{cf} 7463@deffn {C Function} gcc_jit_object * gcc_jit_block_as_object (gcc_jit_block@w{ }*block) 7464 7465Upcast from block to object. 7466@end deffn 7467 7468@geindex gcc_jit_block_get_function (C function) 7469@anchor{topics/functions gcc_jit_block_get_function}@anchor{d0} 7470@deffn {C Function} gcc_jit_function * gcc_jit_block_get_function (gcc_jit_block@w{ }*block) 7471 7472Which function is this block within? 7473@end deffn 7474 7475@node Statements,,Blocks,Creating and using functions 7476@anchor{topics/functions statements}@anchor{d1} 7477@subsection Statements 7478 7479 7480@geindex gcc_jit_block_add_eval (C function) 7481@anchor{topics/functions gcc_jit_block_add_eval}@anchor{ab} 7482@deffn {C Function} void gcc_jit_block_add_eval (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue) 7483 7484Add evaluation of an rvalue, discarding the result 7485(e.g. a function call that "returns" void). 7486 7487This is equivalent to this C code: 7488 7489@example 7490(void)expression; 7491@end example 7492 7493@noindent 7494@end deffn 7495 7496@geindex gcc_jit_block_add_assignment (C function) 7497@anchor{topics/functions gcc_jit_block_add_assignment}@anchor{2a} 7498@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) 7499 7500Add evaluation of an rvalue, assigning the result to the given 7501lvalue. 7502 7503This is roughly equivalent to this C code: 7504 7505@example 7506lvalue = rvalue; 7507@end example 7508 7509@noindent 7510@end deffn 7511 7512@geindex gcc_jit_block_add_assignment_op (C function) 7513@anchor{topics/functions gcc_jit_block_add_assignment_op}@anchor{2e} 7514@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) 7515 7516Add evaluation of an rvalue, using the result to modify an 7517lvalue. 7518 7519This is analogous to "+=" and friends: 7520 7521@example 7522lvalue += rvalue; 7523lvalue *= rvalue; 7524lvalue /= rvalue; 7525@end example 7526 7527@noindent 7528 7529etc. For example: 7530 7531@example 7532/* "i++" */ 7533gcc_jit_block_add_assignment_op ( 7534 loop_body, NULL, 7535 i, 7536 GCC_JIT_BINARY_OP_PLUS, 7537 gcc_jit_context_one (ctxt, int_type)); 7538@end example 7539 7540@noindent 7541@end deffn 7542 7543@geindex gcc_jit_block_add_comment (C function) 7544@anchor{topics/functions gcc_jit_block_add_comment}@anchor{3d} 7545@deffn {C Function} void gcc_jit_block_add_comment (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*text) 7546 7547Add a no-op textual comment to the internal representation of the 7548code. It will be optimized away, but will be visible in the dumps 7549seen via @pxref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} 7550and @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, 7551and thus may be of use when debugging how your project's internal 7552representation gets converted to the libgccjit IR. 7553 7554The parameter @code{text} must be non-NULL. It is copied, so the input 7555buffer does not need to outlive the call. For example: 7556 7557@example 7558char buf[100]; 7559snprintf (buf, sizeof (buf), 7560 "op%i: %s", 7561 pc, opcode_names[op->op_opcode]); 7562gcc_jit_block_add_comment (block, loc, buf); 7563@end example 7564 7565@noindent 7566@end deffn 7567 7568@geindex gcc_jit_block_end_with_conditional (C function) 7569@anchor{topics/functions gcc_jit_block_end_with_conditional}@anchor{2d} 7570@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) 7571 7572Terminate a block by adding evaluation of an rvalue, branching on the 7573result to the appropriate successor block. 7574 7575This is roughly equivalent to this C code: 7576 7577@example 7578if (boolval) 7579 goto on_true; 7580else 7581 goto on_false; 7582@end example 7583 7584@noindent 7585 7586block, boolval, on_true, and on_false must be non-NULL. 7587@end deffn 7588 7589@geindex gcc_jit_block_end_with_jump (C function) 7590@anchor{topics/functions gcc_jit_block_end_with_jump}@anchor{d2} 7591@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) 7592 7593Terminate a block by adding a jump to the given target block. 7594 7595This is roughly equivalent to this C code: 7596 7597@example 7598goto target; 7599@end example 7600 7601@noindent 7602@end deffn 7603 7604@geindex gcc_jit_block_end_with_return (C function) 7605@anchor{topics/functions gcc_jit_block_end_with_return}@anchor{d3} 7606@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) 7607 7608Terminate a block by adding evaluation of an rvalue, returning the value. 7609 7610This is roughly equivalent to this C code: 7611 7612@example 7613return expression; 7614@end example 7615 7616@noindent 7617@end deffn 7618 7619@geindex gcc_jit_block_end_with_void_return (C function) 7620@anchor{topics/functions gcc_jit_block_end_with_void_return}@anchor{d4} 7621@deffn {C Function} void gcc_jit_block_end_with_void_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc) 7622 7623Terminate a block by adding a valueless return, for use within a function 7624with "void" return type. 7625 7626This is equivalent to this C code: 7627 7628@example 7629return; 7630@end example 7631 7632@noindent 7633@end deffn 7634 7635@geindex gcc_jit_block_end_with_switch (C function) 7636@anchor{topics/functions gcc_jit_block_end_with_switch}@anchor{d5} 7637@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) 7638 7639Terminate a block by adding evalation of an rvalue, then performing 7640a multiway branch. 7641 7642This is roughly equivalent to this C code: 7643 7644@example 7645switch (expr) 7646 @{ 7647 default: 7648 goto default_block; 7649 7650 case C0.min_value ... C0.max_value: 7651 goto C0.dest_block; 7652 7653 case C1.min_value ... C1.max_value: 7654 goto C1.dest_block; 7655 7656 ...etc... 7657 7658 case C[N - 1].min_value ... C[N - 1].max_value: 7659 goto C[N - 1].dest_block; 7660@} 7661@end example 7662 7663@noindent 7664 7665@code{block}, @code{expr}, @code{default_block} and @code{cases} must all be 7666non-NULL. 7667 7668@code{expr} must be of the same integer type as all of the @code{min_value} 7669and @code{max_value} within the cases. 7670 7671@code{num_cases} must be >= 0. 7672 7673The ranges of the cases must not overlap (or have duplicate 7674values). 7675 7676The API entrypoints relating to switch statements and cases: 7677 7678@quotation 7679 7680 7681@itemize * 7682 7683@item 7684@pxref{d5,,gcc_jit_block_end_with_switch()} 7685 7686@item 7687@pxref{d6,,gcc_jit_case_as_object()} 7688 7689@item 7690@pxref{d7,,gcc_jit_context_new_case()} 7691@end itemize 7692@end quotation 7693 7694were added in @pxref{d8,,LIBGCCJIT_ABI_3}; you can test for their presence 7695using 7696 7697@example 7698#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 7699@end example 7700 7701@noindent 7702 7703@geindex gcc_jit_case (C type) 7704@anchor{topics/functions gcc_jit_case}@anchor{d9} 7705@deffn {C Type} gcc_jit_case 7706@end deffn 7707 7708A @cite{gcc_jit_case} represents a case within a switch statement, and 7709is created within a particular @pxref{8,,gcc_jit_context} using 7710@pxref{d7,,gcc_jit_context_new_case()}. 7711 7712Each case expresses a multivalued range of integer values. You 7713can express single-valued cases by passing in the same value for 7714both @cite{min_value} and @cite{max_value}. 7715 7716@geindex gcc_jit_context_new_case (C function) 7717@anchor{topics/functions gcc_jit_context_new_case}@anchor{d7} 7718@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) 7719 7720Create a new gcc_jit_case instance for use in a switch statement. 7721@cite{min_value} and @cite{max_value} must be constants of an integer type, 7722which must match that of the expression of the switch statement. 7723 7724@cite{dest_block} must be within the same function as the switch 7725statement. 7726@end deffn 7727 7728@geindex gcc_jit_case_as_object (C function) 7729@anchor{topics/functions gcc_jit_case_as_object}@anchor{d6} 7730@deffn {C Function} gcc_jit_object * gcc_jit_case_as_object (gcc_jit_case@w{ }*case_) 7731 7732Upcast from a case to an object. 7733@end deffn 7734 7735Here's an example of creating a switch statement: 7736 7737@quotation 7738 7739@example 7740 7741void 7742create_code (gcc_jit_context *ctxt, void *user_data) 7743@{ 7744 /* Let's try to inject the equivalent of: 7745 int 7746 test_switch (int x) 7747 @{ 7748 switch (x) 7749 @{ 7750 case 0 ... 5: 7751 return 3; 7752 7753 case 25 ... 27: 7754 return 4; 7755 7756 case -42 ... -17: 7757 return 83; 7758 7759 case 40: 7760 return 8; 7761 7762 default: 7763 return 10; 7764 @} 7765 @} 7766 */ 7767 gcc_jit_type *t_int = 7768 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 7769 gcc_jit_type *return_type = t_int; 7770 gcc_jit_param *x = 7771 gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); 7772 gcc_jit_param *params[1] = @{x@}; 7773 gcc_jit_function *func = 7774 gcc_jit_context_new_function (ctxt, NULL, 7775 GCC_JIT_FUNCTION_EXPORTED, 7776 return_type, 7777 "test_switch", 7778 1, params, 0); 7779 7780 gcc_jit_block *b_initial = 7781 gcc_jit_function_new_block (func, "initial"); 7782 7783 gcc_jit_block *b_default = 7784 gcc_jit_function_new_block (func, "default"); 7785 gcc_jit_block *b_case_0_5 = 7786 gcc_jit_function_new_block (func, "case_0_5"); 7787 gcc_jit_block *b_case_25_27 = 7788 gcc_jit_function_new_block (func, "case_25_27"); 7789 gcc_jit_block *b_case_m42_m17 = 7790 gcc_jit_function_new_block (func, "case_m42_m17"); 7791 gcc_jit_block *b_case_40 = 7792 gcc_jit_function_new_block (func, "case_40"); 7793 7794 gcc_jit_case *cases[4] = @{ 7795 gcc_jit_context_new_case ( 7796 ctxt, 7797 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0), 7798 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5), 7799 b_case_0_5), 7800 gcc_jit_context_new_case ( 7801 ctxt, 7802 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 25), 7803 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 27), 7804 b_case_25_27), 7805 gcc_jit_context_new_case ( 7806 ctxt, 7807 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -42), 7808 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -17), 7809 b_case_m42_m17), 7810 gcc_jit_context_new_case ( 7811 ctxt, 7812 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), 7813 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), 7814 b_case_40) 7815 @}; 7816 gcc_jit_block_end_with_switch ( 7817 b_initial, NULL, 7818 gcc_jit_param_as_rvalue (x), 7819 b_default, 7820 4, cases); 7821 7822 gcc_jit_block_end_with_return ( 7823 b_case_0_5, NULL, 7824 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); 7825 gcc_jit_block_end_with_return ( 7826 b_case_25_27, NULL, 7827 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4)); 7828 gcc_jit_block_end_with_return ( 7829 b_case_m42_m17, NULL, 7830 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 83)); 7831 gcc_jit_block_end_with_return ( 7832 b_case_40, NULL, 7833 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 8)); 7834 gcc_jit_block_end_with_return ( 7835 b_default, NULL, 7836 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); 7837@} 7838 7839 7840@end example 7841 7842@noindent 7843@end quotation 7844@end deffn 7845 7846@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 7847@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7848@c 7849@c This is free software: you can redistribute it and/or modify it 7850@c under the terms of the GNU General Public License as published by 7851@c the Free Software Foundation, either version 3 of the License, or 7852@c (at your option) any later version. 7853@c 7854@c This program is distributed in the hope that it will be useful, but 7855@c WITHOUT ANY WARRANTY; without even the implied warranty of 7856@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7857@c General Public License for more details. 7858@c 7859@c You should have received a copy of the GNU General Public License 7860@c along with this program. If not, see 7861@c <http://www.gnu.org/licenses/>. 7862 7863@node Source Locations,Compiling a context,Creating and using functions,Topic Reference 7864@anchor{topics/locations source-locations}@anchor{da}@anchor{topics/locations doc}@anchor{db} 7865@section Source Locations 7866 7867 7868@geindex gcc_jit_location (C type) 7869@anchor{topics/locations gcc_jit_location}@anchor{3b} 7870@deffn {C Type} gcc_jit_location 7871 7872A @cite{gcc_jit_location} encapsulates a source code location, so that 7873you can (optionally) associate locations in your language with 7874statements in the JIT-compiled code, allowing the debugger to 7875single-step through your language. 7876 7877@cite{gcc_jit_location} instances are optional: you can always pass NULL to 7878any API entrypoint accepting one. 7879 7880You can construct them using @pxref{41,,gcc_jit_context_new_location()}. 7881 7882You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 7883@pxref{8,,gcc_jit_context} for these locations to actually be usable by 7884the debugger: 7885 7886@example 7887gcc_jit_context_set_bool_option ( 7888 ctxt, 7889 GCC_JIT_BOOL_OPTION_DEBUGINFO, 7890 1); 7891@end example 7892 7893@noindent 7894@end deffn 7895 7896@geindex gcc_jit_context_new_location (C function) 7897@anchor{topics/locations gcc_jit_context_new_location}@anchor{41} 7898@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) 7899 7900Create a @cite{gcc_jit_location} instance representing the given source 7901location. 7902 7903The parameter @code{filename} must be non-NULL. The call takes a copy of 7904the underlying string, so it is valid to pass in a pointer to an 7905on-stack buffer. 7906@end deffn 7907 7908@menu 7909* Faking it:: 7910 7911@end menu 7912 7913@node Faking it,,,Source Locations 7914@anchor{topics/locations faking-it}@anchor{dc} 7915@subsection Faking it 7916 7917 7918If you don't have source code for your internal representation, but need 7919to debug, you can generate a C-like representation of the functions in 7920your context using @pxref{5a,,gcc_jit_context_dump_to_file()}: 7921 7922@example 7923gcc_jit_context_dump_to_file (ctxt, "/tmp/something.c", 7924 1 /* update_locations */); 7925@end example 7926 7927@noindent 7928 7929This will dump C-like code to the given path. If the @cite{update_locations} 7930argument is true, this will also set up @cite{gcc_jit_location} information 7931throughout the context, pointing at the dump file as if it were a source 7932file, giving you @emph{something} you can step through in the debugger. 7933 7934@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 7935@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7936@c 7937@c This is free software: you can redistribute it and/or modify it 7938@c under the terms of the GNU General Public License as published by 7939@c the Free Software Foundation, either version 3 of the License, or 7940@c (at your option) any later version. 7941@c 7942@c This program is distributed in the hope that it will be useful, but 7943@c WITHOUT ANY WARRANTY; without even the implied warranty of 7944@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7945@c General Public License for more details. 7946@c 7947@c You should have received a copy of the GNU General Public License 7948@c along with this program. If not, see 7949@c <http://www.gnu.org/licenses/>. 7950 7951@node Compiling a context,ABI and API compatibility,Source Locations,Topic Reference 7952@anchor{topics/compilation compiling-a-context}@anchor{dd}@anchor{topics/compilation doc}@anchor{de} 7953@section Compiling a context 7954 7955 7956Once populated, a @pxref{8,,gcc_jit_context *} can be compiled to 7957machine code, either in-memory via @pxref{15,,gcc_jit_context_compile()} or 7958to disk via @pxref{4a,,gcc_jit_context_compile_to_file()}. 7959 7960You can compile a context multiple times (using either form of 7961compilation), although any errors that occur on the context will 7962prevent any future compilation of that context. 7963 7964@menu 7965* In-memory compilation:: 7966* Ahead-of-time compilation:: 7967 7968@end menu 7969 7970@node In-memory compilation,Ahead-of-time compilation,,Compiling a context 7971@anchor{topics/compilation in-memory-compilation}@anchor{df} 7972@subsection In-memory compilation 7973 7974 7975@geindex gcc_jit_context_compile (C function) 7976@anchor{topics/compilation gcc_jit_context_compile}@anchor{15} 7977@deffn {C Function} gcc_jit_result * gcc_jit_context_compile (gcc_jit_context@w{ }*ctxt) 7978 7979This calls into GCC and builds the code, returning a 7980@cite{gcc_jit_result *}. 7981 7982If the result is non-NULL, the caller becomes responsible for 7983calling @pxref{39,,gcc_jit_result_release()} on it once they're done 7984with it. 7985@end deffn 7986 7987@geindex gcc_jit_result (C type) 7988@anchor{topics/compilation gcc_jit_result}@anchor{16} 7989@deffn {C Type} gcc_jit_result 7990 7991A @cite{gcc_jit_result} encapsulates the result of compiling a context 7992in-memory, and the lifetimes of any machine code functions or globals 7993that are within the result. 7994@end deffn 7995 7996@geindex gcc_jit_result_get_code (C function) 7997@anchor{topics/compilation gcc_jit_result_get_code}@anchor{17} 7998@deffn {C Function} void * gcc_jit_result_get_code (gcc_jit_result@w{ }*result, const char@w{ }*funcname) 7999 8000Locate a given function within the built machine code. 8001 8002Functions are looked up by name. For this to succeed, a function 8003with a name matching @cite{funcname} must have been created on 8004@cite{result}'s context (or a parent context) via a call to 8005@pxref{11,,gcc_jit_context_new_function()} with @cite{kind} 8006@pxref{c6,,GCC_JIT_FUNCTION_EXPORTED}: 8007 8008@example 8009gcc_jit_context_new_function (ctxt, 8010 any_location, /* or NULL */ 8011 /* Required for func to be visible to 8012 gcc_jit_result_get_code: */ 8013 GCC_JIT_FUNCTION_EXPORTED, 8014 any_return_type, 8015 /* Must string-compare equal: */ 8016 funcname, 8017 /* etc */); 8018@end example 8019 8020@noindent 8021 8022If such a function is not found (or @cite{result} or @cite{funcname} are 8023@code{NULL}), an error message will be emitted on stderr and 8024@code{NULL} will be returned. 8025 8026If the function is found, the result will need to be cast to a 8027function pointer of the correct type before it can be called. 8028 8029Note that the resulting machine code becomes invalid after 8030@pxref{39,,gcc_jit_result_release()} is called on the 8031@pxref{16,,gcc_jit_result *}; attempting to call it after that may lead 8032to a segmentation fault. 8033@end deffn 8034 8035@geindex gcc_jit_result_get_global (C function) 8036@anchor{topics/compilation gcc_jit_result_get_global}@anchor{b6} 8037@deffn {C Function} void * gcc_jit_result_get_global (gcc_jit_result@w{ }*result, const char@w{ }*name) 8038 8039Locate a given global within the built machine code. 8040 8041Globals are looked up by name. For this to succeed, a global 8042with a name matching @cite{name} must have been created on 8043@cite{result}'s context (or a parent context) via a call to 8044@pxref{b3,,gcc_jit_context_new_global()} with @cite{kind} 8045@pxref{b5,,GCC_JIT_GLOBAL_EXPORTED}. 8046 8047If the global is found, the result will need to be cast to a 8048pointer of the correct type before it can be called. 8049 8050This is a @emph{pointer} to the global, so e.g. for an @code{int} this is 8051an @code{int *}. 8052 8053For example, given an @code{int foo;} created this way: 8054 8055@example 8056gcc_jit_lvalue *exported_global = 8057 gcc_jit_context_new_global (ctxt, 8058 any_location, /* or NULL */ 8059 GCC_JIT_GLOBAL_EXPORTED, 8060 int_type, 8061 "foo"); 8062@end example 8063 8064@noindent 8065 8066we can access it like this: 8067 8068@example 8069int *ptr_to_foo = 8070 (int *)gcc_jit_result_get_global (result, "foo"); 8071@end example 8072 8073@noindent 8074 8075If such a global is not found (or @cite{result} or @cite{name} are 8076@code{NULL}), an error message will be emitted on stderr and 8077@code{NULL} will be returned. 8078 8079Note that the resulting address becomes invalid after 8080@pxref{39,,gcc_jit_result_release()} is called on the 8081@pxref{16,,gcc_jit_result *}; attempting to use it after that may lead 8082to a segmentation fault. 8083@end deffn 8084 8085@geindex gcc_jit_result_release (C function) 8086@anchor{topics/compilation gcc_jit_result_release}@anchor{39} 8087@deffn {C Function} void gcc_jit_result_release (gcc_jit_result@w{ }*result) 8088 8089Once we're done with the code, this unloads the built .so file. 8090This cleans up the result; after calling this, it's no longer 8091valid to use the result, or any code or globals that were obtained 8092by calling @pxref{17,,gcc_jit_result_get_code()} or 8093@pxref{b6,,gcc_jit_result_get_global()} on it. 8094@end deffn 8095 8096@node Ahead-of-time compilation,,In-memory compilation,Compiling a context 8097@anchor{topics/compilation ahead-of-time-compilation}@anchor{e0} 8098@subsection Ahead-of-time compilation 8099 8100 8101Although libgccjit is primarily aimed at just-in-time compilation, it 8102can also be used for implementing more traditional ahead-of-time 8103compilers, via the @pxref{4a,,gcc_jit_context_compile_to_file()} 8104API entrypoint. 8105 8106@geindex gcc_jit_context_compile_to_file (C function) 8107@anchor{topics/compilation gcc_jit_context_compile_to_file}@anchor{4a} 8108@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) 8109 8110Compile the @pxref{8,,gcc_jit_context *} to a file of the given 8111kind. 8112@end deffn 8113 8114@pxref{4a,,gcc_jit_context_compile_to_file()} ignores the suffix of 8115@code{output_path}, and insteads uses the given 8116@code{enum gcc_jit_output_kind} to decide what to do. 8117 8118@cartouche 8119@quotation Note 8120This is different from the @code{gcc} program, which does make use of the 8121suffix of the output file when determining what to do. 8122@end quotation 8123@end cartouche 8124 8125@geindex gcc_jit_output_kind (C type) 8126@anchor{topics/compilation gcc_jit_output_kind}@anchor{e1} 8127@deffn {C Type} enum gcc_jit_output_kind 8128@end deffn 8129 8130The available kinds of output are: 8131 8132 8133@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxx} 8134@headitem 8135 8136Output kind 8137 8138@tab 8139 8140Typical suffix 8141 8142@item 8143 8144@pxref{e2,,GCC_JIT_OUTPUT_KIND_ASSEMBLER} 8145 8146@tab 8147 8148.s 8149 8150@item 8151 8152@pxref{e3,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE} 8153 8154@tab 8155 8156.o 8157 8158@item 8159 8160@pxref{e4,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY} 8161 8162@tab 8163 8164.so or .dll 8165 8166@item 8167 8168@pxref{e5,,GCC_JIT_OUTPUT_KIND_EXECUTABLE} 8169 8170@tab 8171 8172None, or .exe 8173 8174@end multitable 8175 8176 8177@geindex GCC_JIT_OUTPUT_KIND_ASSEMBLER (C macro) 8178@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{e2} 8179@deffn {C Macro} GCC_JIT_OUTPUT_KIND_ASSEMBLER 8180 8181Compile the context to an assembler file. 8182@end deffn 8183 8184@geindex GCC_JIT_OUTPUT_KIND_OBJECT_FILE (C macro) 8185@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{e3} 8186@deffn {C Macro} GCC_JIT_OUTPUT_KIND_OBJECT_FILE 8187 8188Compile the context to an object file. 8189@end deffn 8190 8191@geindex GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY (C macro) 8192@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{e4} 8193@deffn {C Macro} GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY 8194 8195Compile the context to a dynamic library. 8196 8197There is currently no support for specifying other libraries to link 8198against. 8199@end deffn 8200 8201@geindex GCC_JIT_OUTPUT_KIND_EXECUTABLE (C macro) 8202@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{e5} 8203@deffn {C Macro} GCC_JIT_OUTPUT_KIND_EXECUTABLE 8204 8205Compile the context to an executable. 8206 8207There is currently no support for specifying libraries to link 8208against. 8209@end deffn 8210 8211@c Copyright (C) 2015 Free Software Foundation, Inc. 8212@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8213@c 8214@c This is free software: you can redistribute it and/or modify it 8215@c under the terms of the GNU General Public License as published by 8216@c the Free Software Foundation, either version 3 of the License, or 8217@c (at your option) any later version. 8218@c 8219@c This program is distributed in the hope that it will be useful, but 8220@c WITHOUT ANY WARRANTY; without even the implied warranty of 8221@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8222@c General Public License for more details. 8223@c 8224@c You should have received a copy of the GNU General Public License 8225@c along with this program. If not, see 8226@c <http://www.gnu.org/licenses/>. 8227 8228@node ABI and API compatibility,,Compiling a context,Topic Reference 8229@anchor{topics/compatibility abi-and-api-compatibility}@anchor{e6}@anchor{topics/compatibility doc}@anchor{e7} 8230@section ABI and API compatibility 8231 8232 8233The libgccjit developers strive for ABI and API backward-compatibility: 8234programs built against libgccjit.so stand a good chance of running 8235without recompilation against newer versions of libgccjit.so, and 8236ought to recompile without modification against newer versions of 8237libgccjit.h. 8238 8239@cartouche 8240@quotation Note 8241The libgccjit++.h C++ API is more experimental, and less 8242locked-down at this time. 8243@end quotation 8244@end cartouche 8245 8246API compatibility is achieved by extending the API rather than changing 8247it. For ABI compatiblity, we avoid bumping the SONAME, and instead use 8248symbol versioning to tag each symbol, so that a binary linked against 8249libgccjit.so is tagged according to the symbols that it uses. 8250 8251For example, @pxref{70,,gcc_jit_context_add_command_line_option()} was added in 8252@code{LIBGCCJIT_ABI_1}. If a client program uses it, this can be detected 8253from metadata by using @code{objdump}: 8254 8255@example 8256$ objdump -p testsuite/jit/test-extra-options.c.exe | tail -n 8 8257 8258Version References: 8259 required from libgccjit.so.0: 8260 0x00824161 0x00 04 LIBGCCJIT_ABI_1 8261 0x00824160 0x00 03 LIBGCCJIT_ABI_0 8262 required from libc.so.6: 8263@end example 8264 8265@noindent 8266 8267You can see the symbol tags provided by libgccjit.so using @code{objdump}: 8268 8269@example 8270$ objdump -p libgccjit.so | less 8271[...snip...] 8272Version definitions: 82731 0x01 0x0ff81f20 libgccjit.so.0 82742 0x00 0x00824160 LIBGCCJIT_ABI_0 82753 0x00 0x00824161 LIBGCCJIT_ABI_1 8276 LIBGCCJIT_ABI_0 8277[...snip...] 8278@end example 8279 8280@noindent 8281 8282@menu 8283* ABI symbol tags:: 8284 8285ABI symbol tags 8286 8287* LIBGCCJIT_ABI_0:: 8288* LIBGCCJIT_ABI_1:: 8289* LIBGCCJIT_ABI_2:: 8290* LIBGCCJIT_ABI_3:: 8291 8292@end menu 8293 8294 8295@node ABI symbol tags,,,ABI and API compatibility 8296@anchor{topics/compatibility abi-symbol-tags}@anchor{e8} 8297@subsection ABI symbol tags 8298 8299 8300The initial release of libgccjit (in gcc 5.1) did not use symbol versioning. 8301 8302Newer releases use the following tags. 8303 8304@menu 8305* LIBGCCJIT_ABI_0:: 8306* LIBGCCJIT_ABI_1:: 8307* LIBGCCJIT_ABI_2:: 8308* LIBGCCJIT_ABI_3:: 8309 8310@end menu 8311 8312@node LIBGCCJIT_ABI_0,LIBGCCJIT_ABI_1,,ABI symbol tags 8313@anchor{topics/compatibility libgccjit-abi-0}@anchor{e9}@anchor{topics/compatibility id1}@anchor{ea} 8314@subsubsection @code{LIBGCCJIT_ABI_0} 8315 8316 8317All entrypoints in the initial release of libgccjit are tagged with 8318@code{LIBGCCJIT_ABI_0}, to signify the transition to symbol versioning. 8319 8320Binaries built against older copies of @code{libgccjit.so} should 8321continue to work, with this being handled transparently by the linker 8322(see this post@footnote{https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html}) 8323 8324@node LIBGCCJIT_ABI_1,LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_0,ABI symbol tags 8325@anchor{topics/compatibility libgccjit-abi-1}@anchor{71}@anchor{topics/compatibility id2}@anchor{eb} 8326@subsubsection @code{LIBGCCJIT_ABI_1} 8327 8328 8329@code{LIBGCCJIT_ABI_1} covers the addition of 8330@pxref{70,,gcc_jit_context_add_command_line_option()} 8331 8332@node LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_1,ABI symbol tags 8333@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c}@anchor{topics/compatibility id3}@anchor{ec} 8334@subsubsection @code{LIBGCCJIT_ABI_2} 8335 8336 8337@code{LIBGCCJIT_ABI_2} covers the addition of 8338@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()} 8339 8340@node LIBGCCJIT_ABI_3,,LIBGCCJIT_ABI_2,ABI symbol tags 8341@anchor{topics/compatibility libgccjit-abi-3}@anchor{d8}@anchor{topics/compatibility id4}@anchor{ed} 8342@subsubsection @code{LIBGCCJIT_ABI_3} 8343 8344 8345@code{LIBGCCJIT_ABI_3} covers the addition of switch statements via API 8346entrypoints: 8347 8348@quotation 8349 8350 8351@itemize * 8352 8353@item 8354@pxref{d5,,gcc_jit_block_end_with_switch()} 8355 8356@item 8357@pxref{d6,,gcc_jit_case_as_object()} 8358 8359@item 8360@pxref{d7,,gcc_jit_context_new_case()} 8361@end itemize 8362@end quotation 8363 8364@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 8365@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8366@c 8367@c This is free software: you can redistribute it and/or modify it 8368@c under the terms of the GNU General Public License as published by 8369@c the Free Software Foundation, either version 3 of the License, or 8370@c (at your option) any later version. 8371@c 8372@c This program is distributed in the hope that it will be useful, but 8373@c WITHOUT ANY WARRANTY; without even the implied warranty of 8374@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8375@c General Public License for more details. 8376@c 8377@c You should have received a copy of the GNU General Public License 8378@c along with this program. If not, see 8379@c <http://www.gnu.org/licenses/>. 8380 8381@node C++ bindings for libgccjit,Internals,Topic Reference,Top 8382@anchor{cp/index c-bindings-for-libgccjit}@anchor{ee}@anchor{cp/index doc}@anchor{ef} 8383@chapter C++ bindings for libgccjit 8384 8385 8386This document describes the C++ bindings to 8387libgccjit@footnote{http://gcc.gnu.org/wiki/JIT}, an API for embedding GCC 8388inside programs and libraries. 8389 8390The C++ bindings consist of a single header file @code{libgccjit++.h}. 8391 8392This is a collection of "thin" wrapper classes around the C API. 8393Everything is an inline function, implemented in terms of the C API, 8394so there is nothing extra to link against. 8395 8396Note that libgccjit is currently of "Alpha" quality; 8397the APIs are not yet set in stone, and they shouldn't be used in 8398production yet. 8399 8400Contents: 8401 8402@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 8403@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8404@c 8405@c This is free software: you can redistribute it and/or modify it 8406@c under the terms of the GNU General Public License as published by 8407@c the Free Software Foundation, either version 3 of the License, or 8408@c (at your option) any later version. 8409@c 8410@c This program is distributed in the hope that it will be useful, but 8411@c WITHOUT ANY WARRANTY; without even the implied warranty of 8412@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8413@c General Public License for more details. 8414@c 8415@c You should have received a copy of the GNU General Public License 8416@c along with this program. If not, see 8417@c <http://www.gnu.org/licenses/>. 8418 8419@menu 8420* Tutorial: Tutorial<2>. 8421* Topic Reference: Topic Reference<2>. 8422 8423Tutorial 8424 8425* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 8426* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 8427* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 8428* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 8429 8430Tutorial part 2: Creating a trivial machine code function 8431 8432* Options: Options<3>. 8433* Full example: Full example<3>. 8434 8435Tutorial part 3: Loops and variables 8436 8437* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 8438* Control flow: Control flow<2>. 8439* Visualizing the control flow graph: Visualizing the control flow graph<2>. 8440* Full example: Full example<4>. 8441 8442Tutorial part 4: Adding JIT-compilation to a toy interpreter 8443 8444* Our toy interpreter: Our toy interpreter<2>. 8445* Compiling to machine code: Compiling to machine code<2>. 8446* Setting things up: Setting things up<2>. 8447* Populating the function: Populating the function<2>. 8448* Verifying the control flow graph: Verifying the control flow graph<2>. 8449* Compiling the context: Compiling the context<2>. 8450* Single-stepping through the generated code: Single-stepping through the generated code<2>. 8451* Examining the generated code: Examining the generated code<2>. 8452* Putting it all together: Putting it all together<2>. 8453* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 8454 8455Behind the curtain: How does our code get optimized? 8456 8457* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 8458* Elimination of tail recursion: Elimination of tail recursion<2>. 8459 8460Topic Reference 8461 8462* Compilation contexts: Compilation contexts<2>. 8463* Objects: Objects<2>. 8464* Types: Types<2>. 8465* Expressions: Expressions<2>. 8466* Creating and using functions: Creating and using functions<2>. 8467* Source Locations: Source Locations<2>. 8468* Compiling a context: Compiling a context<2>. 8469 8470Compilation contexts 8471 8472* Lifetime-management: Lifetime-management<2>. 8473* Thread-safety: Thread-safety<2>. 8474* Error-handling: Error-handling<3>. 8475* Debugging: Debugging<2>. 8476* Options: Options<4>. 8477 8478Options 8479 8480* String Options: String Options<2>. 8481* Boolean options: Boolean options<2>. 8482* Integer options: Integer options<2>. 8483* Additional command-line options: Additional command-line options<2>. 8484 8485Types 8486 8487* Standard types: Standard types<2>. 8488* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 8489* Structures and unions: Structures and unions<2>. 8490 8491Expressions 8492 8493* Rvalues: Rvalues<2>. 8494* Lvalues: Lvalues<2>. 8495* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 8496 8497Rvalues 8498 8499* Simple expressions: Simple expressions<2>. 8500* Unary Operations: Unary Operations<2>. 8501* Binary Operations: Binary Operations<2>. 8502* Comparisons: Comparisons<2>. 8503* Function calls: Function calls<2>. 8504* Type-coercion: Type-coercion<2>. 8505 8506Lvalues 8507 8508* Global variables: Global variables<2>. 8509 8510Creating and using functions 8511 8512* Params: Params<2>. 8513* Functions: Functions<2>. 8514* Blocks: Blocks<2>. 8515* Statements: Statements<2>. 8516 8517Source Locations 8518 8519* Faking it: Faking it<2>. 8520 8521Compiling a context 8522 8523* In-memory compilation: In-memory compilation<2>. 8524* Ahead-of-time compilation: Ahead-of-time compilation<2>. 8525 8526@end menu 8527 8528 8529@node Tutorial<2>,Topic Reference<2>,,C++ bindings for libgccjit 8530@anchor{cp/intro/index doc}@anchor{f0}@anchor{cp/intro/index tutorial}@anchor{f1} 8531@section Tutorial 8532 8533 8534@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 8535@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8536@c 8537@c This is free software: you can redistribute it and/or modify it 8538@c under the terms of the GNU General Public License as published by 8539@c the Free Software Foundation, either version 3 of the License, or 8540@c (at your option) any later version. 8541@c 8542@c This program is distributed in the hope that it will be useful, but 8543@c WITHOUT ANY WARRANTY; without even the implied warranty of 8544@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8545@c General Public License for more details. 8546@c 8547@c You should have received a copy of the GNU General Public License 8548@c along with this program. If not, see 8549@c <http://www.gnu.org/licenses/>. 8550 8551@menu 8552* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 8553* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 8554* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 8555* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 8556 8557@end menu 8558 8559@node Tutorial part 1 "Hello world"<2>,Tutorial part 2 Creating a trivial machine code function<2>,,Tutorial<2> 8560@anchor{cp/intro/tutorial01 doc}@anchor{f2}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{f3} 8561@subsection Tutorial part 1: "Hello world" 8562 8563 8564Before we look at the details of the API, let's look at building and 8565running programs that use the library. 8566 8567Here's a toy "hello world" program that uses the library's C++ API to 8568synthesize a call to @cite{printf} and uses it to write a message to stdout. 8569 8570Don't worry about the content of the program for now; we'll cover 8571the details in later parts of this tutorial. 8572 8573@quotation 8574 8575@example 8576/* Smoketest example for libgccjit.so C++ API 8577 Copyright (C) 2014-2015 Free Software Foundation, Inc. 8578 8579This file is part of GCC. 8580 8581GCC is free software; you can redistribute it and/or modify it 8582under the terms of the GNU General Public License as published by 8583the Free Software Foundation; either version 3, or (at your option) 8584any later version. 8585 8586GCC is distributed in the hope that it will be useful, but 8587WITHOUT ANY WARRANTY; without even the implied warranty of 8588MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8589General Public License for more details. 8590 8591You should have received a copy of the GNU General Public License 8592along with GCC; see the file COPYING3. If not see 8593<http://www.gnu.org/licenses/>. */ 8594 8595#include <libgccjit++.h> 8596 8597#include <stdlib.h> 8598#include <stdio.h> 8599 8600static void 8601create_code (gccjit::context ctxt) 8602@{ 8603 /* Let's try to inject the equivalent of this C code: 8604 void 8605 greet (const char *name) 8606 @{ 8607 printf ("hello %s\n", name); 8608 @} 8609 */ 8610 gccjit::type void_type = ctxt.get_type (GCC_JIT_TYPE_VOID); 8611 gccjit::type const_char_ptr_type = 8612 ctxt.get_type (GCC_JIT_TYPE_CONST_CHAR_PTR); 8613 gccjit::param param_name = 8614 ctxt.new_param (const_char_ptr_type, "name"); 8615 std::vector<gccjit::param> func_params; 8616 func_params.push_back (param_name); 8617 gccjit::function func = 8618 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 8619 void_type, 8620 "greet", 8621 func_params, 0); 8622 8623 gccjit::param param_format = 8624 ctxt.new_param (const_char_ptr_type, "format"); 8625 std::vector<gccjit::param> printf_params; 8626 printf_params.push_back (param_format); 8627 gccjit::function printf_func = 8628 ctxt.new_function (GCC_JIT_FUNCTION_IMPORTED, 8629 ctxt.get_type (GCC_JIT_TYPE_INT), 8630 "printf", 8631 printf_params, 1); 8632 8633 gccjit::block block = func.new_block (); 8634 block.add_eval (ctxt.new_call (printf_func, 8635 ctxt.new_rvalue ("hello %s\n"), 8636 param_name)); 8637 block.end_with_return (); 8638@} 8639 8640int 8641main (int argc, char **argv) 8642@{ 8643 gccjit::context ctxt; 8644 gcc_jit_result *result; 8645 8646 /* Get a "context" object for working with the library. */ 8647 ctxt = gccjit::context::acquire (); 8648 8649 /* Set some options on the context. 8650 Turn this on to see the code being generated, in assembler form. */ 8651 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 0); 8652 8653 /* Populate the context. */ 8654 create_code (ctxt); 8655 8656 /* Compile the code. */ 8657 result = ctxt.compile (); 8658 if (!result) 8659 @{ 8660 fprintf (stderr, "NULL result"); 8661 exit (1); 8662 @} 8663 8664 ctxt.release (); 8665 8666 /* Extract the generated code from "result". */ 8667 typedef void (*fn_type) (const char *); 8668 fn_type greet = 8669 (fn_type)gcc_jit_result_get_code (result, "greet"); 8670 if (!greet) 8671 @{ 8672 fprintf (stderr, "NULL greet"); 8673 exit (1); 8674 @} 8675 8676 /* Now call the generated function: */ 8677 greet ("world"); 8678 fflush (stdout); 8679 8680 gcc_jit_result_release (result); 8681 return 0; 8682@} 8683 8684@end example 8685 8686@noindent 8687@end quotation 8688 8689Copy the above to @cite{tut01-hello-world.cc}. 8690 8691Assuming you have the jit library installed, build the test program 8692using: 8693 8694@example 8695$ gcc \ 8696 tut01-hello-world.cc \ 8697 -o tut01-hello-world \ 8698 -lgccjit 8699@end example 8700 8701@noindent 8702 8703You should then be able to run the built program: 8704 8705@example 8706$ ./tut01-hello-world 8707hello world 8708@end example 8709 8710@noindent 8711 8712@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 8713@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8714@c 8715@c This is free software: you can redistribute it and/or modify it 8716@c under the terms of the GNU General Public License as published by 8717@c the Free Software Foundation, either version 3 of the License, or 8718@c (at your option) any later version. 8719@c 8720@c This program is distributed in the hope that it will be useful, but 8721@c WITHOUT ANY WARRANTY; without even the implied warranty of 8722@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8723@c General Public License for more details. 8724@c 8725@c You should have received a copy of the GNU General Public License 8726@c along with this program. If not, see 8727@c <http://www.gnu.org/licenses/>. 8728 8729@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> 8730@anchor{cp/intro/tutorial02 doc}@anchor{f4}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{f5} 8731@subsection Tutorial part 2: Creating a trivial machine code function 8732 8733 8734Consider this C function: 8735 8736@example 8737int square (int i) 8738@{ 8739 return i * i; 8740@} 8741@end example 8742 8743@noindent 8744 8745How can we construct this at run-time using libgccjit's C++ API? 8746 8747First we need to include the relevant header: 8748 8749@example 8750#include <libgccjit++.h> 8751@end example 8752 8753@noindent 8754 8755All state associated with compilation is associated with a 8756@code{gccjit::context}, which is a thin C++ wrapper around the C API's 8757@pxref{8,,gcc_jit_context *}. 8758 8759Create one using @pxref{f6,,gccjit;;context;;acquire()}: 8760 8761@example 8762gccjit::context ctxt; 8763ctxt = gccjit::context::acquire (); 8764@end example 8765 8766@noindent 8767 8768The JIT library has a system of types. It is statically-typed: every 8769expression is of a specific type, fixed at compile-time. In our example, 8770all of the expressions are of the C @cite{int} type, so let's obtain this from 8771the context, as a @code{gccjit::type}, using 8772@pxref{f7,,gccjit;;context;;get_type()}: 8773 8774@example 8775gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 8776@end example 8777 8778@noindent 8779 8780@code{gccjit::type} is an example of a "contextual" object: every 8781entity in the API is associated with a @code{gccjit::context}. 8782 8783Memory management is easy: all such "contextual" objects are automatically 8784cleaned up for you when the context is released, using 8785@pxref{f8,,gccjit;;context;;release()}: 8786 8787@example 8788ctxt.release (); 8789@end example 8790 8791@noindent 8792 8793so you don't need to manually track and cleanup all objects, just the 8794contexts. 8795 8796All of the C++ classes in the API are thin wrappers around pointers to 8797types in the C API. 8798 8799The C++ class hierarchy within the @code{gccjit} namespace looks like this: 8800 8801@example 8802+- object 8803 +- location 8804 +- type 8805 +- struct 8806 +- field 8807 +- function 8808 +- block 8809 +- rvalue 8810 +- lvalue 8811 +- param 8812@end example 8813 8814@noindent 8815 8816One thing you can do with a @code{gccjit::object} is 8817to ask it for a human-readable description as a @code{std::string}, using 8818@pxref{f9,,gccjit;;object;;get_debug_string()}: 8819 8820@example 8821printf ("obj: %s\n", obj.get_debug_string ().c_str ()); 8822@end example 8823 8824@noindent 8825 8826giving this text on stdout: 8827 8828@example 8829obj: int 8830@end example 8831 8832@noindent 8833 8834This is invaluable when debugging. 8835 8836Let's create the function. To do so, we first need to construct 8837its single parameter, specifying its type and giving it a name, 8838using @pxref{fa,,gccjit;;context;;new_param()}: 8839 8840@example 8841gccjit::param param_i = ctxt.new_param (int_type, "i"); 8842@end example 8843 8844@noindent 8845 8846and we can then make a vector of all of the params of the function, 8847in this case just one: 8848 8849@example 8850std::vector<gccjit::param> params; 8851params.push_back (param_i); 8852@end example 8853 8854@noindent 8855 8856Now we can create the function, using 8857@code{gccjit::context::new_function()}: 8858 8859@example 8860gccjit::function func = 8861 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 8862 int_type, 8863 "square", 8864 params, 8865 0); 8866@end example 8867 8868@noindent 8869 8870To define the code within the function, we must create basic blocks 8871containing statements. 8872 8873Every basic block contains a list of statements, eventually terminated 8874by a statement that either returns, or jumps to another basic block. 8875 8876Our function has no control-flow, so we just need one basic block: 8877 8878@example 8879gccjit::block block = func.new_block (); 8880@end example 8881 8882@noindent 8883 8884Our basic block is relatively simple: it immediately terminates by 8885returning the value of an expression. 8886 8887We can build the expression using @pxref{fb,,gccjit;;context;;new_binary_op()}: 8888 8889@example 8890gccjit::rvalue expr = 8891 ctxt.new_binary_op ( 8892 GCC_JIT_BINARY_OP_MULT, int_type, 8893 param_i, param_i); 8894@end example 8895 8896@noindent 8897 8898A @code{gccjit::rvalue} is another example of a 8899@code{gccjit::object} subclass. As before, we can print it with 8900@pxref{f9,,gccjit;;object;;get_debug_string()}. 8901 8902@example 8903printf ("expr: %s\n", expr.get_debug_string ().c_str ()); 8904@end example 8905 8906@noindent 8907 8908giving this output: 8909 8910@example 8911expr: i * i 8912@end example 8913 8914@noindent 8915 8916Note that @code{gccjit::rvalue} provides numerous overloaded operators 8917which can be used to dramatically reduce the amount of typing needed. 8918We can build the above binary operation more directly with this one-liner: 8919 8920@example 8921gccjit::rvalue expr = param_i * param_i; 8922@end example 8923 8924@noindent 8925 8926Creating the expression in itself doesn't do anything; we have to add 8927this expression to a statement within the block. In this case, we use it 8928to build a return statement, which terminates the basic block: 8929 8930@example 8931block.end_with_return (expr); 8932@end example 8933 8934@noindent 8935 8936OK, we've populated the context. We can now compile it using 8937@pxref{fc,,gccjit;;context;;compile()}: 8938 8939@example 8940gcc_jit_result *result; 8941result = ctxt.compile (); 8942@end example 8943 8944@noindent 8945 8946and get a @pxref{16,,gcc_jit_result *}. 8947 8948We can now use @pxref{17,,gcc_jit_result_get_code()} to look up a specific 8949machine code routine within the result, in this case, the function we 8950created above. 8951 8952@example 8953void *fn_ptr = gcc_jit_result_get_code (result, "square"); 8954if (!fn_ptr) 8955 @{ 8956 fprintf (stderr, "NULL fn_ptr"); 8957 goto error; 8958 @} 8959@end example 8960 8961@noindent 8962 8963We can now cast the pointer to an appropriate function pointer type, and 8964then call it: 8965 8966@example 8967typedef int (*fn_type) (int); 8968fn_type square = (fn_type)fn_ptr; 8969printf ("result: %d", square (5)); 8970@end example 8971 8972@noindent 8973 8974@example 8975result: 25 8976@end example 8977 8978@noindent 8979 8980@menu 8981* Options: Options<3>. 8982* Full example: Full example<3>. 8983 8984@end menu 8985 8986@node Options<3>,Full example<3>,,Tutorial part 2 Creating a trivial machine code function<2> 8987@anchor{cp/intro/tutorial02 options}@anchor{fd} 8988@subsubsection Options 8989 8990 8991To get more information on what's going on, you can set debugging flags 8992on the context using @pxref{fe,,gccjit;;context;;set_bool_option()}. 8993 8994@c (I'm deliberately not mentioning 8995@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think 8996@c it's probably more of use to implementors than to users) 8997 8998Setting @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a 8999C-like representation to stderr when you compile (GCC's "GIMPLE" 9000representation): 9001 9002@example 9003ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); 9004result = ctxt.compile (); 9005@end example 9006 9007@noindent 9008 9009@example 9010square (signed int i) 9011@{ 9012 signed int D.260; 9013 9014 entry: 9015 D.260 = i * i; 9016 return D.260; 9017@} 9018@end example 9019 9020@noindent 9021 9022We can see the generated machine code in assembler form (on stderr) by 9023setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context 9024before compiling: 9025 9026@example 9027ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); 9028result = ctxt.compile (); 9029@end example 9030 9031@noindent 9032 9033@example 9034 .file "fake.c" 9035 .text 9036 .globl square 9037 .type square, @@function 9038square: 9039.LFB6: 9040 .cfi_startproc 9041 pushq %rbp 9042 .cfi_def_cfa_offset 16 9043 .cfi_offset 6, -16 9044 movq %rsp, %rbp 9045 .cfi_def_cfa_register 6 9046 movl %edi, -4(%rbp) 9047.L14: 9048 movl -4(%rbp), %eax 9049 imull -4(%rbp), %eax 9050 popq %rbp 9051 .cfi_def_cfa 7, 8 9052 ret 9053 .cfi_endproc 9054.LFE6: 9055 .size square, .-square 9056 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 9057 .section .note.GNU-stack,"",@@progbits 9058@end example 9059 9060@noindent 9061 9062By default, no optimizations are performed, the equivalent of GCC's 9063@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling 9064@pxref{ff,,gccjit;;context;;set_int_option()} with 9065@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 9066 9067@example 9068ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); 9069@end example 9070 9071@noindent 9072 9073@example 9074 .file "fake.c" 9075 .text 9076 .p2align 4,,15 9077 .globl square 9078 .type square, @@function 9079square: 9080.LFB7: 9081 .cfi_startproc 9082.L16: 9083 movl %edi, %eax 9084 imull %edi, %eax 9085 ret 9086 .cfi_endproc 9087.LFE7: 9088 .size square, .-square 9089 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 9090 .section .note.GNU-stack,"",@@progbits 9091@end example 9092 9093@noindent 9094 9095Naturally this has only a small effect on such a trivial function. 9096 9097@node Full example<3>,,Options<3>,Tutorial part 2 Creating a trivial machine code function<2> 9098@anchor{cp/intro/tutorial02 full-example}@anchor{100} 9099@subsubsection Full example 9100 9101 9102Here's what the above looks like as a complete program: 9103 9104@quotation 9105 9106@example 9107/* Usage example for libgccjit.so's C++ API 9108 Copyright (C) 2014-2015 Free Software Foundation, Inc. 9109 9110This file is part of GCC. 9111 9112GCC is free software; you can redistribute it and/or modify it 9113under the terms of the GNU General Public License as published by 9114the Free Software Foundation; either version 3, or (at your option) 9115any later version. 9116 9117GCC is distributed in the hope that it will be useful, but 9118WITHOUT ANY WARRANTY; without even the implied warranty of 9119MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9120General Public License for more details. 9121 9122You should have received a copy of the GNU General Public License 9123along with GCC; see the file COPYING3. If not see 9124<http://www.gnu.org/licenses/>. */ 9125 9126#include <libgccjit++.h> 9127 9128#include <stdlib.h> 9129#include <stdio.h> 9130 9131void 9132create_code (gccjit::context ctxt) 9133@{ 9134 /* Let's try to inject the equivalent of this C code: 9135 9136 int square (int i) 9137 @{ 9138 return i * i; 9139 @} 9140 */ 9141 gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 9142 gccjit::param param_i = ctxt.new_param (int_type, "i"); 9143 std::vector<gccjit::param> params; 9144 params.push_back (param_i); 9145 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9146 int_type, 9147 "square", 9148 params, 0); 9149 9150 gccjit::block block = func.new_block (); 9151 9152 gccjit::rvalue expr = 9153 ctxt.new_binary_op (GCC_JIT_BINARY_OP_MULT, int_type, 9154 param_i, param_i); 9155 9156 block.end_with_return (expr); 9157@} 9158 9159int 9160main (int argc, char **argv) 9161@{ 9162 /* Get a "context" object for working with the library. */ 9163 gccjit::context ctxt = gccjit::context::acquire (); 9164 9165 /* Set some options on the context. 9166 Turn this on to see the code being generated, in assembler form. */ 9167 ctxt.set_bool_option ( 9168 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 9169 0); 9170 9171 /* Populate the context. */ 9172 create_code (ctxt); 9173 9174 /* Compile the code. */ 9175 gcc_jit_result *result = ctxt.compile (); 9176 9177 /* We're done with the context; we can release it: */ 9178 ctxt.release (); 9179 9180 if (!result) 9181 @{ 9182 fprintf (stderr, "NULL result"); 9183 return 1; 9184 @} 9185 9186 /* Extract the generated code from "result". */ 9187 void *fn_ptr = gcc_jit_result_get_code (result, "square"); 9188 if (!fn_ptr) 9189 @{ 9190 fprintf (stderr, "NULL fn_ptr"); 9191 gcc_jit_result_release (result); 9192 return 1; 9193 @} 9194 9195 typedef int (*fn_type) (int); 9196 fn_type square = (fn_type)fn_ptr; 9197 printf ("result: %d\n", square (5)); 9198 9199 gcc_jit_result_release (result); 9200 return 0; 9201@} 9202 9203@end example 9204 9205@noindent 9206@end quotation 9207 9208Building and running it: 9209 9210@example 9211$ gcc \ 9212 tut02-square.cc \ 9213 -o tut02-square \ 9214 -lgccjit 9215 9216# Run the built program: 9217$ ./tut02-square 9218result: 25 9219@end example 9220 9221@noindent 9222 9223@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 9224@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9225@c 9226@c This is free software: you can redistribute it and/or modify it 9227@c under the terms of the GNU General Public License as published by 9228@c the Free Software Foundation, either version 3 of the License, or 9229@c (at your option) any later version. 9230@c 9231@c This program is distributed in the hope that it will be useful, but 9232@c WITHOUT ANY WARRANTY; without even the implied warranty of 9233@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9234@c General Public License for more details. 9235@c 9236@c You should have received a copy of the GNU General Public License 9237@c along with this program. If not, see 9238@c <http://www.gnu.org/licenses/>. 9239 9240@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> 9241@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{101}@anchor{cp/intro/tutorial03 doc}@anchor{102} 9242@subsection Tutorial part 3: Loops and variables 9243 9244 9245Consider this C function: 9246 9247@quotation 9248 9249@example 9250int loop_test (int n) 9251@{ 9252 int sum = 0; 9253 for (int i = 0; i < n; i++) 9254 sum += i * i; 9255 return sum; 9256@} 9257@end example 9258 9259@noindent 9260@end quotation 9261 9262This example demonstrates some more features of libgccjit, with local 9263variables and a loop. 9264 9265To break this down into libgccjit terms, it's usually easier to reword 9266the @cite{for} loop as a @cite{while} loop, giving: 9267 9268@quotation 9269 9270@example 9271int loop_test (int n) 9272@{ 9273 int sum = 0; 9274 int i = 0; 9275 while (i < n) 9276 @{ 9277 sum += i * i; 9278 i++; 9279 @} 9280 return sum; 9281@} 9282@end example 9283 9284@noindent 9285@end quotation 9286 9287Here's what the final control flow graph will look like: 9288 9289@quotation 9290 9291 9292@float Figure 9293 9294@image{sum-of-squares,,,image of a control flow graph,png} 9295 9296@end float 9297 9298@end quotation 9299 9300As before, we include the libgccjit++ header and make a 9301@code{gccjit::context}. 9302 9303@example 9304#include <libgccjit++.h> 9305 9306void test (void) 9307@{ 9308 gccjit::context ctxt; 9309 ctxt = gccjit::context::acquire (); 9310@end example 9311 9312@noindent 9313 9314The function works with the C @cite{int} type. 9315 9316In the previous tutorial we acquired this via 9317 9318@example 9319gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_INT); 9320@end example 9321 9322@noindent 9323 9324though we could equally well make it work on, say, @cite{double}: 9325 9326@example 9327gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_DOUBLE); 9328@end example 9329 9330@noindent 9331 9332For integer types we can use @code{gccjit::context::get_int_type} 9333to directly bind a specific type: 9334 9335@example 9336gccjit::type the_type = ctxt.get_int_type <int> (); 9337@end example 9338 9339@noindent 9340 9341Let's build the function: 9342 9343@example 9344gcc_jit_param n = ctxt.new_param (the_type, "n"); 9345std::vector<gccjit::param> params; 9346params.push_back (n); 9347gccjit::function func = 9348 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9349 return_type, 9350 "loop_test", 9351 params, 0); 9352@end example 9353 9354@noindent 9355 9356@menu 9357* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 9358* Control flow: Control flow<2>. 9359* Visualizing the control flow graph: Visualizing the control flow graph<2>. 9360* Full example: Full example<4>. 9361 9362@end menu 9363 9364@node Expressions lvalues and rvalues<2>,Control flow<2>,,Tutorial part 3 Loops and variables<2> 9365@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{103} 9366@subsubsection Expressions: lvalues and rvalues 9367 9368 9369The base class of expression is the @code{gccjit::rvalue}, 9370representing an expression that can be on the @emph{right}-hand side of 9371an assignment: a value that can be computed somehow, and assigned 9372@emph{to} a storage area (such as a variable). It has a specific 9373@code{gccjit::type}. 9374 9375Anothe important class is @code{gccjit::lvalue}. 9376A @code{gccjit::lvalue}. is something that can of the @emph{left}-hand 9377side of an assignment: a storage area (such as a variable). 9378 9379In other words, every assignment can be thought of as: 9380 9381@example 9382LVALUE = RVALUE; 9383@end example 9384 9385@noindent 9386 9387Note that @code{gccjit::lvalue} is a subclass of 9388@code{gccjit::rvalue}, where in an assignment of the form: 9389 9390@example 9391LVALUE_A = LVALUE_B; 9392@end example 9393 9394@noindent 9395 9396the @cite{LVALUE_B} implies reading the current value of that storage 9397area, assigning it into the @cite{LVALUE_A}. 9398 9399So far the only expressions we've seen are from the previous tutorial: 9400 9401 9402@enumerate 9403 9404@item 9405the multiplication @cite{i * i}: 9406@end enumerate 9407 9408@quotation 9409 9410@example 9411gccjit::rvalue expr = 9412 ctxt.new_binary_op ( 9413 GCC_JIT_BINARY_OP_MULT, int_type, 9414 param_i, param_i); 9415 9416/* Alternatively, using operator-overloading: */ 9417gccjit::rvalue expr = param_i * param_i; 9418@end example 9419 9420@noindent 9421 9422which is a @code{gccjit::rvalue}, and 9423@end quotation 9424 9425 9426@enumerate 2 9427 9428@item 9429the various function parameters: @cite{param_i} and @cite{param_n}, instances of 9430@code{gccjit::param}, which is a subclass of @code{gccjit::lvalue} 9431(and, in turn, of @code{gccjit::rvalue}): 9432we can both read from and write to function parameters within the 9433body of a function. 9434@end enumerate 9435 9436Our new example has a new kind of expression: we have two local 9437variables. We create them by calling 9438@pxref{104,,gccjit;;function;;new_local()}, supplying a type and a name: 9439 9440@example 9441/* Build locals: */ 9442gccjit::lvalue i = func.new_local (the_type, "i"); 9443gccjit::lvalue sum = func.new_local (the_type, "sum"); 9444@end example 9445 9446@noindent 9447 9448These are instances of @code{gccjit::lvalue} - they can be read from 9449and written to. 9450 9451Note that there is no precanned way to create @emph{and} initialize a variable 9452like in C: 9453 9454@example 9455int i = 0; 9456@end example 9457 9458@noindent 9459 9460Instead, having added the local to the function, we have to separately add 9461an assignment of @cite{0} to @cite{local_i} at the beginning of the function. 9462 9463@node Control flow<2>,Visualizing the control flow graph<2>,Expressions lvalues and rvalues<2>,Tutorial part 3 Loops and variables<2> 9464@anchor{cp/intro/tutorial03 control-flow}@anchor{105} 9465@subsubsection Control flow 9466 9467 9468This function has a loop, so we need to build some basic blocks to 9469handle the control flow. In this case, we need 4 blocks: 9470 9471 9472@enumerate 9473 9474@item 9475before the loop (initializing the locals) 9476 9477@item 9478the conditional at the top of the loop (comparing @cite{i < n}) 9479 9480@item 9481the body of the loop 9482 9483@item 9484after the loop terminates (@cite{return sum}) 9485@end enumerate 9486 9487so we create these as @code{gccjit::block} instances within the 9488@code{gccjit::function}: 9489 9490@example 9491gccjit::block b_initial = func.new_block ("initial"); 9492gccjit::block b_loop_cond = func.new_block ("loop_cond"); 9493gccjit::block b_loop_body = func.new_block ("loop_body"); 9494gccjit::block b_after_loop = func.new_block ("after_loop"); 9495@end example 9496 9497@noindent 9498 9499We now populate each block with statements. 9500 9501The entry block @cite{b_initial} consists of initializations followed by a jump 9502to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using 9503@pxref{106,,gccjit;;block;;add_assignment()} to add 9504an assignment statement, and using @pxref{107,,gccjit;;context;;zero()} to get 9505the constant value @cite{0} for the relevant type for the right-hand side of 9506the assignment: 9507 9508@example 9509/* sum = 0; */ 9510b_initial.add_assignment (sum, ctxt.zero (the_type)); 9511 9512/* i = 0; */ 9513b_initial.add_assignment (i, ctxt.zero (the_type)); 9514@end example 9515 9516@noindent 9517 9518We can then terminate the entry block by jumping to the conditional: 9519 9520@example 9521b_initial.end_with_jump (b_loop_cond); 9522@end example 9523 9524@noindent 9525 9526The conditional block is equivalent to the line @cite{while (i < n)} from our 9527C example. It contains a single statement: a conditional, which jumps to 9528one of two destination blocks depending on a boolean 9529@code{gccjit::rvalue}, in this case the comparison of @cite{i} and @cite{n}. 9530 9531We could build the comparison using @pxref{108,,gccjit;;context;;new_comparison()}: 9532 9533@example 9534gccjit::rvalue guard = 9535 ctxt.new_comparison (GCC_JIT_COMPARISON_GE, 9536 i, n); 9537@end example 9538 9539@noindent 9540 9541and can then use this to add @cite{b_loop_cond}'s sole statement, via 9542@pxref{109,,gccjit;;block;;end_with_conditional()}: 9543 9544@example 9545b_loop_cond.end_with_conditional (guard, 9546 b_after_loop, // on_true 9547 b_loop_body); // on_false 9548@end example 9549 9550@noindent 9551 9552However @code{gccjit::rvalue} has overloaded operators for this, so we 9553express the conditional as 9554 9555@example 9556gccjit::rvalue guard = (i >= n); 9557@end example 9558 9559@noindent 9560 9561and hence we can write the block more concisely as: 9562 9563@example 9564b_loop_cond.end_with_conditional ( 9565 i >= n, 9566 b_after_loop, // on_true 9567 b_loop_body); // on_false 9568@end example 9569 9570@noindent 9571 9572Next, we populate the body of the loop. 9573 9574The C statement @cite{sum += i * i;} is an assignment operation, where an 9575lvalue is modified "in-place". We use 9576@pxref{10a,,gccjit;;block;;add_assignment_op()} to handle these operations: 9577 9578@example 9579/* sum += i * i */ 9580b_loop_body.add_assignment_op (sum, 9581 GCC_JIT_BINARY_OP_PLUS, 9582 i * i); 9583@end example 9584 9585@noindent 9586 9587The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in 9588a similar way. We use @pxref{2f,,gcc_jit_context_one()} to get the constant 9589value @cite{1} (for the relevant type) for the right-hand side 9590of the assignment. 9591 9592@example 9593/* i++ */ 9594b_loop_body.add_assignment_op (i, 9595 GCC_JIT_BINARY_OP_PLUS, 9596 ctxt.one (the_type)); 9597@end example 9598 9599@noindent 9600 9601@cartouche 9602@quotation Note 9603For numeric constants other than 0 or 1, we could use 9604@pxref{10b,,gccjit;;context;;new_rvalue()}, which has overloads 9605for both @code{int} and @code{double}. 9606@end quotation 9607@end cartouche 9608 9609The loop body completes by jumping back to the conditional: 9610 9611@example 9612b_loop_body.end_with_jump (b_loop_cond); 9613@end example 9614 9615@noindent 9616 9617Finally, we populate the @cite{b_after_loop} block, reached when the loop 9618conditional is false. We want to generate the equivalent of: 9619 9620@example 9621return sum; 9622@end example 9623 9624@noindent 9625 9626so the block is just one statement: 9627 9628@example 9629/* return sum */ 9630b_after_loop.end_with_return (sum); 9631@end example 9632 9633@noindent 9634 9635@cartouche 9636@quotation Note 9637You can intermingle block creation with statement creation, 9638but given that the terminator statements generally include references 9639to other blocks, I find it's clearer to create all the blocks, 9640@emph{then} all the statements. 9641@end quotation 9642@end cartouche 9643 9644We've finished populating the function. As before, we can now compile it 9645to machine code: 9646 9647@example 9648gcc_jit_result *result; 9649result = ctxt.compile (); 9650 9651ctxt.release (); 9652 9653if (!result) 9654 @{ 9655 fprintf (stderr, "NULL result"); 9656 return 1; 9657 @} 9658 9659typedef int (*loop_test_fn_type) (int); 9660loop_test_fn_type loop_test = 9661 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 9662if (!loop_test) 9663 @{ 9664 fprintf (stderr, "NULL loop_test"); 9665 gcc_jit_result_release (result); 9666 return 1; 9667 @} 9668printf ("result: %d", loop_test (10)); 9669@end example 9670 9671@noindent 9672 9673@example 9674result: 285 9675@end example 9676 9677@noindent 9678 9679@node Visualizing the control flow graph<2>,Full example<4>,Control flow<2>,Tutorial part 3 Loops and variables<2> 9680@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{10c} 9681@subsubsection Visualizing the control flow graph 9682 9683 9684You can see the control flow graph of a function using 9685@pxref{10d,,gccjit;;function;;dump_to_dot()}: 9686 9687@example 9688func.dump_to_dot ("/tmp/sum-of-squares.dot"); 9689@end example 9690 9691@noindent 9692 9693giving a .dot file in GraphViz format. 9694 9695You can convert this to an image using @cite{dot}: 9696 9697@example 9698$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png 9699@end example 9700 9701@noindent 9702 9703or use a viewer (my preferred one is xdot.py; see 9704@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can 9705install it with @cite{yum install python-xdot}): 9706 9707@quotation 9708 9709 9710@float Figure 9711 9712@image{sum-of-squares,,,image of a control flow graph,png} 9713 9714@end float 9715 9716@end quotation 9717 9718@node Full example<4>,,Visualizing the control flow graph<2>,Tutorial part 3 Loops and variables<2> 9719@anchor{cp/intro/tutorial03 full-example}@anchor{10e} 9720@subsubsection Full example 9721 9722 9723@quotation 9724 9725@example 9726/* Usage example for libgccjit.so's C++ API 9727 Copyright (C) 2014-2015 Free Software Foundation, Inc. 9728 9729This file is part of GCC. 9730 9731GCC is free software; you can redistribute it and/or modify it 9732under the terms of the GNU General Public License as published by 9733the Free Software Foundation; either version 3, or (at your option) 9734any later version. 9735 9736GCC is distributed in the hope that it will be useful, but 9737WITHOUT ANY WARRANTY; without even the implied warranty of 9738MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9739General Public License for more details. 9740 9741You should have received a copy of the GNU General Public License 9742along with GCC; see the file COPYING3. If not see 9743<http://www.gnu.org/licenses/>. */ 9744 9745#include <libgccjit++.h> 9746 9747#include <stdlib.h> 9748#include <stdio.h> 9749 9750void 9751create_code (gccjit::context ctxt) 9752@{ 9753 /* 9754 Simple sum-of-squares, to test conditionals and looping 9755 9756 int loop_test (int n) 9757 @{ 9758 int i; 9759 int sum = 0; 9760 for (i = 0; i < n ; i ++) 9761 @{ 9762 sum += i * i; 9763 @} 9764 return sum; 9765 */ 9766 gccjit::type the_type = ctxt.get_int_type <int> (); 9767 gccjit::type return_type = the_type; 9768 9769 gccjit::param n = ctxt.new_param (the_type, "n"); 9770 std::vector<gccjit::param> params; 9771 params.push_back (n); 9772 gccjit::function func = 9773 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9774 return_type, 9775 "loop_test", 9776 params, 0); 9777 9778 /* Build locals: */ 9779 gccjit::lvalue i = func.new_local (the_type, "i"); 9780 gccjit::lvalue sum = func.new_local (the_type, "sum"); 9781 9782 gccjit::block b_initial = func.new_block ("initial"); 9783 gccjit::block b_loop_cond = func.new_block ("loop_cond"); 9784 gccjit::block b_loop_body = func.new_block ("loop_body"); 9785 gccjit::block b_after_loop = func.new_block ("after_loop"); 9786 9787 /* sum = 0; */ 9788 b_initial.add_assignment (sum, ctxt.zero (the_type)); 9789 9790 /* i = 0; */ 9791 b_initial.add_assignment (i, ctxt.zero (the_type)); 9792 9793 b_initial.end_with_jump (b_loop_cond); 9794 9795 /* if (i >= n) */ 9796 b_loop_cond.end_with_conditional ( 9797 i >= n, 9798 b_after_loop, 9799 b_loop_body); 9800 9801 /* sum += i * i */ 9802 b_loop_body.add_assignment_op (sum, 9803 GCC_JIT_BINARY_OP_PLUS, 9804 i * i); 9805 9806 /* i++ */ 9807 b_loop_body.add_assignment_op (i, 9808 GCC_JIT_BINARY_OP_PLUS, 9809 ctxt.one (the_type)); 9810 9811 b_loop_body.end_with_jump (b_loop_cond); 9812 9813 /* return sum */ 9814 b_after_loop.end_with_return (sum); 9815@} 9816 9817int 9818main (int argc, char **argv) 9819@{ 9820 gccjit::context ctxt; 9821 gcc_jit_result *result = NULL; 9822 9823 /* Get a "context" object for working with the library. */ 9824 ctxt = gccjit::context::acquire (); 9825 9826 /* Set some options on the context. 9827 Turn this on to see the code being generated, in assembler form. */ 9828 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 9829 0); 9830 9831 /* Populate the context. */ 9832 create_code (ctxt); 9833 9834 /* Compile the code. */ 9835 result = ctxt.compile (); 9836 9837 ctxt.release (); 9838 9839 if (!result) 9840 @{ 9841 fprintf (stderr, "NULL result"); 9842 return 1; 9843 @} 9844 9845 /* Extract the generated code from "result". */ 9846 typedef int (*loop_test_fn_type) (int); 9847 loop_test_fn_type loop_test = 9848 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 9849 if (!loop_test) 9850 @{ 9851 fprintf (stderr, "NULL loop_test"); 9852 gcc_jit_result_release (result); 9853 return 1; 9854 @} 9855 9856 /* Run the generated code. */ 9857 int val = loop_test (10); 9858 printf("loop_test returned: %d\n", val); 9859 9860 gcc_jit_result_release (result); 9861 return 0; 9862@} 9863 9864@end example 9865 9866@noindent 9867@end quotation 9868 9869Building and running it: 9870 9871@example 9872$ gcc \ 9873 tut03-sum-of-squares.cc \ 9874 -o tut03-sum-of-squares \ 9875 -lgccjit 9876 9877# Run the built program: 9878$ ./tut03-sum-of-squares 9879loop_test returned: 285 9880@end example 9881 9882@noindent 9883 9884@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 9885@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9886@c 9887@c This is free software: you can redistribute it and/or modify it 9888@c under the terms of the GNU General Public License as published by 9889@c the Free Software Foundation, either version 3 of the License, or 9890@c (at your option) any later version. 9891@c 9892@c This program is distributed in the hope that it will be useful, but 9893@c WITHOUT ANY WARRANTY; without even the implied warranty of 9894@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9895@c General Public License for more details. 9896@c 9897@c You should have received a copy of the GNU General Public License 9898@c along with this program. If not, see 9899@c <http://www.gnu.org/licenses/>. 9900 9901@node Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,,Tutorial part 3 Loops and variables<2>,Tutorial<2> 9902@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{10f}@anchor{cp/intro/tutorial04 doc}@anchor{110} 9903@subsection Tutorial part 4: Adding JIT-compilation to a toy interpreter 9904 9905 9906In this example we construct a "toy" interpreter, and add JIT-compilation 9907to it. 9908 9909@menu 9910* Our toy interpreter: Our toy interpreter<2>. 9911* Compiling to machine code: Compiling to machine code<2>. 9912* Setting things up: Setting things up<2>. 9913* Populating the function: Populating the function<2>. 9914* Verifying the control flow graph: Verifying the control flow graph<2>. 9915* Compiling the context: Compiling the context<2>. 9916* Single-stepping through the generated code: Single-stepping through the generated code<2>. 9917* Examining the generated code: Examining the generated code<2>. 9918* Putting it all together: Putting it all together<2>. 9919* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 9920 9921@end menu 9922 9923@node Our toy interpreter<2>,Compiling to machine code<2>,,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 9924@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{111} 9925@subsubsection Our toy interpreter 9926 9927 9928It's a stack-based interpreter, and is intended as a (very simple) example 9929of the kind of bytecode interpreter seen in dynamic languages such as 9930Python, Ruby etc. 9931 9932For the sake of simplicity, our toy virtual machine is very limited: 9933 9934@quotation 9935 9936 9937@itemize * 9938 9939@item 9940The only data type is @cite{int} 9941 9942@item 9943It can only work on one function at a time (so that the only 9944function call that can be made is to recurse). 9945 9946@item 9947Functions can only take one parameter. 9948 9949@item 9950Functions have a stack of @cite{int} values. 9951 9952@item 9953We'll implement function call within the interpreter by calling a 9954function in our implementation, rather than implementing our own 9955frame stack. 9956 9957@item 9958The parser is only good enough to get the examples to work. 9959@end itemize 9960@end quotation 9961 9962Naturally, a real interpreter would be much more complicated that this. 9963 9964The following operations are supported: 9965 9966 9967@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx} 9968@headitem 9969 9970Operation 9971 9972@tab 9973 9974Meaning 9975 9976@tab 9977 9978Old Stack 9979 9980@tab 9981 9982New Stack 9983 9984@item 9985 9986DUP 9987 9988@tab 9989 9990Duplicate top of stack. 9991 9992@tab 9993 9994@code{[..., x]} 9995 9996@tab 9997 9998@code{[..., x, x]} 9999 10000@item 10001 10002ROT 10003 10004@tab 10005 10006Swap top two elements 10007of stack. 10008 10009@tab 10010 10011@code{[..., x, y]} 10012 10013@tab 10014 10015@code{[..., y, x]} 10016 10017@item 10018 10019BINARY_ADD 10020 10021@tab 10022 10023Add the top two elements 10024on the stack. 10025 10026@tab 10027 10028@code{[..., x, y]} 10029 10030@tab 10031 10032@code{[..., (x+y)]} 10033 10034@item 10035 10036BINARY_SUBTRACT 10037 10038@tab 10039 10040Likewise, but subtract. 10041 10042@tab 10043 10044@code{[..., x, y]} 10045 10046@tab 10047 10048@code{[..., (x-y)]} 10049 10050@item 10051 10052BINARY_MULT 10053 10054@tab 10055 10056Likewise, but multiply. 10057 10058@tab 10059 10060@code{[..., x, y]} 10061 10062@tab 10063 10064@code{[..., (x*y)]} 10065 10066@item 10067 10068BINARY_COMPARE_LT 10069 10070@tab 10071 10072Compare the top two 10073elements on the stack 10074and push a nonzero/zero 10075if (x<y). 10076 10077@tab 10078 10079@code{[..., x, y]} 10080 10081@tab 10082 10083@code{[..., (x<y)]} 10084 10085@item 10086 10087RECURSE 10088 10089@tab 10090 10091Recurse, passing the top 10092of the stack, and 10093popping the result. 10094 10095@tab 10096 10097@code{[..., x]} 10098 10099@tab 10100 10101@code{[..., fn(x)]} 10102 10103@item 10104 10105RETURN 10106 10107@tab 10108 10109Return the top of the 10110stack. 10111 10112@tab 10113 10114@code{[x]} 10115 10116@tab 10117 10118@code{[]} 10119 10120@item 10121 10122PUSH_CONST @cite{arg} 10123 10124@tab 10125 10126Push an int const. 10127 10128@tab 10129 10130@code{[...]} 10131 10132@tab 10133 10134@code{[..., arg]} 10135 10136@item 10137 10138JUMP_ABS_IF_TRUE @cite{arg} 10139 10140@tab 10141 10142Pop; if top of stack was 10143nonzero, jump to 10144@code{arg}. 10145 10146@tab 10147 10148@code{[..., x]} 10149 10150@tab 10151 10152@code{[...]} 10153 10154@end multitable 10155 10156 10157Programs can be interpreted, disassembled, and compiled to machine code. 10158 10159The interpreter reads @code{.toy} scripts. Here's what a simple recursive 10160factorial program looks like, the script @code{factorial.toy}. 10161The parser ignores lines beginning with a @cite{#}. 10162 10163@quotation 10164 10165@example 10166# Simple recursive factorial implementation, roughly equivalent to: 10167# 10168# int factorial (int arg) 10169# @{ 10170# if (arg < 2) 10171# return arg 10172# return arg * factorial (arg - 1) 10173# @} 10174 10175# Initial state: 10176# stack: [arg] 10177 10178# 0: 10179DUP 10180# stack: [arg, arg] 10181 10182# 1: 10183PUSH_CONST 2 10184# stack: [arg, arg, 2] 10185 10186# 2: 10187BINARY_COMPARE_LT 10188# stack: [arg, (arg < 2)] 10189 10190# 3: 10191JUMP_ABS_IF_TRUE 9 10192# stack: [arg] 10193 10194# 4: 10195DUP 10196# stack: [arg, arg] 10197 10198# 5: 10199PUSH_CONST 1 10200# stack: [arg, arg, 1] 10201 10202# 6: 10203BINARY_SUBTRACT 10204# stack: [arg, (arg - 1) 10205 10206# 7: 10207RECURSE 10208# stack: [arg, factorial(arg - 1)] 10209 10210# 8: 10211BINARY_MULT 10212# stack: [arg * factorial(arg - 1)] 10213 10214# 9: 10215RETURN 10216 10217@end example 10218 10219@noindent 10220@end quotation 10221 10222The interpreter is a simple infinite loop with a big @code{switch} statement 10223based on what the next opcode is: 10224 10225@quotation 10226 10227@example 10228 10229int 10230toyvm_function::interpret (int arg, FILE *trace) 10231@{ 10232 toyvm_frame frame; 10233#define PUSH(ARG) (frame.push (ARG)) 10234#define POP(ARG) (frame.pop ()) 10235 10236 frame.frm_function = this; 10237 frame.frm_pc = 0; 10238 frame.frm_cur_depth = 0; 10239 10240 PUSH (arg); 10241 10242 while (1) 10243 @{ 10244 toyvm_op *op; 10245 int x, y; 10246 assert (frame.frm_pc < fn_num_ops); 10247 op = &fn_ops[frame.frm_pc++]; 10248 10249 if (trace) 10250 @{ 10251 frame.dump_stack (trace); 10252 disassemble_op (op, frame.frm_pc, trace); 10253 @} 10254 10255 switch (op->op_opcode) 10256 @{ 10257 /* Ops taking no operand. */ 10258 case DUP: 10259 x = POP (); 10260 PUSH (x); 10261 PUSH (x); 10262 break; 10263 10264 case ROT: 10265 y = POP (); 10266 x = POP (); 10267 PUSH (y); 10268 PUSH (x); 10269 break; 10270 10271 case BINARY_ADD: 10272 y = POP (); 10273 x = POP (); 10274 PUSH (x + y); 10275 break; 10276 10277 case BINARY_SUBTRACT: 10278 y = POP (); 10279 x = POP (); 10280 PUSH (x - y); 10281 break; 10282 10283 case BINARY_MULT: 10284 y = POP (); 10285 x = POP (); 10286 PUSH (x * y); 10287 break; 10288 10289 case BINARY_COMPARE_LT: 10290 y = POP (); 10291 x = POP (); 10292 PUSH (x < y); 10293 break; 10294 10295 case RECURSE: 10296 x = POP (); 10297 x = interpret (x, trace); 10298 PUSH (x); 10299 break; 10300 10301 case RETURN: 10302 return POP (); 10303 10304 /* Ops taking an operand. */ 10305 case PUSH_CONST: 10306 PUSH (op->op_operand); 10307 break; 10308 10309 case JUMP_ABS_IF_TRUE: 10310 x = POP (); 10311 if (x) 10312 frame.frm_pc = op->op_operand; 10313 break; 10314 10315 default: 10316 assert (0); /* unknown opcode */ 10317 10318 @} /* end of switch on opcode */ 10319 @} /* end of while loop */ 10320 10321#undef PUSH 10322#undef POP 10323@} 10324 10325 10326@end example 10327 10328@noindent 10329@end quotation 10330 10331@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> 10332@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{112} 10333@subsubsection Compiling to machine code 10334 10335 10336We want to generate machine code that can be cast to this type and 10337then directly executed in-process: 10338 10339@quotation 10340 10341@example 10342typedef int (*toyvm_compiled_func) (int); 10343 10344 10345@end example 10346 10347@noindent 10348@end quotation 10349 10350Our compiler isn't very sophisticated; it takes the implementation of 10351each opcode above, and maps it directly to the operations supported by 10352the libgccjit API. 10353 10354How should we handle the stack? In theory we could calculate what the 10355stack depth will be at each opcode, and optimize away the stack 10356manipulation "by hand". We'll see below that libgccjit is able to do 10357this for us, so we'll implement stack manipulation 10358in a direct way, by creating a @code{stack} array and @code{stack_depth} 10359variables, local within the generated function, equivalent to this C code: 10360 10361@example 10362int stack_depth; 10363int stack[MAX_STACK_DEPTH]; 10364@end example 10365 10366@noindent 10367 10368We'll also have local variables @code{x} and @code{y} for use when implementing 10369the opcodes, equivalent to this: 10370 10371@example 10372int x; 10373int y; 10374@end example 10375 10376@noindent 10377 10378This means our compiler has the following state: 10379 10380@quotation 10381 10382@example 10383 10384 toyvm_function &toyvmfn; 10385 10386 gccjit::context ctxt; 10387 10388 gccjit::type int_type; 10389 gccjit::type bool_type; 10390 gccjit::type stack_type; /* int[MAX_STACK_DEPTH] */ 10391 10392 gccjit::rvalue const_one; 10393 10394 gccjit::function fn; 10395 gccjit::param param_arg; 10396 gccjit::lvalue stack; 10397 gccjit::lvalue stack_depth; 10398 gccjit::lvalue x; 10399 gccjit::lvalue y; 10400 10401 gccjit::location op_locs[MAX_OPS]; 10402 gccjit::block initial_block; 10403 gccjit::block op_blocks[MAX_OPS]; 10404 10405 10406@end example 10407 10408@noindent 10409@end quotation 10410 10411@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> 10412@anchor{cp/intro/tutorial04 setting-things-up}@anchor{113} 10413@subsubsection Setting things up 10414 10415 10416First we create our types: 10417 10418@quotation 10419 10420@example 10421 10422void 10423compilation_state::create_types () 10424@{ 10425 /* Create types. */ 10426 int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 10427 bool_type = ctxt.get_type (GCC_JIT_TYPE_BOOL); 10428 stack_type = ctxt.new_array_type (int_type, MAX_STACK_DEPTH); 10429 10430 10431@end example 10432 10433@noindent 10434@end quotation 10435 10436along with extracting a useful @cite{int} constant: 10437 10438@quotation 10439 10440@example 10441 const_one = ctxt.one (int_type); 10442 10443@} 10444 10445 10446@end example 10447 10448@noindent 10449@end quotation 10450 10451We'll implement push and pop in terms of the @code{stack} array and 10452@code{stack_depth}. Here are helper functions for adding statements to 10453a block, implementing pushing and popping values: 10454 10455@quotation 10456 10457@example 10458 10459void 10460compilation_state::add_push (gccjit::block block, 10461 gccjit::rvalue rvalue, 10462 gccjit::location loc) 10463@{ 10464 /* stack[stack_depth] = RVALUE */ 10465 block.add_assignment ( 10466 /* stack[stack_depth] */ 10467 ctxt.new_array_access ( 10468 stack, 10469 stack_depth, 10470 loc), 10471 rvalue, 10472 loc); 10473 10474 /* "stack_depth++;". */ 10475 block.add_assignment_op ( 10476 stack_depth, 10477 GCC_JIT_BINARY_OP_PLUS, 10478 const_one, 10479 loc); 10480@} 10481 10482void 10483compilation_state::add_pop (gccjit::block block, 10484 gccjit::lvalue lvalue, 10485 gccjit::location loc) 10486@{ 10487 /* "--stack_depth;". */ 10488 block.add_assignment_op ( 10489 stack_depth, 10490 GCC_JIT_BINARY_OP_MINUS, 10491 const_one, 10492 loc); 10493 10494 /* "LVALUE = stack[stack_depth];". */ 10495 block.add_assignment ( 10496 lvalue, 10497 /* stack[stack_depth] */ 10498 ctxt.new_array_access (stack, 10499 stack_depth, 10500 loc), 10501 loc); 10502@} 10503 10504 10505@end example 10506 10507@noindent 10508@end quotation 10509 10510We will support single-stepping through the generated code in the 10511debugger, so we need to create @code{gccjit::location} instances, one 10512per operation in the source code. These will reference the lines of 10513e.g. @code{factorial.toy}. 10514 10515@quotation 10516 10517@example 10518 10519void 10520compilation_state::create_locations () 10521@{ 10522 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 10523 @{ 10524 toyvm_op *op = &toyvmfn.fn_ops[pc]; 10525 10526 op_locs[pc] = ctxt.new_location (toyvmfn.fn_filename, 10527 op->op_linenum, 10528 0); /* column */ 10529 @} 10530@} 10531 10532 10533@end example 10534 10535@noindent 10536@end quotation 10537 10538Let's create the function itself. As usual, we create its parameter 10539first, then use the parameter to create the function: 10540 10541@quotation 10542 10543@example 10544 10545void 10546compilation_state::create_function (const char *funcname) 10547@{ 10548 std::vector <gccjit::param> params; 10549 param_arg = ctxt.new_param (int_type, "arg", op_locs[0]); 10550 params.push_back (param_arg); 10551 fn = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10552 int_type, 10553 funcname, 10554 params, 0, 10555 op_locs[0]); 10556 10557 10558@end example 10559 10560@noindent 10561@end quotation 10562 10563We create the locals within the function. 10564 10565@quotation 10566 10567@example 10568 stack = fn.new_local (stack_type, "stack"); 10569 stack_depth = fn.new_local (int_type, "stack_depth"); 10570 x = fn.new_local (int_type, "x"); 10571 y = fn.new_local (int_type, "y"); 10572 10573 10574@end example 10575 10576@noindent 10577@end quotation 10578 10579@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> 10580@anchor{cp/intro/tutorial04 populating-the-function}@anchor{114} 10581@subsubsection Populating the function 10582 10583 10584There's some one-time initialization, and the API treats the first block 10585you create as the entrypoint of the function, so we need to create that 10586block first: 10587 10588@quotation 10589 10590@example 10591 initial_block = fn.new_block ("initial"); 10592 10593 10594@end example 10595 10596@noindent 10597@end quotation 10598 10599We can now create blocks for each of the operations. Most of these will 10600be consolidated into larger blocks when the optimizer runs. 10601 10602@quotation 10603 10604@example 10605 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 10606 @{ 10607 char buf[16]; 10608 sprintf (buf, "instr%i", pc); 10609 op_blocks[pc] = fn.new_block (buf); 10610 @} 10611 10612 10613@end example 10614 10615@noindent 10616@end quotation 10617 10618Now that we have a block it can jump to when it's done, we can populate 10619the initial block: 10620 10621@quotation 10622 10623@example 10624 10625 /* "stack_depth = 0;". */ 10626 initial_block.add_assignment (stack_depth, 10627 ctxt.zero (int_type), 10628 op_locs[0]); 10629 10630 /* "PUSH (arg);". */ 10631 add_push (initial_block, 10632 param_arg, 10633 op_locs[0]); 10634 10635 /* ...and jump to insn 0. */ 10636 initial_block.end_with_jump (op_blocks[0], 10637 op_locs[0]); 10638 10639 10640@end example 10641 10642@noindent 10643@end quotation 10644 10645We can now populate the blocks for the individual operations. We loop 10646through them, adding instructions to their blocks: 10647 10648@quotation 10649 10650@example 10651 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 10652 @{ 10653 gccjit::location loc = op_locs[pc]; 10654 10655 gccjit::block block = op_blocks[pc]; 10656 gccjit::block next_block = (pc < toyvmfn.fn_num_ops 10657 ? op_blocks[pc + 1] 10658 : NULL); 10659 10660 toyvm_op *op; 10661 op = &toyvmfn.fn_ops[pc]; 10662 10663 10664@end example 10665 10666@noindent 10667@end quotation 10668 10669We're going to have another big @code{switch} statement for implementing 10670the opcodes, this time for compiling them, rather than interpreting 10671them. It's helpful to have macros for implementing push and pop, so that 10672we can make the @code{switch} statement that's coming up look as much as 10673possible like the one above within the interpreter: 10674 10675@example 10676 10677#define X_EQUALS_POP()\ 10678 add_pop (block, x, loc) 10679#define Y_EQUALS_POP()\ 10680 add_pop (block, y, loc) 10681#define PUSH_RVALUE(RVALUE)\ 10682 add_push (block, (RVALUE), loc) 10683#define PUSH_X()\ 10684 PUSH_RVALUE (x) 10685#define PUSH_Y() \ 10686 PUSH_RVALUE (y) 10687 10688 10689@end example 10690 10691@noindent 10692 10693@cartouche 10694@quotation Note 10695A particularly clever implementation would have an @emph{identical} 10696@code{switch} statement shared by the interpreter and the compiler, with 10697some preprocessor "magic". We're not doing that here, for the sake 10698of simplicity. 10699@end quotation 10700@end cartouche 10701 10702When I first implemented this compiler, I accidentally missed an edit 10703when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the 10704stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y} 10705uninitialized. 10706 10707To track this kind of thing down, we can use 10708@pxref{115,,gccjit;;block;;add_comment()} to add descriptive comments 10709to the internal representation. This is invaluable when looking through 10710the generated IR for, say @code{factorial}: 10711 10712@quotation 10713 10714@example 10715 10716 block.add_comment (opcode_names[op->op_opcode], loc); 10717 10718 10719@end example 10720 10721@noindent 10722@end quotation 10723 10724We can now write the big @code{switch} statement that implements the 10725individual opcodes, populating the relevant block with statements: 10726 10727@quotation 10728 10729@example 10730 10731 switch (op->op_opcode) 10732 @{ 10733 case DUP: 10734 X_EQUALS_POP (); 10735 PUSH_X (); 10736 PUSH_X (); 10737 break; 10738 10739 case ROT: 10740 Y_EQUALS_POP (); 10741 X_EQUALS_POP (); 10742 PUSH_Y (); 10743 PUSH_X (); 10744 break; 10745 10746 case BINARY_ADD: 10747 Y_EQUALS_POP (); 10748 X_EQUALS_POP (); 10749 PUSH_RVALUE ( 10750 ctxt.new_binary_op ( 10751 GCC_JIT_BINARY_OP_PLUS, 10752 int_type, 10753 x, y, 10754 loc)); 10755 break; 10756 10757 case BINARY_SUBTRACT: 10758 Y_EQUALS_POP (); 10759 X_EQUALS_POP (); 10760 PUSH_RVALUE ( 10761 ctxt.new_binary_op ( 10762 GCC_JIT_BINARY_OP_MINUS, 10763 int_type, 10764 x, y, 10765 loc)); 10766 break; 10767 10768 case BINARY_MULT: 10769 Y_EQUALS_POP (); 10770 X_EQUALS_POP (); 10771 PUSH_RVALUE ( 10772 ctxt.new_binary_op ( 10773 GCC_JIT_BINARY_OP_MULT, 10774 int_type, 10775 x, y, 10776 loc)); 10777 break; 10778 10779 case BINARY_COMPARE_LT: 10780 Y_EQUALS_POP (); 10781 X_EQUALS_POP (); 10782 PUSH_RVALUE ( 10783 /* cast of bool to int */ 10784 ctxt.new_cast ( 10785 /* (x < y) as a bool */ 10786 ctxt.new_comparison ( 10787 GCC_JIT_COMPARISON_LT, 10788 x, y, 10789 loc), 10790 int_type, 10791 loc)); 10792 break; 10793 10794 case RECURSE: 10795 @{ 10796 X_EQUALS_POP (); 10797 PUSH_RVALUE ( 10798 ctxt.new_call ( 10799 fn, 10800 x, 10801 loc)); 10802 break; 10803 @} 10804 10805 case RETURN: 10806 X_EQUALS_POP (); 10807 block.end_with_return (x, loc); 10808 break; 10809 10810 /* Ops taking an operand. */ 10811 case PUSH_CONST: 10812 PUSH_RVALUE ( 10813 ctxt.new_rvalue (int_type, op->op_operand)); 10814 break; 10815 10816 case JUMP_ABS_IF_TRUE: 10817 X_EQUALS_POP (); 10818 block.end_with_conditional ( 10819 /* "(bool)x". */ 10820 ctxt.new_cast (x, bool_type, loc), 10821 op_blocks[op->op_operand], /* on_true */ 10822 next_block, /* on_false */ 10823 loc); 10824 break; 10825 10826 default: 10827 assert(0); 10828 @} /* end of switch on opcode */ 10829 10830 10831@end example 10832 10833@noindent 10834@end quotation 10835 10836Every block must be terminated, via a call to one of the 10837@code{gccjit::block::end_with_} entrypoints. This has been done for two 10838of the opcodes, but we need to do it for the other ones, by jumping 10839to the next block. 10840 10841@quotation 10842 10843@example 10844 if (op->op_opcode != JUMP_ABS_IF_TRUE 10845 && op->op_opcode != RETURN) 10846 block.end_with_jump (next_block, loc); 10847 10848 10849@end example 10850 10851@noindent 10852@end quotation 10853 10854This is analogous to simply incrementing the program counter. 10855 10856@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> 10857@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{116} 10858@subsubsection Verifying the control flow graph 10859 10860 10861Having finished looping over the blocks, the context is complete. 10862 10863As before, we can verify that the control flow and statements are sane by 10864using @pxref{10d,,gccjit;;function;;dump_to_dot()}: 10865 10866@example 10867fn.dump_to_dot ("/tmp/factorial.dot"); 10868@end example 10869 10870@noindent 10871 10872and viewing the result. Note how the label names, comments, and 10873variable names show up in the dump, to make it easier to spot 10874errors in our compiler. 10875 10876@quotation 10877 10878 10879@float Figure 10880 10881@image{factorial,,,image of a control flow graph,png} 10882 10883@end float 10884 10885@end quotation 10886 10887@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> 10888@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{117} 10889@subsubsection Compiling the context 10890 10891 10892Having finished looping over the blocks and populating them with 10893statements, the context is complete. 10894 10895We can now compile it, and extract machine code from the result: 10896 10897@quotation 10898 10899@example 10900 gcc_jit_result *result = state.compile (); 10901 10902 return (toyvm_compiled_func)gcc_jit_result_get_code (result, funcname); 10903 10904@end example 10905 10906@noindent 10907@end quotation 10908 10909We can now run the result: 10910 10911@quotation 10912 10913@example 10914 toyvm_compiled_func code = fn->compile (); 10915 printf ("compiler result: %d\n", 10916 code (atoi (argv[2]))); 10917 10918 10919@end example 10920 10921@noindent 10922@end quotation 10923 10924@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> 10925@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{118} 10926@subsubsection Single-stepping through the generated code 10927 10928 10929It's possible to debug the generated code. To do this we need to both: 10930 10931@quotation 10932 10933 10934@itemize * 10935 10936@item 10937Set up source code locations for our statements, so that we can 10938meaningfully step through the code. We did this above by 10939calling @pxref{119,,gccjit;;context;;new_location()} and using the 10940results. 10941 10942@item 10943Enable the generation of debugging information, by setting 10944@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 10945@code{gccjit::context} via 10946@pxref{fe,,gccjit;;context;;set_bool_option()}: 10947 10948@example 10949ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1); 10950@end example 10951 10952@noindent 10953@end itemize 10954@end quotation 10955 10956Having done this, we can put a breakpoint on the generated function: 10957 10958@example 10959$ gdb --args ./toyvm factorial.toy 10 10960(gdb) break factorial 10961Function "factorial" not defined. 10962Make breakpoint pending on future shared library load? (y or [n]) y 10963Breakpoint 1 (factorial) pending. 10964(gdb) run 10965Breakpoint 1, factorial (arg=10) at factorial.toy:14 1096614 DUP 10967@end example 10968 10969@noindent 10970 10971We've set up location information, which references @code{factorial.toy}. 10972This allows us to use e.g. @code{list} to see where we are in the script: 10973 10974@example 10975(gdb) list 109769 1097710 # Initial state: 1097811 # stack: [arg] 1097912 1098013 # 0: 1098114 DUP 1098215 # stack: [arg, arg] 1098316 1098417 # 1: 1098518 PUSH_CONST 2 10986@end example 10987 10988@noindent 10989 10990and to step through the function, examining the data: 10991 10992@example 10993(gdb) n 1099418 PUSH_CONST 2 10995(gdb) n 1099622 BINARY_COMPARE_LT 10997(gdb) print stack 10998$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@} 10999(gdb) print stack_depth 11000$6 = 3 11001@end example 11002 11003@noindent 11004 11005You'll see that the parts of the @code{stack} array that haven't been 11006touched yet are uninitialized. 11007 11008@cartouche 11009@quotation Note 11010Turning on optimizations may lead to unpredictable results when 11011stepping through the generated code: the execution may appear to 11012"jump around" the source code. This is analogous to turning up the 11013optimization level in a regular compiler. 11014@end quotation 11015@end cartouche 11016 11017@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> 11018@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{11a} 11019@subsubsection Examining the generated code 11020 11021 11022How good is the optimized code? 11023 11024We can turn up optimizations, by calling 11025@pxref{ff,,gccjit;;context;;set_int_option()} with 11026@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 11027 11028@example 11029ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); 11030@end example 11031 11032@noindent 11033 11034One of GCC's internal representations is called "gimple". A dump of the 11035initial gimple representation of the code can be seen by setting: 11036 11037@example 11038ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); 11039@end example 11040 11041@noindent 11042 11043With optimization on and source locations displayed, this gives: 11044 11045@c We'll use "c" for gimple dumps 11046 11047@example 11048factorial (signed int arg) 11049@{ 11050 <unnamed type> D.80; 11051 signed int D.81; 11052 signed int D.82; 11053 signed int D.83; 11054 signed int D.84; 11055 signed int D.85; 11056 signed int y; 11057 signed int x; 11058 signed int stack_depth; 11059 signed int stack[8]; 11060 11061 try 11062 @{ 11063 initial: 11064 stack_depth = 0; 11065 stack[stack_depth] = arg; 11066 stack_depth = stack_depth + 1; 11067 goto instr0; 11068 instr0: 11069 /* DUP */: 11070 stack_depth = stack_depth + -1; 11071 x = stack[stack_depth]; 11072 stack[stack_depth] = x; 11073 stack_depth = stack_depth + 1; 11074 stack[stack_depth] = x; 11075 stack_depth = stack_depth + 1; 11076 goto instr1; 11077 instr1: 11078 /* PUSH_CONST */: 11079 stack[stack_depth] = 2; 11080 stack_depth = stack_depth + 1; 11081 goto instr2; 11082 11083 /* etc */ 11084@end example 11085 11086@noindent 11087 11088You can see the generated machine code in assembly form via: 11089 11090@example 11091ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); 11092result = ctxt.compile (); 11093@end example 11094 11095@noindent 11096 11097which shows that (on this x86_64 box) the compiler has unrolled the loop 11098and is using MMX instructions to perform several multiplications 11099simultaneously: 11100 11101@example 11102 .file "fake.c" 11103 .text 11104.Ltext0: 11105 .p2align 4,,15 11106 .globl factorial 11107 .type factorial, @@function 11108factorial: 11109.LFB0: 11110 .file 1 "factorial.toy" 11111 .loc 1 14 0 11112 .cfi_startproc 11113.LVL0: 11114.L2: 11115 .loc 1 26 0 11116 cmpl $1, %edi 11117 jle .L13 11118 leal -1(%rdi), %edx 11119 movl %edx, %ecx 11120 shrl $2, %ecx 11121 leal 0(,%rcx,4), %esi 11122 testl %esi, %esi 11123 je .L14 11124 cmpl $9, %edx 11125 jbe .L14 11126 leal -2(%rdi), %eax 11127 movl %eax, -16(%rsp) 11128 leal -3(%rdi), %eax 11129 movd -16(%rsp), %xmm0 11130 movl %edi, -16(%rsp) 11131 movl %eax, -12(%rsp) 11132 movd -16(%rsp), %xmm1 11133 xorl %eax, %eax 11134 movl %edx, -16(%rsp) 11135 movd -12(%rsp), %xmm4 11136 movd -16(%rsp), %xmm6 11137 punpckldq %xmm4, %xmm0 11138 movdqa .LC1(%rip), %xmm4 11139 punpckldq %xmm6, %xmm1 11140 punpcklqdq %xmm0, %xmm1 11141 movdqa .LC0(%rip), %xmm0 11142 jmp .L5 11143 # etc - edited for brevity 11144@end example 11145 11146@noindent 11147 11148This is clearly overkill for a function that will likely overflow the 11149@code{int} type before the vectorization is worthwhile - but then again, this 11150is a toy example. 11151 11152Turning down the optimization level to 2: 11153 11154@example 11155ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2); 11156@end example 11157 11158@noindent 11159 11160yields this code, which is simple enough to quote in its entirety: 11161 11162@example 11163 .file "fake.c" 11164 .text 11165 .p2align 4,,15 11166 .globl factorial 11167 .type factorial, @@function 11168factorial: 11169.LFB0: 11170 .cfi_startproc 11171.L2: 11172 cmpl $1, %edi 11173 jle .L8 11174 movl $1, %edx 11175 jmp .L4 11176 .p2align 4,,10 11177 .p2align 3 11178.L6: 11179 movl %eax, %edi 11180.L4: 11181.L5: 11182 leal -1(%rdi), %eax 11183 imull %edi, %edx 11184 cmpl $1, %eax 11185 jne .L6 11186.L3: 11187.L7: 11188 imull %edx, %eax 11189 ret 11190.L8: 11191 movl %edi, %eax 11192 movl $1, %edx 11193 jmp .L7 11194 .cfi_endproc 11195.LFE0: 11196 .size factorial, .-factorial 11197 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})" 11198 .section .note.GNU-stack,"",@@progbits 11199@end example 11200 11201@noindent 11202 11203Note that the stack pushing and popping have been eliminated, as has the 11204recursive call (in favor of an iteration). 11205 11206@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> 11207@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{11b} 11208@subsubsection Putting it all together 11209 11210 11211The complete example can be seen in the source tree at 11212@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.cc} 11213 11214along with a Makefile and a couple of sample .toy scripts: 11215 11216@example 11217$ ls -al 11218drwxrwxr-x. 2 david david 4096 Sep 19 17:46 . 11219drwxrwxr-x. 3 david david 4096 Sep 19 15:26 .. 11220-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy 11221-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy 11222-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile 11223-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.cc 11224 11225$ make toyvm 11226g++ -Wall -g -o toyvm toyvm.cc -lgccjit 11227 11228$ ./toyvm factorial.toy 10 11229interpreter result: 3628800 11230compiler result: 3628800 11231 11232$ ./toyvm fibonacci.toy 10 11233interpreter result: 55 11234compiler result: 55 11235@end example 11236 11237@noindent 11238 11239@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> 11240@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{11c} 11241@subsubsection Behind the curtain: How does our code get optimized? 11242 11243 11244Our example is done, but you may be wondering about exactly how the 11245compiler turned what we gave it into the machine code seen above. 11246 11247We can examine what the compiler is doing in detail by setting: 11248 11249@example 11250state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 1); 11251state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 1); 11252@end example 11253 11254@noindent 11255 11256This will dump detailed information about the compiler's state to a 11257directory under @code{/tmp}, and keep it from being cleaned up. 11258 11259The precise names and their formats of these files is subject to change. 11260Higher optimization levels lead to more files. 11261Here's what I saw (edited for brevity; there were almost 200 files): 11262 11263@example 11264intermediate files written to /tmp/libgccjit-KPQbGw 11265$ ls /tmp/libgccjit-KPQbGw/ 11266fake.c.000i.cgraph 11267fake.c.000i.type-inheritance 11268fake.c.004t.gimple 11269fake.c.007t.omplower 11270fake.c.008t.lower 11271fake.c.011t.eh 11272fake.c.012t.cfg 11273fake.c.014i.visibility 11274fake.c.015i.early_local_cleanups 11275fake.c.016t.ssa 11276# etc 11277@end example 11278 11279@noindent 11280 11281The gimple code is converted into Static Single Assignment form, 11282with annotations for use when generating the debuginfo: 11283 11284@example 11285$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa 11286@end example 11287 11288@noindent 11289 11290@example 11291;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11292 11293factorial (signed int arg) 11294@{ 11295 signed int stack[8]; 11296 signed int stack_depth; 11297 signed int x; 11298 signed int y; 11299 <unnamed type> _20; 11300 signed int _21; 11301 signed int _38; 11302 signed int _44; 11303 signed int _51; 11304 signed int _56; 11305 11306initial: 11307 stack_depth_3 = 0; 11308 # DEBUG stack_depth => stack_depth_3 11309 stack[stack_depth_3] = arg_5(D); 11310 stack_depth_7 = stack_depth_3 + 1; 11311 # DEBUG stack_depth => stack_depth_7 11312 # DEBUG instr0 => NULL 11313 # DEBUG /* DUP */ => NULL 11314 stack_depth_8 = stack_depth_7 + -1; 11315 # DEBUG stack_depth => stack_depth_8 11316 x_9 = stack[stack_depth_8]; 11317 # DEBUG x => x_9 11318 stack[stack_depth_8] = x_9; 11319 stack_depth_11 = stack_depth_8 + 1; 11320 # DEBUG stack_depth => stack_depth_11 11321 stack[stack_depth_11] = x_9; 11322 stack_depth_13 = stack_depth_11 + 1; 11323 # DEBUG stack_depth => stack_depth_13 11324 # DEBUG instr1 => NULL 11325 # DEBUG /* PUSH_CONST */ => NULL 11326 stack[stack_depth_13] = 2; 11327 11328 /* etc; edited for brevity */ 11329@end example 11330 11331@noindent 11332 11333We can perhaps better see the code by turning off 11334@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG} 11335statements, giving: 11336 11337@example 11338$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa 11339@end example 11340 11341@noindent 11342 11343@example 11344;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11345 11346factorial (signed int arg) 11347@{ 11348 signed int stack[8]; 11349 signed int stack_depth; 11350 signed int x; 11351 signed int y; 11352 <unnamed type> _20; 11353 signed int _21; 11354 signed int _38; 11355 signed int _44; 11356 signed int _51; 11357 signed int _56; 11358 11359initial: 11360 stack_depth_3 = 0; 11361 stack[stack_depth_3] = arg_5(D); 11362 stack_depth_7 = stack_depth_3 + 1; 11363 stack_depth_8 = stack_depth_7 + -1; 11364 x_9 = stack[stack_depth_8]; 11365 stack[stack_depth_8] = x_9; 11366 stack_depth_11 = stack_depth_8 + 1; 11367 stack[stack_depth_11] = x_9; 11368 stack_depth_13 = stack_depth_11 + 1; 11369 stack[stack_depth_13] = 2; 11370 stack_depth_15 = stack_depth_13 + 1; 11371 stack_depth_16 = stack_depth_15 + -1; 11372 y_17 = stack[stack_depth_16]; 11373 stack_depth_18 = stack_depth_16 + -1; 11374 x_19 = stack[stack_depth_18]; 11375 _20 = x_19 < y_17; 11376 _21 = (signed int) _20; 11377 stack[stack_depth_18] = _21; 11378 stack_depth_23 = stack_depth_18 + 1; 11379 stack_depth_24 = stack_depth_23 + -1; 11380 x_25 = stack[stack_depth_24]; 11381 if (x_25 != 0) 11382 goto <bb 4> (instr9); 11383 else 11384 goto <bb 3> (instr4); 11385 11386instr4: 11387/* DUP */: 11388 stack_depth_26 = stack_depth_24 + -1; 11389 x_27 = stack[stack_depth_26]; 11390 stack[stack_depth_26] = x_27; 11391 stack_depth_29 = stack_depth_26 + 1; 11392 stack[stack_depth_29] = x_27; 11393 stack_depth_31 = stack_depth_29 + 1; 11394 stack[stack_depth_31] = 1; 11395 stack_depth_33 = stack_depth_31 + 1; 11396 stack_depth_34 = stack_depth_33 + -1; 11397 y_35 = stack[stack_depth_34]; 11398 stack_depth_36 = stack_depth_34 + -1; 11399 x_37 = stack[stack_depth_36]; 11400 _38 = x_37 - y_35; 11401 stack[stack_depth_36] = _38; 11402 stack_depth_40 = stack_depth_36 + 1; 11403 stack_depth_41 = stack_depth_40 + -1; 11404 x_42 = stack[stack_depth_41]; 11405 _44 = factorial (x_42); 11406 stack[stack_depth_41] = _44; 11407 stack_depth_46 = stack_depth_41 + 1; 11408 stack_depth_47 = stack_depth_46 + -1; 11409 y_48 = stack[stack_depth_47]; 11410 stack_depth_49 = stack_depth_47 + -1; 11411 x_50 = stack[stack_depth_49]; 11412 _51 = x_50 * y_48; 11413 stack[stack_depth_49] = _51; 11414 stack_depth_53 = stack_depth_49 + 1; 11415 11416 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)> 11417instr9: 11418/* RETURN */: 11419 stack_depth_54 = stack_depth_1 + -1; 11420 x_55 = stack[stack_depth_54]; 11421 _56 = x_55; 11422 stack =@{v@} @{CLOBBER@}; 11423 return _56; 11424 11425@} 11426@end example 11427 11428@noindent 11429 11430Note in the above how all the @code{gccjit::block} instances we 11431created have been consolidated into just 3 blocks in GCC's internal 11432representation: @code{initial}, @code{instr4} and @code{instr9}. 11433 11434@menu 11435* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 11436* Elimination of tail recursion: Elimination of tail recursion<2>. 11437 11438@end menu 11439 11440@node Optimizing away stack manipulation<2>,Elimination of tail recursion<2>,,Behind the curtain How does our code get optimized?<2> 11441@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{11d} 11442@subsubsection Optimizing away stack manipulation 11443 11444 11445Recall our simple implementation of stack operations. Let's examine 11446how the stack operations are optimized away. 11447 11448After a pass of constant-propagation, the depth of the stack at each 11449opcode can be determined at compile-time: 11450 11451@example 11452$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1 11453@end example 11454 11455@noindent 11456 11457@example 11458;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11459 11460factorial (signed int arg) 11461@{ 11462 signed int stack[8]; 11463 signed int stack_depth; 11464 signed int x; 11465 signed int y; 11466 <unnamed type> _20; 11467 signed int _21; 11468 signed int _38; 11469 signed int _44; 11470 signed int _51; 11471 11472initial: 11473 stack[0] = arg_5(D); 11474 x_9 = stack[0]; 11475 stack[0] = x_9; 11476 stack[1] = x_9; 11477 stack[2] = 2; 11478 y_17 = stack[2]; 11479 x_19 = stack[1]; 11480 _20 = x_19 < y_17; 11481 _21 = (signed int) _20; 11482 stack[1] = _21; 11483 x_25 = stack[1]; 11484 if (x_25 != 0) 11485 goto <bb 4> (instr9); 11486 else 11487 goto <bb 3> (instr4); 11488 11489instr4: 11490/* DUP */: 11491 x_27 = stack[0]; 11492 stack[0] = x_27; 11493 stack[1] = x_27; 11494 stack[2] = 1; 11495 y_35 = stack[2]; 11496 x_37 = stack[1]; 11497 _38 = x_37 - y_35; 11498 stack[1] = _38; 11499 x_42 = stack[1]; 11500 _44 = factorial (x_42); 11501 stack[1] = _44; 11502 y_48 = stack[1]; 11503 x_50 = stack[0]; 11504 _51 = x_50 * y_48; 11505 stack[0] = _51; 11506 11507instr9: 11508/* RETURN */: 11509 x_55 = stack[0]; 11510 x_56 = x_55; 11511 stack =@{v@} @{CLOBBER@}; 11512 return x_56; 11513 11514@} 11515@end example 11516 11517@noindent 11518 11519Note how, in the above, all those @code{stack_depth} values are now just 11520constants: we're accessing specific stack locations at each opcode. 11521 11522The "esra" pass ("Early Scalar Replacement of Aggregates") breaks 11523out our "stack" array into individual elements: 11524 11525@example 11526$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra 11527@end example 11528 11529@noindent 11530 11531@example 11532;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11533 11534Created a replacement for stack offset: 0, size: 32: stack$0 11535Created a replacement for stack offset: 32, size: 32: stack$1 11536Created a replacement for stack offset: 64, size: 32: stack$2 11537 11538Symbols to be put in SSA form 11539@{ D.89 D.90 D.91 @} 11540Incremental SSA update started at block: 0 11541Number of blocks in CFG: 5 11542Number of blocks to update: 4 ( 80%) 11543 11544 11545factorial (signed int arg) 11546@{ 11547 signed int stack$2; 11548 signed int stack$1; 11549 signed int stack$0; 11550 signed int stack[8]; 11551 signed int stack_depth; 11552 signed int x; 11553 signed int y; 11554 <unnamed type> _20; 11555 signed int _21; 11556 signed int _38; 11557 signed int _44; 11558 signed int _51; 11559 11560initial: 11561 stack$0_45 = arg_5(D); 11562 x_9 = stack$0_45; 11563 stack$0_39 = x_9; 11564 stack$1_32 = x_9; 11565 stack$2_30 = 2; 11566 y_17 = stack$2_30; 11567 x_19 = stack$1_32; 11568 _20 = x_19 < y_17; 11569 _21 = (signed int) _20; 11570 stack$1_28 = _21; 11571 x_25 = stack$1_28; 11572 if (x_25 != 0) 11573 goto <bb 4> (instr9); 11574 else 11575 goto <bb 3> (instr4); 11576 11577instr4: 11578/* DUP */: 11579 x_27 = stack$0_39; 11580 stack$0_22 = x_27; 11581 stack$1_14 = x_27; 11582 stack$2_12 = 1; 11583 y_35 = stack$2_12; 11584 x_37 = stack$1_14; 11585 _38 = x_37 - y_35; 11586 stack$1_10 = _38; 11587 x_42 = stack$1_10; 11588 _44 = factorial (x_42); 11589 stack$1_6 = _44; 11590 y_48 = stack$1_6; 11591 x_50 = stack$0_22; 11592 _51 = x_50 * y_48; 11593 stack$0_1 = _51; 11594 11595 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)> 11596instr9: 11597/* RETURN */: 11598 x_55 = stack$0_52; 11599 x_56 = x_55; 11600 stack =@{v@} @{CLOBBER@}; 11601 return x_56; 11602 11603@} 11604@end example 11605 11606@noindent 11607 11608Hence at this point, all those pushes and pops of the stack are now 11609simply assignments to specific temporary variables. 11610 11611After some copy propagation, the stack manipulation has been completely 11612optimized away: 11613 11614@example 11615$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1 11616@end example 11617 11618@noindent 11619 11620@example 11621;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11622 11623factorial (signed int arg) 11624@{ 11625 signed int stack$2; 11626 signed int stack$1; 11627 signed int stack$0; 11628 signed int stack[8]; 11629 signed int stack_depth; 11630 signed int x; 11631 signed int y; 11632 <unnamed type> _20; 11633 signed int _21; 11634 signed int _38; 11635 signed int _44; 11636 signed int _51; 11637 11638initial: 11639 stack$0_39 = arg_5(D); 11640 _20 = arg_5(D) <= 1; 11641 _21 = (signed int) _20; 11642 if (_21 != 0) 11643 goto <bb 4> (instr9); 11644 else 11645 goto <bb 3> (instr4); 11646 11647instr4: 11648/* DUP */: 11649 _38 = arg_5(D) + -1; 11650 _44 = factorial (_38); 11651 _51 = arg_5(D) * _44; 11652 stack$0_1 = _51; 11653 11654 # stack$0_52 = PHI <arg_5(D)(2), _51(3)> 11655instr9: 11656/* RETURN */: 11657 stack =@{v@} @{CLOBBER@}; 11658 return stack$0_52; 11659 11660@} 11661@end example 11662 11663@noindent 11664 11665Later on, another pass finally eliminated @code{stack_depth} local and the 11666unused parts of the @cite{stack`} array altogether: 11667 11668@example 11669$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa 11670@end example 11671 11672@noindent 11673 11674@example 11675;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11676 11677Released 44 names, 314.29%, removed 44 holes 11678factorial (signed int arg) 11679@{ 11680 signed int stack$0; 11681 signed int mult_acc_1; 11682 <unnamed type> _5; 11683 signed int _6; 11684 signed int _7; 11685 signed int mul_tmp_10; 11686 signed int mult_acc_11; 11687 signed int mult_acc_13; 11688 11689 # arg_9 = PHI <arg_8(D)(0)> 11690 # mult_acc_13 = PHI <1(0)> 11691initial: 11692 11693 <bb 5>: 11694 # arg_4 = PHI <arg_9(2), _7(3)> 11695 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)> 11696 _5 = arg_4 <= 1; 11697 _6 = (signed int) _5; 11698 if (_6 != 0) 11699 goto <bb 4> (instr9); 11700 else 11701 goto <bb 3> (instr4); 11702 11703instr4: 11704/* DUP */: 11705 _7 = arg_4 + -1; 11706 mult_acc_11 = mult_acc_1 * arg_4; 11707 goto <bb 5>; 11708 11709 # stack$0_12 = PHI <arg_4(5)> 11710instr9: 11711/* RETURN */: 11712 mul_tmp_10 = mult_acc_1 * stack$0_12; 11713 return mul_tmp_10; 11714 11715@} 11716@end example 11717 11718@noindent 11719 11720@node Elimination of tail recursion<2>,,Optimizing away stack manipulation<2>,Behind the curtain How does our code get optimized?<2> 11721@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{11e} 11722@subsubsection Elimination of tail recursion 11723 11724 11725Another significant optimization is the detection that the call to 11726@code{factorial} is tail recursion, which can be eliminated in favor of 11727an iteration: 11728 11729@example 11730$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1 11731@end example 11732 11733@noindent 11734 11735@example 11736;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11737 11738 11739Symbols to be put in SSA form 11740@{ D.88 @} 11741Incremental SSA update started at block: 0 11742Number of blocks in CFG: 5 11743Number of blocks to update: 4 ( 80%) 11744 11745 11746factorial (signed int arg) 11747@{ 11748 signed int stack$2; 11749 signed int stack$1; 11750 signed int stack$0; 11751 signed int stack[8]; 11752 signed int stack_depth; 11753 signed int x; 11754 signed int y; 11755 signed int mult_acc_1; 11756 <unnamed type> _20; 11757 signed int _21; 11758 signed int _38; 11759 signed int mul_tmp_44; 11760 signed int mult_acc_51; 11761 11762 # arg_5 = PHI <arg_39(D)(0), _38(3)> 11763 # mult_acc_1 = PHI <1(0), mult_acc_51(3)> 11764initial: 11765 _20 = arg_5 <= 1; 11766 _21 = (signed int) _20; 11767 if (_21 != 0) 11768 goto <bb 4> (instr9); 11769 else 11770 goto <bb 3> (instr4); 11771 11772instr4: 11773/* DUP */: 11774 _38 = arg_5 + -1; 11775 mult_acc_51 = mult_acc_1 * arg_5; 11776 goto <bb 2> (initial); 11777 11778 # stack$0_52 = PHI <arg_5(2)> 11779instr9: 11780/* RETURN */: 11781 stack =@{v@} @{CLOBBER@}; 11782 mul_tmp_44 = mult_acc_1 * stack$0_52; 11783 return mul_tmp_44; 11784 11785@} 11786@end example 11787 11788@noindent 11789 11790@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 11791@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 11792@c 11793@c This is free software: you can redistribute it and/or modify it 11794@c under the terms of the GNU General Public License as published by 11795@c the Free Software Foundation, either version 3 of the License, or 11796@c (at your option) any later version. 11797@c 11798@c This program is distributed in the hope that it will be useful, but 11799@c WITHOUT ANY WARRANTY; without even the implied warranty of 11800@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11801@c General Public License for more details. 11802@c 11803@c You should have received a copy of the GNU General Public License 11804@c along with this program. If not, see 11805@c <http://www.gnu.org/licenses/>. 11806 11807@node Topic Reference<2>,,Tutorial<2>,C++ bindings for libgccjit 11808@anchor{cp/topics/index doc}@anchor{11f}@anchor{cp/topics/index topic-reference}@anchor{120} 11809@section Topic Reference 11810 11811 11812@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 11813@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 11814@c 11815@c This is free software: you can redistribute it and/or modify it 11816@c under the terms of the GNU General Public License as published by 11817@c the Free Software Foundation, either version 3 of the License, or 11818@c (at your option) any later version. 11819@c 11820@c This program is distributed in the hope that it will be useful, but 11821@c WITHOUT ANY WARRANTY; without even the implied warranty of 11822@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11823@c General Public License for more details. 11824@c 11825@c You should have received a copy of the GNU General Public License 11826@c along with this program. If not, see 11827@c <http://www.gnu.org/licenses/>. 11828 11829@menu 11830* Compilation contexts: Compilation contexts<2>. 11831* Objects: Objects<2>. 11832* Types: Types<2>. 11833* Expressions: Expressions<2>. 11834* Creating and using functions: Creating and using functions<2>. 11835* Source Locations: Source Locations<2>. 11836* Compiling a context: Compiling a context<2>. 11837 11838Compilation contexts 11839 11840* Lifetime-management: Lifetime-management<2>. 11841* Thread-safety: Thread-safety<2>. 11842* Error-handling: Error-handling<3>. 11843* Debugging: Debugging<2>. 11844* Options: Options<4>. 11845 11846Options 11847 11848* String Options: String Options<2>. 11849* Boolean options: Boolean options<2>. 11850* Integer options: Integer options<2>. 11851* Additional command-line options: Additional command-line options<2>. 11852 11853Types 11854 11855* Standard types: Standard types<2>. 11856* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 11857* Structures and unions: Structures and unions<2>. 11858 11859Expressions 11860 11861* Rvalues: Rvalues<2>. 11862* Lvalues: Lvalues<2>. 11863* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 11864 11865Rvalues 11866 11867* Simple expressions: Simple expressions<2>. 11868* Unary Operations: Unary Operations<2>. 11869* Binary Operations: Binary Operations<2>. 11870* Comparisons: Comparisons<2>. 11871* Function calls: Function calls<2>. 11872* Type-coercion: Type-coercion<2>. 11873 11874Lvalues 11875 11876* Global variables: Global variables<2>. 11877 11878Creating and using functions 11879 11880* Params: Params<2>. 11881* Functions: Functions<2>. 11882* Blocks: Blocks<2>. 11883* Statements: Statements<2>. 11884 11885Source Locations 11886 11887* Faking it: Faking it<2>. 11888 11889Compiling a context 11890 11891* In-memory compilation: In-memory compilation<2>. 11892* Ahead-of-time compilation: Ahead-of-time compilation<2>. 11893 11894@end menu 11895 11896 11897@node Compilation contexts<2>,Objects<2>,,Topic Reference<2> 11898@anchor{cp/topics/contexts compilation-contexts}@anchor{121}@anchor{cp/topics/contexts doc}@anchor{122} 11899@subsection Compilation contexts 11900 11901 11902@geindex gccjit;;context (C++ class) 11903@anchor{cp/topics/contexts gccjit context}@anchor{123} 11904@deffn {C++ Class} gccjit::context 11905@end deffn 11906 11907The top-level of the C++ API is the @pxref{123,,gccjit;;context} type. 11908 11909A @pxref{123,,gccjit;;context} instance encapsulates the state of a 11910compilation. 11911 11912You can set up options on it, and add types, functions and code. 11913Invoking @pxref{fc,,gccjit;;context;;compile()} on it gives you a 11914@pxref{16,,gcc_jit_result *}. 11915 11916It is a thin wrapper around the C API's @pxref{8,,gcc_jit_context *}. 11917 11918@menu 11919* Lifetime-management: Lifetime-management<2>. 11920* Thread-safety: Thread-safety<2>. 11921* Error-handling: Error-handling<3>. 11922* Debugging: Debugging<2>. 11923* Options: Options<4>. 11924 11925@end menu 11926 11927@node Lifetime-management<2>,Thread-safety<2>,,Compilation contexts<2> 11928@anchor{cp/topics/contexts lifetime-management}@anchor{124} 11929@subsubsection Lifetime-management 11930 11931 11932Contexts are the unit of lifetime-management within the API: objects 11933have their lifetime bounded by the context they are created within, and 11934cleanup of such objects is done for you when the context is released. 11935 11936@geindex gccjit;;context;;acquire (C++ function) 11937@anchor{cp/topics/contexts gccjit context acquire}@anchor{f6} 11938@deffn {C++ Function} gccjit::context gccjit::context::acquire () 11939 11940This function acquires a new @pxref{123,,gccjit;;context} instance, 11941which is independent of any others that may be present within this 11942process. 11943@end deffn 11944 11945@geindex gccjit;;context;;release (C++ function) 11946@anchor{cp/topics/contexts gccjit context release}@anchor{f8} 11947@deffn {C++ Function} void gccjit::context::release () 11948 11949This function releases all resources associated with the given context. 11950Both the context itself and all of its @code{gccjit::object *} 11951instances are cleaned up. It should be called exactly once on a given 11952context. 11953 11954It is invalid to use the context or any of its "contextual" objects 11955after calling this. 11956 11957@example 11958ctxt.release (); 11959@end example 11960 11961@noindent 11962@end deffn 11963 11964@geindex gccjit;;context;;new_child_context (C++ function) 11965@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{125} 11966@deffn {C++ Function} gccjit::context gccjit::context::new_child_context () 11967 11968Given an existing JIT context, create a child context. 11969 11970The child inherits a copy of all option-settings from the parent. 11971 11972The child can reference objects created within the parent, but not 11973vice-versa. 11974 11975The lifetime of the child context must be bounded by that of the 11976parent: you should release a child context before releasing the parent 11977context. 11978 11979If you use a function from a parent context within a child context, 11980you have to compile the parent context before you can compile the 11981child context, and the gccjit::result of the parent context must 11982outlive the gccjit::result of the child context. 11983 11984This allows caching of shared initializations. For example, you could 11985create types and declarations of global functions in a parent context 11986once within a process, and then create child contexts whenever a 11987function or loop becomes hot. Each such child context can be used for 11988JIT-compiling just one function or loop, but can reference types 11989and helper functions created within the parent context. 11990 11991Contexts can be arbitrarily nested, provided the above rules are 11992followed, but it's probably not worth going above 2 or 3 levels, and 11993there will likely be a performance hit for such nesting. 11994@end deffn 11995 11996@node Thread-safety<2>,Error-handling<3>,Lifetime-management<2>,Compilation contexts<2> 11997@anchor{cp/topics/contexts thread-safety}@anchor{126} 11998@subsubsection Thread-safety 11999 12000 12001Instances of @pxref{123,,gccjit;;context} created via 12002@pxref{f6,,gccjit;;context;;acquire()} are independent from each other: 12003only one thread may use a given context at once, but multiple threads 12004could each have their own contexts without needing locks. 12005 12006Contexts created via @pxref{125,,gccjit;;context;;new_child_context()} are 12007related to their parent context. They can be partitioned by their 12008ultimate ancestor into independent "family trees". Only one thread 12009within a process may use a given "family tree" of such contexts at once, 12010and if you're using multiple threads you should provide your own locking 12011around entire such context partitions. 12012 12013@node Error-handling<3>,Debugging<2>,Thread-safety<2>,Compilation contexts<2> 12014@anchor{cp/topics/contexts error-handling}@anchor{127} 12015@subsubsection Error-handling 12016 12017 12018@c FIXME: How does error-handling work for C++ API? 12019 12020You can only compile and get code from a context if no errors occur. 12021 12022In general, if an error occurs when using an API entrypoint, it returns 12023NULL. You don't have to check everywhere for NULL results, since the 12024API gracefully handles a NULL being passed in for any argument. 12025 12026Errors are printed on stderr and can be queried using 12027@pxref{128,,gccjit;;context;;get_first_error()}. 12028 12029@geindex gccjit;;context;;get_first_error (C++ function) 12030@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{128} 12031@deffn {C++ Function} const char* gccjit::context::get_first_error (gccjit::context* ctxt) 12032 12033Returns the first error message that occurred on the context. 12034 12035The returned string is valid for the rest of the lifetime of the 12036context. 12037 12038If no errors occurred, this will be NULL. 12039@end deffn 12040 12041@node Debugging<2>,Options<4>,Error-handling<3>,Compilation contexts<2> 12042@anchor{cp/topics/contexts debugging}@anchor{129} 12043@subsubsection Debugging 12044 12045 12046@geindex gccjit;;context;;dump_to_file (C++ function) 12047@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{12a} 12048@deffn {C++ Function} void gccjit::context::dump_to_file (const std::string& path, int update_locations) 12049 12050To help with debugging: dump a C-like representation to the given path, 12051describing what's been set up on the context. 12052 12053If "update_locations" is true, then also set up @pxref{12b,,gccjit;;location} 12054information throughout the context, pointing at the dump file as if it 12055were a source file. This may be of use in conjunction with 12056@code{GCCJIT::BOOL_OPTION_DEBUGINFO} to allow stepping through the 12057code in a debugger. 12058@end deffn 12059 12060@geindex gccjit;;context;;dump_reproducer_to_file (C++ function) 12061@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{12c} 12062@deffn {C++ Function} void gccjit::context::dump_reproducer_to_file (gcc_jit_context* ctxt, const char* path) 12063 12064This is a thin wrapper around the C API 12065@pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}, and hence works the 12066same way. 12067 12068Note that the generated source is C code, not C++; this might be of use 12069for seeing what the C++ bindings are doing at the C level. 12070@end deffn 12071 12072@node Options<4>,,Debugging<2>,Compilation contexts<2> 12073@anchor{cp/topics/contexts options}@anchor{12d} 12074@subsubsection Options 12075 12076 12077@menu 12078* String Options: String Options<2>. 12079* Boolean options: Boolean options<2>. 12080* Integer options: Integer options<2>. 12081* Additional command-line options: Additional command-line options<2>. 12082 12083@end menu 12084 12085@node String Options<2>,Boolean options<2>,,Options<4> 12086@anchor{cp/topics/contexts string-options}@anchor{12e} 12087@subsubsection String Options 12088 12089 12090@geindex gccjit;;context;;set_str_option (C++ function) 12091@anchor{cp/topics/contexts gccjit context set_str_option__enum cCP}@anchor{12f} 12092@deffn {C++ Function} void gccjit::context::set_str_option (enum gcc_jit_str_option, const char* value) 12093 12094Set a string option of the context. 12095 12096This is a thin wrapper around the C API 12097@pxref{61,,gcc_jit_context_set_str_option()}; the options have the same 12098meaning. 12099@end deffn 12100 12101@node Boolean options<2>,Integer options<2>,String Options<2>,Options<4> 12102@anchor{cp/topics/contexts boolean-options}@anchor{130} 12103@subsubsection Boolean options 12104 12105 12106@geindex gccjit;;context;;set_bool_option (C++ function) 12107@anchor{cp/topics/contexts gccjit context set_bool_option__enum i}@anchor{fe} 12108@deffn {C++ Function} void gccjit::context::set_bool_option (enum gcc_jit_bool_option, int value) 12109 12110Set a boolean option of the context. 12111 12112This is a thin wrapper around the C API 12113@pxref{1b,,gcc_jit_context_set_bool_option()}; the options have the same 12114meaning. 12115@end deffn 12116 12117@geindex gccjit;;context;;set_bool_allow_unreachable_blocks (C++ function) 12118@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{131} 12119@deffn {C++ Function} void gccjit::context::set_bool_allow_unreachable_blocks (int bool_value) 12120 12121By default, libgccjit will issue an error about unreachable blocks 12122within a function. 12123 12124This entrypoint can be used to disable that error; it is a thin wrapper 12125around the C API 12126@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}. 12127 12128This entrypoint was added in @pxref{6c,,LIBGCCJIT_ABI_2}; you can test for 12129its presence using 12130 12131@example 12132#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 12133@end example 12134 12135@noindent 12136@end deffn 12137 12138@node Integer options<2>,Additional command-line options<2>,Boolean options<2>,Options<4> 12139@anchor{cp/topics/contexts integer-options}@anchor{132} 12140@subsubsection Integer options 12141 12142 12143@geindex gccjit;;context;;set_int_option (C++ function) 12144@anchor{cp/topics/contexts gccjit context set_int_option__enum i}@anchor{ff} 12145@deffn {C++ Function} void gccjit::context::set_int_option (enum gcc_jit_int_option, int value) 12146 12147Set an integer option of the context. 12148 12149This is a thin wrapper around the C API 12150@pxref{1e,,gcc_jit_context_set_int_option()}; the options have the same 12151meaning. 12152@end deffn 12153 12154@node Additional command-line options<2>,,Integer options<2>,Options<4> 12155@anchor{cp/topics/contexts additional-command-line-options}@anchor{133} 12156@subsubsection Additional command-line options 12157 12158 12159@geindex gccjit;;context;;add_command_line_option (C++ function) 12160@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{134} 12161@deffn {C++ Function} void gccjit::context::add_command_line_option (const char* optname) 12162 12163Add an arbitrary gcc command-line option to the context for use 12164when compiling. 12165 12166This is a thin wrapper around the C API 12167@pxref{70,,gcc_jit_context_add_command_line_option()}. 12168 12169This entrypoint was added in @pxref{71,,LIBGCCJIT_ABI_1}; you can test for 12170its presence using 12171 12172@example 12173#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 12174@end example 12175 12176@noindent 12177@end deffn 12178 12179@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 12180@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12181@c 12182@c This is free software: you can redistribute it and/or modify it 12183@c under the terms of the GNU General Public License as published by 12184@c the Free Software Foundation, either version 3 of the License, or 12185@c (at your option) any later version. 12186@c 12187@c This program is distributed in the hope that it will be useful, but 12188@c WITHOUT ANY WARRANTY; without even the implied warranty of 12189@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12190@c General Public License for more details. 12191@c 12192@c You should have received a copy of the GNU General Public License 12193@c along with this program. If not, see 12194@c <http://www.gnu.org/licenses/>. 12195 12196@node Objects<2>,Types<2>,Compilation contexts<2>,Topic Reference<2> 12197@anchor{cp/topics/objects objects}@anchor{135}@anchor{cp/topics/objects doc}@anchor{136} 12198@subsection Objects 12199 12200 12201@geindex gccjit;;object (C++ class) 12202@anchor{cp/topics/objects gccjit object}@anchor{137} 12203@deffn {C++ Class} gccjit::object 12204@end deffn 12205 12206Almost every entity in the API (with the exception of 12207@pxref{123,,gccjit;;context} and @pxref{16,,gcc_jit_result *}) is a 12208"contextual" object, a @pxref{137,,gccjit;;object}. 12209 12210A JIT object: 12211 12212@quotation 12213 12214 12215@itemize * 12216 12217@item 12218is associated with a @pxref{123,,gccjit;;context}. 12219 12220@item 12221is automatically cleaned up for you when its context is released so 12222you don't need to manually track and cleanup all objects, just the 12223contexts. 12224@end itemize 12225@end quotation 12226 12227The C++ class hierarchy within the @code{gccjit} namespace looks like this: 12228 12229@example 12230+- object 12231 +- location 12232 +- type 12233 +- struct 12234 +- field 12235 +- function 12236 +- block 12237 +- rvalue 12238 +- lvalue 12239 +- param 12240 +- case_ 12241@end example 12242 12243@noindent 12244 12245The @pxref{137,,gccjit;;object} base class has the following operations: 12246 12247@geindex gccjit;;object;;get_context (C++ function) 12248@anchor{cp/topics/objects gccjit object get_contextC}@anchor{138} 12249@deffn {C++ Function} gccjit::context gccjit::object::get_context () const 12250 12251Which context is the obj within? 12252@end deffn 12253 12254@geindex gccjit;;object;;get_debug_string (C++ function) 12255@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{f9} 12256@deffn {C++ Function} std::string gccjit::object::get_debug_string () const 12257 12258Generate a human-readable description for the given object. 12259 12260For example, 12261 12262@example 12263printf ("obj: %s\n", obj.get_debug_string ().c_str ()); 12264@end example 12265 12266@noindent 12267 12268might give this text on stdout: 12269 12270@example 12271obj: 4.0 * (float)i 12272@end example 12273 12274@noindent 12275@end deffn 12276 12277@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 12278@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12279@c 12280@c This is free software: you can redistribute it and/or modify it 12281@c under the terms of the GNU General Public License as published by 12282@c the Free Software Foundation, either version 3 of the License, or 12283@c (at your option) any later version. 12284@c 12285@c This program is distributed in the hope that it will be useful, but 12286@c WITHOUT ANY WARRANTY; without even the implied warranty of 12287@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12288@c General Public License for more details. 12289@c 12290@c You should have received a copy of the GNU General Public License 12291@c along with this program. If not, see 12292@c <http://www.gnu.org/licenses/>. 12293 12294@node Types<2>,Expressions<2>,Objects<2>,Topic Reference<2> 12295@anchor{cp/topics/types doc}@anchor{139}@anchor{cp/topics/types types}@anchor{13a} 12296@subsection Types 12297 12298 12299@geindex gccjit;;type (C++ class) 12300@anchor{cp/topics/types gccjit type}@anchor{13b} 12301@deffn {C++ Class} gccjit::type 12302 12303gccjit::type represents a type within the library. It is a subclass 12304of @pxref{137,,gccjit;;object}. 12305@end deffn 12306 12307Types can be created in several ways: 12308 12309 12310@itemize * 12311 12312@item 12313fundamental types can be accessed using 12314@pxref{f7,,gccjit;;context;;get_type()}: 12315 12316@example 12317gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 12318@end example 12319 12320@noindent 12321 12322or using the @code{gccjit::context::get_int_type} template: 12323 12324@example 12325gccjit::type t = ctxt.get_int_type <unsigned short> (); 12326@end example 12327 12328@noindent 12329 12330See @pxref{b,,gcc_jit_context_get_type()} for the available types. 12331 12332@item 12333derived types can be accessed by using functions such as 12334@pxref{13c,,gccjit;;type;;get_pointer()} and @pxref{13d,,gccjit;;type;;get_const()}: 12335 12336@example 12337gccjit::type const_int_star = int_type.get_const ().get_pointer (); 12338gccjit::type int_const_star = int_type.get_pointer ().get_const (); 12339@end example 12340 12341@noindent 12342 12343@item 12344by creating structures (see below). 12345@end itemize 12346 12347@menu 12348* Standard types: Standard types<2>. 12349* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 12350* Structures and unions: Structures and unions<2>. 12351 12352@end menu 12353 12354@node Standard types<2>,Pointers const and volatile<2>,,Types<2> 12355@anchor{cp/topics/types standard-types}@anchor{13e} 12356@subsubsection Standard types 12357 12358 12359@geindex gccjit;;context;;get_type (C++ function) 12360@anchor{cp/topics/types gccjit context get_type__enum}@anchor{f7} 12361@deffn {C++ Function} gccjit::type gccjit::context::get_type (enum gcc_jit_types) 12362 12363Access a specific type. This is a thin wrapper around 12364@pxref{b,,gcc_jit_context_get_type()}; the parameter has the same meaning. 12365@end deffn 12366 12367@geindex gccjit;;context;;get_int_type (C++ function) 12368@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{13f} 12369@deffn {C++ Function} gccjit::type gccjit::context::get_int_type (size_t num_bytes, int is_signed) 12370 12371Access the integer type of the given size. 12372@end deffn 12373 12374@geindex gccjit;;context;;get_int_type<T> (C++ function) 12375@anchor{cp/topics/types gccjit context get_int_type T}@anchor{140} 12376@deffn {C++ Function} gccjit::type gccjit::context::get_int_type<T> () 12377 12378Access the given integer type. For example, you could map the 12379@code{unsigned short} type into a gccjit::type via: 12380 12381@example 12382gccjit::type t = ctxt.get_int_type <unsigned short> (); 12383@end example 12384 12385@noindent 12386@end deffn 12387 12388@node Pointers const and volatile<2>,Structures and unions<2>,Standard types<2>,Types<2> 12389@anchor{cp/topics/types pointers-const-and-volatile}@anchor{141} 12390@subsubsection Pointers, @cite{const}, and @cite{volatile} 12391 12392 12393@geindex gccjit;;type;;get_pointer (C++ function) 12394@anchor{cp/topics/types gccjit type get_pointer}@anchor{13c} 12395@deffn {C++ Function} gccjit::type gccjit::type::get_pointer () 12396 12397Given type "T", get type "T*". 12398@end deffn 12399 12400@c FIXME: get_const doesn't seem to exist 12401 12402@geindex gccjit;;type;;get_const (C++ function) 12403@anchor{cp/topics/types gccjit type get_const}@anchor{13d} 12404@deffn {C++ Function} gccjit::type gccjit::type::get_const () 12405 12406Given type "T", get type "const T". 12407@end deffn 12408 12409@geindex gccjit;;type;;get_volatile (C++ function) 12410@anchor{cp/topics/types gccjit type get_volatile}@anchor{142} 12411@deffn {C++ Function} gccjit::type gccjit::type::get_volatile () 12412 12413Given type "T", get type "volatile T". 12414@end deffn 12415 12416@geindex gccjit;;context;;new_array_type (C++ function) 12417@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{143} 12418@deffn {C++ Function} gccjit::type gccjit::context::new_array_type (gccjit::type element_type, int num_elements, gccjit::location loc) 12419 12420Given type "T", get type "T[N]" (for a constant N). 12421Param "loc" is optional. 12422@end deffn 12423 12424@node Structures and unions<2>,,Pointers const and volatile<2>,Types<2> 12425@anchor{cp/topics/types structures-and-unions}@anchor{144} 12426@subsubsection Structures and unions 12427 12428 12429@geindex gccjit;;struct_ (C++ class) 12430@anchor{cp/topics/types gccjit struct_}@anchor{145} 12431@deffn {C++ Class} gccjit::struct_ 12432@end deffn 12433 12434A compound type analagous to a C @cite{struct}. 12435 12436@pxref{145,,gccjit;;struct_} is a subclass of @pxref{13b,,gccjit;;type} (and thus 12437of @pxref{137,,gccjit;;object} in turn). 12438 12439@geindex gccjit;;field (C++ class) 12440@anchor{cp/topics/types gccjit field}@anchor{146} 12441@deffn {C++ Class} gccjit::field 12442@end deffn 12443 12444A field within a @pxref{145,,gccjit;;struct_}. 12445 12446@pxref{146,,gccjit;;field} is a subclass of @pxref{137,,gccjit;;object}. 12447 12448You can model C @cite{struct} types by creating @pxref{145,,gccjit;;struct_} and 12449@pxref{146,,gccjit;;field} instances, in either order: 12450 12451 12452@itemize * 12453 12454@item 12455by creating the fields, then the structure. For example, to model: 12456 12457@example 12458struct coord @{double x; double y; @}; 12459@end example 12460 12461@noindent 12462 12463you could call: 12464 12465@example 12466gccjit::field field_x = ctxt.new_field (double_type, "x"); 12467gccjit::field field_y = ctxt.new_field (double_type, "y"); 12468std::vector fields; 12469fields.push_back (field_x); 12470fields.push_back (field_y); 12471gccjit::struct_ coord = ctxt.new_struct_type ("coord", fields); 12472@end example 12473 12474@noindent 12475 12476@item 12477by creating the structure, then populating it with fields, typically 12478to allow modelling self-referential structs such as: 12479 12480@example 12481struct node @{ int m_hash; struct node *m_next; @}; 12482@end example 12483 12484@noindent 12485 12486like this: 12487 12488@example 12489gccjit::struct_ node = ctxt.new_opaque_struct_type ("node"); 12490gccjit::type node_ptr = node.get_pointer (); 12491gccjit::field field_hash = ctxt.new_field (int_type, "m_hash"); 12492gccjit::field field_next = ctxt.new_field (node_ptr, "m_next"); 12493std::vector fields; 12494fields.push_back (field_hash); 12495fields.push_back (field_next); 12496node.set_fields (fields); 12497@end example 12498 12499@noindent 12500@end itemize 12501 12502@c FIXME: the above API doesn't seem to exist yet 12503 12504@geindex gccjit;;context;;new_field (C++ function) 12505@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{147} 12506@deffn {C++ Function} gccjit::field gccjit::context::new_field (gccjit::type type, const char* name, gccjit::location loc) 12507 12508Construct a new field, with the given type and name. 12509@end deffn 12510 12511@geindex gccjit;;context;;new_struct_type (C++ function) 12512@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{148} 12513@deffn {C++ Function} gccjit::struct_ gccjit::context::new_struct_type (const std::string& name, std::vector<field>& fields, gccjit::location loc) 12514 12515@quotation 12516 12517Construct a new struct type, with the given name and fields. 12518@end quotation 12519@end deffn 12520 12521@geindex gccjit;;context;;new_opaque_struct (C++ function) 12522@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{149} 12523@deffn {C++ Function} gccjit::struct_ gccjit::context::new_opaque_struct (const std::string& name, gccjit::location loc) 12524 12525Construct a new struct type, with the given name, but without 12526specifying the fields. The fields can be omitted (in which case the 12527size of the struct is not known), or later specified using 12528@pxref{85,,gcc_jit_struct_set_fields()}. 12529@end deffn 12530 12531@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 12532@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12533@c 12534@c This is free software: you can redistribute it and/or modify it 12535@c under the terms of the GNU General Public License as published by 12536@c the Free Software Foundation, either version 3 of the License, or 12537@c (at your option) any later version. 12538@c 12539@c This program is distributed in the hope that it will be useful, but 12540@c WITHOUT ANY WARRANTY; without even the implied warranty of 12541@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12542@c General Public License for more details. 12543@c 12544@c You should have received a copy of the GNU General Public License 12545@c along with this program. If not, see 12546@c <http://www.gnu.org/licenses/>. 12547 12548@node Expressions<2>,Creating and using functions<2>,Types<2>,Topic Reference<2> 12549@anchor{cp/topics/expressions expressions}@anchor{14a}@anchor{cp/topics/expressions doc}@anchor{14b} 12550@subsection Expressions 12551 12552 12553@menu 12554* Rvalues: Rvalues<2>. 12555* Lvalues: Lvalues<2>. 12556* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 12557 12558Rvalues 12559 12560* Simple expressions: Simple expressions<2>. 12561* Unary Operations: Unary Operations<2>. 12562* Binary Operations: Binary Operations<2>. 12563* Comparisons: Comparisons<2>. 12564* Function calls: Function calls<2>. 12565* Type-coercion: Type-coercion<2>. 12566 12567Lvalues 12568 12569* Global variables: Global variables<2>. 12570 12571@end menu 12572 12573 12574@node Rvalues<2>,Lvalues<2>,,Expressions<2> 12575@anchor{cp/topics/expressions rvalues}@anchor{14c} 12576@subsubsection Rvalues 12577 12578 12579@geindex gccjit;;rvalue (C++ class) 12580@anchor{cp/topics/expressions gccjit rvalue}@anchor{14d} 12581@deffn {C++ Class} gccjit::rvalue 12582@end deffn 12583 12584A @pxref{14d,,gccjit;;rvalue} is an expression that can be computed. It is a 12585subclass of @pxref{137,,gccjit;;object}, and is a thin wrapper around 12586@pxref{13,,gcc_jit_rvalue *} from the C API. 12587 12588It can be simple, e.g.: 12589 12590@quotation 12591 12592 12593@itemize * 12594 12595@item 12596an integer value e.g. @cite{0} or @cite{42} 12597 12598@item 12599a string literal e.g. @cite{"Hello world"} 12600 12601@item 12602a variable e.g. @cite{i}. These are also lvalues (see below). 12603@end itemize 12604@end quotation 12605 12606or compound e.g.: 12607 12608@quotation 12609 12610 12611@itemize * 12612 12613@item 12614a unary expression e.g. @cite{!cond} 12615 12616@item 12617a binary expression e.g. @cite{(a + b)} 12618 12619@item 12620a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} 12621 12622@item 12623etc. 12624@end itemize 12625@end quotation 12626 12627Every rvalue has an associated type, and the API will check to ensure 12628that types match up correctly (otherwise the context will emit an error). 12629 12630@geindex gccjit;;rvalue;;get_type (C++ function) 12631@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{14e} 12632@deffn {C++ Function} gccjit::type gccjit::rvalue::get_type () 12633 12634Get the type of this rvalue. 12635@end deffn 12636 12637@menu 12638* Simple expressions: Simple expressions<2>. 12639* Unary Operations: Unary Operations<2>. 12640* Binary Operations: Binary Operations<2>. 12641* Comparisons: Comparisons<2>. 12642* Function calls: Function calls<2>. 12643* Type-coercion: Type-coercion<2>. 12644 12645@end menu 12646 12647@node Simple expressions<2>,Unary Operations<2>,,Rvalues<2> 12648@anchor{cp/topics/expressions simple-expressions}@anchor{14f} 12649@subsubsection Simple expressions 12650 12651 12652@geindex gccjit;;context;;new_rvalue (C++ function) 12653@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{10b} 12654@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, int value) const 12655 12656Given a numeric type (integer or floating point), build an rvalue for 12657the given constant @code{int} value. 12658@end deffn 12659 12660@geindex gccjit;;context;;new_rvalue (C++ function) 12661@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{150} 12662@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, long value) const 12663 12664Given a numeric type (integer or floating point), build an rvalue for 12665the given constant @code{long} value. 12666@end deffn 12667 12668@geindex gccjit;;context;;zero (C++ function) 12669@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{107} 12670@deffn {C++ Function} gccjit::rvalue gccjit::context::zero (gccjit::type numeric_type) const 12671 12672Given a numeric type (integer or floating point), get the rvalue for 12673zero. Essentially this is just a shortcut for: 12674 12675@example 12676ctxt.new_rvalue (numeric_type, 0) 12677@end example 12678 12679@noindent 12680@end deffn 12681 12682@geindex gccjit;;context;;one (C++ function) 12683@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{151} 12684@deffn {C++ Function} gccjit::rvalue gccjit::context::one (gccjit::type numeric_type) const 12685 12686Given a numeric type (integer or floating point), get the rvalue for 12687one. Essentially this is just a shortcut for: 12688 12689@example 12690ctxt.new_rvalue (numeric_type, 1) 12691@end example 12692 12693@noindent 12694@end deffn 12695 12696@geindex gccjit;;context;;new_rvalue (C++ function) 12697@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{152} 12698@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, double value) const 12699 12700Given a numeric type (integer or floating point), build an rvalue for 12701the given constant @code{double} value. 12702@end deffn 12703 12704@geindex gccjit;;context;;new_rvalue (C++ function) 12705@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{153} 12706@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type pointer_type, void* value) const 12707 12708Given a pointer type, build an rvalue for the given address. 12709@end deffn 12710 12711@geindex gccjit;;context;;new_rvalue (C++ function) 12712@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{154} 12713@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (const std::string& value) const 12714 12715Generate an rvalue of type @code{GCC_JIT_TYPE_CONST_CHAR_PTR} for 12716the given string. This is akin to a string literal. 12717@end deffn 12718 12719@node Unary Operations<2>,Binary Operations<2>,Simple expressions<2>,Rvalues<2> 12720@anchor{cp/topics/expressions unary-operations}@anchor{155} 12721@subsubsection Unary Operations 12722 12723 12724@geindex gccjit;;context;;new_unary_op (C++ function) 12725@anchor{cp/topics/expressions gccjit context new_unary_op__enum gccjit type gccjit rvalue gccjit location}@anchor{156} 12726@deffn {C++ Function} gccjit::rvalue gccjit::context::new_unary_op (enum gcc_jit_unary_op, gccjit::type result_type, gccjit::rvalue rvalue, gccjit::location loc) 12727 12728Build a unary operation out of an input rvalue. 12729 12730Parameter @code{loc} is optional. 12731 12732This is a thin wrapper around the C API's 12733@pxref{92,,gcc_jit_context_new_unary_op()} and the available unary 12734operations are documented there. 12735@end deffn 12736 12737There are shorter ways to spell the various specific kinds of unary 12738operation: 12739 12740@geindex gccjit;;context;;new_minus (C++ function) 12741@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{157} 12742@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 12743 12744Negate an arithmetic value; for example: 12745 12746@example 12747gccjit::rvalue negpi = ctxt.new_minus (t_double, pi); 12748@end example 12749 12750@noindent 12751 12752builds the equivalent of this C expression: 12753 12754@example 12755-pi 12756@end example 12757 12758@noindent 12759@end deffn 12760 12761@geindex new_bitwise_negate (C++ function) 12762@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{158} 12763@deffn {C++ Function} gccjit::rvalue new_bitwise_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 12764 12765Bitwise negation of an integer value (one's complement); for example: 12766 12767@example 12768gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a); 12769@end example 12770 12771@noindent 12772 12773builds the equivalent of this C expression: 12774 12775@example 12776~a 12777@end example 12778 12779@noindent 12780@end deffn 12781 12782@geindex new_logical_negate (C++ function) 12783@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{159} 12784@deffn {C++ Function} gccjit::rvalue new_logical_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 12785 12786Logical negation of an arithmetic or pointer value; for example: 12787 12788@example 12789gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond); 12790@end example 12791 12792@noindent 12793 12794builds the equivalent of this C expression: 12795 12796@example 12797!cond 12798@end example 12799 12800@noindent 12801@end deffn 12802 12803The most concise way to spell them is with overloaded operators: 12804 12805@geindex operator- (C++ function) 12806@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{15a} 12807@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a) 12808 12809@example 12810gccjit::rvalue negpi = -pi; 12811@end example 12812 12813@noindent 12814@end deffn 12815 12816@geindex operator~ (C++ function) 12817@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{15b} 12818@deffn {C++ Function} gccjit::rvalue operator~ (gccjit::rvalue a) 12819 12820@example 12821gccjit::rvalue mask = ~a; 12822@end example 12823 12824@noindent 12825@end deffn 12826 12827@geindex operator! (C++ function) 12828@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{15c} 12829@deffn {C++ Function} gccjit::rvalue operator! (gccjit::rvalue a) 12830 12831@example 12832gccjit::rvalue guard = !cond; 12833@end example 12834 12835@noindent 12836@end deffn 12837 12838@node Binary Operations<2>,Comparisons<2>,Unary Operations<2>,Rvalues<2> 12839@anchor{cp/topics/expressions binary-operations}@anchor{15d} 12840@subsubsection Binary Operations 12841 12842 12843@geindex gccjit;;context;;new_binary_op (C++ function) 12844@anchor{cp/topics/expressions gccjit context new_binary_op__enum gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{fb} 12845@deffn {C++ Function} gccjit::rvalue gccjit::context::new_binary_op (enum gcc_jit_binary_op, gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12846 12847Build a binary operation out of two constituent rvalues. 12848 12849Parameter @code{loc} is optional. 12850 12851This is a thin wrapper around the C API's 12852@pxref{12,,gcc_jit_context_new_binary_op()} and the available binary 12853operations are documented there. 12854@end deffn 12855 12856There are shorter ways to spell the various specific kinds of binary 12857operation: 12858 12859@geindex gccjit;;context;;new_plus (C++ function) 12860@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{15e} 12861@deffn {C++ Function} gccjit::rvalue gccjit::context::new_plus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12862@end deffn 12863 12864@geindex gccjit;;context;;new_minus (C++ function) 12865@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{15f} 12866@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12867@end deffn 12868 12869@geindex gccjit;;context;;new_mult (C++ function) 12870@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{160} 12871@deffn {C++ Function} gccjit::rvalue gccjit::context::new_mult (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12872@end deffn 12873 12874@geindex gccjit;;context;;new_divide (C++ function) 12875@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{161} 12876@deffn {C++ Function} gccjit::rvalue gccjit::context::new_divide (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12877@end deffn 12878 12879@geindex gccjit;;context;;new_modulo (C++ function) 12880@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{162} 12881@deffn {C++ Function} gccjit::rvalue gccjit::context::new_modulo (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12882@end deffn 12883 12884@geindex gccjit;;context;;new_bitwise_and (C++ function) 12885@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{163} 12886@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12887@end deffn 12888 12889@geindex gccjit;;context;;new_bitwise_xor (C++ function) 12890@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{164} 12891@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_xor (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12892@end deffn 12893 12894@geindex gccjit;;context;;new_bitwise_or (C++ function) 12895@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{165} 12896@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12897@end deffn 12898 12899@geindex gccjit;;context;;new_logical_and (C++ function) 12900@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{166} 12901@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12902@end deffn 12903 12904@geindex gccjit;;context;;new_logical_or (C++ function) 12905@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{167} 12906@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 12907@end deffn 12908 12909The most concise way to spell them is with overloaded operators: 12910 12911@geindex operator+ (C++ function) 12912@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{168} 12913@deffn {C++ Function} gccjit::rvalue operator+ (gccjit::rvalue a, gccjit::rvalue b) 12914 12915@example 12916gccjit::rvalue sum = a + b; 12917@end example 12918 12919@noindent 12920@end deffn 12921 12922@geindex operator- (C++ function) 12923@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{169} 12924@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a, gccjit::rvalue b) 12925 12926@example 12927gccjit::rvalue diff = a - b; 12928@end example 12929 12930@noindent 12931@end deffn 12932 12933@geindex operator* (C++ function) 12934@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{16a} 12935@deffn {C++ Function} gccjit::rvalue operator* (gccjit::rvalue a, gccjit::rvalue b) 12936 12937@example 12938gccjit::rvalue prod = a * b; 12939@end example 12940 12941@noindent 12942@end deffn 12943 12944@geindex operator/ (C++ function) 12945@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{16b} 12946@deffn {C++ Function} gccjit::rvalue operator/ (gccjit::rvalue a, gccjit::rvalue b) 12947 12948@example 12949gccjit::rvalue result = a / b; 12950@end example 12951 12952@noindent 12953@end deffn 12954 12955@geindex operator% (C++ function) 12956@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{16c} 12957@deffn {C++ Function} gccjit::rvalue operator% (gccjit::rvalue a, gccjit::rvalue b) 12958 12959@example 12960gccjit::rvalue mod = a % b; 12961@end example 12962 12963@noindent 12964@end deffn 12965 12966@geindex operator& (C++ function) 12967@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{16d} 12968@deffn {C++ Function} gccjit::rvalue operator& (gccjit::rvalue a, gccjit::rvalue b) 12969 12970@example 12971gccjit::rvalue x = a & b; 12972@end example 12973 12974@noindent 12975@end deffn 12976 12977@geindex operator^ (C++ function) 12978@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{16e} 12979@deffn {C++ Function} gccjit::rvalue operator^ (gccjit::rvalue a, gccjit::rvalue b) 12980 12981@example 12982gccjit::rvalue x = a ^ b; 12983@end example 12984 12985@noindent 12986@end deffn 12987 12988@geindex operator| (C++ function) 12989@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{16f} 12990@deffn {C++ Function} gccjit::rvalue operator| (gccjit::rvalue a, gccjit::rvalue b) 12991 12992@example 12993gccjit::rvalue x = a | b; 12994@end example 12995 12996@noindent 12997@end deffn 12998 12999@geindex operator&& (C++ function) 13000@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{170} 13001@deffn {C++ Function} gccjit::rvalue operator&& (gccjit::rvalue a, gccjit::rvalue b) 13002 13003@example 13004gccjit::rvalue cond = a && b; 13005@end example 13006 13007@noindent 13008@end deffn 13009 13010@geindex operator|| (C++ function) 13011@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{171} 13012@deffn {C++ Function} gccjit::rvalue operator|| (gccjit::rvalue a, gccjit::rvalue b) 13013 13014@example 13015gccjit::rvalue cond = a || b; 13016@end example 13017 13018@noindent 13019@end deffn 13020 13021These can of course be combined, giving a terse way to build compound 13022expressions: 13023 13024@quotation 13025 13026@example 13027gccjit::rvalue discriminant = (b * b) - (four * a * c); 13028@end example 13029 13030@noindent 13031@end quotation 13032 13033@node Comparisons<2>,Function calls<2>,Binary Operations<2>,Rvalues<2> 13034@anchor{cp/topics/expressions comparisons}@anchor{172} 13035@subsubsection Comparisons 13036 13037 13038@geindex gccjit;;context;;new_comparison (C++ function) 13039@anchor{cp/topics/expressions gccjit context new_comparison__enum gccjit rvalue gccjit rvalue gccjit location}@anchor{108} 13040@deffn {C++ Function} gccjit::rvalue gccjit::context::new_comparison (enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13041 13042Build a boolean rvalue out of the comparison of two other rvalues. 13043 13044Parameter @code{loc} is optional. 13045 13046This is a thin wrapper around the C API's 13047@pxref{2c,,gcc_jit_context_new_comparison()} and the available kinds 13048of comparison are documented there. 13049@end deffn 13050 13051There are shorter ways to spell the various specific kinds of binary 13052operation: 13053 13054@geindex gccjit;;context;;new_eq (C++ function) 13055@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{173} 13056@deffn {C++ Function} gccjit::rvalue gccjit::context::new_eq (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13057@end deffn 13058 13059@geindex gccjit;;context;;new_ne (C++ function) 13060@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{174} 13061@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ne (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13062@end deffn 13063 13064@geindex gccjit;;context;;new_lt (C++ function) 13065@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{175} 13066@deffn {C++ Function} gccjit::rvalue gccjit::context::new_lt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13067@end deffn 13068 13069@geindex gccjit;;context;;new_le (C++ function) 13070@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{176} 13071@deffn {C++ Function} gccjit::rvalue gccjit::context::new_le (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13072@end deffn 13073 13074@geindex gccjit;;context;;new_gt (C++ function) 13075@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{177} 13076@deffn {C++ Function} gccjit::rvalue gccjit::context::new_gt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13077@end deffn 13078 13079@geindex gccjit;;context;;new_ge (C++ function) 13080@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{178} 13081@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ge (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13082@end deffn 13083 13084The most concise way to spell them is with overloaded operators: 13085 13086@geindex operator== (C++ function) 13087@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{179} 13088@deffn {C++ Function} gccjit::rvalue operator== (gccjit::rvalue a, gccjit::rvalue b) 13089 13090@example 13091gccjit::rvalue cond = (a == ctxt.zero (t_int)); 13092@end example 13093 13094@noindent 13095@end deffn 13096 13097@geindex operator!= (C++ function) 13098@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{17a} 13099@deffn {C++ Function} gccjit::rvalue operator!= (gccjit::rvalue a, gccjit::rvalue b) 13100 13101@example 13102gccjit::rvalue cond = (i != j); 13103@end example 13104 13105@noindent 13106@end deffn 13107 13108@geindex operator< (C++ function) 13109@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{17b} 13110@deffn {C++ Function} gccjit::rvalue operator< (gccjit::rvalue a, gccjit::rvalue b) 13111 13112@example 13113gccjit::rvalue cond = i < n; 13114@end example 13115 13116@noindent 13117@end deffn 13118 13119@geindex operator<= (C++ function) 13120@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{17c} 13121@deffn {C++ Function} gccjit::rvalue operator<= (gccjit::rvalue a, gccjit::rvalue b) 13122 13123@example 13124gccjit::rvalue cond = i <= n; 13125@end example 13126 13127@noindent 13128@end deffn 13129 13130@geindex operator> (C++ function) 13131@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{17d} 13132@deffn {C++ Function} gccjit::rvalue operator> (gccjit::rvalue a, gccjit::rvalue b) 13133 13134@example 13135gccjit::rvalue cond = (ch > limit); 13136@end example 13137 13138@noindent 13139@end deffn 13140 13141@geindex operator>= (C++ function) 13142@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{17e} 13143@deffn {C++ Function} gccjit::rvalue operator>= (gccjit::rvalue a, gccjit::rvalue b) 13144 13145@example 13146gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100)); 13147@end example 13148 13149@noindent 13150@end deffn 13151 13152@c TODO: beyond this point 13153 13154@node Function calls<2>,Type-coercion<2>,Comparisons<2>,Rvalues<2> 13155@anchor{cp/topics/expressions function-calls}@anchor{17f} 13156@subsubsection Function calls 13157 13158 13159@geindex gcc_jit_context_new_call (C++ function) 13160@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{180} 13161@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) 13162 13163Given a function and the given table of argument rvalues, construct a 13164call to the function, with the result as an rvalue. 13165 13166@cartouche 13167@quotation Note 13168@code{gccjit::context::new_call()} merely builds a 13169@pxref{14d,,gccjit;;rvalue} i.e. an expression that can be evaluated, 13170perhaps as part of a more complicated expression. 13171The call @emph{won't} happen unless you add a statement to a function 13172that evaluates the expression. 13173 13174For example, if you want to call a function and discard the result 13175(or to call a function with @code{void} return type), use 13176@pxref{181,,gccjit;;block;;add_eval()}: 13177 13178@example 13179/* Add "(void)printf (arg0, arg1);". */ 13180block.add_eval (ctxt.new_call (printf_func, arg0, arg1)); 13181@end example 13182 13183@noindent 13184@end quotation 13185@end cartouche 13186@end deffn 13187 13188@node Type-coercion<2>,,Function calls<2>,Rvalues<2> 13189@anchor{cp/topics/expressions type-coercion}@anchor{182} 13190@subsubsection Type-coercion 13191 13192 13193@geindex gccjit;;context;;new_cast (C++ function) 13194@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{183} 13195@deffn {C++ Function} gccjit::rvalue gccjit::context::new_cast (gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc) 13196 13197Given an rvalue of T, construct another rvalue of another type. 13198 13199Currently only a limited set of conversions are possible: 13200 13201@quotation 13202 13203 13204@itemize * 13205 13206@item 13207int <-> float 13208 13209@item 13210int <-> bool 13211 13212@item 13213P* <-> Q*, for pointer types P and Q 13214@end itemize 13215@end quotation 13216@end deffn 13217 13218@node Lvalues<2>,Working with pointers structs and unions<2>,Rvalues<2>,Expressions<2> 13219@anchor{cp/topics/expressions lvalues}@anchor{184} 13220@subsubsection Lvalues 13221 13222 13223@geindex gccjit;;lvalue (C++ class) 13224@anchor{cp/topics/expressions gccjit lvalue}@anchor{185} 13225@deffn {C++ Class} gccjit::lvalue 13226@end deffn 13227 13228An lvalue is something that can of the @emph{left}-hand side of an assignment: 13229a storage area (such as a variable). It is a subclass of 13230@pxref{14d,,gccjit;;rvalue}, where the rvalue is computed by reading from the 13231storage area. 13232 13233It iss a thin wrapper around @pxref{24,,gcc_jit_lvalue *} from the C API. 13234 13235@geindex gccjit;;lvalue;;get_address (C++ function) 13236@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{186} 13237@deffn {C++ Function} gccjit::rvalue gccjit::lvalue::get_address (gccjit::location loc) 13238 13239Take the address of an lvalue; analogous to: 13240 13241@example 13242&(EXPR) 13243@end example 13244 13245@noindent 13246 13247in C. 13248 13249Parameter "loc" is optional. 13250@end deffn 13251 13252@menu 13253* Global variables: Global variables<2>. 13254 13255@end menu 13256 13257@node Global variables<2>,,,Lvalues<2> 13258@anchor{cp/topics/expressions global-variables}@anchor{187} 13259@subsubsection Global variables 13260 13261 13262@geindex gccjit;;context;;new_global (C++ function) 13263@anchor{cp/topics/expressions gccjit context new_global__enum gccjit type cCP gccjit location}@anchor{188} 13264@deffn {C++ Function} gccjit::lvalue gccjit::context::new_global (enum gcc_jit_global_kind, gccjit::type type, const char* name, gccjit::location loc) 13265 13266Add a new global variable of the given type and name to the context. 13267 13268This is a thin wrapper around @pxref{b3,,gcc_jit_context_new_global()} from 13269the C API; the "kind" parameter has the same meaning as there. 13270@end deffn 13271 13272@node Working with pointers structs and unions<2>,,Lvalues<2>,Expressions<2> 13273@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{189} 13274@subsubsection Working with pointers, structs and unions 13275 13276 13277@geindex gccjit;;rvalue;;dereference (C++ function) 13278@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{18a} 13279@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference (gccjit::location loc) 13280 13281Given an rvalue of pointer type @code{T *}, dereferencing the pointer, 13282getting an lvalue of type @code{T}. Analogous to: 13283 13284@example 13285*(EXPR) 13286@end example 13287 13288@noindent 13289 13290in C. 13291 13292Parameter "loc" is optional. 13293@end deffn 13294 13295If you don't need to specify the location, this can also be expressed using 13296an overloaded operator: 13297 13298@geindex gccjit;;rvalue;;operator* (C++ function) 13299@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{18b} 13300@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::operator* () 13301 13302@example 13303gccjit::lvalue content = *ptr; 13304@end example 13305 13306@noindent 13307@end deffn 13308 13309Field access is provided separately for both lvalues and rvalues: 13310 13311@geindex gccjit;;lvalue;;access_field (C++ function) 13312@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{18c} 13313@deffn {C++ Function} gccjit::lvalue gccjit::lvalue::access_field (gccjit::field field, gccjit::location loc) 13314 13315Given an lvalue of struct or union type, access the given field, 13316getting an lvalue of the field's type. Analogous to: 13317 13318@example 13319(EXPR).field = ...; 13320@end example 13321 13322@noindent 13323 13324in C. 13325@end deffn 13326 13327@geindex gccjit;;rvalue;;access_field (C++ function) 13328@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{18d} 13329@deffn {C++ Function} gccjit::rvalue gccjit::rvalue::access_field (gccjit::field field, gccjit::location loc) 13330 13331Given an rvalue of struct or union type, access the given field 13332as an rvalue. Analogous to: 13333 13334@example 13335(EXPR).field 13336@end example 13337 13338@noindent 13339 13340in C. 13341@end deffn 13342 13343@geindex gccjit;;rvalue;;dereference_field (C++ function) 13344@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{18e} 13345@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference_field (gccjit::field field, gccjit::location loc) 13346 13347Given an rvalue of pointer type @code{T *} where T is of struct or union 13348type, access the given field as an lvalue. Analogous to: 13349 13350@example 13351(EXPR)->field 13352@end example 13353 13354@noindent 13355 13356in C, itself equivalent to @code{(*EXPR).FIELD}. 13357@end deffn 13358 13359@geindex gccjit;;context;;new_array_access (C++ function) 13360@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{18f} 13361@deffn {C++ Function} gccjit::lvalue gccjit::context::new_array_access (gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc) 13362 13363Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at 13364the given index, using standard C array indexing rules i.e. each 13365increment of @code{index} corresponds to @code{sizeof(T)} bytes. 13366Analogous to: 13367 13368@example 13369PTR[INDEX] 13370@end example 13371 13372@noindent 13373 13374in C (or, indeed, to @code{PTR + INDEX}). 13375 13376Parameter "loc" is optional. 13377@end deffn 13378 13379For array accesses where you don't need to specify a @pxref{12b,,gccjit;;location}, 13380two overloaded operators are available: 13381 13382@quotation 13383 13384gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index) 13385 13386@example 13387gccjit::lvalue element = array[idx]; 13388@end example 13389 13390@noindent 13391 13392gccjit::lvalue gccjit::rvalue::operator[] (int index) 13393 13394@example 13395gccjit::lvalue element = array[0]; 13396@end example 13397 13398@noindent 13399@end quotation 13400 13401@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 13402@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13403@c 13404@c This is free software: you can redistribute it and/or modify it 13405@c under the terms of the GNU General Public License as published by 13406@c the Free Software Foundation, either version 3 of the License, or 13407@c (at your option) any later version. 13408@c 13409@c This program is distributed in the hope that it will be useful, but 13410@c WITHOUT ANY WARRANTY; without even the implied warranty of 13411@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13412@c General Public License for more details. 13413@c 13414@c You should have received a copy of the GNU General Public License 13415@c along with this program. If not, see 13416@c <http://www.gnu.org/licenses/>. 13417 13418@node Creating and using functions<2>,Source Locations<2>,Expressions<2>,Topic Reference<2> 13419@anchor{cp/topics/functions doc}@anchor{190}@anchor{cp/topics/functions creating-and-using-functions}@anchor{191} 13420@subsection Creating and using functions 13421 13422 13423@menu 13424* Params: Params<2>. 13425* Functions: Functions<2>. 13426* Blocks: Blocks<2>. 13427* Statements: Statements<2>. 13428 13429@end menu 13430 13431@node Params<2>,Functions<2>,,Creating and using functions<2> 13432@anchor{cp/topics/functions params}@anchor{192} 13433@subsubsection Params 13434 13435 13436@geindex gccjit;;param (C++ class) 13437@anchor{cp/topics/functions gccjit param}@anchor{193} 13438@deffn {C++ Class} gccjit::param 13439 13440A @cite{gccjit::param} represents a parameter to a function. 13441@end deffn 13442 13443@geindex gccjit;;context;;new_param (C++ function) 13444@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{fa} 13445@deffn {C++ Function} gccjit::param gccjit::context::new_param (gccjit::type type, const char* name, gccjit::location loc) 13446 13447In preparation for creating a function, create a new parameter of the 13448given type and name. 13449@end deffn 13450 13451@pxref{193,,gccjit;;param} is a subclass of @pxref{185,,gccjit;;lvalue} (and thus 13452of @pxref{14d,,gccjit;;rvalue} and @pxref{137,,gccjit;;object}). It is a thin 13453wrapper around the C API's @pxref{25,,gcc_jit_param *}. 13454 13455@node Functions<2>,Blocks<2>,Params<2>,Creating and using functions<2> 13456@anchor{cp/topics/functions functions}@anchor{194} 13457@subsubsection Functions 13458 13459 13460@geindex gccjit;;function (C++ class) 13461@anchor{cp/topics/functions gccjit function}@anchor{195} 13462@deffn {C++ Class} gccjit::function 13463 13464A @cite{gccjit::function} represents a function - either one that we're 13465creating ourselves, or one that we're referencing. 13466@end deffn 13467 13468@geindex gccjit;;context;;new_function (C++ function) 13469@anchor{cp/topics/functions gccjit context new_function__enum gccjit type cCP std vector param R i gccjit location}@anchor{196} 13470@deffn {C++ Function} gccjit::function gccjit::context::new_function (enum gcc_jit_function_kind, gccjit::type return_type, const char* name, std::vector<param>& params, int is_variadic, gccjit::location loc) 13471 13472Create a gcc_jit_function with the given name and parameters. 13473 13474Parameters "is_variadic" and "loc" are optional. 13475 13476This is a wrapper around the C API's @pxref{11,,gcc_jit_context_new_function()}. 13477@end deffn 13478 13479@geindex gccjit;;context;;get_builtin_function (C++ function) 13480@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{197} 13481@deffn {C++ Function} gccjit::function gccjit::context::get_builtin_function (const char* name) 13482 13483This is a wrapper around the C API's 13484@pxref{ca,,gcc_jit_context_get_builtin_function()}. 13485@end deffn 13486 13487@geindex gccjit;;function;;get_param (C++ function) 13488@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{198} 13489@deffn {C++ Function} gccjit::param gccjit::function::get_param (int index) const 13490 13491Get the param of the given index (0-based). 13492@end deffn 13493 13494@geindex gccjit;;function;;dump_to_dot (C++ function) 13495@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{10d} 13496@deffn {C++ Function} void gccjit::function::dump_to_dot (const char* path) 13497 13498Emit the function in graphviz format to the given path. 13499@end deffn 13500 13501@geindex gccjit;;function;;new_local (C++ function) 13502@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{104} 13503@deffn {C++ Function} gccjit::lvalue gccjit::function::new_local (gccjit::type type, const char* name, gccjit::location loc) 13504 13505Create a new local variable within the function, of the given type and 13506name. 13507@end deffn 13508 13509@node Blocks<2>,Statements<2>,Functions<2>,Creating and using functions<2> 13510@anchor{cp/topics/functions blocks}@anchor{199} 13511@subsubsection Blocks 13512 13513 13514@geindex gccjit;;block (C++ class) 13515@anchor{cp/topics/functions gccjit block}@anchor{19a} 13516@deffn {C++ Class} gccjit::block 13517 13518A @cite{gccjit::block} represents a basic block within a function i.e. a 13519sequence of statements with a single entry point and a single exit 13520point. 13521 13522@pxref{19a,,gccjit;;block} is a subclass of @pxref{137,,gccjit;;object}. 13523 13524The first basic block that you create within a function will 13525be the entrypoint. 13526 13527Each basic block that you create within a function must be 13528terminated, either with a conditional, a jump, a return, or 13529a switch. 13530 13531It's legal to have multiple basic blocks that return within 13532one function. 13533@end deffn 13534 13535@geindex gccjit;;function;;new_block (C++ function) 13536@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{19b} 13537@deffn {C++ Function} gccjit::block gccjit::function::new_block (const char* name) 13538 13539Create a basic block of the given name. The name may be NULL, but 13540providing meaningful names is often helpful when debugging: it may 13541show up in dumps of the internal representation, and in error 13542messages. 13543@end deffn 13544 13545@node Statements<2>,,Blocks<2>,Creating and using functions<2> 13546@anchor{cp/topics/functions statements}@anchor{19c} 13547@subsubsection Statements 13548 13549 13550@geindex gccjit;;block;;add_eval (C++ function) 13551@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{181} 13552@deffn {C++ Function} void gccjit::block::add_eval (gccjit::rvalue rvalue, gccjit::location loc) 13553 13554Add evaluation of an rvalue, discarding the result 13555(e.g. a function call that "returns" void). 13556 13557This is equivalent to this C code: 13558 13559@example 13560(void)expression; 13561@end example 13562 13563@noindent 13564@end deffn 13565 13566@geindex gccjit;;block;;add_assignment (C++ function) 13567@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{106} 13568@deffn {C++ Function} void gccjit::block::add_assignment (gccjit::lvalue lvalue, gccjit::rvalue rvalue, gccjit::location loc) 13569 13570Add evaluation of an rvalue, assigning the result to the given 13571lvalue. 13572 13573This is roughly equivalent to this C code: 13574 13575@example 13576lvalue = rvalue; 13577@end example 13578 13579@noindent 13580@end deffn 13581 13582@geindex gccjit;;block;;add_assignment_op (C++ function) 13583@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue enum gccjit rvalue gccjit location}@anchor{10a} 13584@deffn {C++ Function} void gccjit::block::add_assignment_op (gccjit::lvalue lvalue, enum gcc_jit_binary_op, gccjit::rvalue rvalue, gccjit::location loc) 13585 13586Add evaluation of an rvalue, using the result to modify an 13587lvalue. 13588 13589This is analogous to "+=" and friends: 13590 13591@example 13592lvalue += rvalue; 13593lvalue *= rvalue; 13594lvalue /= rvalue; 13595@end example 13596 13597@noindent 13598 13599etc. For example: 13600 13601@example 13602/* "i++" */ 13603loop_body.add_assignment_op ( 13604 i, 13605 GCC_JIT_BINARY_OP_PLUS, 13606 ctxt.one (int_type)); 13607@end example 13608 13609@noindent 13610@end deffn 13611 13612@geindex gccjit;;block;;add_comment (C++ function) 13613@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{115} 13614@deffn {C++ Function} void gccjit::block::add_comment (const char* text, gccjit::location loc) 13615 13616Add a no-op textual comment to the internal representation of the 13617code. It will be optimized away, but will be visible in the dumps 13618seen via @pxref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} 13619and @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, 13620and thus may be of use when debugging how your project's internal 13621representation gets converted to the libgccjit IR. 13622 13623Parameter "loc" is optional. 13624@end deffn 13625 13626@geindex gccjit;;block;;end_with_conditional (C++ function) 13627@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{109} 13628@deffn {C++ Function} void gccjit::block::end_with_conditional (gccjit::rvalue boolval, gccjit::block on_true, gccjit::block on_false, gccjit::location loc) 13629 13630Terminate a block by adding evaluation of an rvalue, branching on the 13631result to the appropriate successor block. 13632 13633This is roughly equivalent to this C code: 13634 13635@example 13636if (boolval) 13637 goto on_true; 13638else 13639 goto on_false; 13640@end example 13641 13642@noindent 13643 13644block, boolval, on_true, and on_false must be non-NULL. 13645@end deffn 13646 13647@geindex gccjit;;block;;end_with_jump (C++ function) 13648@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{19d} 13649@deffn {C++ Function} void gccjit::block::end_with_jump (gccjit::block target, gccjit::location loc) 13650 13651Terminate a block by adding a jump to the given target block. 13652 13653This is roughly equivalent to this C code: 13654 13655@example 13656goto target; 13657@end example 13658 13659@noindent 13660@end deffn 13661 13662@geindex gccjit;;block;;end_with_return (C++ function) 13663@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{19e} 13664@deffn {C++ Function} void gccjit::block::end_with_return (gccjit::rvalue rvalue, gccjit::location loc) 13665 13666Terminate a block. 13667 13668Both params are optional. 13669 13670An rvalue must be provided for a function returning non-void, and 13671must not be provided by a function "returning" @cite{void}. 13672 13673If an rvalue is provided, the block is terminated by evaluating the 13674rvalue and returning the value. 13675 13676This is roughly equivalent to this C code: 13677 13678@example 13679return expression; 13680@end example 13681 13682@noindent 13683 13684If an rvalue is not provided, the block is terminated by adding a 13685valueless return, for use within a function with "void" return type. 13686 13687This is equivalent to this C code: 13688 13689@example 13690return; 13691@end example 13692 13693@noindent 13694@end deffn 13695 13696@geindex gccjit;;block;;end_with_switch (C++ function) 13697@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{19f} 13698@deffn {C++ Function} void gccjit::block::end_with_switch (gccjit::rvalue expr, gccjit::block default_block, std::vector<gccjit::case_> cases, gccjit::location loc) 13699 13700Terminate a block by adding evalation of an rvalue, then performing 13701a multiway branch. 13702 13703This is roughly equivalent to this C code: 13704 13705@example 13706switch (expr) 13707 @{ 13708 default: 13709 goto default_block; 13710 13711 case C0.min_value ... C0.max_value: 13712 goto C0.dest_block; 13713 13714 case C1.min_value ... C1.max_value: 13715 goto C1.dest_block; 13716 13717 ...etc... 13718 13719 case C[N - 1].min_value ... C[N - 1].max_value: 13720 goto C[N - 1].dest_block; 13721@} 13722@end example 13723 13724@noindent 13725 13726@code{expr} must be of the same integer type as all of the @code{min_value} 13727and @code{max_value} within the cases. 13728 13729The ranges of the cases must not overlap (or have duplicate 13730values). 13731 13732The API entrypoints relating to switch statements and cases: 13733 13734@quotation 13735 13736 13737@itemize * 13738 13739@item 13740@pxref{19f,,gccjit;;block;;end_with_switch()} 13741 13742@item 13743@pxref{1a0,,gccjit;;context;;new_case()} 13744@end itemize 13745@end quotation 13746 13747were added in @pxref{d8,,LIBGCCJIT_ABI_3}; you can test for their presence 13748using 13749 13750@example 13751#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 13752@end example 13753 13754@noindent 13755 13756@geindex gccjit;;block;;end_with_switch;;gccjit;;case_ (C++ class) 13757@anchor{cp/topics/functions gccjit block end_with_switch gccjit case_}@anchor{1a1} 13758@deffn {C++ Class} gccjit::case_ 13759@end deffn 13760 13761A @cite{gccjit::case_} represents a case within a switch statement, and 13762is created within a particular @pxref{123,,gccjit;;context} using 13763@pxref{1a0,,gccjit;;context;;new_case()}. It is a subclass of 13764@pxref{137,,gccjit;;object}. 13765 13766Each case expresses a multivalued range of integer values. You 13767can express single-valued cases by passing in the same value for 13768both @cite{min_value} and @cite{max_value}. 13769 13770@geindex gccjit;;block;;end_with_switch;;gccjit;;context;;new_case (C++ function) 13771@anchor{cp/topics/functions gccjit block end_with_switch gccjit context new_case__gccjit rvalue gccjit rvalue gccjit block}@anchor{1a0} 13772@deffn {C++ Function} gccjit::case_* gccjit::context::new_case (gccjit::rvalue min_value, gccjit::rvalue max_value, gccjit::block dest_block) 13773 13774Create a new gccjit::case for use in a switch statement. 13775@cite{min_value} and @cite{max_value} must be constants of an integer type, 13776which must match that of the expression of the switch statement. 13777 13778@cite{dest_block} must be within the same function as the switch 13779statement. 13780@end deffn 13781 13782Here's an example of creating a switch statement: 13783 13784@quotation 13785 13786@example 13787 13788void 13789create_code (gcc_jit_context *c_ctxt, void *user_data) 13790@{ 13791 /* Let's try to inject the equivalent of: 13792 int 13793 test_switch (int x) 13794 @{ 13795 switch (x) 13796 @{ 13797 case 0 ... 5: 13798 return 3; 13799 13800 case 25 ... 27: 13801 return 4; 13802 13803 case -42 ... -17: 13804 return 83; 13805 13806 case 40: 13807 return 8; 13808 13809 default: 13810 return 10; 13811 @} 13812 @} 13813 */ 13814 gccjit::context ctxt (c_ctxt); 13815 gccjit::type t_int = ctxt.get_type (GCC_JIT_TYPE_INT); 13816 gccjit::type return_type = t_int; 13817 gccjit::param x = ctxt.new_param (t_int, "x"); 13818 std::vector <gccjit::param> params; 13819 params.push_back (x); 13820 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 13821 return_type, 13822 "test_switch", 13823 params, 0); 13824 13825 gccjit::block b_initial = func.new_block ("initial"); 13826 13827 gccjit::block b_default = func.new_block ("default"); 13828 gccjit::block b_case_0_5 = func.new_block ("case_0_5"); 13829 gccjit::block b_case_25_27 = func.new_block ("case_25_27"); 13830 gccjit::block b_case_m42_m17 = func.new_block ("case_m42_m17"); 13831 gccjit::block b_case_40 = func.new_block ("case_40"); 13832 13833 std::vector <gccjit::case_> cases; 13834 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 0), 13835 ctxt.new_rvalue (t_int, 5), 13836 b_case_0_5)); 13837 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 25), 13838 ctxt.new_rvalue (t_int, 27), 13839 b_case_25_27)); 13840 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, -42), 13841 ctxt.new_rvalue (t_int, -17), 13842 b_case_m42_m17)); 13843 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 40), 13844 ctxt.new_rvalue (t_int, 40), 13845 b_case_40)); 13846 b_initial.end_with_switch (x, 13847 b_default, 13848 cases); 13849 13850 b_case_0_5.end_with_return (ctxt.new_rvalue (t_int, 3)); 13851 b_case_25_27.end_with_return (ctxt.new_rvalue (t_int, 4)); 13852 b_case_m42_m17.end_with_return (ctxt.new_rvalue (t_int, 83)); 13853 b_case_40.end_with_return (ctxt.new_rvalue (t_int, 8)); 13854 b_default.end_with_return (ctxt.new_rvalue (t_int, 10)); 13855@} 13856 13857 13858@end example 13859 13860@noindent 13861@end quotation 13862@end deffn 13863 13864@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 13865@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13866@c 13867@c This is free software: you can redistribute it and/or modify it 13868@c under the terms of the GNU General Public License as published by 13869@c the Free Software Foundation, either version 3 of the License, or 13870@c (at your option) any later version. 13871@c 13872@c This program is distributed in the hope that it will be useful, but 13873@c WITHOUT ANY WARRANTY; without even the implied warranty of 13874@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13875@c General Public License for more details. 13876@c 13877@c You should have received a copy of the GNU General Public License 13878@c along with this program. If not, see 13879@c <http://www.gnu.org/licenses/>. 13880 13881@node Source Locations<2>,Compiling a context<2>,Creating and using functions<2>,Topic Reference<2> 13882@anchor{cp/topics/locations source-locations}@anchor{1a2}@anchor{cp/topics/locations doc}@anchor{1a3} 13883@subsection Source Locations 13884 13885 13886@geindex gccjit;;location (C++ class) 13887@anchor{cp/topics/locations gccjit location}@anchor{12b} 13888@deffn {C++ Class} gccjit::location 13889 13890A @cite{gccjit::location} encapsulates a source code location, so that 13891you can (optionally) associate locations in your language with 13892statements in the JIT-compiled code, allowing the debugger to 13893single-step through your language. 13894 13895@cite{gccjit::location} instances are optional: you can always omit them 13896from any C++ API entrypoint accepting one. 13897 13898You can construct them using @pxref{119,,gccjit;;context;;new_location()}. 13899 13900You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 13901@pxref{123,,gccjit;;context} for these locations to actually be usable by 13902the debugger: 13903 13904@example 13905ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1); 13906@end example 13907 13908@noindent 13909@end deffn 13910 13911@geindex gccjit;;context;;new_location (C++ function) 13912@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{119} 13913@deffn {C++ Function} gccjit::location gccjit::context::new_location (const char* filename, int line, int column) 13914 13915Create a @cite{gccjit::location} instance representing the given source 13916location. 13917@end deffn 13918 13919@menu 13920* Faking it: Faking it<2>. 13921 13922@end menu 13923 13924@node Faking it<2>,,,Source Locations<2> 13925@anchor{cp/topics/locations faking-it}@anchor{1a4} 13926@subsubsection Faking it 13927 13928 13929If you don't have source code for your internal representation, but need 13930to debug, you can generate a C-like representation of the functions in 13931your context using @pxref{12a,,gccjit;;context;;dump_to_file()}: 13932 13933@example 13934ctxt.dump_to_file ("/tmp/something.c", 13935 1 /* update_locations */); 13936@end example 13937 13938@noindent 13939 13940This will dump C-like code to the given path. If the @cite{update_locations} 13941argument is true, this will also set up @cite{gccjit::location} information 13942throughout the context, pointing at the dump file as if it were a source 13943file, giving you @emph{something} you can step through in the debugger. 13944 13945@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 13946@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13947@c 13948@c This is free software: you can redistribute it and/or modify it 13949@c under the terms of the GNU General Public License as published by 13950@c the Free Software Foundation, either version 3 of the License, or 13951@c (at your option) any later version. 13952@c 13953@c This program is distributed in the hope that it will be useful, but 13954@c WITHOUT ANY WARRANTY; without even the implied warranty of 13955@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13956@c General Public License for more details. 13957@c 13958@c You should have received a copy of the GNU General Public License 13959@c along with this program. If not, see 13960@c <http://www.gnu.org/licenses/>. 13961 13962@node Compiling a context<2>,,Source Locations<2>,Topic Reference<2> 13963@anchor{cp/topics/compilation compiling-a-context}@anchor{1a5}@anchor{cp/topics/compilation doc}@anchor{1a6} 13964@subsection Compiling a context 13965 13966 13967Once populated, a @pxref{123,,gccjit;;context} can be compiled to 13968machine code, either in-memory via @pxref{fc,,gccjit;;context;;compile()} or 13969to disk via @pxref{1a7,,gccjit;;context;;compile_to_file()}. 13970 13971You can compile a context multiple times (using either form of 13972compilation), although any errors that occur on the context will 13973prevent any future compilation of that context. 13974 13975@menu 13976* In-memory compilation: In-memory compilation<2>. 13977* Ahead-of-time compilation: Ahead-of-time compilation<2>. 13978 13979@end menu 13980 13981@node In-memory compilation<2>,Ahead-of-time compilation<2>,,Compiling a context<2> 13982@anchor{cp/topics/compilation in-memory-compilation}@anchor{1a8} 13983@subsubsection In-memory compilation 13984 13985 13986@geindex gccjit;;context;;compile (C++ function) 13987@anchor{cp/topics/compilation gccjit context compile}@anchor{fc} 13988@deffn {C++ Function} gcc_jit_result* gccjit::context::compile () 13989 13990This calls into GCC and builds the code, returning a 13991@cite{gcc_jit_result *}. 13992 13993This is a thin wrapper around the 13994@pxref{15,,gcc_jit_context_compile()} API entrypoint. 13995@end deffn 13996 13997@node Ahead-of-time compilation<2>,,In-memory compilation<2>,Compiling a context<2> 13998@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{1a9} 13999@subsubsection Ahead-of-time compilation 14000 14001 14002Although libgccjit is primarily aimed at just-in-time compilation, it 14003can also be used for implementing more traditional ahead-of-time 14004compilers, via the @pxref{1a7,,gccjit;;context;;compile_to_file()} method. 14005 14006@geindex gccjit;;context;;compile_to_file (C++ function) 14007@anchor{cp/topics/compilation gccjit context compile_to_file__enum cCP}@anchor{1a7} 14008@deffn {C++ Function} void gccjit::context::compile_to_file (enum gcc_jit_output_kind, const char* output_path) 14009 14010Compile the @pxref{123,,gccjit;;context} to a file of the given 14011kind. 14012 14013This is a thin wrapper around the 14014@pxref{4a,,gcc_jit_context_compile_to_file()} API entrypoint. 14015@end deffn 14016 14017@c Copyright (C) 2014-2015 Free Software Foundation, Inc. 14018@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14019@c 14020@c This is free software: you can redistribute it and/or modify it 14021@c under the terms of the GNU General Public License as published by 14022@c the Free Software Foundation, either version 3 of the License, or 14023@c (at your option) any later version. 14024@c 14025@c This program is distributed in the hope that it will be useful, but 14026@c WITHOUT ANY WARRANTY; without even the implied warranty of 14027@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14028@c General Public License for more details. 14029@c 14030@c You should have received a copy of the GNU General Public License 14031@c along with this program. If not, see 14032@c <http://www.gnu.org/licenses/>. 14033 14034@node Internals,Indices and tables,C++ bindings for libgccjit,Top 14035@anchor{internals/index internals}@anchor{1aa}@anchor{internals/index doc}@anchor{1ab} 14036@chapter Internals 14037 14038 14039@menu 14040* Working on the JIT library:: 14041* Running the test suite:: 14042* Environment variables:: 14043* Packaging notes:: 14044* Overview of code structure:: 14045* Design notes:: 14046 14047@end menu 14048 14049@node Working on the JIT library,Running the test suite,,Internals 14050@anchor{internals/index working-on-the-jit-library}@anchor{1ac} 14051@section Working on the JIT library 14052 14053 14054Having checked out the source code (to "src"), you can configure and build 14055the JIT library like this: 14056 14057@example 14058mkdir build 14059mkdir install 14060PREFIX=$(pwd)/install 14061cd build 14062../src/configure \ 14063 --enable-host-shared \ 14064 --enable-languages=jit,c++ \ 14065 --disable-bootstrap \ 14066 --enable-checking=release \ 14067 --prefix=$PREFIX 14068nice make -j4 # altering the "4" to however many cores you have 14069@end example 14070 14071@noindent 14072 14073This should build a libgccjit.so within jit/build/gcc: 14074 14075@example 14076[build] $ file gcc/libgccjit.so* 14077gcc/libgccjit.so: symbolic link to `libgccjit.so.0' 14078gcc/libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' 14079gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped 14080@end example 14081 14082@noindent 14083 14084Here's what those configuration options mean: 14085 14086@geindex command line option; --enable-host-shared 14087@anchor{internals/index cmdoption--enable-host-shared}@anchor{1ad} 14088@deffn {Option} --enable-host-shared 14089 14090Configuring with this option means that the compiler is built as 14091position-independent code, which incurs a slight performance hit, 14092but it necessary for a shared library. 14093@end deffn 14094 14095@geindex command line option; --enable-languages=jit@comma{}c++ 14096@anchor{internals/index cmdoption--enable-languages}@anchor{1ae} 14097@deffn {Option} --enable-languages=jit,c++ 14098 14099This specifies which frontends to build. The JIT library looks like 14100a frontend to the rest of the code. 14101 14102The C++ portion of the JIT test suite requires the C++ frontend to be 14103enabled at configure-time, or you may see errors like this when 14104running the test suite: 14105 14106@example 14107xgcc: error: /home/david/jit/src/gcc/testsuite/jit.dg/test-quadratic.cc: C++ compiler not installed on this system 14108c++: error trying to exec 'cc1plus': execvp: No such file or directory 14109@end example 14110 14111@noindent 14112@end deffn 14113 14114@geindex command line option; --disable-bootstrap 14115@anchor{internals/index cmdoption--disable-bootstrap}@anchor{1af} 14116@deffn {Option} --disable-bootstrap 14117 14118For hacking on the "jit" subdirectory, performing a full 14119bootstrap can be overkill, since it's unused by a bootstrap. However, 14120when submitting patches, you should remove this option, to ensure that 14121the compiler can still bootstrap itself. 14122@end deffn 14123 14124@geindex command line option; --enable-checking=release 14125@anchor{internals/index cmdoption--enable-checking}@anchor{1b0} 14126@deffn {Option} --enable-checking=release 14127 14128The compile can perform extensive self-checking as it runs, useful when 14129debugging, but slowing things down. 14130 14131For maximum speed, configure with @code{--enable-checking=release} to 14132disable this self-checking. 14133@end deffn 14134 14135@node Running the test suite,Environment variables,Working on the JIT library,Internals 14136@anchor{internals/index running-the-test-suite}@anchor{1b1} 14137@section Running the test suite 14138 14139 14140@example 14141[build] $ cd gcc 14142[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v" 14143@end example 14144 14145@noindent 14146 14147A summary of the tests can then be seen in: 14148 14149@example 14150jit/build/gcc/testsuite/jit/jit.sum 14151@end example 14152 14153@noindent 14154 14155and detailed logs in: 14156 14157@example 14158jit/build/gcc/testsuite/jit/jit.log 14159@end example 14160 14161@noindent 14162 14163The test executables can be seen as: 14164 14165@example 14166jit/build/gcc/testsuite/jit/*.exe 14167@end example 14168 14169@noindent 14170 14171which can be run independently. 14172 14173You can compile and run individual tests by passing "jit.exp=TESTNAME" to RUNTESTFLAGS e.g.: 14174 14175@example 14176[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v jit.exp=test-factorial.c" 14177@end example 14178 14179@noindent 14180 14181and once a test has been compiled, you can debug it directly: 14182 14183@example 14184[gcc] $ PATH=.:$PATH \ 14185 LD_LIBRARY_PATH=. \ 14186 LIBRARY_PATH=. \ 14187 gdb --args \ 14188 testsuite/jit/test-factorial.c.exe 14189@end example 14190 14191@noindent 14192 14193@menu 14194* Running under valgrind:: 14195 14196@end menu 14197 14198@node Running under valgrind,,,Running the test suite 14199@anchor{internals/index running-under-valgrind}@anchor{1b2} 14200@subsection Running under valgrind 14201 14202 14203The jit testsuite detects if RUN_UNDER_VALGRIND is present in the 14204environment (with any value). If it is present, it runs the test client 14205code under valgrind@footnote{http://valgrind.org}, 14206specifcally, the default 14207memcheck@footnote{http://valgrind.org/docs/manual/mc-manual.html} 14208tool with 14209--leak-check=full@footnote{http://valgrind.org/docs/manual/mc-manual.html#opt.leak-check}. 14210 14211It automatically parses the output from valgrind, injecting XFAIL results if 14212any issues are found, or PASS results if the output is clean. The output 14213is saved to @code{TESTNAME.exe.valgrind.txt}. 14214 14215For example, the following invocation verbosely runs the testcase 14216@code{test-sum-of-squares.c} under valgrind, showing an issue: 14217 14218@example 14219$ RUN_UNDER_VALGRIND= \ 14220 make check-jit \ 14221 RUNTESTFLAGS="-v -v -v jit.exp=test-sum-of-squares.c" 14222 14223(...verbose log contains detailed valgrind errors, if any...) 14224 14225 === jit Summary === 14226 14227# of expected passes 28 14228# of expected failures 2 14229 14230$ less testsuite/jit/jit.sum 14231(...other results...) 14232XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: definitely lost: 8 bytes in 1 blocks 14233XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: unsuppressed errors: 1 14234(...other results...) 14235 14236$ less testsuite/jit/test-sum-of-squares.c.exe.valgrind.txt 14237(...shows full valgrind report for this test case...) 14238@end example 14239 14240@noindent 14241 14242When running under valgrind, it's best to have configured gcc with 14243@code{--enable-valgrind-annotations}, which automatically suppresses 14244various known false positives. 14245 14246@node Environment variables,Packaging notes,Running the test suite,Internals 14247@anchor{internals/index environment-variables}@anchor{1b3} 14248@section Environment variables 14249 14250 14251When running client code against a locally-built libgccjit, three 14252environment variables need to be set up: 14253 14254@geindex environment variable; LD_LIBRARY_PATH 14255@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{1b4} 14256@deffn {Environment Variable} LD_LIBRARY_PATH 14257 14258@quotation 14259 14260@cite{libgccjit.so} is dynamically linked into client code, so if running 14261against a locally-built library, @code{LD_LIBRARY_PATH} needs to be set 14262up appropriately. The library can be found within the "gcc" 14263subdirectory of the build tree: 14264@end quotation 14265 14266@example 14267$ file libgccjit.so* 14268libgccjit.so: symbolic link to `libgccjit.so.0' 14269libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' 14270libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, not stripped 14271@end example 14272 14273@noindent 14274@end deffn 14275 14276@geindex environment variable; PATH 14277@anchor{internals/index envvar-PATH}@anchor{1b5} 14278@deffn {Environment Variable} PATH 14279 14280The library uses a driver executable for converting from .s assembler 14281files to .so shared libraries. Specifically, it looks for a name 14282expanded from 14283@code{$@{target_noncanonical@}-gcc-$@{gcc_BASEVER@}$@{exeext@}} 14284such as @code{x86_64-unknown-linux-gnu-gcc-5.0.0}. 14285 14286Hence @code{PATH} needs to include a directory where the library can 14287locate this executable. 14288 14289The executable is normally installed to the installation bindir 14290(e.g. /usr/bin), but a copy is also created within the "gcc" 14291subdirectory of the build tree for running the testsuite, and for ease 14292of development. 14293@end deffn 14294 14295@geindex environment variable; LIBRARY_PATH 14296@anchor{internals/index envvar-LIBRARY_PATH}@anchor{1b6} 14297@deffn {Environment Variable} LIBRARY_PATH 14298 14299The driver executable invokes the linker, and the latter needs to locate 14300support libraries needed by the generated code, or you will see errors 14301like: 14302 14303@example 14304ld: cannot find crtbeginS.o: No such file or directory 14305ld: cannot find -lgcc 14306ld: cannot find -lgcc_s 14307@end example 14308 14309@noindent 14310 14311Hence if running directly from a locally-built copy (without installing), 14312@code{LIBRARY_PATH} needs to contain the "gcc" subdirectory of the build 14313tree. 14314@end deffn 14315 14316For example, to run a binary that uses the library against a non-installed 14317build of the library in LIBGCCJIT_BUILD_DIR you need an invocation of the 14318client code like this, to preprend the dir to each of the environment 14319variables: 14320 14321@example 14322$ LD_LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LD_LIBRARY_PATH) \ 14323 PATH=$(LIBGCCJIT_BUILD_DIR):$(PATH) \ 14324 LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LIBRARY_PATH) \ 14325 ./jit-hello-world 14326hello world 14327@end example 14328 14329@noindent 14330 14331@node Packaging notes,Overview of code structure,Environment variables,Internals 14332@anchor{internals/index packaging-notes}@anchor{1b7} 14333@section Packaging notes 14334 14335 14336The configure-time option @pxref{1ad,,--enable-host-shared} is needed when 14337building the jit in order to get position-independent code. This will 14338slow down the regular compiler by a few percent. Hence when packaging gcc 14339with libgccjit, please configure and build twice: 14340 14341@quotation 14342 14343 14344@itemize * 14345 14346@item 14347once without @pxref{1ad,,--enable-host-shared} for most languages, and 14348 14349@item 14350once with @pxref{1ad,,--enable-host-shared} for the jit 14351@end itemize 14352@end quotation 14353 14354For example: 14355 14356@example 14357# Configure and build with --enable-host-shared 14358# for the jit: 14359mkdir configuration-for-jit 14360pushd configuration-for-jit 14361$(SRCDIR)/configure \ 14362 --enable-host-shared \ 14363 --enable-languages=jit \ 14364 --prefix=$(DESTDIR) 14365make 14366popd 14367 14368# Configure and build *without* --enable-host-shared 14369# for maximum speed: 14370mkdir standard-configuration 14371pushd standard-configuration 14372$(SRCDIR)/configure \ 14373 --enable-languages=all \ 14374 --prefix=$(DESTDIR) 14375make 14376popd 14377 14378# Both of the above are configured to install to $(DESTDIR) 14379# Install the configuration with --enable-host-shared first 14380# *then* the one without, so that the faster build 14381# of "cc1" et al overwrites the slower build. 14382pushd configuration-for-jit 14383make install 14384popd 14385 14386pushd standard-configuration 14387make install 14388popd 14389@end example 14390 14391@noindent 14392 14393@node Overview of code structure,Design notes,Packaging notes,Internals 14394@anchor{internals/index overview-of-code-structure}@anchor{1b8} 14395@section Overview of code structure 14396 14397 14398 14399@itemize * 14400 14401@item 14402@code{libgccjit.c} implements the API entrypoints. It performs error 14403checking, then calls into classes of the gcc::jit::recording namespace 14404within @code{jit-recording.c} and @code{jit-recording.h}. 14405 14406@item 14407The gcc::jit::recording classes (within @code{jit-recording.c} and 14408@code{jit-recording.h}) record the API calls that are made: 14409 14410@quotation 14411 14412@example 14413 14414 /* Indentation indicates inheritance: */ 14415 class context; 14416 class memento; 14417 class string; 14418 class location; 14419 class type; 14420 class function_type; 14421 class compound_type; 14422 class struct_; 14423 class union_; 14424 class field; 14425 class fields; 14426 class function; 14427 class block; 14428 class rvalue; 14429 class lvalue; 14430 class local; 14431 class global; 14432 class param; 14433 class statement; 14434 class case_; 14435 14436 14437@end example 14438 14439@noindent 14440@end quotation 14441 14442@item 14443When the context is compiled, the gcc::jit::playback classes (within 14444@code{jit-playback.c} and @code{jit-playback.h}) replay the API calls 14445within langhook:parse_file: 14446 14447@quotation 14448 14449@example 14450 14451 /* Indentation indicates inheritance: */ 14452 class context; 14453 class wrapper; 14454 class type; 14455 class compound_type; 14456 class field; 14457 class function; 14458 class block; 14459 class rvalue; 14460 class lvalue; 14461 class param; 14462 class source_file; 14463 class source_line; 14464 class location; 14465 class case_; 14466 14467 14468@end example 14469 14470@noindent 14471 14472@example 14473Client Code . Generated . libgccjit.so 14474 . code . 14475 . . JIT API . JIT "Frontend". (libbackend.a) 14476.................................................................................... 14477 ��� . . . . 14478 ������������������������������������������������������������������������������> . . 14479 . . ��� . . 14480 . . V . . 14481 . . ������> libgccjit.c . 14482 . . ��� (error-checking). 14483 . . ��� . 14484 . . ������> jit-recording.c 14485 . . (record API calls) 14486 . . <��������������������� . 14487 . . ��� . . 14488 <��������������������������������������������������������������������������������� . . 14489 ��� . . . . 14490 ��� . . . . 14491 V . . gcc_jit_context_compile . 14492 ������������������������������������������������������������������������������> . . 14493 . . ��� start of recording::context::compile () 14494 . . ��� . . 14495 . . ��� start of playback::context::compile () 14496 . . ��� (create tempdir) . 14497 . . ��� . . 14498 . . ��� ACQUIRE MUTEX . 14499 . . ��� . . 14500 . . V���������������������������������������������������������������������> toplev::main (for now) 14501 . . . . ��� 14502 . . . . (various code) 14503 . . . . ��� 14504 . . . . V 14505 . . . <��������������������������������������������������� langhook:parse_file 14506 . . . ��� . 14507 . . . ��� (jit_langhook_parse_file) 14508 . . . ��� . 14509..........................................���..................VVVVVVVVVVVVV... 14510 . . . ��� . No GC in here 14511 . . . ��� jit-playback.c 14512 . . . ��� (playback of API calls) 14513 . . . ���������������������������������������������> creation of functions, 14514 . . . . types, expression trees 14515 . . . <������������������������������������������������ etc 14516 . . . ���(handle_locations: add locations to 14517 . . . ��� linemap and associate them with trees) 14518 . . . ��� . 14519 . . . ��� . No GC in here 14520..........................................���..................AAAAAAAAAAAAA... 14521 . . . ��� for each function 14522 . . . ������> postprocess 14523 . . . ��� . 14524 . . . ������������������������������������> cgraph_finalize_function 14525 . . . <������������������������������������ 14526 . . . <������ . 14527 . . . ��� . 14528 . . . ������������������������������������������������������> (end of 14529 . . . . ��� langhook_parse_file) 14530 . . . . ��� 14531 . . . . (various code) 14532 . . . . ��� 14533 . . . . ��� 14534 . . . <��������������������������������������������������� langhook:write_globals 14535 . . . ��� . 14536 . . . ��� (jit_langhook_write_globals) 14537 . . . ��� . 14538 . . . ��� . 14539 . . . ������������������������������������������������������> finalize_compilation_unit 14540 . . . . ��� 14541 . . . . (the middle���end and backend) 14542 . . . . ��� 14543 . . <��������������������������������������������������������������������������������������� end of toplev::main 14544 . . ��� . . 14545 . . V���������������������������������������������������������������������> toplev::finalize 14546 . . . . ��� (purge internal state) 14547 . . <������������������������������������������������������������������������ end of toplev::finalize 14548 . . ��� . . 14549 . . V���> playback::context::postprocess: 14550 . . ��� . . 14551 . . ��� (assuming an in-memory compile): 14552 . . ��� . . 14553 . . ��� . Convert assembler to DSO ("fake.so") 14554 . . ��� . . 14555 . . ��� . Load DSO (dlopen "fake.so") 14556 . . ��� . . 14557 . . ��� . Bundle it up in a jit::result 14558 . . <������ . . 14559 . . ��� . . 14560 . . ��� RELEASE MUTEX . 14561 . . ��� . . 14562 . . ��� end of playback::context::compile () 14563 . . ��� . . 14564 . . ��� playback::context dtor 14565 . . ������> . . 14566 . . ��� Normally we cleanup the tempdir here: 14567 . . ��� ("fake.so" is unlinked from the 14568 . . ��� filesystem at this point) 14569 . . ��� If the client code requested debuginfo, the 14570 . . ��� cleanup happens later (in gcc_jit_result_release) 14571 . . ��� to make it easier on the debugger (see PR jit/64206) 14572 . . <������ . . 14573 . . ��� . . 14574 . . ��� end of recording::context::compile () 14575 <��������������������������������������������������������������������������������� . . 14576 ��� . . . . 14577 V . . gcc_jit_result_get_code . 14578 ������������������������������������������������������������������������������> . . 14579 . . ��� dlsym () within loaded DSO 14580 <��������������������������������������������������������������������������������� . . 14581 Get (void*). . . . 14582 ��� . . . . 14583 ��� Call it . . . . 14584 ���������������������������������������������> . . . 14585 . ��� . . . 14586 . ��� . . . 14587 <��������������������������������������������� . . . 14588 ��� . . . . 14589etc��� . . . . 14590 ��� . . . . 14591 V . . gcc_jit_result_release . 14592 ������������������������������������������������������������������������������> . . 14593 . . ��� dlclose () the loaded DSO 14594 . . ��� (code becomes uncallable) 14595 . . ��� . . 14596 . . ��� If the client code requested debuginfo, then 14597 . . ��� cleanup of the tempdir was delayed. 14598 . . ��� If that was the case, clean it up now. 14599 <��������������������������������������������������������������������������������� . . 14600 ��� . . . . 14601 14602@end example 14603 14604@noindent 14605@end quotation 14606@end itemize 14607 14608Here is a high-level summary from @code{jit-common.h}: 14609 14610@quotation 14611 14612In order to allow jit objects to be usable outside of a compile 14613whilst working with the existing structure of GCC's code the 14614C API is implemented in terms of a gcc::jit::recording::context, 14615which records the calls made to it. 14616 14617When a gcc_jit_context is compiled, the recording context creates a 14618playback context. The playback context invokes the bulk of the GCC 14619code, and within the "frontend" parsing hook, plays back the recorded 14620API calls, creating GCC tree objects. 14621 14622So there are two parallel families of classes: those relating to 14623recording, and those relating to playback: 14624 14625 14626@itemize * 14627 14628@item 14629Visibility: recording objects are exposed back to client code, 14630whereas playback objects are internal to the library. 14631 14632@item 14633Lifetime: recording objects have a lifetime equal to that of the 14634recording context that created them, whereas playback objects only 14635exist within the frontend hook. 14636 14637@item 14638Memory allocation: recording objects are allocated by the recording 14639context, and automatically freed by it when the context is released, 14640whereas playback objects are allocated within the GC heap, and 14641garbage-collected; they can own GC-references. 14642 14643@item 14644Integration with rest of GCC: recording objects are unrelated to the 14645rest of GCC, whereas playback objects are wrappers around "tree" 14646instances. Hence you can't ask a recording rvalue or lvalue what its 14647type is, whereas you can for a playback rvalue of lvalue (since it 14648can work with the underlying GCC tree nodes). 14649 14650@item 14651Instancing: There can be multiple recording contexts "alive" at once 14652(albeit it only one compiling at once), whereas there can only be one 14653playback context alive at one time (since it interacts with the GC). 14654@end itemize 14655 14656Ultimately if GCC could support multiple GC heaps and contexts, and 14657finer-grained initialization, then this recording vs playback 14658distinction could be eliminated. 14659 14660During a playback, we associate objects from the recording with 14661their counterparts during this playback. For simplicity, we store this 14662within the recording objects, as @code{void *m_playback_obj}, casting it to 14663the appropriate playback object subclass. For these casts to make 14664sense, the two class hierarchies need to have the same structure. 14665 14666Note that the playback objects that @code{m_playback_obj} points to are 14667GC-allocated, but the recording objects don't own references: 14668these associations only exist within a part of the code where 14669the GC doesn't collect, and are set back to NULL before the GC can 14670run. 14671@end quotation 14672@anchor{internals/index example-of-log-file}@anchor{5c} 14673Another way to understand the structure of the code is to enable logging, 14674via @pxref{5b,,gcc_jit_context_set_logfile()}. Here is an example of a log 14675generated via this call: 14676 14677@example 14678JIT: libgccjit (GCC) version 5.2.1 20150723 (x86_64-unknown-linux-gnu) 14679JIT: 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 14680JIT: entering: gcc_jit_context_set_str_option 14681JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe" 14682JIT: exiting: gcc_jit_context_set_str_option 14683JIT: entering: gcc_jit_context_set_int_option 14684JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3 14685JIT: exiting: gcc_jit_context_set_int_option 14686JIT: entering: gcc_jit_context_set_bool_option 14687JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true 14688JIT: exiting: gcc_jit_context_set_bool_option 14689JIT: entering: gcc_jit_context_set_bool_option 14690JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false 14691JIT: exiting: gcc_jit_context_set_bool_option 14692JIT: entering: gcc_jit_context_set_bool_option 14693JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false 14694JIT: exiting: gcc_jit_context_set_bool_option 14695JIT: entering: gcc_jit_context_set_bool_option 14696JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true 14697JIT: exiting: gcc_jit_context_set_bool_option 14698JIT: entering: gcc_jit_context_set_bool_option 14699JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false 14700JIT: exiting: gcc_jit_context_set_bool_option 14701JIT: entering: gcc_jit_context_get_type 14702JIT: exiting: gcc_jit_context_get_type 14703JIT: entering: gcc_jit_context_get_type 14704JIT: exiting: gcc_jit_context_get_type 14705JIT: entering: gcc_jit_context_new_param 14706JIT: exiting: gcc_jit_context_new_param 14707JIT: entering: gcc_jit_context_new_function 14708JIT: exiting: gcc_jit_context_new_function 14709JIT: entering: gcc_jit_context_new_param 14710JIT: exiting: gcc_jit_context_new_param 14711JIT: entering: gcc_jit_context_get_type 14712JIT: exiting: gcc_jit_context_get_type 14713JIT: entering: gcc_jit_context_new_function 14714JIT: exiting: gcc_jit_context_new_function 14715JIT: entering: gcc_jit_context_new_string_literal 14716JIT: exiting: gcc_jit_context_new_string_literal 14717JIT: entering: gcc_jit_function_new_block 14718JIT: exiting: gcc_jit_function_new_block 14719JIT: entering: gcc_jit_block_add_comment 14720JIT: exiting: gcc_jit_block_add_comment 14721JIT: entering: gcc_jit_context_new_call 14722JIT: exiting: gcc_jit_context_new_call 14723JIT: entering: gcc_jit_block_add_eval 14724JIT: exiting: gcc_jit_block_add_eval 14725JIT: entering: gcc_jit_block_end_with_void_return 14726JIT: exiting: gcc_jit_block_end_with_void_return 14727JIT: entering: gcc_jit_context_dump_reproducer_to_file 14728JIT: entering: void gcc::jit::recording::context::dump_reproducer_to_file(const char*) 14729JIT: exiting: void gcc::jit::recording::context::dump_reproducer_to_file(const char*) 14730JIT: exiting: gcc_jit_context_dump_reproducer_to_file 14731JIT: entering: gcc_jit_context_compile 14732JIT: in-memory compile of ctxt: 0x1283e20 14733JIT: entering: gcc::jit::result* gcc::jit::recording::context::compile() 14734JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe" 14735JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3 14736JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true 14737JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false 14738JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false 14739JIT: GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE: false 14740JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false 14741JIT: GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING: false 14742JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true 14743JIT: GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES: false 14744JIT: gcc_jit_context_set_bool_allow_unreachable_blocks: false 14745JIT: entering: void gcc::jit::recording::context::validate() 14746JIT: exiting: void gcc::jit::recording::context::validate() 14747JIT: entering: gcc::jit::playback::context::context(gcc::jit::recording::context*) 14748JIT: exiting: gcc::jit::playback::context::context(gcc::jit::recording::context*) 14749JIT: entering: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*) 14750JIT: exiting: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*) 14751JIT: entering: void gcc::jit::playback::context::compile() 14752JIT: entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int) 14753JIT: exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int) 14754JIT: entering: bool gcc::jit::tempdir::create() 14755JIT: m_path_template: /tmp/libgccjit-XXXXXX 14756JIT: m_path_tempdir: /tmp/libgccjit-CKq1M9 14757JIT: exiting: bool gcc::jit::tempdir::create() 14758JIT: entering: void gcc::jit::playback::context::acquire_mutex() 14759JIT: exiting: void gcc::jit::playback::context::acquire_mutex() 14760JIT: entering: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*) 14761JIT: reusing cached configure-time options 14762JIT: configure_time_options[0]: -mtune=generic 14763JIT: configure_time_options[1]: -march=x86-64 14764JIT: exiting: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*) 14765JIT: entering: toplev::main 14766JIT: argv[0]: ./test-hello-world.c.exe 14767JIT: argv[1]: /tmp/libgccjit-CKq1M9/fake.c 14768JIT: argv[2]: -fPIC 14769JIT: argv[3]: -O3 14770JIT: argv[4]: -g 14771JIT: argv[5]: -quiet 14772JIT: argv[6]: --param 14773JIT: argv[7]: ggc-min-expand=0 14774JIT: argv[8]: --param 14775JIT: argv[9]: ggc-min-heapsize=0 14776JIT: argv[10]: -mtune=generic 14777JIT: argv[11]: -march=x86-64 14778JIT: entering: bool jit_langhook_init() 14779JIT: exiting: bool jit_langhook_init() 14780JIT: entering: void gcc::jit::playback::context::replay() 14781JIT: entering: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*) 14782JIT: exiting: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*) 14783JIT: entering: void gcc::jit::recording::context::disassociate_from_playback() 14784JIT: exiting: void gcc::jit::recording::context::disassociate_from_playback() 14785JIT: entering: void gcc::jit::playback::context::handle_locations() 14786JIT: exiting: void gcc::jit::playback::context::handle_locations() 14787JIT: entering: void gcc::jit::playback::function::build_stmt_list() 14788JIT: exiting: void gcc::jit::playback::function::build_stmt_list() 14789JIT: entering: void gcc::jit::playback::function::build_stmt_list() 14790JIT: exiting: void gcc::jit::playback::function::build_stmt_list() 14791JIT: entering: void gcc::jit::playback::function::postprocess() 14792JIT: exiting: void gcc::jit::playback::function::postprocess() 14793JIT: entering: void gcc::jit::playback::function::postprocess() 14794JIT: exiting: void gcc::jit::playback::function::postprocess() 14795JIT: exiting: void gcc::jit::playback::context::replay() 14796JIT: entering: void jit_langhook_write_globals() 14797JIT: entering: void gcc::jit::playback::context::write_global_decls_1() 14798JIT: exiting: void gcc::jit::playback::context::write_global_decls_1() 14799JIT: entering: void gcc::jit::playback::context::write_global_decls_2() 14800JIT: exiting: void gcc::jit::playback::context::write_global_decls_2() 14801JIT: exiting: void jit_langhook_write_globals() 14802JIT: exiting: toplev::main 14803JIT: entering: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*) 14804JIT: exiting: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*) 14805JIT: entering: toplev::finalize 14806JIT: exiting: toplev::finalize 14807JIT: entering: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*) 14808JIT: entering: void gcc::jit::playback::context::convert_to_dso(const char*) 14809JIT: entering: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool) 14810JIT: entering: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*) 14811JIT: exiting: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*) 14812JIT: argv[0]: x86_64-unknown-linux-gnu-gcc-5.2.1 14813JIT: argv[1]: -m64 14814JIT: argv[2]: -shared 14815JIT: argv[3]: /tmp/libgccjit-CKq1M9/fake.s 14816JIT: argv[4]: -o 14817JIT: argv[5]: /tmp/libgccjit-CKq1M9/fake.so 14818JIT: argv[6]: -fno-use-linker-plugin 14819JIT: argv[7]: (null) 14820JIT: exiting: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool) 14821JIT: exiting: void gcc::jit::playback::context::convert_to_dso(const char*) 14822JIT: entering: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso() 14823JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir to jit::result 14824JIT: entering: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*) 14825JIT: exiting: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*) 14826JIT: exiting: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso() 14827JIT: exiting: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*) 14828JIT: entering: void gcc::jit::playback::context::release_mutex() 14829JIT: exiting: void gcc::jit::playback::context::release_mutex() 14830JIT: exiting: void gcc::jit::playback::context::compile() 14831JIT: entering: gcc::jit::playback::context::~context() 14832JIT: exiting: gcc::jit::playback::context::~context() 14833JIT: exiting: gcc::jit::result* gcc::jit::recording::context::compile() 14834JIT: gcc_jit_context_compile: returning (gcc_jit_result *)0x12f75d0 14835JIT: exiting: gcc_jit_context_compile 14836JIT: entering: gcc_jit_result_get_code 14837JIT: locating fnname: hello_world 14838JIT: entering: void* gcc::jit::result::get_code(const char*) 14839JIT: exiting: void* gcc::jit::result::get_code(const char*) 14840JIT: gcc_jit_result_get_code: returning (void *)0x7ff6b8cd87f0 14841JIT: exiting: gcc_jit_result_get_code 14842JIT: entering: gcc_jit_context_release 14843JIT: deleting ctxt: 0x1283e20 14844JIT: entering: gcc::jit::recording::context::~context() 14845JIT: exiting: gcc::jit::recording::context::~context() 14846JIT: exiting: gcc_jit_context_release 14847JIT: entering: gcc_jit_result_release 14848JIT: deleting result: 0x12f75d0 14849JIT: entering: virtual gcc::jit::result::~result() 14850JIT: entering: gcc::jit::tempdir::~tempdir() 14851JIT: unlinking .s file: /tmp/libgccjit-CKq1M9/fake.s 14852JIT: unlinking .so file: /tmp/libgccjit-CKq1M9/fake.so 14853JIT: removing tempdir: /tmp/libgccjit-CKq1M9 14854JIT: exiting: gcc::jit::tempdir::~tempdir() 14855JIT: exiting: virtual gcc::jit::result::~result() 14856JIT: exiting: gcc_jit_result_release 14857JIT: gcc::jit::logger::~logger() 14858 14859@end example 14860 14861@noindent 14862 14863@node Design notes,,Overview of code structure,Internals 14864@anchor{internals/index design-notes}@anchor{1b9} 14865@section Design notes 14866 14867 14868It should not be possible for client code to cause an internal compiler 14869error. If this @emph{does} happen, the root cause should be isolated (perhaps 14870using @pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}) and the cause 14871should be rejected via additional checking. The checking ideally should 14872be within the libgccjit API entrypoints in libgccjit.c, since this is as 14873close as possible to the error; failing that, a good place is within 14874@code{recording::context::validate ()} in jit-recording.c. 14875 14876@node Indices and tables,Index,Internals,Top 14877@anchor{index indices-and-tables}@anchor{1ba} 14878@unnumbered Indices and tables 14879 14880 14881 14882@itemize * 14883 14884@item 14885@emph{genindex} 14886 14887@item 14888@emph{modindex} 14889 14890@item 14891@emph{search} 14892@end itemize 14893 14894@c Some notes: 14895@c 14896@c The Sphinx C domain appears to lack explicit support for enum values, 14897@c so I've been using :c:macro: for them. 14898@c 14899@c See http://sphinx-doc.org/domains.html#the-c-domain 14900 14901@node Index,,Indices and tables,Top 14902@unnumbered Index 14903 14904 14905@printindex ge 14906 14907@c %**end of body 14908@bye 14909