libgccjit.texi revision 1.1.1.2
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 6.0.0 (experimental 20160108), January 19, 2016 23 24David Malcolm 25 26Copyright @copyright{} 2014-2016 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-2016 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-2016 Free Software Foundation, Inc. 89@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 90@c 91@c This is free software: you can redistribute it and/or modify it 92@c under the terms of the GNU General Public License as published by 93@c the Free Software Foundation, either version 3 of the License, or 94@c (at your option) any later version. 95@c 96@c This program is distributed in the hope that it will be useful, but 97@c WITHOUT ANY WARRANTY; without even the implied warranty of 98@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 99@c General Public License for more details. 100@c 101@c You should have received a copy of the GNU General Public License 102@c along with this program. If not, see 103@c <http://www.gnu.org/licenses/>. 104 105@menu 106* Tutorial:: 107* Topic Reference:: 108* C++ bindings for libgccjit:: 109* Internals:: 110* Indices and tables:: 111* Index:: 112 113@detailmenu 114 --- The Detailed Node Listing --- 115 116Tutorial 117 118* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world". 119* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function. 120* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables. 121* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter. 122* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler. 123 124Tutorial part 2: Creating a trivial machine code function 125 126* Error-handling:: 127* Options:: 128* Full example:: 129 130Tutorial part 3: Loops and variables 131 132* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. 133* Control flow:: 134* Visualizing the control flow graph:: 135* Full example: Full example<2>. 136 137Tutorial part 4: Adding JIT-compilation to a toy interpreter 138 139* Our toy interpreter:: 140* Compiling to machine code:: 141* Setting things up:: 142* Populating the function:: 143* Verifying the control flow graph:: 144* Compiling the context:: 145* Single-stepping through the generated code:: 146* Examining the generated code:: 147* Putting it all together:: 148* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?. 149 150Behind the curtain: How does our code get optimized? 151 152* Optimizing away stack manipulation:: 153* Elimination of tail recursion:: 154 155Tutorial part 5: Implementing an Ahead-of-Time compiler 156 157* The "brainf" language:: 158* Converting a brainf script to libgccjit IR:: 159* Compiling a context to a file:: 160* Other forms of ahead-of-time-compilation:: 161 162Topic Reference 163 164* Compilation contexts:: 165* Objects:: 166* Types:: 167* Expressions:: 168* Creating and using functions:: 169* Source Locations:: 170* Compiling a context:: 171* ABI and API compatibility:: 172* Performance:: 173 174Compilation contexts 175 176* Lifetime-management:: 177* Thread-safety:: 178* Error-handling: Error-handling<2>. 179* Debugging:: 180* Options: Options<2>. 181 182Options 183 184* String Options:: 185* Boolean options:: 186* Integer options:: 187* Additional command-line options:: 188 189Types 190 191* Standard types:: 192* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 193* Structures and unions:: 194 195Expressions 196 197* Rvalues:: 198* Lvalues:: 199* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 200 201Rvalues 202 203* Simple expressions:: 204* Unary Operations:: 205* Binary Operations:: 206* Comparisons:: 207* Function calls:: 208* Type-coercion:: 209 210Lvalues 211 212* Global variables:: 213 214Creating and using functions 215 216* Params:: 217* Functions:: 218* Blocks:: 219* Statements:: 220 221Source Locations 222 223* Faking it:: 224 225Compiling a context 226 227* In-memory compilation:: 228* Ahead-of-time compilation:: 229 230ABI and API compatibility 231 232* ABI symbol tags:: 233 234ABI symbol tags 235 236* LIBGCCJIT_ABI_0:: 237* LIBGCCJIT_ABI_1:: 238* LIBGCCJIT_ABI_2:: 239* LIBGCCJIT_ABI_3:: 240* LIBGCCJIT_ABI_4:: 241* LIBGCCJIT_ABI_5:: 242 243Performance 244 245* The timing API:: 246 247C++ bindings for libgccjit 248 249* Tutorial: Tutorial<2>. 250* Topic Reference: Topic Reference<2>. 251 252Tutorial 253 254* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 255* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 256* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 257* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 258 259Tutorial part 2: Creating a trivial machine code function 260 261* Options: Options<3>. 262* Full example: Full example<3>. 263 264Tutorial part 3: Loops and variables 265 266* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 267* Control flow: Control flow<2>. 268* Visualizing the control flow graph: Visualizing the control flow graph<2>. 269* Full example: Full example<4>. 270 271Tutorial part 4: Adding JIT-compilation to a toy interpreter 272 273* Our toy interpreter: Our toy interpreter<2>. 274* Compiling to machine code: Compiling to machine code<2>. 275* Setting things up: Setting things up<2>. 276* Populating the function: Populating the function<2>. 277* Verifying the control flow graph: Verifying the control flow graph<2>. 278* Compiling the context: Compiling the context<2>. 279* Single-stepping through the generated code: Single-stepping through the generated code<2>. 280* Examining the generated code: Examining the generated code<2>. 281* Putting it all together: Putting it all together<2>. 282* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 283 284Behind the curtain: How does our code get optimized? 285 286* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 287* Elimination of tail recursion: Elimination of tail recursion<2>. 288 289Topic Reference 290 291* Compilation contexts: Compilation contexts<2>. 292* Objects: Objects<2>. 293* Types: Types<2>. 294* Expressions: Expressions<2>. 295* Creating and using functions: Creating and using functions<2>. 296* Source Locations: Source Locations<2>. 297* Compiling a context: Compiling a context<2>. 298 299Compilation contexts 300 301* Lifetime-management: Lifetime-management<2>. 302* Thread-safety: Thread-safety<2>. 303* Error-handling: Error-handling<3>. 304* Debugging: Debugging<2>. 305* Options: Options<4>. 306 307Options 308 309* String Options: String Options<2>. 310* Boolean options: Boolean options<2>. 311* Integer options: Integer options<2>. 312* Additional command-line options: Additional command-line options<2>. 313 314Types 315 316* Standard types: Standard types<2>. 317* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 318* Structures and unions: Structures and unions<2>. 319 320Expressions 321 322* Rvalues: Rvalues<2>. 323* Lvalues: Lvalues<2>. 324* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 325 326Rvalues 327 328* Simple expressions: Simple expressions<2>. 329* Unary Operations: Unary Operations<2>. 330* Binary Operations: Binary Operations<2>. 331* Comparisons: Comparisons<2>. 332* Function calls: Function calls<2>. 333* Type-coercion: Type-coercion<2>. 334 335Lvalues 336 337* Global variables: Global variables<2>. 338 339Creating and using functions 340 341* Params: Params<2>. 342* Functions: Functions<2>. 343* Blocks: Blocks<2>. 344* Statements: Statements<2>. 345 346Source Locations 347 348* Faking it: Faking it<2>. 349 350Compiling a context 351 352* In-memory compilation: In-memory compilation<2>. 353* Ahead-of-time compilation: Ahead-of-time compilation<2>. 354 355Internals 356 357* Working on the JIT library:: 358* Running the test suite:: 359* Environment variables:: 360* Packaging notes:: 361* Overview of code structure:: 362* Design notes:: 363* Submitting patches:: 364 365Running the test suite 366 367* Running under valgrind:: 368 369@end detailmenu 370@end menu 371 372 373@node Tutorial,Topic Reference,Top,Top 374@anchor{intro/index libgccjit}@anchor{1}@anchor{intro/index doc}@anchor{2}@anchor{intro/index tutorial}@anchor{3} 375@chapter Tutorial 376 377 378@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 379@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 380@c 381@c This is free software: you can redistribute it and/or modify it 382@c under the terms of the GNU General Public License as published by 383@c the Free Software Foundation, either version 3 of the License, or 384@c (at your option) any later version. 385@c 386@c This program is distributed in the hope that it will be useful, but 387@c WITHOUT ANY WARRANTY; without even the implied warranty of 388@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 389@c General Public License for more details. 390@c 391@c You should have received a copy of the GNU General Public License 392@c along with this program. If not, see 393@c <http://www.gnu.org/licenses/>. 394 395@menu 396* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world". 397* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function. 398* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables. 399* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter. 400* Tutorial part 5; Implementing an Ahead-of-Time compiler: Tutorial part 5 Implementing an Ahead-of-Time compiler. 401 402@end menu 403 404@node Tutorial part 1 "Hello world",Tutorial part 2 Creating a trivial machine code function,,Tutorial 405@anchor{intro/tutorial01 doc}@anchor{4}@anchor{intro/tutorial01 tutorial-part-1-hello-world}@anchor{5} 406@section Tutorial part 1: "Hello world" 407 408 409Before we look at the details of the API, let's look at building and 410running programs that use the library. 411 412Here's a toy "hello world" program that uses the library to synthesize 413a call to @cite{printf} and uses it to write a message to stdout. 414 415Don't worry about the content of the program for now; we'll cover 416the details in later parts of this tutorial. 417 418@quotation 419 420@example 421/* Smoketest example for libgccjit.so 422 Copyright (C) 2014-2016 Free Software Foundation, Inc. 423 424This file is part of GCC. 425 426GCC is free software; you can redistribute it and/or modify it 427under the terms of the GNU General Public License as published by 428the Free Software Foundation; either version 3, or (at your option) 429any later version. 430 431GCC is distributed in the hope that it will be useful, but 432WITHOUT ANY WARRANTY; without even the implied warranty of 433MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 434General Public License for more details. 435 436You should have received a copy of the GNU General Public License 437along with GCC; see the file COPYING3. If not see 438<http://www.gnu.org/licenses/>. */ 439 440#include <libgccjit.h> 441 442#include <stdlib.h> 443#include <stdio.h> 444 445static void 446create_code (gcc_jit_context *ctxt) 447@{ 448 /* Let's try to inject the equivalent of: 449 void 450 greet (const char *name) 451 @{ 452 printf ("hello %s\n", name); 453 @} 454 */ 455 gcc_jit_type *void_type = 456 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); 457 gcc_jit_type *const_char_ptr_type = 458 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); 459 gcc_jit_param *param_name = 460 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); 461 gcc_jit_function *func = 462 gcc_jit_context_new_function (ctxt, NULL, 463 GCC_JIT_FUNCTION_EXPORTED, 464 void_type, 465 "greet", 466 1, ¶m_name, 467 0); 468 469 gcc_jit_param *param_format = 470 gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); 471 gcc_jit_function *printf_func = 472 gcc_jit_context_new_function (ctxt, NULL, 473 GCC_JIT_FUNCTION_IMPORTED, 474 gcc_jit_context_get_type ( 475 ctxt, GCC_JIT_TYPE_INT), 476 "printf", 477 1, ¶m_format, 478 1); 479 gcc_jit_rvalue *args[2]; 480 args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); 481 args[1] = gcc_jit_param_as_rvalue (param_name); 482 483 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 484 485 gcc_jit_block_add_eval ( 486 block, NULL, 487 gcc_jit_context_new_call (ctxt, 488 NULL, 489 printf_func, 490 2, args)); 491 gcc_jit_block_end_with_void_return (block, NULL); 492@} 493 494int 495main (int argc, char **argv) 496@{ 497 gcc_jit_context *ctxt; 498 gcc_jit_result *result; 499 500 /* Get a "context" object for working with the library. */ 501 ctxt = gcc_jit_context_acquire (); 502 if (!ctxt) 503 @{ 504 fprintf (stderr, "NULL ctxt"); 505 exit (1); 506 @} 507 508 /* Set some options on the context. 509 Let's see the code being generated, in assembler form. */ 510 gcc_jit_context_set_bool_option ( 511 ctxt, 512 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 513 0); 514 515 /* Populate the context. */ 516 create_code (ctxt); 517 518 /* Compile the code. */ 519 result = gcc_jit_context_compile (ctxt); 520 if (!result) 521 @{ 522 fprintf (stderr, "NULL result"); 523 exit (1); 524 @} 525 526 /* Extract the generated code from "result". */ 527 typedef void (*fn_type) (const char *); 528 fn_type greet = 529 (fn_type)gcc_jit_result_get_code (result, "greet"); 530 if (!greet) 531 @{ 532 fprintf (stderr, "NULL greet"); 533 exit (1); 534 @} 535 536 /* Now call the generated function: */ 537 greet ("world"); 538 fflush (stdout); 539 540 gcc_jit_context_release (ctxt); 541 gcc_jit_result_release (result); 542 return 0; 543@} 544 545@end example 546 547@noindent 548@end quotation 549 550Copy the above to @cite{tut01-hello-world.c}. 551 552Assuming you have the jit library installed, build the test program 553using: 554 555@example 556$ gcc \ 557 tut01-hello-world.c \ 558 -o tut01-hello-world \ 559 -lgccjit 560@end example 561 562@noindent 563 564You should then be able to run the built program: 565 566@example 567$ ./tut01-hello-world 568hello world 569@end example 570 571@noindent 572 573@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 574@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 575@c 576@c This is free software: you can redistribute it and/or modify it 577@c under the terms of the GNU General Public License as published by 578@c the Free Software Foundation, either version 3 of the License, or 579@c (at your option) any later version. 580@c 581@c This program is distributed in the hope that it will be useful, but 582@c WITHOUT ANY WARRANTY; without even the implied warranty of 583@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 584@c General Public License for more details. 585@c 586@c You should have received a copy of the GNU General Public License 587@c along with this program. If not, see 588@c <http://www.gnu.org/licenses/>. 589 590@node Tutorial part 2 Creating a trivial machine code function,Tutorial part 3 Loops and variables,Tutorial part 1 "Hello world",Tutorial 591@anchor{intro/tutorial02 doc}@anchor{6}@anchor{intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{7} 592@section Tutorial part 2: Creating a trivial machine code function 593 594 595Consider this C function: 596 597@example 598int square (int i) 599@{ 600 return i * i; 601@} 602@end example 603 604@noindent 605 606How can we construct this at run-time using libgccjit? 607 608First we need to include the relevant header: 609 610@example 611#include <libgccjit.h> 612@end example 613 614@noindent 615 616All state associated with compilation is associated with a 617@pxref{8,,gcc_jit_context *}. 618 619Create one using @pxref{9,,gcc_jit_context_acquire()}: 620 621@example 622gcc_jit_context *ctxt; 623ctxt = gcc_jit_context_acquire (); 624@end example 625 626@noindent 627 628The JIT library has a system of types. It is statically-typed: every 629expression is of a specific type, fixed at compile-time. In our example, 630all of the expressions are of the C @cite{int} type, so let's obtain this from 631the context, as a @pxref{a,,gcc_jit_type *}, using 632@pxref{b,,gcc_jit_context_get_type()}: 633 634@example 635gcc_jit_type *int_type = 636 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 637@end example 638 639@noindent 640 641@pxref{a,,gcc_jit_type *} is an example of a "contextual" object: every 642entity in the API is associated with a @pxref{8,,gcc_jit_context *}. 643 644Memory management is easy: all such "contextual" objects are automatically 645cleaned up for you when the context is released, using 646@pxref{c,,gcc_jit_context_release()}: 647 648@example 649gcc_jit_context_release (ctxt); 650@end example 651 652@noindent 653 654so you don't need to manually track and cleanup all objects, just the 655contexts. 656 657Although the API is C-based, there is a form of class hierarchy, which 658looks like this: 659 660@example 661+- gcc_jit_object 662 +- gcc_jit_location 663 +- gcc_jit_type 664 +- gcc_jit_struct 665 +- gcc_jit_field 666 +- gcc_jit_function 667 +- gcc_jit_block 668 +- gcc_jit_rvalue 669 +- gcc_jit_lvalue 670 +- gcc_jit_param 671@end example 672 673@noindent 674 675There are casting methods for upcasting from subclasses to parent classes. 676For example, @pxref{d,,gcc_jit_type_as_object()}: 677 678@example 679gcc_jit_object *obj = gcc_jit_type_as_object (int_type); 680@end example 681 682@noindent 683 684One thing you can do with a @pxref{e,,gcc_jit_object *} is 685to ask it for a human-readable description, using 686@pxref{f,,gcc_jit_object_get_debug_string()}: 687 688@example 689printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); 690@end example 691 692@noindent 693 694giving this text on stdout: 695 696@example 697obj: int 698@end example 699 700@noindent 701 702This is invaluable when debugging. 703 704Let's create the function. To do so, we first need to construct 705its single parameter, specifying its type and giving it a name, 706using @pxref{10,,gcc_jit_context_new_param()}: 707 708@example 709gcc_jit_param *param_i = 710 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 711@end example 712 713@noindent 714 715Now we can create the function, using 716@pxref{11,,gcc_jit_context_new_function()}: 717 718@example 719gcc_jit_function *func = 720 gcc_jit_context_new_function (ctxt, NULL, 721 GCC_JIT_FUNCTION_EXPORTED, 722 int_type, 723 "square", 724 1, ¶m_i, 725 0); 726@end example 727 728@noindent 729 730To define the code within the function, we must create basic blocks 731containing statements. 732 733Every basic block contains a list of statements, eventually terminated 734by a statement that either returns, or jumps to another basic block. 735 736Our function has no control-flow, so we just need one basic block: 737 738@example 739gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 740@end example 741 742@noindent 743 744Our basic block is relatively simple: it immediately terminates by 745returning the value of an expression. 746 747We can build the expression using @pxref{12,,gcc_jit_context_new_binary_op()}: 748 749@example 750gcc_jit_rvalue *expr = 751 gcc_jit_context_new_binary_op ( 752 ctxt, NULL, 753 GCC_JIT_BINARY_OP_MULT, int_type, 754 gcc_jit_param_as_rvalue (param_i), 755 gcc_jit_param_as_rvalue (param_i)); 756@end example 757 758@noindent 759 760A @pxref{13,,gcc_jit_rvalue *} is another example of a 761@pxref{e,,gcc_jit_object *} subclass. We can upcast it using 762@pxref{14,,gcc_jit_rvalue_as_object()} and as before print it with 763@pxref{f,,gcc_jit_object_get_debug_string()}. 764 765@example 766printf ("expr: %s\n", 767 gcc_jit_object_get_debug_string ( 768 gcc_jit_rvalue_as_object (expr))); 769@end example 770 771@noindent 772 773giving this output: 774 775@example 776expr: i * i 777@end example 778 779@noindent 780 781Creating the expression in itself doesn't do anything; we have to add 782this expression to a statement within the block. In this case, we use it 783to build a return statement, which terminates the basic block: 784 785@example 786gcc_jit_block_end_with_return (block, NULL, expr); 787@end example 788 789@noindent 790 791OK, we've populated the context. We can now compile it using 792@pxref{15,,gcc_jit_context_compile()}: 793 794@example 795gcc_jit_result *result; 796result = gcc_jit_context_compile (ctxt); 797@end example 798 799@noindent 800 801and get a @pxref{16,,gcc_jit_result *}. 802 803At this point we're done with the context; we can release it: 804 805@example 806gcc_jit_context_release (ctxt); 807@end example 808 809@noindent 810 811We can now use @pxref{17,,gcc_jit_result_get_code()} to look up a specific 812machine code routine within the result, in this case, the function we 813created above. 814 815@example 816void *fn_ptr = gcc_jit_result_get_code (result, "square"); 817if (!fn_ptr) 818 @{ 819 fprintf (stderr, "NULL fn_ptr"); 820 goto error; 821 @} 822@end example 823 824@noindent 825 826We can now cast the pointer to an appropriate function pointer type, and 827then call it: 828 829@example 830typedef int (*fn_type) (int); 831fn_type square = (fn_type)fn_ptr; 832printf ("result: %d", square (5)); 833@end example 834 835@noindent 836 837@example 838result: 25 839@end example 840 841@noindent 842 843Once we're done with the code, we can release the result: 844 845@example 846gcc_jit_result_release (result); 847@end example 848 849@noindent 850 851We can't call @code{square} anymore once we've released @code{result}. 852 853@menu 854* Error-handling:: 855* Options:: 856* Full example:: 857 858@end menu 859 860@node Error-handling,Options,,Tutorial part 2 Creating a trivial machine code function 861@anchor{intro/tutorial02 error-handling}@anchor{18} 862@subsection Error-handling 863 864 865Various kinds of errors are possible when using the API, such as 866mismatched types in an assignment. You can only compile and get code 867from a context if no errors occur. 868 869Errors are printed on stderr; they typically contain the name of the API 870entrypoint where the error occurred, and pertinent information on the 871problem: 872 873@example 874./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *) 875@end example 876 877@noindent 878 879The API is designed to cope with errors without crashing, so you can get 880away with having a single error-handling check in your code: 881 882@example 883void *fn_ptr = gcc_jit_result_get_code (result, "square"); 884if (!fn_ptr) 885 @{ 886 fprintf (stderr, "NULL fn_ptr"); 887 goto error; 888 @} 889@end example 890 891@noindent 892 893For more information, see the @pxref{19,,error-handling guide} 894within the Topic eference. 895 896@node Options,Full example,Error-handling,Tutorial part 2 Creating a trivial machine code function 897@anchor{intro/tutorial02 options}@anchor{1a} 898@subsection Options 899 900 901To get more information on what's going on, you can set debugging flags 902on the context using @pxref{1b,,gcc_jit_context_set_bool_option()}. 903 904@c (I'm deliberately not mentioning 905@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think 906@c it's probably more of use to implementors than to users) 907 908Setting @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a 909C-like representation to stderr when you compile (GCC's "GIMPLE" 910representation): 911 912@example 913gcc_jit_context_set_bool_option ( 914 ctxt, 915 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 916 1); 917result = gcc_jit_context_compile (ctxt); 918@end example 919 920@noindent 921 922@example 923square (signed int i) 924@{ 925 signed int D.260; 926 927 entry: 928 D.260 = i * i; 929 return D.260; 930@} 931@end example 932 933@noindent 934 935We can see the generated machine code in assembler form (on stderr) by 936setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context 937before compiling: 938 939@example 940gcc_jit_context_set_bool_option ( 941 ctxt, 942 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 943 1); 944result = gcc_jit_context_compile (ctxt); 945@end example 946 947@noindent 948 949@example 950 .file "fake.c" 951 .text 952 .globl square 953 .type square, @@function 954square: 955.LFB6: 956 .cfi_startproc 957 pushq %rbp 958 .cfi_def_cfa_offset 16 959 .cfi_offset 6, -16 960 movq %rsp, %rbp 961 .cfi_def_cfa_register 6 962 movl %edi, -4(%rbp) 963.L14: 964 movl -4(%rbp), %eax 965 imull -4(%rbp), %eax 966 popq %rbp 967 .cfi_def_cfa 7, 8 968 ret 969 .cfi_endproc 970.LFE6: 971 .size square, .-square 972 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 973 .section .note.GNU-stack,"",@@progbits 974@end example 975 976@noindent 977 978By default, no optimizations are performed, the equivalent of GCC's 979@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling 980@pxref{1e,,gcc_jit_context_set_int_option()} with 981@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 982 983@example 984gcc_jit_context_set_int_option ( 985 ctxt, 986 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 987 3); 988@end example 989 990@noindent 991 992@example 993 .file "fake.c" 994 .text 995 .p2align 4,,15 996 .globl square 997 .type square, @@function 998square: 999.LFB7: 1000 .cfi_startproc 1001.L16: 1002 movl %edi, %eax 1003 imull %edi, %eax 1004 ret 1005 .cfi_endproc 1006.LFE7: 1007 .size square, .-square 1008 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 1009 .section .note.GNU-stack,"",@@progbits 1010@end example 1011 1012@noindent 1013 1014Naturally this has only a small effect on such a trivial function. 1015 1016@node Full example,,Options,Tutorial part 2 Creating a trivial machine code function 1017@anchor{intro/tutorial02 full-example}@anchor{20} 1018@subsection Full example 1019 1020 1021Here's what the above looks like as a complete program: 1022 1023@quotation 1024 1025@example 1026/* Usage example for libgccjit.so 1027 Copyright (C) 2014-2016 Free Software Foundation, Inc. 1028 1029This file is part of GCC. 1030 1031GCC is free software; you can redistribute it and/or modify it 1032under the terms of the GNU General Public License as published by 1033the Free Software Foundation; either version 3, or (at your option) 1034any later version. 1035 1036GCC is distributed in the hope that it will be useful, but 1037WITHOUT ANY WARRANTY; without even the implied warranty of 1038MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1039General Public License for more details. 1040 1041You should have received a copy of the GNU General Public License 1042along with GCC; see the file COPYING3. If not see 1043<http://www.gnu.org/licenses/>. */ 1044 1045#include <libgccjit.h> 1046 1047#include <stdlib.h> 1048#include <stdio.h> 1049 1050void 1051create_code (gcc_jit_context *ctxt) 1052@{ 1053 /* Let's try to inject the equivalent of: 1054 1055 int square (int i) 1056 @{ 1057 return i * i; 1058 @} 1059 */ 1060 gcc_jit_type *int_type = 1061 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1062 gcc_jit_param *param_i = 1063 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 1064 gcc_jit_function *func = 1065 gcc_jit_context_new_function (ctxt, NULL, 1066 GCC_JIT_FUNCTION_EXPORTED, 1067 int_type, 1068 "square", 1069 1, ¶m_i, 1070 0); 1071 1072 gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); 1073 1074 gcc_jit_rvalue *expr = 1075 gcc_jit_context_new_binary_op ( 1076 ctxt, NULL, 1077 GCC_JIT_BINARY_OP_MULT, int_type, 1078 gcc_jit_param_as_rvalue (param_i), 1079 gcc_jit_param_as_rvalue (param_i)); 1080 1081 gcc_jit_block_end_with_return (block, NULL, expr); 1082@} 1083 1084int 1085main (int argc, char **argv) 1086@{ 1087 gcc_jit_context *ctxt = NULL; 1088 gcc_jit_result *result = NULL; 1089 1090 /* Get a "context" object for working with the library. */ 1091 ctxt = gcc_jit_context_acquire (); 1092 if (!ctxt) 1093 @{ 1094 fprintf (stderr, "NULL ctxt"); 1095 goto error; 1096 @} 1097 1098 /* Set some options on the context. 1099 Let's see the code being generated, in assembler form. */ 1100 gcc_jit_context_set_bool_option ( 1101 ctxt, 1102 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1103 0); 1104 1105 /* Populate the context. */ 1106 create_code (ctxt); 1107 1108 /* Compile the code. */ 1109 result = gcc_jit_context_compile (ctxt); 1110 if (!result) 1111 @{ 1112 fprintf (stderr, "NULL result"); 1113 goto error; 1114 @} 1115 1116 /* We're done with the context; we can release it: */ 1117 gcc_jit_context_release (ctxt); 1118 ctxt = NULL; 1119 1120 /* Extract the generated code from "result". */ 1121 void *fn_ptr = gcc_jit_result_get_code (result, "square"); 1122 if (!fn_ptr) 1123 @{ 1124 fprintf (stderr, "NULL fn_ptr"); 1125 goto error; 1126 @} 1127 1128 typedef int (*fn_type) (int); 1129 fn_type square = (fn_type)fn_ptr; 1130 printf ("result: %d\n", square (5)); 1131 1132 error: 1133 if (ctxt) 1134 gcc_jit_context_release (ctxt); 1135 if (result) 1136 gcc_jit_result_release (result); 1137 return 0; 1138@} 1139 1140@end example 1141 1142@noindent 1143@end quotation 1144 1145Building and running it: 1146 1147@example 1148$ gcc \ 1149 tut02-square.c \ 1150 -o tut02-square \ 1151 -lgccjit 1152 1153# Run the built program: 1154$ ./tut02-square 1155result: 25 1156@end example 1157 1158@noindent 1159 1160@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 1161@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 1162@c 1163@c This is free software: you can redistribute it and/or modify it 1164@c under the terms of the GNU General Public License as published by 1165@c the Free Software Foundation, either version 3 of the License, or 1166@c (at your option) any later version. 1167@c 1168@c This program is distributed in the hope that it will be useful, but 1169@c WITHOUT ANY WARRANTY; without even the implied warranty of 1170@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1171@c General Public License for more details. 1172@c 1173@c You should have received a copy of the GNU General Public License 1174@c along with this program. If not, see 1175@c <http://www.gnu.org/licenses/>. 1176 1177@node Tutorial part 3 Loops and variables,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial part 2 Creating a trivial machine code function,Tutorial 1178@anchor{intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{21}@anchor{intro/tutorial03 doc}@anchor{22} 1179@section Tutorial part 3: Loops and variables 1180 1181 1182Consider this C function: 1183 1184@quotation 1185 1186@example 1187int loop_test (int n) 1188@{ 1189 int sum = 0; 1190 for (int i = 0; i < n; i++) 1191 sum += i * i; 1192 return sum; 1193@} 1194@end example 1195 1196@noindent 1197@end quotation 1198 1199This example demonstrates some more features of libgccjit, with local 1200variables and a loop. 1201 1202To break this down into libgccjit terms, it's usually easier to reword 1203the @cite{for} loop as a @cite{while} loop, giving: 1204 1205@quotation 1206 1207@example 1208int loop_test (int n) 1209@{ 1210 int sum = 0; 1211 int i = 0; 1212 while (i < n) 1213 @{ 1214 sum += i * i; 1215 i++; 1216 @} 1217 return sum; 1218@} 1219@end example 1220 1221@noindent 1222@end quotation 1223 1224Here's what the final control flow graph will look like: 1225 1226@quotation 1227 1228 1229@float Figure 1230 1231@image{sum-of-squares1,,,image of a control flow graph,png} 1232 1233@end float 1234 1235@end quotation 1236 1237As before, we include the libgccjit header and make a 1238@pxref{8,,gcc_jit_context *}. 1239 1240@example 1241#include <libgccjit.h> 1242 1243void test (void) 1244@{ 1245 gcc_jit_context *ctxt; 1246 ctxt = gcc_jit_context_acquire (); 1247@end example 1248 1249@noindent 1250 1251The function works with the C @cite{int} type: 1252 1253@example 1254gcc_jit_type *the_type = 1255 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1256gcc_jit_type *return_type = the_type; 1257@end example 1258 1259@noindent 1260 1261though we could equally well make it work on, say, @cite{double}: 1262 1263@example 1264gcc_jit_type *the_type = 1265 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE); 1266@end example 1267 1268@noindent 1269 1270Let's build the function: 1271 1272@example 1273gcc_jit_param *n = 1274 gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); 1275gcc_jit_param *params[1] = @{n@}; 1276gcc_jit_function *func = 1277 gcc_jit_context_new_function (ctxt, NULL, 1278 GCC_JIT_FUNCTION_EXPORTED, 1279 return_type, 1280 "loop_test", 1281 1, params, 0); 1282@end example 1283 1284@noindent 1285 1286@menu 1287* Expressions; lvalues and rvalues: Expressions lvalues and rvalues. 1288* Control flow:: 1289* Visualizing the control flow graph:: 1290* Full example: Full example<2>. 1291 1292@end menu 1293 1294@node Expressions lvalues and rvalues,Control flow,,Tutorial part 3 Loops and variables 1295@anchor{intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{23} 1296@subsection Expressions: lvalues and rvalues 1297 1298 1299The base class of expression is the @pxref{13,,gcc_jit_rvalue *}, 1300representing an expression that can be on the @emph{right}-hand side of 1301an assignment: a value that can be computed somehow, and assigned 1302@emph{to} a storage area (such as a variable). It has a specific 1303@pxref{a,,gcc_jit_type *}. 1304 1305Anothe important class is @pxref{24,,gcc_jit_lvalue *}. 1306A @pxref{24,,gcc_jit_lvalue *}. is something that can of the @emph{left}-hand 1307side of an assignment: a storage area (such as a variable). 1308 1309In other words, every assignment can be thought of as: 1310 1311@example 1312LVALUE = RVALUE; 1313@end example 1314 1315@noindent 1316 1317Note that @pxref{24,,gcc_jit_lvalue *} is a subclass of 1318@pxref{13,,gcc_jit_rvalue *}, where in an assignment of the form: 1319 1320@example 1321LVALUE_A = LVALUE_B; 1322@end example 1323 1324@noindent 1325 1326the @cite{LVALUE_B} implies reading the current value of that storage 1327area, assigning it into the @cite{LVALUE_A}. 1328 1329So far the only expressions we've seen are @cite{i * i}: 1330 1331@example 1332gcc_jit_rvalue *expr = 1333 gcc_jit_context_new_binary_op ( 1334 ctxt, NULL, 1335 GCC_JIT_BINARY_OP_MULT, int_type, 1336 gcc_jit_param_as_rvalue (param_i), 1337 gcc_jit_param_as_rvalue (param_i)); 1338@end example 1339 1340@noindent 1341 1342which is a @pxref{13,,gcc_jit_rvalue *}, and the various function 1343parameters: @cite{param_i} and @cite{param_n}, instances of 1344@pxref{25,,gcc_jit_param *}, which is a subclass of 1345@pxref{24,,gcc_jit_lvalue *} (and, in turn, of @pxref{13,,gcc_jit_rvalue *}): 1346we can both read from and write to function parameters within the 1347body of a function. 1348 1349Our new example has a couple of local variables. We create them by 1350calling @pxref{26,,gcc_jit_function_new_local()}, supplying a type and a 1351name: 1352 1353@example 1354/* Build locals: */ 1355gcc_jit_lvalue *i = 1356 gcc_jit_function_new_local (func, NULL, the_type, "i"); 1357gcc_jit_lvalue *sum = 1358 gcc_jit_function_new_local (func, NULL, the_type, "sum"); 1359@end example 1360 1361@noindent 1362 1363These are instances of @pxref{24,,gcc_jit_lvalue *} - they can be read from 1364and written to. 1365 1366Note that there is no precanned way to create @emph{and} initialize a variable 1367like in C: 1368 1369@example 1370int i = 0; 1371@end example 1372 1373@noindent 1374 1375Instead, having added the local to the function, we have to separately add 1376an assignment of @cite{0} to @cite{local_i} at the beginning of the function. 1377 1378@node Control flow,Visualizing the control flow graph,Expressions lvalues and rvalues,Tutorial part 3 Loops and variables 1379@anchor{intro/tutorial03 control-flow}@anchor{27} 1380@subsection Control flow 1381 1382 1383This function has a loop, so we need to build some basic blocks to 1384handle the control flow. In this case, we need 4 blocks: 1385 1386 1387@enumerate 1388 1389@item 1390before the loop (initializing the locals) 1391 1392@item 1393the conditional at the top of the loop (comparing @cite{i < n}) 1394 1395@item 1396the body of the loop 1397 1398@item 1399after the loop terminates (@cite{return sum}) 1400@end enumerate 1401 1402so we create these as @pxref{28,,gcc_jit_block *} instances within the 1403@pxref{29,,gcc_jit_function *}: 1404 1405@example 1406gcc_jit_block *b_initial = 1407 gcc_jit_function_new_block (func, "initial"); 1408gcc_jit_block *b_loop_cond = 1409 gcc_jit_function_new_block (func, "loop_cond"); 1410gcc_jit_block *b_loop_body = 1411 gcc_jit_function_new_block (func, "loop_body"); 1412gcc_jit_block *b_after_loop = 1413 gcc_jit_function_new_block (func, "after_loop"); 1414@end example 1415 1416@noindent 1417 1418We now populate each block with statements. 1419 1420The entry block @cite{b_initial} consists of initializations followed by a jump 1421to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using 1422@pxref{2a,,gcc_jit_block_add_assignment()} to add 1423an assignment statement, and using @pxref{2b,,gcc_jit_context_zero()} to get 1424the constant value @cite{0} for the relevant type for the right-hand side of 1425the assignment: 1426 1427@example 1428/* sum = 0; */ 1429gcc_jit_block_add_assignment ( 1430 b_initial, NULL, 1431 sum, 1432 gcc_jit_context_zero (ctxt, the_type)); 1433 1434/* i = 0; */ 1435gcc_jit_block_add_assignment ( 1436 b_initial, NULL, 1437 i, 1438 gcc_jit_context_zero (ctxt, the_type)); 1439@end example 1440 1441@noindent 1442 1443We can then terminate the entry block by jumping to the conditional: 1444 1445@example 1446gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); 1447@end example 1448 1449@noindent 1450 1451The conditional block is equivalent to the line @cite{while (i < n)} from our 1452C example. It contains a single statement: a conditional, which jumps to 1453one of two destination blocks depending on a boolean 1454@pxref{13,,gcc_jit_rvalue *}, in this case the comparison of @cite{i} and @cite{n}. 1455We build the comparison using @pxref{2c,,gcc_jit_context_new_comparison()}: 1456 1457@example 1458/* (i >= n) */ 1459 gcc_jit_rvalue *guard = 1460 gcc_jit_context_new_comparison ( 1461 ctxt, NULL, 1462 GCC_JIT_COMPARISON_GE, 1463 gcc_jit_lvalue_as_rvalue (i), 1464 gcc_jit_param_as_rvalue (n)); 1465@end example 1466 1467@noindent 1468 1469and can then use this to add @cite{b_loop_cond}'s sole statement, via 1470@pxref{2d,,gcc_jit_block_end_with_conditional()}: 1471 1472@example 1473/* Equivalent to: 1474 if (guard) 1475 goto after_loop; 1476 else 1477 goto loop_body; */ 1478gcc_jit_block_end_with_conditional ( 1479 b_loop_cond, NULL, 1480 guard, 1481 b_after_loop, /* on_true */ 1482 b_loop_body); /* on_false */ 1483@end example 1484 1485@noindent 1486 1487Next, we populate the body of the loop. 1488 1489The C statement @cite{sum += i * i;} is an assignment operation, where an 1490lvalue is modified "in-place". We use 1491@pxref{2e,,gcc_jit_block_add_assignment_op()} to handle these operations: 1492 1493@example 1494/* sum += i * i */ 1495gcc_jit_block_add_assignment_op ( 1496 b_loop_body, NULL, 1497 sum, 1498 GCC_JIT_BINARY_OP_PLUS, 1499 gcc_jit_context_new_binary_op ( 1500 ctxt, NULL, 1501 GCC_JIT_BINARY_OP_MULT, the_type, 1502 gcc_jit_lvalue_as_rvalue (i), 1503 gcc_jit_lvalue_as_rvalue (i))); 1504@end example 1505 1506@noindent 1507 1508The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in 1509a similar way. We use @pxref{2f,,gcc_jit_context_one()} to get the constant 1510value @cite{1} (for the relevant type) for the right-hand side 1511of the assignment. 1512 1513@example 1514/* i++ */ 1515gcc_jit_block_add_assignment_op ( 1516 b_loop_body, NULL, 1517 i, 1518 GCC_JIT_BINARY_OP_PLUS, 1519 gcc_jit_context_one (ctxt, the_type)); 1520@end example 1521 1522@noindent 1523 1524@cartouche 1525@quotation Note 1526For numeric constants other than 0 or 1, we could use 1527@pxref{30,,gcc_jit_context_new_rvalue_from_int()} and 1528@pxref{31,,gcc_jit_context_new_rvalue_from_double()}. 1529@end quotation 1530@end cartouche 1531 1532The loop body completes by jumping back to the conditional: 1533 1534@example 1535gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); 1536@end example 1537 1538@noindent 1539 1540Finally, we populate the @cite{b_after_loop} block, reached when the loop 1541conditional is false. We want to generate the equivalent of: 1542 1543@example 1544return sum; 1545@end example 1546 1547@noindent 1548 1549so the block is just one statement: 1550 1551@example 1552/* return sum */ 1553gcc_jit_block_end_with_return ( 1554 b_after_loop, 1555 NULL, 1556 gcc_jit_lvalue_as_rvalue (sum)); 1557@end example 1558 1559@noindent 1560 1561@cartouche 1562@quotation Note 1563You can intermingle block creation with statement creation, 1564but given that the terminator statements generally include references 1565to other blocks, I find it's clearer to create all the blocks, 1566@emph{then} all the statements. 1567@end quotation 1568@end cartouche 1569 1570We've finished populating the function. As before, we can now compile it 1571to machine code: 1572 1573@example 1574gcc_jit_result *result; 1575result = gcc_jit_context_compile (ctxt); 1576 1577typedef int (*loop_test_fn_type) (int); 1578loop_test_fn_type loop_test = 1579 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 1580if (!loop_test) 1581 goto error; 1582printf ("result: %d", loop_test (10)); 1583@end example 1584 1585@noindent 1586 1587@example 1588result: 285 1589@end example 1590 1591@noindent 1592 1593@node Visualizing the control flow graph,Full example<2>,Control flow,Tutorial part 3 Loops and variables 1594@anchor{intro/tutorial03 visualizing-the-control-flow-graph}@anchor{32} 1595@subsection Visualizing the control flow graph 1596 1597 1598You can see the control flow graph of a function using 1599@pxref{33,,gcc_jit_function_dump_to_dot()}: 1600 1601@example 1602gcc_jit_function_dump_to_dot (func, "/tmp/sum-of-squares.dot"); 1603@end example 1604 1605@noindent 1606 1607giving a .dot file in GraphViz format. 1608 1609You can convert this to an image using @cite{dot}: 1610 1611@example 1612$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png 1613@end example 1614 1615@noindent 1616 1617or use a viewer (my preferred one is xdot.py; see 1618@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can 1619install it with @cite{yum install python-xdot}): 1620 1621@quotation 1622 1623 1624@float Figure 1625 1626@image{sum-of-squares1,,,image of a control flow graph,png} 1627 1628@end float 1629 1630@end quotation 1631 1632@node Full example<2>,,Visualizing the control flow graph,Tutorial part 3 Loops and variables 1633@anchor{intro/tutorial03 full-example}@anchor{34} 1634@subsection Full example 1635 1636 1637@quotation 1638 1639@example 1640/* Usage example for libgccjit.so 1641 Copyright (C) 2014-2016 Free Software Foundation, Inc. 1642 1643This file is part of GCC. 1644 1645GCC is free software; you can redistribute it and/or modify it 1646under the terms of the GNU General Public License as published by 1647the Free Software Foundation; either version 3, or (at your option) 1648any later version. 1649 1650GCC is distributed in the hope that it will be useful, but 1651WITHOUT ANY WARRANTY; without even the implied warranty of 1652MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1653General Public License for more details. 1654 1655You should have received a copy of the GNU General Public License 1656along with GCC; see the file COPYING3. If not see 1657<http://www.gnu.org/licenses/>. */ 1658 1659#include <libgccjit.h> 1660 1661#include <stdlib.h> 1662#include <stdio.h> 1663 1664void 1665create_code (gcc_jit_context *ctxt) 1666@{ 1667 /* 1668 Simple sum-of-squares, to test conditionals and looping 1669 1670 int loop_test (int n) 1671 @{ 1672 int i; 1673 int sum = 0; 1674 for (i = 0; i < n ; i ++) 1675 @{ 1676 sum += i * i; 1677 @} 1678 return sum; 1679 */ 1680 gcc_jit_type *the_type = 1681 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 1682 gcc_jit_type *return_type = the_type; 1683 1684 gcc_jit_param *n = 1685 gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); 1686 gcc_jit_param *params[1] = @{n@}; 1687 gcc_jit_function *func = 1688 gcc_jit_context_new_function (ctxt, NULL, 1689 GCC_JIT_FUNCTION_EXPORTED, 1690 return_type, 1691 "loop_test", 1692 1, params, 0); 1693 1694 /* Build locals: */ 1695 gcc_jit_lvalue *i = 1696 gcc_jit_function_new_local (func, NULL, the_type, "i"); 1697 gcc_jit_lvalue *sum = 1698 gcc_jit_function_new_local (func, NULL, the_type, "sum"); 1699 1700 gcc_jit_block *b_initial = 1701 gcc_jit_function_new_block (func, "initial"); 1702 gcc_jit_block *b_loop_cond = 1703 gcc_jit_function_new_block (func, "loop_cond"); 1704 gcc_jit_block *b_loop_body = 1705 gcc_jit_function_new_block (func, "loop_body"); 1706 gcc_jit_block *b_after_loop = 1707 gcc_jit_function_new_block (func, "after_loop"); 1708 1709 /* sum = 0; */ 1710 gcc_jit_block_add_assignment ( 1711 b_initial, NULL, 1712 sum, 1713 gcc_jit_context_zero (ctxt, the_type)); 1714 1715 /* i = 0; */ 1716 gcc_jit_block_add_assignment ( 1717 b_initial, NULL, 1718 i, 1719 gcc_jit_context_zero (ctxt, the_type)); 1720 1721 gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); 1722 1723 /* if (i >= n) */ 1724 gcc_jit_block_end_with_conditional ( 1725 b_loop_cond, NULL, 1726 gcc_jit_context_new_comparison ( 1727 ctxt, NULL, 1728 GCC_JIT_COMPARISON_GE, 1729 gcc_jit_lvalue_as_rvalue (i), 1730 gcc_jit_param_as_rvalue (n)), 1731 b_after_loop, 1732 b_loop_body); 1733 1734 /* sum += i * i */ 1735 gcc_jit_block_add_assignment_op ( 1736 b_loop_body, NULL, 1737 sum, 1738 GCC_JIT_BINARY_OP_PLUS, 1739 gcc_jit_context_new_binary_op ( 1740 ctxt, NULL, 1741 GCC_JIT_BINARY_OP_MULT, the_type, 1742 gcc_jit_lvalue_as_rvalue (i), 1743 gcc_jit_lvalue_as_rvalue (i))); 1744 1745 /* i++ */ 1746 gcc_jit_block_add_assignment_op ( 1747 b_loop_body, NULL, 1748 i, 1749 GCC_JIT_BINARY_OP_PLUS, 1750 gcc_jit_context_one (ctxt, the_type)); 1751 1752 gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); 1753 1754 /* return sum */ 1755 gcc_jit_block_end_with_return ( 1756 b_after_loop, 1757 NULL, 1758 gcc_jit_lvalue_as_rvalue (sum)); 1759@} 1760 1761int 1762main (int argc, char **argv) 1763@{ 1764 gcc_jit_context *ctxt = NULL; 1765 gcc_jit_result *result = NULL; 1766 1767 /* Get a "context" object for working with the library. */ 1768 ctxt = gcc_jit_context_acquire (); 1769 if (!ctxt) 1770 @{ 1771 fprintf (stderr, "NULL ctxt"); 1772 goto error; 1773 @} 1774 1775 /* Set some options on the context. 1776 Let's see the code being generated, in assembler form. */ 1777 gcc_jit_context_set_bool_option ( 1778 ctxt, 1779 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1780 0); 1781 1782 /* Populate the context. */ 1783 create_code (ctxt); 1784 1785 /* Compile the code. */ 1786 result = gcc_jit_context_compile (ctxt); 1787 if (!result) 1788 @{ 1789 fprintf (stderr, "NULL result"); 1790 goto error; 1791 @} 1792 1793 /* Extract the generated code from "result". */ 1794 typedef int (*loop_test_fn_type) (int); 1795 loop_test_fn_type loop_test = 1796 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 1797 if (!loop_test) 1798 @{ 1799 fprintf (stderr, "NULL loop_test"); 1800 goto error; 1801 @} 1802 1803 /* Run the generated code. */ 1804 int val = loop_test (10); 1805 printf("loop_test returned: %d\n", val); 1806 1807 error: 1808 gcc_jit_context_release (ctxt); 1809 gcc_jit_result_release (result); 1810 return 0; 1811@} 1812 1813@end example 1814 1815@noindent 1816@end quotation 1817 1818Building and running it: 1819 1820@example 1821$ gcc \ 1822 tut03-sum-of-squares.c \ 1823 -o tut03-sum-of-squares \ 1824 -lgccjit 1825 1826# Run the built program: 1827$ ./tut03-sum-of-squares 1828loop_test returned: 285 1829@end example 1830 1831@noindent 1832 1833@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 1834@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 1835@c 1836@c This is free software: you can redistribute it and/or modify it 1837@c under the terms of the GNU General Public License as published by 1838@c the Free Software Foundation, either version 3 of the License, or 1839@c (at your option) any later version. 1840@c 1841@c This program is distributed in the hope that it will be useful, but 1842@c WITHOUT ANY WARRANTY; without even the implied warranty of 1843@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1844@c General Public License for more details. 1845@c 1846@c You should have received a copy of the GNU General Public License 1847@c along with this program. If not, see 1848@c <http://www.gnu.org/licenses/>. 1849 1850@node Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial part 5 Implementing an Ahead-of-Time compiler,Tutorial part 3 Loops and variables,Tutorial 1851@anchor{intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{35}@anchor{intro/tutorial04 doc}@anchor{36} 1852@section Tutorial part 4: Adding JIT-compilation to a toy interpreter 1853 1854 1855In this example we construct a "toy" interpreter, and add JIT-compilation 1856to it. 1857 1858@menu 1859* Our toy interpreter:: 1860* Compiling to machine code:: 1861* Setting things up:: 1862* Populating the function:: 1863* Verifying the control flow graph:: 1864* Compiling the context:: 1865* Single-stepping through the generated code:: 1866* Examining the generated code:: 1867* Putting it all together:: 1868* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?. 1869 1870@end menu 1871 1872@node Our toy interpreter,Compiling to machine code,,Tutorial part 4 Adding JIT-compilation to a toy interpreter 1873@anchor{intro/tutorial04 our-toy-interpreter}@anchor{37} 1874@subsection Our toy interpreter 1875 1876 1877It's a stack-based interpreter, and is intended as a (very simple) example 1878of the kind of bytecode interpreter seen in dynamic languages such as 1879Python, Ruby etc. 1880 1881For the sake of simplicity, our toy virtual machine is very limited: 1882 1883@quotation 1884 1885 1886@itemize * 1887 1888@item 1889The only data type is @cite{int} 1890 1891@item 1892It can only work on one function at a time (so that the only 1893function call that can be made is to recurse). 1894 1895@item 1896Functions can only take one parameter. 1897 1898@item 1899Functions have a stack of @cite{int} values. 1900 1901@item 1902We'll implement function call within the interpreter by calling a 1903function in our implementation, rather than implementing our own 1904frame stack. 1905 1906@item 1907The parser is only good enough to get the examples to work. 1908@end itemize 1909@end quotation 1910 1911Naturally, a real interpreter would be much more complicated that this. 1912 1913The following operations are supported: 1914 1915 1916@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx} 1917@headitem 1918 1919Operation 1920 1921@tab 1922 1923Meaning 1924 1925@tab 1926 1927Old Stack 1928 1929@tab 1930 1931New Stack 1932 1933@item 1934 1935DUP 1936 1937@tab 1938 1939Duplicate top of stack. 1940 1941@tab 1942 1943@code{[..., x]} 1944 1945@tab 1946 1947@code{[..., x, x]} 1948 1949@item 1950 1951ROT 1952 1953@tab 1954 1955Swap top two elements 1956of stack. 1957 1958@tab 1959 1960@code{[..., x, y]} 1961 1962@tab 1963 1964@code{[..., y, x]} 1965 1966@item 1967 1968BINARY_ADD 1969 1970@tab 1971 1972Add the top two elements 1973on the stack. 1974 1975@tab 1976 1977@code{[..., x, y]} 1978 1979@tab 1980 1981@code{[..., (x+y)]} 1982 1983@item 1984 1985BINARY_SUBTRACT 1986 1987@tab 1988 1989Likewise, but subtract. 1990 1991@tab 1992 1993@code{[..., x, y]} 1994 1995@tab 1996 1997@code{[..., (x-y)]} 1998 1999@item 2000 2001BINARY_MULT 2002 2003@tab 2004 2005Likewise, but multiply. 2006 2007@tab 2008 2009@code{[..., x, y]} 2010 2011@tab 2012 2013@code{[..., (x*y)]} 2014 2015@item 2016 2017BINARY_COMPARE_LT 2018 2019@tab 2020 2021Compare the top two 2022elements on the stack 2023and push a nonzero/zero 2024if (x<y). 2025 2026@tab 2027 2028@code{[..., x, y]} 2029 2030@tab 2031 2032@code{[..., (x<y)]} 2033 2034@item 2035 2036RECURSE 2037 2038@tab 2039 2040Recurse, passing the top 2041of the stack, and 2042popping the result. 2043 2044@tab 2045 2046@code{[..., x]} 2047 2048@tab 2049 2050@code{[..., fn(x)]} 2051 2052@item 2053 2054RETURN 2055 2056@tab 2057 2058Return the top of the 2059stack. 2060 2061@tab 2062 2063@code{[x]} 2064 2065@tab 2066 2067@code{[]} 2068 2069@item 2070 2071PUSH_CONST @cite{arg} 2072 2073@tab 2074 2075Push an int const. 2076 2077@tab 2078 2079@code{[...]} 2080 2081@tab 2082 2083@code{[..., arg]} 2084 2085@item 2086 2087JUMP_ABS_IF_TRUE @cite{arg} 2088 2089@tab 2090 2091Pop; if top of stack was 2092nonzero, jump to 2093@code{arg}. 2094 2095@tab 2096 2097@code{[..., x]} 2098 2099@tab 2100 2101@code{[...]} 2102 2103@end multitable 2104 2105 2106Programs can be interpreted, disassembled, and compiled to machine code. 2107 2108The interpreter reads @code{.toy} scripts. Here's what a simple recursive 2109factorial program looks like, the script @code{factorial.toy}. 2110The parser ignores lines beginning with a @cite{#}. 2111 2112@quotation 2113 2114@example 2115# Simple recursive factorial implementation, roughly equivalent to: 2116# 2117# int factorial (int arg) 2118# @{ 2119# if (arg < 2) 2120# return arg 2121# return arg * factorial (arg - 1) 2122# @} 2123 2124# Initial state: 2125# stack: [arg] 2126 2127# 0: 2128DUP 2129# stack: [arg, arg] 2130 2131# 1: 2132PUSH_CONST 2 2133# stack: [arg, arg, 2] 2134 2135# 2: 2136BINARY_COMPARE_LT 2137# stack: [arg, (arg < 2)] 2138 2139# 3: 2140JUMP_ABS_IF_TRUE 9 2141# stack: [arg] 2142 2143# 4: 2144DUP 2145# stack: [arg, arg] 2146 2147# 5: 2148PUSH_CONST 1 2149# stack: [arg, arg, 1] 2150 2151# 6: 2152BINARY_SUBTRACT 2153# stack: [arg, (arg - 1) 2154 2155# 7: 2156RECURSE 2157# stack: [arg, factorial(arg - 1)] 2158 2159# 8: 2160BINARY_MULT 2161# stack: [arg * factorial(arg - 1)] 2162 2163# 9: 2164RETURN 2165 2166@end example 2167 2168@noindent 2169@end quotation 2170 2171The interpreter is a simple infinite loop with a big @code{switch} statement 2172based on what the next opcode is: 2173 2174@quotation 2175 2176@example 2177 2178static int 2179toyvm_function_interpret (toyvm_function *fn, int arg, FILE *trace) 2180@{ 2181 toyvm_frame frame; 2182#define PUSH(ARG) (toyvm_frame_push (&frame, (ARG))) 2183#define POP(ARG) (toyvm_frame_pop (&frame)) 2184 2185 frame.frm_function = fn; 2186 frame.frm_pc = 0; 2187 frame.frm_cur_depth = 0; 2188 2189 PUSH (arg); 2190 2191 while (1) 2192 @{ 2193 toyvm_op *op; 2194 int x, y; 2195 assert (frame.frm_pc < fn->fn_num_ops); 2196 op = &fn->fn_ops[frame.frm_pc++]; 2197 2198 if (trace) 2199 @{ 2200 toyvm_frame_dump_stack (&frame, trace); 2201 toyvm_function_disassemble_op (fn, op, frame.frm_pc, trace); 2202 @} 2203 2204 switch (op->op_opcode) 2205 @{ 2206 /* Ops taking no operand. */ 2207 case DUP: 2208 x = POP (); 2209 PUSH (x); 2210 PUSH (x); 2211 break; 2212 2213 case ROT: 2214 y = POP (); 2215 x = POP (); 2216 PUSH (y); 2217 PUSH (x); 2218 break; 2219 2220 case BINARY_ADD: 2221 y = POP (); 2222 x = POP (); 2223 PUSH (x + y); 2224 break; 2225 2226 case BINARY_SUBTRACT: 2227 y = POP (); 2228 x = POP (); 2229 PUSH (x - y); 2230 break; 2231 2232 case BINARY_MULT: 2233 y = POP (); 2234 x = POP (); 2235 PUSH (x * y); 2236 break; 2237 2238 case BINARY_COMPARE_LT: 2239 y = POP (); 2240 x = POP (); 2241 PUSH (x < y); 2242 break; 2243 2244 case RECURSE: 2245 x = POP (); 2246 x = toyvm_function_interpret (fn, x, trace); 2247 PUSH (x); 2248 break; 2249 2250 case RETURN: 2251 return POP (); 2252 2253 /* Ops taking an operand. */ 2254 case PUSH_CONST: 2255 PUSH (op->op_operand); 2256 break; 2257 2258 case JUMP_ABS_IF_TRUE: 2259 x = POP (); 2260 if (x) 2261 frame.frm_pc = op->op_operand; 2262 break; 2263 2264 default: 2265 assert (0); /* unknown opcode */ 2266 2267 @} /* end of switch on opcode */ 2268 @} /* end of while loop */ 2269 2270#undef PUSH 2271#undef POP 2272@} 2273 2274 2275@end example 2276 2277@noindent 2278@end quotation 2279 2280@node Compiling to machine code,Setting things up,Our toy interpreter,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2281@anchor{intro/tutorial04 compiling-to-machine-code}@anchor{38} 2282@subsection Compiling to machine code 2283 2284 2285We want to generate machine code that can be cast to this type and 2286then directly executed in-process: 2287 2288@quotation 2289 2290@example 2291typedef int (*toyvm_compiled_code) (int); 2292 2293 2294@end example 2295 2296@noindent 2297@end quotation 2298 2299The lifetime of the code is tied to that of a @pxref{16,,gcc_jit_result *}. 2300We'll handle this by bundling them up in a structure, so that we can 2301clean them up together by calling @pxref{39,,gcc_jit_result_release()}: 2302 2303@quotation 2304 2305@example 2306 2307struct toyvm_compiled_function 2308@{ 2309 gcc_jit_result *cf_jit_result; 2310 toyvm_compiled_code cf_code; 2311@}; 2312 2313 2314@end example 2315 2316@noindent 2317@end quotation 2318 2319Our compiler isn't very sophisticated; it takes the implementation of 2320each opcode above, and maps it directly to the operations supported by 2321the libgccjit API. 2322 2323How should we handle the stack? In theory we could calculate what the 2324stack depth will be at each opcode, and optimize away the stack 2325manipulation "by hand". We'll see below that libgccjit is able to do 2326this for us, so we'll implement stack manipulation 2327in a direct way, by creating a @code{stack} array and @code{stack_depth} 2328variables, local within the generated function, equivalent to this C code: 2329 2330@example 2331int stack_depth; 2332int stack[MAX_STACK_DEPTH]; 2333@end example 2334 2335@noindent 2336 2337We'll also have local variables @code{x} and @code{y} for use when implementing 2338the opcodes, equivalent to this: 2339 2340@example 2341int x; 2342int y; 2343@end example 2344 2345@noindent 2346 2347This means our compiler has the following state: 2348 2349@quotation 2350 2351@example 2352 2353struct compilation_state 2354@{ 2355 gcc_jit_context *ctxt; 2356 2357 gcc_jit_type *int_type; 2358 gcc_jit_type *bool_type; 2359 gcc_jit_type *stack_type; /* int[MAX_STACK_DEPTH] */ 2360 2361 gcc_jit_rvalue *const_one; 2362 2363 gcc_jit_function *fn; 2364 gcc_jit_param *param_arg; 2365 gcc_jit_lvalue *stack; 2366 gcc_jit_lvalue *stack_depth; 2367 gcc_jit_lvalue *x; 2368 gcc_jit_lvalue *y; 2369 2370 gcc_jit_location *op_locs[MAX_OPS]; 2371 gcc_jit_block *initial_block; 2372 gcc_jit_block *op_blocks[MAX_OPS]; 2373 2374@}; 2375 2376 2377@end example 2378 2379@noindent 2380@end quotation 2381 2382@node Setting things up,Populating the function,Compiling to machine code,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2383@anchor{intro/tutorial04 setting-things-up}@anchor{3a} 2384@subsection Setting things up 2385 2386 2387First we create our types: 2388 2389@quotation 2390 2391@example 2392 state.int_type = 2393 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_INT); 2394 state.bool_type = 2395 gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_BOOL); 2396 state.stack_type = 2397 gcc_jit_context_new_array_type (state.ctxt, NULL, 2398 state.int_type, MAX_STACK_DEPTH); 2399 2400 2401@end example 2402 2403@noindent 2404@end quotation 2405 2406along with extracting a useful @cite{int} constant: 2407 2408@quotation 2409 2410@example 2411 state.const_one = gcc_jit_context_one (state.ctxt, state.int_type); 2412 2413 2414@end example 2415 2416@noindent 2417@end quotation 2418 2419We'll implement push and pop in terms of the @code{stack} array and 2420@code{stack_depth}. Here are helper functions for adding statements to 2421a block, implementing pushing and popping values: 2422 2423@quotation 2424 2425@example 2426 2427static void 2428add_push (compilation_state *state, 2429 gcc_jit_block *block, 2430 gcc_jit_rvalue *rvalue, 2431 gcc_jit_location *loc) 2432@{ 2433 /* stack[stack_depth] = RVALUE */ 2434 gcc_jit_block_add_assignment ( 2435 block, 2436 loc, 2437 /* stack[stack_depth] */ 2438 gcc_jit_context_new_array_access ( 2439 state->ctxt, 2440 loc, 2441 gcc_jit_lvalue_as_rvalue (state->stack), 2442 gcc_jit_lvalue_as_rvalue (state->stack_depth)), 2443 rvalue); 2444 2445 /* "stack_depth++;". */ 2446 gcc_jit_block_add_assignment_op ( 2447 block, 2448 loc, 2449 state->stack_depth, 2450 GCC_JIT_BINARY_OP_PLUS, 2451 state->const_one); 2452@} 2453 2454static void 2455add_pop (compilation_state *state, 2456 gcc_jit_block *block, 2457 gcc_jit_lvalue *lvalue, 2458 gcc_jit_location *loc) 2459@{ 2460 /* "--stack_depth;". */ 2461 gcc_jit_block_add_assignment_op ( 2462 block, 2463 loc, 2464 state->stack_depth, 2465 GCC_JIT_BINARY_OP_MINUS, 2466 state->const_one); 2467 2468 /* "LVALUE = stack[stack_depth];". */ 2469 gcc_jit_block_add_assignment ( 2470 block, 2471 loc, 2472 lvalue, 2473 /* stack[stack_depth] */ 2474 gcc_jit_lvalue_as_rvalue ( 2475 gcc_jit_context_new_array_access ( 2476 state->ctxt, 2477 loc, 2478 gcc_jit_lvalue_as_rvalue (state->stack), 2479 gcc_jit_lvalue_as_rvalue (state->stack_depth)))); 2480@} 2481 2482 2483@end example 2484 2485@noindent 2486@end quotation 2487 2488We will support single-stepping through the generated code in the 2489debugger, so we need to create @pxref{3b,,gcc_jit_location} instances, one 2490per operation in the source code. These will reference the lines of 2491e.g. @code{factorial.toy}. 2492 2493@quotation 2494 2495@example 2496 for (pc = 0; pc < fn->fn_num_ops; pc++) 2497 @{ 2498 toyvm_op *op = &fn->fn_ops[pc]; 2499 2500 state.op_locs[pc] = gcc_jit_context_new_location (state.ctxt, 2501 fn->fn_filename, 2502 op->op_linenum, 2503 0); /* column */ 2504 @} 2505 2506 2507@end example 2508 2509@noindent 2510@end quotation 2511 2512Let's create the function itself. As usual, we create its parameter 2513first, then use the parameter to create the function: 2514 2515@quotation 2516 2517@example 2518 state.param_arg = 2519 gcc_jit_context_new_param (state.ctxt, state.op_locs[0], 2520 state.int_type, "arg"); 2521 state.fn = 2522 gcc_jit_context_new_function (state.ctxt, 2523 state.op_locs[0], 2524 GCC_JIT_FUNCTION_EXPORTED, 2525 state.int_type, 2526 funcname, 2527 1, &state.param_arg, 0); 2528 2529 2530@end example 2531 2532@noindent 2533@end quotation 2534 2535We create the locals within the function. 2536 2537@quotation 2538 2539@example 2540 state.stack = 2541 gcc_jit_function_new_local (state.fn, NULL, 2542 state.stack_type, "stack"); 2543 state.stack_depth = 2544 gcc_jit_function_new_local (state.fn, NULL, 2545 state.int_type, "stack_depth"); 2546 state.x = 2547 gcc_jit_function_new_local (state.fn, NULL, 2548 state.int_type, "x"); 2549 state.y = 2550 gcc_jit_function_new_local (state.fn, NULL, 2551 state.int_type, "y"); 2552 2553 2554@end example 2555 2556@noindent 2557@end quotation 2558 2559@node Populating the function,Verifying the control flow graph,Setting things up,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2560@anchor{intro/tutorial04 populating-the-function}@anchor{3c} 2561@subsection Populating the function 2562 2563 2564There's some one-time initialization, and the API treats the first block 2565you create as the entrypoint of the function, so we need to create that 2566block first: 2567 2568@quotation 2569 2570@example 2571 state.initial_block = gcc_jit_function_new_block (state.fn, "initial"); 2572 2573 2574@end example 2575 2576@noindent 2577@end quotation 2578 2579We can now create blocks for each of the operations. Most of these will 2580be consolidated into larger blocks when the optimizer runs. 2581 2582@quotation 2583 2584@example 2585 for (pc = 0; pc < fn->fn_num_ops; pc++) 2586 @{ 2587 char buf[16]; 2588 sprintf (buf, "instr%i", pc); 2589 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); 2590 @} 2591 2592 2593@end example 2594 2595@noindent 2596@end quotation 2597 2598Now that we have a block it can jump to when it's done, we can populate 2599the initial block: 2600 2601@quotation 2602 2603@example 2604 2605 /* "stack_depth = 0;". */ 2606 gcc_jit_block_add_assignment ( 2607 state.initial_block, 2608 state.op_locs[0], 2609 state.stack_depth, 2610 gcc_jit_context_zero (state.ctxt, state.int_type)); 2611 2612 /* "PUSH (arg);". */ 2613 add_push (&state, 2614 state.initial_block, 2615 gcc_jit_param_as_rvalue (state.param_arg), 2616 state.op_locs[0]); 2617 2618 /* ...and jump to insn 0. */ 2619 gcc_jit_block_end_with_jump (state.initial_block, 2620 state.op_locs[0], 2621 state.op_blocks[0]); 2622 2623 2624@end example 2625 2626@noindent 2627@end quotation 2628 2629We can now populate the blocks for the individual operations. We loop 2630through them, adding instructions to their blocks: 2631 2632@quotation 2633 2634@example 2635 for (pc = 0; pc < fn->fn_num_ops; pc++) 2636 @{ 2637 gcc_jit_location *loc = state.op_locs[pc]; 2638 2639 gcc_jit_block *block = state.op_blocks[pc]; 2640 gcc_jit_block *next_block = (pc < fn->fn_num_ops 2641 ? state.op_blocks[pc + 1] 2642 : NULL); 2643 2644 toyvm_op *op; 2645 op = &fn->fn_ops[pc]; 2646 2647 2648@end example 2649 2650@noindent 2651@end quotation 2652 2653We're going to have another big @code{switch} statement for implementing 2654the opcodes, this time for compiling them, rather than interpreting 2655them. It's helpful to have macros for implementing push and pop, so that 2656we can make the @code{switch} statement that's coming up look as much as 2657possible like the one above within the interpreter: 2658 2659@example 2660 2661#define X_EQUALS_POP()\ 2662 add_pop (&state, block, state.x, loc) 2663#define Y_EQUALS_POP()\ 2664 add_pop (&state, block, state.y, loc) 2665#define PUSH_RVALUE(RVALUE)\ 2666 add_push (&state, block, (RVALUE), loc) 2667#define PUSH_X()\ 2668 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.x)) 2669#define PUSH_Y() \ 2670 PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.y)) 2671 2672 2673@end example 2674 2675@noindent 2676 2677@cartouche 2678@quotation Note 2679A particularly clever implementation would have an @emph{identical} 2680@code{switch} statement shared by the interpreter and the compiler, with 2681some preprocessor "magic". We're not doing that here, for the sake 2682of simplicity. 2683@end quotation 2684@end cartouche 2685 2686When I first implemented this compiler, I accidentally missed an edit 2687when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the 2688stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y} 2689uninitialized. 2690 2691To track this kind of thing down, we can use 2692@pxref{3d,,gcc_jit_block_add_comment()} to add descriptive comments 2693to the internal representation. This is invaluable when looking through 2694the generated IR for, say @code{factorial}: 2695 2696@quotation 2697 2698@example 2699 2700 gcc_jit_block_add_comment (block, loc, opcode_names[op->op_opcode]); 2701 2702 2703@end example 2704 2705@noindent 2706@end quotation 2707 2708We can now write the big @code{switch} statement that implements the 2709individual opcodes, populating the relevant block with statements: 2710 2711@quotation 2712 2713@example 2714 2715 switch (op->op_opcode) 2716 @{ 2717 case DUP: 2718 X_EQUALS_POP (); 2719 PUSH_X (); 2720 PUSH_X (); 2721 break; 2722 2723 case ROT: 2724 Y_EQUALS_POP (); 2725 X_EQUALS_POP (); 2726 PUSH_Y (); 2727 PUSH_X (); 2728 break; 2729 2730 case BINARY_ADD: 2731 Y_EQUALS_POP (); 2732 X_EQUALS_POP (); 2733 PUSH_RVALUE ( 2734 gcc_jit_context_new_binary_op ( 2735 state.ctxt, 2736 loc, 2737 GCC_JIT_BINARY_OP_PLUS, 2738 state.int_type, 2739 gcc_jit_lvalue_as_rvalue (state.x), 2740 gcc_jit_lvalue_as_rvalue (state.y))); 2741 break; 2742 2743 case BINARY_SUBTRACT: 2744 Y_EQUALS_POP (); 2745 X_EQUALS_POP (); 2746 PUSH_RVALUE ( 2747 gcc_jit_context_new_binary_op ( 2748 state.ctxt, 2749 loc, 2750 GCC_JIT_BINARY_OP_MINUS, 2751 state.int_type, 2752 gcc_jit_lvalue_as_rvalue (state.x), 2753 gcc_jit_lvalue_as_rvalue (state.y))); 2754 break; 2755 2756 case BINARY_MULT: 2757 Y_EQUALS_POP (); 2758 X_EQUALS_POP (); 2759 PUSH_RVALUE ( 2760 gcc_jit_context_new_binary_op ( 2761 state.ctxt, 2762 loc, 2763 GCC_JIT_BINARY_OP_MULT, 2764 state.int_type, 2765 gcc_jit_lvalue_as_rvalue (state.x), 2766 gcc_jit_lvalue_as_rvalue (state.y))); 2767 break; 2768 2769 case BINARY_COMPARE_LT: 2770 Y_EQUALS_POP (); 2771 X_EQUALS_POP (); 2772 PUSH_RVALUE ( 2773 /* cast of bool to int */ 2774 gcc_jit_context_new_cast ( 2775 state.ctxt, 2776 loc, 2777 /* (x < y) as a bool */ 2778 gcc_jit_context_new_comparison ( 2779 state.ctxt, 2780 loc, 2781 GCC_JIT_COMPARISON_LT, 2782 gcc_jit_lvalue_as_rvalue (state.x), 2783 gcc_jit_lvalue_as_rvalue (state.y)), 2784 state.int_type)); 2785 break; 2786 2787 case RECURSE: 2788 @{ 2789 X_EQUALS_POP (); 2790 gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (state.x); 2791 PUSH_RVALUE ( 2792 gcc_jit_context_new_call ( 2793 state.ctxt, 2794 loc, 2795 state.fn, 2796 1, &arg)); 2797 break; 2798 @} 2799 2800 case RETURN: 2801 X_EQUALS_POP (); 2802 gcc_jit_block_end_with_return ( 2803 block, 2804 loc, 2805 gcc_jit_lvalue_as_rvalue (state.x)); 2806 break; 2807 2808 /* Ops taking an operand. */ 2809 case PUSH_CONST: 2810 PUSH_RVALUE ( 2811 gcc_jit_context_new_rvalue_from_int ( 2812 state.ctxt, 2813 state.int_type, 2814 op->op_operand)); 2815 break; 2816 2817 case JUMP_ABS_IF_TRUE: 2818 X_EQUALS_POP (); 2819 gcc_jit_block_end_with_conditional ( 2820 block, 2821 loc, 2822 /* "(bool)x". */ 2823 gcc_jit_context_new_cast ( 2824 state.ctxt, 2825 loc, 2826 gcc_jit_lvalue_as_rvalue (state.x), 2827 state.bool_type), 2828 state.op_blocks[op->op_operand], /* on_true */ 2829 next_block); /* on_false */ 2830 break; 2831 2832 default: 2833 assert(0); 2834 @} /* end of switch on opcode */ 2835 2836 2837@end example 2838 2839@noindent 2840@end quotation 2841 2842Every block must be terminated, via a call to one of the 2843@code{gcc_jit_block_end_with_} entrypoints. This has been done for two 2844of the opcodes, but we need to do it for the other ones, by jumping 2845to the next block. 2846 2847@quotation 2848 2849@example 2850 if (op->op_opcode != JUMP_ABS_IF_TRUE 2851 && op->op_opcode != RETURN) 2852 gcc_jit_block_end_with_jump ( 2853 block, 2854 loc, 2855 next_block); 2856 2857 2858@end example 2859 2860@noindent 2861@end quotation 2862 2863This is analogous to simply incrementing the program counter. 2864 2865@node Verifying the control flow graph,Compiling the context,Populating the function,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2866@anchor{intro/tutorial04 verifying-the-control-flow-graph}@anchor{3e} 2867@subsection Verifying the control flow graph 2868 2869 2870Having finished looping over the blocks, the context is complete. 2871 2872As before, we can verify that the control flow and statements are sane by 2873using @pxref{33,,gcc_jit_function_dump_to_dot()}: 2874 2875@example 2876gcc_jit_function_dump_to_dot (state.fn, "/tmp/factorial.dot"); 2877@end example 2878 2879@noindent 2880 2881and viewing the result. Note how the label names, comments, and 2882variable names show up in the dump, to make it easier to spot 2883errors in our compiler. 2884 2885@quotation 2886 2887 2888@float Figure 2889 2890@image{factorial1,,,image of a control flow graph,png} 2891 2892@end float 2893 2894@end quotation 2895 2896@node Compiling the context,Single-stepping through the generated code,Verifying the control flow graph,Tutorial part 4 Adding JIT-compilation to a toy interpreter 2897@anchor{intro/tutorial04 compiling-the-context}@anchor{3f} 2898@subsection Compiling the context 2899 2900 2901Having finished looping over the blocks and populating them with 2902statements, the context is complete. 2903 2904We can now compile it, and extract machine code from the result: 2905 2906@quotation 2907 2908@example 2909 gcc_jit_result *jit_result = gcc_jit_context_compile (state.ctxt); 2910 gcc_jit_context_release (state.ctxt); 2911 2912 toyvm_compiled_function *toyvm_result = 2913 (toyvm_compiled_function *)calloc (1, sizeof (toyvm_compiled_function)); 2914 if (!toyvm_result) 2915 @{ 2916 fprintf (stderr, "out of memory allocating toyvm_compiled_function\n"); 2917 gcc_jit_result_release (jit_result); 2918 return NULL; 2919 @} 2920 2921 toyvm_result->cf_jit_result = jit_result; 2922 toyvm_result->cf_code = 2923 (toyvm_compiled_code)gcc_jit_result_get_code (jit_result, 2924 funcname); 2925 2926 free (funcname); 2927 2928 return toyvm_result; 2929@} 2930 2931char test[1024]; 2932 2933#define CHECK_NON_NULL(PTR) \ 2934 do @{ \ 2935 if ((PTR) != NULL) \ 2936 @{ \ 2937 pass ("%s: %s is non-null", test, #PTR); \ 2938 @} \ 2939 else \ 2940 @{ \ 2941 fail ("%s: %s is NULL", test, #PTR); \ 2942 abort (); \ 2943 @} \ 2944 @} while (0) 2945 2946#define CHECK_VALUE(ACTUAL, EXPECTED) \ 2947 do @{ \ 2948 if ((ACTUAL) == (EXPECTED)) \ 2949 @{ \ 2950 pass ("%s: actual: %s == expected: %s", test, #ACTUAL, #EXPECTED); \ 2951 @} \ 2952 else \ 2953 @{ \ 2954 fail ("%s: actual: %s != expected: %s", test, #ACTUAL, #EXPECTED); \ 2955 fprintf (stderr, "incorrect value\n"); \ 2956 abort (); \ 2957 @} \ 2958 @} while (0) 2959 2960static void 2961test_script (const char *scripts_dir, const char *script_name, int input, 2962 int expected_result) 2963@{ 2964 char *script_path; 2965 toyvm_function *fn; 2966 int interpreted_result; 2967 toyvm_compiled_function *compiled_fn; 2968 toyvm_compiled_code code; 2969 int compiled_result; 2970 2971 snprintf (test, sizeof (test), "toyvm.c: %s", script_name); 2972 2973 script_path = (char *)malloc (strlen (scripts_dir) 2974 + strlen (script_name) + 1); 2975 CHECK_NON_NULL (script_path); 2976 sprintf (script_path, "%s%s", scripts_dir, script_name); 2977 2978 fn = toyvm_function_parse (script_path, script_name); 2979 CHECK_NON_NULL (fn); 2980 2981 interpreted_result = toyvm_function_interpret (fn, input, NULL); 2982 CHECK_VALUE (interpreted_result, expected_result); 2983 2984 compiled_fn = toyvm_function_compile (fn); 2985 CHECK_NON_NULL (compiled_fn); 2986 2987 code = (toyvm_compiled_code)compiled_fn->cf_code; 2988 CHECK_NON_NULL (code); 2989 2990 compiled_result = code (input); 2991 CHECK_VALUE (compiled_result, expected_result); 2992 2993 gcc_jit_result_release (compiled_fn->cf_jit_result); 2994 free (compiled_fn); 2995 free (fn); 2996 free (script_path); 2997@} 2998 2999#define PATH_TO_SCRIPTS ("/jit/docs/examples/tut04-toyvm/") 3000 3001static void 3002test_suite (void) 3003@{ 3004 const char *srcdir; 3005 char *scripts_dir; 3006 3007 snprintf (test, sizeof (test), "toyvm.c"); 3008 3009 /* We need to locate the test scripts. 3010 Rely on "srcdir" being set in the environment. */ 3011 3012 srcdir = getenv ("srcdir"); 3013 CHECK_NON_NULL (srcdir); 3014 3015 scripts_dir = (char *)malloc (strlen (srcdir) + strlen(PATH_TO_SCRIPTS) 3016 + 1); 3017 CHECK_NON_NULL (scripts_dir); 3018 sprintf (scripts_dir, "%s%s", srcdir, PATH_TO_SCRIPTS); 3019 3020 test_script (scripts_dir, "factorial.toy", 10, 3628800); 3021 test_script (scripts_dir, "fibonacci.toy", 10, 55); 3022 3023 free (scripts_dir); 3024@} 3025 3026int 3027main (int argc, char **argv) 3028@{ 3029 const char *filename = NULL; 3030 toyvm_function *fn = NULL; 3031 3032 /* If called with no args, assume we're being run by the test suite. */ 3033 if (argc < 3) 3034 @{ 3035 test_suite (); 3036 return 0; 3037 @} 3038 3039 if (argc != 3) 3040 @{ 3041 fprintf (stdout, 3042 "%s FILENAME INPUT: Parse and run a .toy file\n", 3043 argv[0]); 3044 exit (1); 3045 @} 3046 3047 filename = argv[1]; 3048 fn = toyvm_function_parse (filename, filename); 3049 if (!fn) 3050 exit (1); 3051 3052 if (0) 3053 toyvm_function_disassemble (fn, stdout); 3054 3055 printf ("interpreter result: %d\n", 3056 toyvm_function_interpret (fn, atoi (argv[2]), NULL)); 3057 3058 /* JIT-compilation. */ 3059 toyvm_compiled_function *compiled_fn 3060 = toyvm_function_compile (fn); 3061 3062 toyvm_compiled_code code = compiled_fn->cf_code; 3063 printf ("compiler result: %d\n", 3064 code (atoi (argv[2]))); 3065 3066 gcc_jit_result_release (compiled_fn->cf_jit_result); 3067 free (compiled_fn); 3068 3069 return 0; 3070@} 3071 3072@end example 3073 3074@noindent 3075@end quotation 3076 3077We can now run the result: 3078 3079@quotation 3080 3081@example 3082 toyvm_compiled_function *compiled_fn 3083 = toyvm_function_compile (fn); 3084 3085 toyvm_compiled_code code = compiled_fn->cf_code; 3086 printf ("compiler result: %d\n", 3087 code (atoi (argv[2]))); 3088 3089 gcc_jit_result_release (compiled_fn->cf_jit_result); 3090 free (compiled_fn); 3091 3092 3093@end example 3094 3095@noindent 3096@end quotation 3097 3098@node Single-stepping through the generated code,Examining the generated code,Compiling the context,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3099@anchor{intro/tutorial04 single-stepping-through-the-generated-code}@anchor{40} 3100@subsection Single-stepping through the generated code 3101 3102 3103It's possible to debug the generated code. To do this we need to both: 3104 3105@quotation 3106 3107 3108@itemize * 3109 3110@item 3111Set up source code locations for our statements, so that we can 3112meaningfully step through the code. We did this above by 3113calling @pxref{41,,gcc_jit_context_new_location()} and using the 3114results. 3115 3116@item 3117Enable the generation of debugging information, by setting 3118@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 3119@pxref{8,,gcc_jit_context} via 3120@pxref{1b,,gcc_jit_context_set_bool_option()}: 3121 3122@example 3123gcc_jit_context_set_bool_option ( 3124 ctxt, 3125 GCC_JIT_BOOL_OPTION_DEBUGINFO, 3126 1); 3127@end example 3128 3129@noindent 3130@end itemize 3131@end quotation 3132 3133Having done this, we can put a breakpoint on the generated function: 3134 3135@example 3136$ gdb --args ./toyvm factorial.toy 10 3137(gdb) break factorial 3138Function "factorial" not defined. 3139Make breakpoint pending on future shared library load? (y or [n]) y 3140Breakpoint 1 (factorial) pending. 3141(gdb) run 3142Breakpoint 1, factorial (arg=10) at factorial.toy:14 314314 DUP 3144@end example 3145 3146@noindent 3147 3148We've set up location information, which references @code{factorial.toy}. 3149This allows us to use e.g. @code{list} to see where we are in the script: 3150 3151@example 3152(gdb) list 31539 315410 # Initial state: 315511 # stack: [arg] 315612 315713 # 0: 315814 DUP 315915 # stack: [arg, arg] 316016 316117 # 1: 316218 PUSH_CONST 2 3163@end example 3164 3165@noindent 3166 3167and to step through the function, examining the data: 3168 3169@example 3170(gdb) n 317118 PUSH_CONST 2 3172(gdb) n 317322 BINARY_COMPARE_LT 3174(gdb) print stack 3175$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@} 3176(gdb) print stack_depth 3177$6 = 3 3178@end example 3179 3180@noindent 3181 3182You'll see that the parts of the @code{stack} array that haven't been 3183touched yet are uninitialized. 3184 3185@cartouche 3186@quotation Note 3187Turning on optimizations may lead to unpredictable results when 3188stepping through the generated code: the execution may appear to 3189"jump around" the source code. This is analogous to turning up the 3190optimization level in a regular compiler. 3191@end quotation 3192@end cartouche 3193 3194@node Examining the generated code,Putting it all together,Single-stepping through the generated code,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3195@anchor{intro/tutorial04 examining-the-generated-code}@anchor{43} 3196@subsection Examining the generated code 3197 3198 3199How good is the optimized code? 3200 3201We can turn up optimizations, by calling 3202@pxref{1e,,gcc_jit_context_set_int_option()} with 3203@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 3204 3205@example 3206gcc_jit_context_set_int_option ( 3207 ctxt, 3208 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3209 3); 3210@end example 3211 3212@noindent 3213 3214One of GCC's internal representations is called "gimple". A dump of the 3215initial gimple representation of the code can be seen by setting: 3216 3217@example 3218gcc_jit_context_set_bool_option (ctxt, 3219 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 3220 1); 3221@end example 3222 3223@noindent 3224 3225With optimization on and source locations displayed, this gives: 3226 3227@c We'll use "c" for gimple dumps 3228 3229@example 3230factorial (signed int arg) 3231@{ 3232 <unnamed type> D.80; 3233 signed int D.81; 3234 signed int D.82; 3235 signed int D.83; 3236 signed int D.84; 3237 signed int D.85; 3238 signed int y; 3239 signed int x; 3240 signed int stack_depth; 3241 signed int stack[8]; 3242 3243 try 3244 @{ 3245 initial: 3246 stack_depth = 0; 3247 stack[stack_depth] = arg; 3248 stack_depth = stack_depth + 1; 3249 goto instr0; 3250 instr0: 3251 /* DUP */: 3252 stack_depth = stack_depth + -1; 3253 x = stack[stack_depth]; 3254 stack[stack_depth] = x; 3255 stack_depth = stack_depth + 1; 3256 stack[stack_depth] = x; 3257 stack_depth = stack_depth + 1; 3258 goto instr1; 3259 instr1: 3260 /* PUSH_CONST */: 3261 stack[stack_depth] = 2; 3262 stack_depth = stack_depth + 1; 3263 goto instr2; 3264 3265 /* etc */ 3266@end example 3267 3268@noindent 3269 3270You can see the generated machine code in assembly form via: 3271 3272@example 3273gcc_jit_context_set_bool_option ( 3274 ctxt, 3275 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 3276 1); 3277result = gcc_jit_context_compile (ctxt); 3278@end example 3279 3280@noindent 3281 3282which shows that (on this x86_64 box) the compiler has unrolled the loop 3283and is using MMX instructions to perform several multiplications 3284simultaneously: 3285 3286@example 3287 .file "fake.c" 3288 .text 3289.Ltext0: 3290 .p2align 4,,15 3291 .globl factorial 3292 .type factorial, @@function 3293factorial: 3294.LFB0: 3295 .file 1 "factorial.toy" 3296 .loc 1 14 0 3297 .cfi_startproc 3298.LVL0: 3299.L2: 3300 .loc 1 26 0 3301 cmpl $1, %edi 3302 jle .L13 3303 leal -1(%rdi), %edx 3304 movl %edx, %ecx 3305 shrl $2, %ecx 3306 leal 0(,%rcx,4), %esi 3307 testl %esi, %esi 3308 je .L14 3309 cmpl $9, %edx 3310 jbe .L14 3311 leal -2(%rdi), %eax 3312 movl %eax, -16(%rsp) 3313 leal -3(%rdi), %eax 3314 movd -16(%rsp), %xmm0 3315 movl %edi, -16(%rsp) 3316 movl %eax, -12(%rsp) 3317 movd -16(%rsp), %xmm1 3318 xorl %eax, %eax 3319 movl %edx, -16(%rsp) 3320 movd -12(%rsp), %xmm4 3321 movd -16(%rsp), %xmm6 3322 punpckldq %xmm4, %xmm0 3323 movdqa .LC1(%rip), %xmm4 3324 punpckldq %xmm6, %xmm1 3325 punpcklqdq %xmm0, %xmm1 3326 movdqa .LC0(%rip), %xmm0 3327 jmp .L5 3328 # etc - edited for brevity 3329@end example 3330 3331@noindent 3332 3333This is clearly overkill for a function that will likely overflow the 3334@code{int} type before the vectorization is worthwhile - but then again, this 3335is a toy example. 3336 3337Turning down the optimization level to 2: 3338 3339@example 3340gcc_jit_context_set_int_option ( 3341 ctxt, 3342 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3343 3); 3344@end example 3345 3346@noindent 3347 3348yields this code, which is simple enough to quote in its entirety: 3349 3350@example 3351 .file "fake.c" 3352 .text 3353 .p2align 4,,15 3354 .globl factorial 3355 .type factorial, @@function 3356factorial: 3357.LFB0: 3358 .cfi_startproc 3359.L2: 3360 cmpl $1, %edi 3361 jle .L8 3362 movl $1, %edx 3363 jmp .L4 3364 .p2align 4,,10 3365 .p2align 3 3366.L6: 3367 movl %eax, %edi 3368.L4: 3369.L5: 3370 leal -1(%rdi), %eax 3371 imull %edi, %edx 3372 cmpl $1, %eax 3373 jne .L6 3374.L3: 3375.L7: 3376 imull %edx, %eax 3377 ret 3378.L8: 3379 movl %edi, %eax 3380 movl $1, %edx 3381 jmp .L7 3382 .cfi_endproc 3383.LFE0: 3384 .size factorial, .-factorial 3385 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})" 3386 .section .note.GNU-stack,"",@@progbits 3387@end example 3388 3389@noindent 3390 3391Note that the stack pushing and popping have been eliminated, as has the 3392recursive call (in favor of an iteration). 3393 3394@node Putting it all together,Behind the curtain How does our code get optimized?,Examining the generated code,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3395@anchor{intro/tutorial04 putting-it-all-together}@anchor{44} 3396@subsection Putting it all together 3397 3398 3399The complete example can be seen in the source tree at 3400@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.c} 3401 3402along with a Makefile and a couple of sample .toy scripts: 3403 3404@example 3405$ ls -al 3406drwxrwxr-x. 2 david david 4096 Sep 19 17:46 . 3407drwxrwxr-x. 3 david david 4096 Sep 19 15:26 .. 3408-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy 3409-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy 3410-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile 3411-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.c 3412 3413$ make toyvm 3414g++ -Wall -g -o toyvm toyvm.c -lgccjit 3415 3416$ ./toyvm factorial.toy 10 3417interpreter result: 3628800 3418compiler result: 3628800 3419 3420$ ./toyvm fibonacci.toy 10 3421interpreter result: 55 3422compiler result: 55 3423@end example 3424 3425@noindent 3426 3427@node Behind the curtain How does our code get optimized?,,Putting it all together,Tutorial part 4 Adding JIT-compilation to a toy interpreter 3428@anchor{intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{45} 3429@subsection Behind the curtain: How does our code get optimized? 3430 3431 3432Our example is done, but you may be wondering about exactly how the 3433compiler turned what we gave it into the machine code seen above. 3434 3435We can examine what the compiler is doing in detail by setting: 3436 3437@example 3438gcc_jit_context_set_bool_option (state.ctxt, 3439 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 3440 1); 3441gcc_jit_context_set_bool_option (state.ctxt, 3442 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 3443 1); 3444@end example 3445 3446@noindent 3447 3448This will dump detailed information about the compiler's state to a 3449directory under @code{/tmp}, and keep it from being cleaned up. 3450 3451The precise names and their formats of these files is subject to change. 3452Higher optimization levels lead to more files. 3453Here's what I saw (edited for brevity; there were almost 200 files): 3454 3455@example 3456intermediate files written to /tmp/libgccjit-KPQbGw 3457$ ls /tmp/libgccjit-KPQbGw/ 3458fake.c.000i.cgraph 3459fake.c.000i.type-inheritance 3460fake.c.004t.gimple 3461fake.c.007t.omplower 3462fake.c.008t.lower 3463fake.c.011t.eh 3464fake.c.012t.cfg 3465fake.c.014i.visibility 3466fake.c.015i.early_local_cleanups 3467fake.c.016t.ssa 3468# etc 3469@end example 3470 3471@noindent 3472 3473The gimple code is converted into Static Single Assignment form, 3474with annotations for use when generating the debuginfo: 3475 3476@example 3477$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa 3478@end example 3479 3480@noindent 3481 3482@example 3483;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3484 3485factorial (signed int arg) 3486@{ 3487 signed int stack[8]; 3488 signed int stack_depth; 3489 signed int x; 3490 signed int y; 3491 <unnamed type> _20; 3492 signed int _21; 3493 signed int _38; 3494 signed int _44; 3495 signed int _51; 3496 signed int _56; 3497 3498initial: 3499 stack_depth_3 = 0; 3500 # DEBUG stack_depth => stack_depth_3 3501 stack[stack_depth_3] = arg_5(D); 3502 stack_depth_7 = stack_depth_3 + 1; 3503 # DEBUG stack_depth => stack_depth_7 3504 # DEBUG instr0 => NULL 3505 # DEBUG /* DUP */ => NULL 3506 stack_depth_8 = stack_depth_7 + -1; 3507 # DEBUG stack_depth => stack_depth_8 3508 x_9 = stack[stack_depth_8]; 3509 # DEBUG x => x_9 3510 stack[stack_depth_8] = x_9; 3511 stack_depth_11 = stack_depth_8 + 1; 3512 # DEBUG stack_depth => stack_depth_11 3513 stack[stack_depth_11] = x_9; 3514 stack_depth_13 = stack_depth_11 + 1; 3515 # DEBUG stack_depth => stack_depth_13 3516 # DEBUG instr1 => NULL 3517 # DEBUG /* PUSH_CONST */ => NULL 3518 stack[stack_depth_13] = 2; 3519 3520 /* etc; edited for brevity */ 3521@end example 3522 3523@noindent 3524 3525We can perhaps better see the code by turning off 3526@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG} 3527statements, giving: 3528 3529@example 3530$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa 3531@end example 3532 3533@noindent 3534 3535@example 3536;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3537 3538factorial (signed int arg) 3539@{ 3540 signed int stack[8]; 3541 signed int stack_depth; 3542 signed int x; 3543 signed int y; 3544 <unnamed type> _20; 3545 signed int _21; 3546 signed int _38; 3547 signed int _44; 3548 signed int _51; 3549 signed int _56; 3550 3551initial: 3552 stack_depth_3 = 0; 3553 stack[stack_depth_3] = arg_5(D); 3554 stack_depth_7 = stack_depth_3 + 1; 3555 stack_depth_8 = stack_depth_7 + -1; 3556 x_9 = stack[stack_depth_8]; 3557 stack[stack_depth_8] = x_9; 3558 stack_depth_11 = stack_depth_8 + 1; 3559 stack[stack_depth_11] = x_9; 3560 stack_depth_13 = stack_depth_11 + 1; 3561 stack[stack_depth_13] = 2; 3562 stack_depth_15 = stack_depth_13 + 1; 3563 stack_depth_16 = stack_depth_15 + -1; 3564 y_17 = stack[stack_depth_16]; 3565 stack_depth_18 = stack_depth_16 + -1; 3566 x_19 = stack[stack_depth_18]; 3567 _20 = x_19 < y_17; 3568 _21 = (signed int) _20; 3569 stack[stack_depth_18] = _21; 3570 stack_depth_23 = stack_depth_18 + 1; 3571 stack_depth_24 = stack_depth_23 + -1; 3572 x_25 = stack[stack_depth_24]; 3573 if (x_25 != 0) 3574 goto <bb 4> (instr9); 3575 else 3576 goto <bb 3> (instr4); 3577 3578instr4: 3579/* DUP */: 3580 stack_depth_26 = stack_depth_24 + -1; 3581 x_27 = stack[stack_depth_26]; 3582 stack[stack_depth_26] = x_27; 3583 stack_depth_29 = stack_depth_26 + 1; 3584 stack[stack_depth_29] = x_27; 3585 stack_depth_31 = stack_depth_29 + 1; 3586 stack[stack_depth_31] = 1; 3587 stack_depth_33 = stack_depth_31 + 1; 3588 stack_depth_34 = stack_depth_33 + -1; 3589 y_35 = stack[stack_depth_34]; 3590 stack_depth_36 = stack_depth_34 + -1; 3591 x_37 = stack[stack_depth_36]; 3592 _38 = x_37 - y_35; 3593 stack[stack_depth_36] = _38; 3594 stack_depth_40 = stack_depth_36 + 1; 3595 stack_depth_41 = stack_depth_40 + -1; 3596 x_42 = stack[stack_depth_41]; 3597 _44 = factorial (x_42); 3598 stack[stack_depth_41] = _44; 3599 stack_depth_46 = stack_depth_41 + 1; 3600 stack_depth_47 = stack_depth_46 + -1; 3601 y_48 = stack[stack_depth_47]; 3602 stack_depth_49 = stack_depth_47 + -1; 3603 x_50 = stack[stack_depth_49]; 3604 _51 = x_50 * y_48; 3605 stack[stack_depth_49] = _51; 3606 stack_depth_53 = stack_depth_49 + 1; 3607 3608 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)> 3609instr9: 3610/* RETURN */: 3611 stack_depth_54 = stack_depth_1 + -1; 3612 x_55 = stack[stack_depth_54]; 3613 _56 = x_55; 3614 stack =@{v@} @{CLOBBER@}; 3615 return _56; 3616 3617@} 3618@end example 3619 3620@noindent 3621 3622Note in the above how all the @pxref{28,,gcc_jit_block} instances we 3623created have been consolidated into just 3 blocks in GCC's internal 3624representation: @code{initial}, @code{instr4} and @code{instr9}. 3625 3626@menu 3627* Optimizing away stack manipulation:: 3628* Elimination of tail recursion:: 3629 3630@end menu 3631 3632@node Optimizing away stack manipulation,Elimination of tail recursion,,Behind the curtain How does our code get optimized? 3633@anchor{intro/tutorial04 optimizing-away-stack-manipulation}@anchor{46} 3634@subsubsection Optimizing away stack manipulation 3635 3636 3637Recall our simple implementation of stack operations. Let's examine 3638how the stack operations are optimized away. 3639 3640After a pass of constant-propagation, the depth of the stack at each 3641opcode can be determined at compile-time: 3642 3643@example 3644$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1 3645@end example 3646 3647@noindent 3648 3649@example 3650;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3651 3652factorial (signed int arg) 3653@{ 3654 signed int stack[8]; 3655 signed int stack_depth; 3656 signed int x; 3657 signed int y; 3658 <unnamed type> _20; 3659 signed int _21; 3660 signed int _38; 3661 signed int _44; 3662 signed int _51; 3663 3664initial: 3665 stack[0] = arg_5(D); 3666 x_9 = stack[0]; 3667 stack[0] = x_9; 3668 stack[1] = x_9; 3669 stack[2] = 2; 3670 y_17 = stack[2]; 3671 x_19 = stack[1]; 3672 _20 = x_19 < y_17; 3673 _21 = (signed int) _20; 3674 stack[1] = _21; 3675 x_25 = stack[1]; 3676 if (x_25 != 0) 3677 goto <bb 4> (instr9); 3678 else 3679 goto <bb 3> (instr4); 3680 3681instr4: 3682/* DUP */: 3683 x_27 = stack[0]; 3684 stack[0] = x_27; 3685 stack[1] = x_27; 3686 stack[2] = 1; 3687 y_35 = stack[2]; 3688 x_37 = stack[1]; 3689 _38 = x_37 - y_35; 3690 stack[1] = _38; 3691 x_42 = stack[1]; 3692 _44 = factorial (x_42); 3693 stack[1] = _44; 3694 y_48 = stack[1]; 3695 x_50 = stack[0]; 3696 _51 = x_50 * y_48; 3697 stack[0] = _51; 3698 3699instr9: 3700/* RETURN */: 3701 x_55 = stack[0]; 3702 x_56 = x_55; 3703 stack =@{v@} @{CLOBBER@}; 3704 return x_56; 3705 3706@} 3707@end example 3708 3709@noindent 3710 3711Note how, in the above, all those @code{stack_depth} values are now just 3712constants: we're accessing specific stack locations at each opcode. 3713 3714The "esra" pass ("Early Scalar Replacement of Aggregates") breaks 3715out our "stack" array into individual elements: 3716 3717@example 3718$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra 3719@end example 3720 3721@noindent 3722 3723@example 3724;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3725 3726Created a replacement for stack offset: 0, size: 32: stack$0 3727Created a replacement for stack offset: 32, size: 32: stack$1 3728Created a replacement for stack offset: 64, size: 32: stack$2 3729 3730Symbols to be put in SSA form 3731@{ D.89 D.90 D.91 @} 3732Incremental SSA update started at block: 0 3733Number of blocks in CFG: 5 3734Number of blocks to update: 4 ( 80%) 3735 3736 3737factorial (signed int arg) 3738@{ 3739 signed int stack$2; 3740 signed int stack$1; 3741 signed int stack$0; 3742 signed int stack[8]; 3743 signed int stack_depth; 3744 signed int x; 3745 signed int y; 3746 <unnamed type> _20; 3747 signed int _21; 3748 signed int _38; 3749 signed int _44; 3750 signed int _51; 3751 3752initial: 3753 stack$0_45 = arg_5(D); 3754 x_9 = stack$0_45; 3755 stack$0_39 = x_9; 3756 stack$1_32 = x_9; 3757 stack$2_30 = 2; 3758 y_17 = stack$2_30; 3759 x_19 = stack$1_32; 3760 _20 = x_19 < y_17; 3761 _21 = (signed int) _20; 3762 stack$1_28 = _21; 3763 x_25 = stack$1_28; 3764 if (x_25 != 0) 3765 goto <bb 4> (instr9); 3766 else 3767 goto <bb 3> (instr4); 3768 3769instr4: 3770/* DUP */: 3771 x_27 = stack$0_39; 3772 stack$0_22 = x_27; 3773 stack$1_14 = x_27; 3774 stack$2_12 = 1; 3775 y_35 = stack$2_12; 3776 x_37 = stack$1_14; 3777 _38 = x_37 - y_35; 3778 stack$1_10 = _38; 3779 x_42 = stack$1_10; 3780 _44 = factorial (x_42); 3781 stack$1_6 = _44; 3782 y_48 = stack$1_6; 3783 x_50 = stack$0_22; 3784 _51 = x_50 * y_48; 3785 stack$0_1 = _51; 3786 3787 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)> 3788instr9: 3789/* RETURN */: 3790 x_55 = stack$0_52; 3791 x_56 = x_55; 3792 stack =@{v@} @{CLOBBER@}; 3793 return x_56; 3794 3795@} 3796@end example 3797 3798@noindent 3799 3800Hence at this point, all those pushes and pops of the stack are now 3801simply assignments to specific temporary variables. 3802 3803After some copy propagation, the stack manipulation has been completely 3804optimized away: 3805 3806@example 3807$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1 3808@end example 3809 3810@noindent 3811 3812@example 3813;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3814 3815factorial (signed int arg) 3816@{ 3817 signed int stack$2; 3818 signed int stack$1; 3819 signed int stack$0; 3820 signed int stack[8]; 3821 signed int stack_depth; 3822 signed int x; 3823 signed int y; 3824 <unnamed type> _20; 3825 signed int _21; 3826 signed int _38; 3827 signed int _44; 3828 signed int _51; 3829 3830initial: 3831 stack$0_39 = arg_5(D); 3832 _20 = arg_5(D) <= 1; 3833 _21 = (signed int) _20; 3834 if (_21 != 0) 3835 goto <bb 4> (instr9); 3836 else 3837 goto <bb 3> (instr4); 3838 3839instr4: 3840/* DUP */: 3841 _38 = arg_5(D) + -1; 3842 _44 = factorial (_38); 3843 _51 = arg_5(D) * _44; 3844 stack$0_1 = _51; 3845 3846 # stack$0_52 = PHI <arg_5(D)(2), _51(3)> 3847instr9: 3848/* RETURN */: 3849 stack =@{v@} @{CLOBBER@}; 3850 return stack$0_52; 3851 3852@} 3853@end example 3854 3855@noindent 3856 3857Later on, another pass finally eliminated @code{stack_depth} local and the 3858unused parts of the @cite{stack`} array altogether: 3859 3860@example 3861$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa 3862@end example 3863 3864@noindent 3865 3866@example 3867;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3868 3869Released 44 names, 314.29%, removed 44 holes 3870factorial (signed int arg) 3871@{ 3872 signed int stack$0; 3873 signed int mult_acc_1; 3874 <unnamed type> _5; 3875 signed int _6; 3876 signed int _7; 3877 signed int mul_tmp_10; 3878 signed int mult_acc_11; 3879 signed int mult_acc_13; 3880 3881 # arg_9 = PHI <arg_8(D)(0)> 3882 # mult_acc_13 = PHI <1(0)> 3883initial: 3884 3885 <bb 5>: 3886 # arg_4 = PHI <arg_9(2), _7(3)> 3887 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)> 3888 _5 = arg_4 <= 1; 3889 _6 = (signed int) _5; 3890 if (_6 != 0) 3891 goto <bb 4> (instr9); 3892 else 3893 goto <bb 3> (instr4); 3894 3895instr4: 3896/* DUP */: 3897 _7 = arg_4 + -1; 3898 mult_acc_11 = mult_acc_1 * arg_4; 3899 goto <bb 5>; 3900 3901 # stack$0_12 = PHI <arg_4(5)> 3902instr9: 3903/* RETURN */: 3904 mul_tmp_10 = mult_acc_1 * stack$0_12; 3905 return mul_tmp_10; 3906 3907@} 3908@end example 3909 3910@noindent 3911 3912@node Elimination of tail recursion,,Optimizing away stack manipulation,Behind the curtain How does our code get optimized? 3913@anchor{intro/tutorial04 elimination-of-tail-recursion}@anchor{47} 3914@subsubsection Elimination of tail recursion 3915 3916 3917Another significant optimization is the detection that the call to 3918@code{factorial} is tail recursion, which can be eliminated in favor of 3919an iteration: 3920 3921@example 3922$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1 3923@end example 3924 3925@noindent 3926 3927@example 3928;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 3929 3930 3931Symbols to be put in SSA form 3932@{ D.88 @} 3933Incremental SSA update started at block: 0 3934Number of blocks in CFG: 5 3935Number of blocks to update: 4 ( 80%) 3936 3937 3938factorial (signed int arg) 3939@{ 3940 signed int stack$2; 3941 signed int stack$1; 3942 signed int stack$0; 3943 signed int stack[8]; 3944 signed int stack_depth; 3945 signed int x; 3946 signed int y; 3947 signed int mult_acc_1; 3948 <unnamed type> _20; 3949 signed int _21; 3950 signed int _38; 3951 signed int mul_tmp_44; 3952 signed int mult_acc_51; 3953 3954 # arg_5 = PHI <arg_39(D)(0), _38(3)> 3955 # mult_acc_1 = PHI <1(0), mult_acc_51(3)> 3956initial: 3957 _20 = arg_5 <= 1; 3958 _21 = (signed int) _20; 3959 if (_21 != 0) 3960 goto <bb 4> (instr9); 3961 else 3962 goto <bb 3> (instr4); 3963 3964instr4: 3965/* DUP */: 3966 _38 = arg_5 + -1; 3967 mult_acc_51 = mult_acc_1 * arg_5; 3968 goto <bb 2> (initial); 3969 3970 # stack$0_52 = PHI <arg_5(2)> 3971instr9: 3972/* RETURN */: 3973 stack =@{v@} @{CLOBBER@}; 3974 mul_tmp_44 = mult_acc_1 * stack$0_52; 3975 return mul_tmp_44; 3976 3977@} 3978@end example 3979 3980@noindent 3981 3982@c Copyright (C) 2015-2016 Free Software Foundation, Inc. 3983@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 3984@c 3985@c This is free software: you can redistribute it and/or modify it 3986@c under the terms of the GNU General Public License as published by 3987@c the Free Software Foundation, either version 3 of the License, or 3988@c (at your option) any later version. 3989@c 3990@c This program is distributed in the hope that it will be useful, but 3991@c WITHOUT ANY WARRANTY; without even the implied warranty of 3992@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 3993@c General Public License for more details. 3994@c 3995@c You should have received a copy of the GNU General Public License 3996@c along with this program. If not, see 3997@c <http://www.gnu.org/licenses/>. 3998 3999@node Tutorial part 5 Implementing an Ahead-of-Time compiler,,Tutorial part 4 Adding JIT-compilation to a toy interpreter,Tutorial 4000@anchor{intro/tutorial05 doc}@anchor{48}@anchor{intro/tutorial05 tutorial-part-5-implementing-an-ahead-of-time-compiler}@anchor{49} 4001@section Tutorial part 5: Implementing an Ahead-of-Time compiler 4002 4003 4004If you have a pre-existing language frontend that's compatible with 4005libgccjit's license, it's possible to hook it up to libgccjit as a 4006backend. In the previous example we showed 4007how to do that for in-memory JIT-compilation, but libgccjit can also 4008compile code directly to a file, allowing you to implement a more 4009traditional ahead-of-time compiler ("JIT" is something of a misnomer 4010for this use-case). 4011 4012The essential difference is to compile the context using 4013@pxref{4a,,gcc_jit_context_compile_to_file()} rather than 4014@pxref{15,,gcc_jit_context_compile()}. 4015 4016@menu 4017* The "brainf" language:: 4018* Converting a brainf script to libgccjit IR:: 4019* Compiling a context to a file:: 4020* Other forms of ahead-of-time-compilation:: 4021 4022@end menu 4023 4024@node The "brainf" language,Converting a brainf script to libgccjit IR,,Tutorial part 5 Implementing an Ahead-of-Time compiler 4025@anchor{intro/tutorial05 the-brainf-language}@anchor{4b} 4026@subsection The "brainf" language 4027 4028 4029In this example we use libgccjit to construct an ahead-of-time compiler 4030for an esoteric programming language that we shall refer to as "brainf". 4031 4032brainf scripts operate on an array of bytes, with a notional data pointer 4033within the array. 4034 4035brainf is hard for humans to read, but it's trivial to write a parser for 4036it, as there is no lexing; just a stream of bytes. The operations are: 4037 4038 4039@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 4040@headitem 4041 4042Character 4043 4044@tab 4045 4046Meaning 4047 4048@item 4049 4050@code{>} 4051 4052@tab 4053 4054@code{idx += 1} 4055 4056@item 4057 4058@code{<} 4059 4060@tab 4061 4062@code{idx -= 1} 4063 4064@item 4065 4066@code{+} 4067 4068@tab 4069 4070@code{data[idx] += 1} 4071 4072@item 4073 4074@code{-} 4075 4076@tab 4077 4078@code{data[idx] -= 1} 4079 4080@item 4081 4082@code{.} 4083 4084@tab 4085 4086@code{output (data[idx])} 4087 4088@item 4089 4090@code{,} 4091 4092@tab 4093 4094@code{data[idx] = input ()} 4095 4096@item 4097 4098@code{[} 4099 4100@tab 4101 4102loop until @code{data[idx] == 0} 4103 4104@item 4105 4106@code{]} 4107 4108@tab 4109 4110end of loop 4111 4112@item 4113 4114Anything else 4115 4116@tab 4117 4118ignored 4119 4120@end multitable 4121 4122 4123Unlike the previous example, we'll implement an ahead-of-time compiler, 4124which reads @code{.bf} scripts and outputs executables (though it would 4125be trivial to have it run them JIT-compiled in-process). 4126 4127Here's what a simple @code{.bf} script looks like: 4128 4129@quotation 4130 4131@example 4132[ 4133 Emit the uppercase alphabet 4134] 4135 4136cell 0 = 26 4137++++++++++++++++++++++++++ 4138 4139cell 1 = 65 4140>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4141 4142while cell#0 != 0 4143[ 4144 > 4145 . emit cell#1 4146 + increment cell@@1 4147 <- decrement cell@@0 4148] 4149 4150@end example 4151 4152@noindent 4153@end quotation 4154 4155@cartouche 4156@quotation Note 4157This example makes use of whitespace and comments for legibility, but 4158could have been written as: 4159 4160@example 4161++++++++++++++++++++++++++ 4162>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4163[>.+<-] 4164@end example 4165 4166@noindent 4167 4168It's not a particularly useful language, except for providing 4169compiler-writers with a test case that's easy to parse. The point 4170is that you can use @pxref{4a,,gcc_jit_context_compile_to_file()} 4171to use libgccjit as a backend for a pre-existing language frontend 4172(provided that the pre-existing frontend is compatible with libgccjit's 4173license). 4174@end quotation 4175@end cartouche 4176 4177@node Converting a brainf script to libgccjit IR,Compiling a context to a file,The "brainf" language,Tutorial part 5 Implementing an Ahead-of-Time compiler 4178@anchor{intro/tutorial05 converting-a-brainf-script-to-libgccjit-ir}@anchor{4c} 4179@subsection Converting a brainf script to libgccjit IR 4180 4181 4182As before we write simple code to populate a @pxref{8,,gcc_jit_context *}. 4183 4184@quotation 4185 4186@example 4187 4188typedef struct bf_compiler 4189@{ 4190 const char *filename; 4191 int line; 4192 int column; 4193 4194 gcc_jit_context *ctxt; 4195 4196 gcc_jit_type *void_type; 4197 gcc_jit_type *int_type; 4198 gcc_jit_type *byte_type; 4199 gcc_jit_type *array_type; 4200 4201 gcc_jit_function *func_getchar; 4202 gcc_jit_function *func_putchar; 4203 4204 gcc_jit_function *func; 4205 gcc_jit_block *curblock; 4206 4207 gcc_jit_rvalue *int_zero; 4208 gcc_jit_rvalue *int_one; 4209 gcc_jit_rvalue *byte_zero; 4210 gcc_jit_rvalue *byte_one; 4211 gcc_jit_lvalue *data_cells; 4212 gcc_jit_lvalue *idx; 4213 4214 int num_open_parens; 4215 gcc_jit_block *paren_test[MAX_OPEN_PARENS]; 4216 gcc_jit_block *paren_body[MAX_OPEN_PARENS]; 4217 gcc_jit_block *paren_after[MAX_OPEN_PARENS]; 4218 4219@} bf_compiler; 4220 4221/* Bail out, with a message on stderr. */ 4222 4223static void 4224fatal_error (bf_compiler *bfc, const char *msg) 4225@{ 4226 fprintf (stderr, 4227 "%s:%i:%i: %s", 4228 bfc->filename, bfc->line, bfc->column, msg); 4229 abort (); 4230@} 4231 4232/* Get "data_cells[idx]" as an lvalue. */ 4233 4234static gcc_jit_lvalue * 4235bf_get_current_data (bf_compiler *bfc, gcc_jit_location *loc) 4236@{ 4237 return gcc_jit_context_new_array_access ( 4238 bfc->ctxt, 4239 loc, 4240 gcc_jit_lvalue_as_rvalue (bfc->data_cells), 4241 gcc_jit_lvalue_as_rvalue (bfc->idx)); 4242@} 4243 4244/* Get "data_cells[idx] == 0" as a boolean rvalue. */ 4245 4246static gcc_jit_rvalue * 4247bf_current_data_is_zero (bf_compiler *bfc, gcc_jit_location *loc) 4248@{ 4249 return gcc_jit_context_new_comparison ( 4250 bfc->ctxt, 4251 loc, 4252 GCC_JIT_COMPARISON_EQ, 4253 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)), 4254 bfc->byte_zero); 4255@} 4256 4257/* Compile one bf character. */ 4258 4259static void 4260bf_compile_char (bf_compiler *bfc, 4261 unsigned char ch) 4262@{ 4263 gcc_jit_location *loc = 4264 gcc_jit_context_new_location (bfc->ctxt, 4265 bfc->filename, 4266 bfc->line, 4267 bfc->column); 4268 4269 /* Turn this on to trace execution, by injecting putchar () 4270 of each source char. */ 4271 if (0) 4272 @{ 4273 gcc_jit_rvalue *arg = 4274 gcc_jit_context_new_rvalue_from_int ( 4275 bfc->ctxt, 4276 bfc->int_type, 4277 ch); 4278 gcc_jit_rvalue *call = 4279 gcc_jit_context_new_call (bfc->ctxt, 4280 loc, 4281 bfc->func_putchar, 4282 1, &arg); 4283 gcc_jit_block_add_eval (bfc->curblock, 4284 loc, 4285 call); 4286 @} 4287 4288 switch (ch) 4289 @{ 4290 case '>': 4291 gcc_jit_block_add_comment (bfc->curblock, 4292 loc, 4293 "'>': idx += 1;"); 4294 gcc_jit_block_add_assignment_op (bfc->curblock, 4295 loc, 4296 bfc->idx, 4297 GCC_JIT_BINARY_OP_PLUS, 4298 bfc->int_one); 4299 break; 4300 4301 case '<': 4302 gcc_jit_block_add_comment (bfc->curblock, 4303 loc, 4304 "'<': idx -= 1;"); 4305 gcc_jit_block_add_assignment_op (bfc->curblock, 4306 loc, 4307 bfc->idx, 4308 GCC_JIT_BINARY_OP_MINUS, 4309 bfc->int_one); 4310 break; 4311 4312 case '+': 4313 gcc_jit_block_add_comment (bfc->curblock, 4314 loc, 4315 "'+': data[idx] += 1;"); 4316 gcc_jit_block_add_assignment_op (bfc->curblock, 4317 loc, 4318 bf_get_current_data (bfc, loc), 4319 GCC_JIT_BINARY_OP_PLUS, 4320 bfc->byte_one); 4321 break; 4322 4323 case '-': 4324 gcc_jit_block_add_comment (bfc->curblock, 4325 loc, 4326 "'-': data[idx] -= 1;"); 4327 gcc_jit_block_add_assignment_op (bfc->curblock, 4328 loc, 4329 bf_get_current_data (bfc, loc), 4330 GCC_JIT_BINARY_OP_MINUS, 4331 bfc->byte_one); 4332 break; 4333 4334 case '.': 4335 @{ 4336 gcc_jit_rvalue *arg = 4337 gcc_jit_context_new_cast ( 4338 bfc->ctxt, 4339 loc, 4340 gcc_jit_lvalue_as_rvalue (bf_get_current_data (bfc, loc)), 4341 bfc->int_type); 4342 gcc_jit_rvalue *call = 4343 gcc_jit_context_new_call (bfc->ctxt, 4344 loc, 4345 bfc->func_putchar, 4346 1, &arg); 4347 gcc_jit_block_add_comment (bfc->curblock, 4348 loc, 4349 "'.': putchar ((int)data[idx]);"); 4350 gcc_jit_block_add_eval (bfc->curblock, 4351 loc, 4352 call); 4353 @} 4354 break; 4355 4356 case ',': 4357 @{ 4358 gcc_jit_rvalue *call = 4359 gcc_jit_context_new_call (bfc->ctxt, 4360 loc, 4361 bfc->func_getchar, 4362 0, NULL); 4363 gcc_jit_block_add_comment ( 4364 bfc->curblock, 4365 loc, 4366 "',': data[idx] = (unsigned char)getchar ();"); 4367 gcc_jit_block_add_assignment (bfc->curblock, 4368 loc, 4369 bf_get_current_data (bfc, loc), 4370 gcc_jit_context_new_cast ( 4371 bfc->ctxt, 4372 loc, 4373 call, 4374 bfc->byte_type)); 4375 @} 4376 break; 4377 4378 case '[': 4379 @{ 4380 gcc_jit_block *loop_test = 4381 gcc_jit_function_new_block (bfc->func, NULL); 4382 gcc_jit_block *on_zero = 4383 gcc_jit_function_new_block (bfc->func, NULL); 4384 gcc_jit_block *on_non_zero = 4385 gcc_jit_function_new_block (bfc->func, NULL); 4386 4387 if (bfc->num_open_parens == MAX_OPEN_PARENS) 4388 fatal_error (bfc, "too many open parens"); 4389 4390 gcc_jit_block_end_with_jump ( 4391 bfc->curblock, 4392 loc, 4393 loop_test); 4394 4395 gcc_jit_block_add_comment ( 4396 loop_test, 4397 loc, 4398 "'['"); 4399 gcc_jit_block_end_with_conditional ( 4400 loop_test, 4401 loc, 4402 bf_current_data_is_zero (bfc, loc), 4403 on_zero, 4404 on_non_zero); 4405 bfc->paren_test[bfc->num_open_parens] = loop_test; 4406 bfc->paren_body[bfc->num_open_parens] = on_non_zero; 4407 bfc->paren_after[bfc->num_open_parens] = on_zero; 4408 bfc->num_open_parens += 1; 4409 bfc->curblock = on_non_zero; 4410 @} 4411 break; 4412 4413 case ']': 4414 @{ 4415 gcc_jit_block_add_comment ( 4416 bfc->curblock, 4417 loc, 4418 "']'"); 4419 4420 if (bfc->num_open_parens == 0) 4421 fatal_error (bfc, "mismatching parens"); 4422 bfc->num_open_parens -= 1; 4423 gcc_jit_block_end_with_jump ( 4424 bfc->curblock, 4425 loc, 4426 bfc->paren_test[bfc->num_open_parens]); 4427 bfc->curblock = bfc->paren_after[bfc->num_open_parens]; 4428 @} 4429 break; 4430 4431 case '\n': 4432 bfc->line +=1; 4433 bfc->column = 0; 4434 break; 4435 @} 4436 4437 if (ch != '\n') 4438 bfc->column += 1; 4439@} 4440 4441/* Compile the given .bf file into a gcc_jit_context, containing a 4442 single "main" function suitable for compiling into an executable. */ 4443 4444gcc_jit_context * 4445bf_compile (const char *filename) 4446@{ 4447 bf_compiler bfc; 4448 FILE *f_in; 4449 int ch; 4450 4451 memset (&bfc, 0, sizeof (bfc)); 4452 4453 bfc.filename = filename; 4454 f_in = fopen (filename, "r"); 4455 if (!f_in) 4456 fatal_error (&bfc, "unable to open file"); 4457 bfc.line = 1; 4458 4459 bfc.ctxt = gcc_jit_context_acquire (); 4460 4461 gcc_jit_context_set_int_option ( 4462 bfc.ctxt, 4463 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 4464 3); 4465 gcc_jit_context_set_bool_option ( 4466 bfc.ctxt, 4467 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 4468 0); 4469 gcc_jit_context_set_bool_option ( 4470 bfc.ctxt, 4471 GCC_JIT_BOOL_OPTION_DEBUGINFO, 4472 1); 4473 gcc_jit_context_set_bool_option ( 4474 bfc.ctxt, 4475 GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 4476 0); 4477 gcc_jit_context_set_bool_option ( 4478 bfc.ctxt, 4479 GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 4480 0); 4481 4482 bfc.void_type = 4483 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_VOID); 4484 bfc.int_type = 4485 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_INT); 4486 bfc.byte_type = 4487 gcc_jit_context_get_type (bfc.ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR); 4488 bfc.array_type = 4489 gcc_jit_context_new_array_type (bfc.ctxt, 4490 NULL, 4491 bfc.byte_type, 4492 30000); 4493 4494 bfc.func_getchar = 4495 gcc_jit_context_new_function (bfc.ctxt, NULL, 4496 GCC_JIT_FUNCTION_IMPORTED, 4497 bfc.int_type, 4498 "getchar", 4499 0, NULL, 4500 0); 4501 4502 gcc_jit_param *param_c = 4503 gcc_jit_context_new_param (bfc.ctxt, NULL, bfc.int_type, "c"); 4504 bfc.func_putchar = 4505 gcc_jit_context_new_function (bfc.ctxt, NULL, 4506 GCC_JIT_FUNCTION_IMPORTED, 4507 bfc.void_type, 4508 "putchar", 4509 1, ¶m_c, 4510 0); 4511 4512 bfc.func = make_main (bfc.ctxt); 4513 bfc.curblock = 4514 gcc_jit_function_new_block (bfc.func, "initial"); 4515 bfc.int_zero = gcc_jit_context_zero (bfc.ctxt, bfc.int_type); 4516 bfc.int_one = gcc_jit_context_one (bfc.ctxt, bfc.int_type); 4517 bfc.byte_zero = gcc_jit_context_zero (bfc.ctxt, bfc.byte_type); 4518 bfc.byte_one = gcc_jit_context_one (bfc.ctxt, bfc.byte_type); 4519 4520 bfc.data_cells = 4521 gcc_jit_context_new_global (bfc.ctxt, NULL, 4522 GCC_JIT_GLOBAL_INTERNAL, 4523 bfc.array_type, 4524 "data_cells"); 4525 bfc.idx = 4526 gcc_jit_function_new_local (bfc.func, NULL, 4527 bfc.int_type, 4528 "idx"); 4529 4530 gcc_jit_block_add_comment (bfc.curblock, 4531 NULL, 4532 "idx = 0;"); 4533 gcc_jit_block_add_assignment (bfc.curblock, 4534 NULL, 4535 bfc.idx, 4536 bfc.int_zero); 4537 4538 bfc.num_open_parens = 0; 4539 4540 while ( EOF != (ch = fgetc (f_in))) 4541 bf_compile_char (&bfc, (unsigned char)ch); 4542 4543 gcc_jit_block_end_with_return (bfc.curblock, NULL, bfc.int_zero); 4544 4545 fclose (f_in); 4546 4547 return bfc.ctxt; 4548@} 4549 4550 4551@end example 4552 4553@noindent 4554@end quotation 4555 4556@node Compiling a context to a file,Other forms of ahead-of-time-compilation,Converting a brainf script to libgccjit IR,Tutorial part 5 Implementing an Ahead-of-Time compiler 4557@anchor{intro/tutorial05 compiling-a-context-to-a-file}@anchor{4d} 4558@subsection Compiling a context to a file 4559 4560 4561Unlike the previous tutorial, this time we'll compile the context 4562directly to an executable, using @pxref{4a,,gcc_jit_context_compile_to_file()}: 4563 4564@example 4565gcc_jit_context_compile_to_file (ctxt, 4566 GCC_JIT_OUTPUT_KIND_EXECUTABLE, 4567 output_file); 4568@end example 4569 4570@noindent 4571 4572Here's the top-level of the compiler, which is what actually calls into 4573@pxref{4a,,gcc_jit_context_compile_to_file()}: 4574 4575@quotation 4576 4577@example 4578 4579int 4580main (int argc, char **argv) 4581@{ 4582 const char *input_file; 4583 const char *output_file; 4584 gcc_jit_context *ctxt; 4585 const char *err; 4586 4587 if (argc != 3) 4588 @{ 4589 fprintf (stderr, "%s: INPUT_FILE OUTPUT_FILE\n", argv[0]); 4590 return 1; 4591 @} 4592 4593 input_file = argv[1]; 4594 output_file = argv[2]; 4595 ctxt = bf_compile (input_file); 4596 4597 gcc_jit_context_compile_to_file (ctxt, 4598 GCC_JIT_OUTPUT_KIND_EXECUTABLE, 4599 output_file); 4600 4601 err = gcc_jit_context_get_first_error (ctxt); 4602 4603 if (err) 4604 @{ 4605 gcc_jit_context_release (ctxt); 4606 return 1; 4607 @} 4608 4609 gcc_jit_context_release (ctxt); 4610 return 0; 4611@} 4612 4613 4614@end example 4615 4616@noindent 4617@end quotation 4618 4619Note how once the context is populated you could trivially instead compile 4620it to memory using @pxref{15,,gcc_jit_context_compile()} and run it in-process 4621as in the previous tutorial. 4622 4623To create an executable, we need to export a @code{main} function. Here's 4624how to create one from the JIT API: 4625 4626@quotation 4627 4628@example 4629 4630/* Make "main" function: 4631 int 4632 main (int argc, char **argv) 4633 @{ 4634 ... 4635 @} 4636*/ 4637static gcc_jit_function * 4638make_main (gcc_jit_context *ctxt) 4639@{ 4640 gcc_jit_type *int_type = 4641 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 4642 gcc_jit_param *param_argc = 4643 gcc_jit_context_new_param (ctxt, NULL, int_type, "argc"); 4644 gcc_jit_type *char_ptr_ptr_type = 4645 gcc_jit_type_get_pointer ( 4646 gcc_jit_type_get_pointer ( 4647 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR))); 4648 gcc_jit_param *param_argv = 4649 gcc_jit_context_new_param (ctxt, NULL, char_ptr_ptr_type, "argv"); 4650 gcc_jit_param *params[2] = @{param_argc, param_argv@}; 4651 gcc_jit_function *func_main = 4652 gcc_jit_context_new_function (ctxt, NULL, 4653 GCC_JIT_FUNCTION_EXPORTED, 4654 int_type, 4655 "main", 4656 2, params, 4657 0); 4658 return func_main; 4659@} 4660 4661 4662@end example 4663 4664@noindent 4665@end quotation 4666 4667@cartouche 4668@quotation Note 4669The above implementation ignores @code{argc} and @code{argv}, but you could 4670make use of them by exposing @code{param_argc} and @code{param_argv} to the 4671caller. 4672@end quotation 4673@end cartouche 4674 4675Upon compiling this C code, we obtain a bf-to-machine-code compiler; 4676let's call it @code{bfc}: 4677 4678@example 4679$ gcc \ 4680 tut05-bf.c \ 4681 -o bfc \ 4682 -lgccjit 4683@end example 4684 4685@noindent 4686 4687We can now use @code{bfc} to compile .bf files into machine code executables: 4688 4689@example 4690$ ./bfc \ 4691 emit-alphabet.bf \ 4692 a.out 4693@end example 4694 4695@noindent 4696 4697which we can run directly: 4698 4699@example 4700$ ./a.out 4701ABCDEFGHIJKLMNOPQRSTUVWXYZ 4702@end example 4703 4704@noindent 4705 4706Success! 4707 4708We can also inspect the generated executable using standard tools: 4709 4710@example 4711$ objdump -d a.out |less 4712@end example 4713 4714@noindent 4715 4716which shows that libgccjit has managed to optimize the function 4717somewhat (for example, the runs of 26 and 65 increment operations 4718have become integer constants 0x1a and 0x41): 4719 4720@example 47210000000000400620 <main>: 4722 400620: 80 3d 39 0a 20 00 00 cmpb $0x0,0x200a39(%rip) # 601060 <data 4723 400627: 74 07 je 400630 <main 4724 400629: eb fe jmp 400629 <main+0x9> 4725 40062b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 4726 400630: 48 83 ec 08 sub $0x8,%rsp 4727 400634: 0f b6 05 26 0a 20 00 movzbl 0x200a26(%rip),%eax # 601061 <data_cells+0x1> 4728 40063b: c6 05 1e 0a 20 00 1a movb $0x1a,0x200a1e(%rip) # 601060 <data_cells> 4729 400642: 8d 78 41 lea 0x41(%rax),%edi 4730 400645: 40 88 3d 15 0a 20 00 mov %dil,0x200a15(%rip) # 601061 <data_cells+0x1> 4731 40064c: 0f 1f 40 00 nopl 0x0(%rax) 4732 400650: 40 0f b6 ff movzbl %dil,%edi 4733 400654: e8 87 fe ff ff callq 4004e0 <putchar@@plt> 4734 400659: 0f b6 05 01 0a 20 00 movzbl 0x200a01(%rip),%eax # 601061 <data_cells+0x1> 4735 400660: 80 2d f9 09 20 00 01 subb $0x1,0x2009f9(%rip) # 601060 <data_cells> 4736 400667: 8d 78 01 lea 0x1(%rax),%edi 4737 40066a: 40 88 3d f0 09 20 00 mov %dil,0x2009f0(%rip) # 601061 <data_cells+0x1> 4738 400671: 75 dd jne 400650 <main+0x30> 4739 400673: 31 c0 xor %eax,%eax 4740 400675: 48 83 c4 08 add $0x8,%rsp 4741 400679: c3 retq 4742 40067a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 4743@end example 4744 4745@noindent 4746 4747We also set up debugging information (via 4748@pxref{41,,gcc_jit_context_new_location()} and 4749@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO}), so it's possible to use @code{gdb} 4750to singlestep through the generated binary and inspect the internal 4751state @code{idx} and @code{data_cells}: 4752 4753@example 4754(gdb) break main 4755Breakpoint 1 at 0x400790 4756(gdb) run 4757Starting program: a.out 4758 4759Breakpoint 1, 0x0000000000400790 in main (argc=1, argv=0x7fffffffe448) 4760(gdb) stepi 47610x0000000000400797 in main (argc=1, argv=0x7fffffffe448) 4762(gdb) stepi 47630x00000000004007a0 in main (argc=1, argv=0x7fffffffe448) 4764(gdb) stepi 47659 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4766(gdb) list 47674 47685 cell 0 = 26 47696 ++++++++++++++++++++++++++ 47707 47718 cell 1 = 65 47729 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 477310 477411 while cell#0 != 0 477512 [ 477613 > 4777(gdb) n 47786 ++++++++++++++++++++++++++ 4779(gdb) n 47809 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 4781(gdb) p idx 4782$1 = 1 4783(gdb) p data_cells 4784$2 = "\032", '\000' <repeats 29998 times> 4785(gdb) p data_cells[0] 4786$3 = 26 '\032' 4787(gdb) p data_cells[1] 4788$4 = 0 '\000' 4789(gdb) list 47904 47915 cell 0 = 26 47926 ++++++++++++++++++++++++++ 47937 47948 cell 1 = 65 47959 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< 479610 479711 while cell#0 != 0 479812 [ 479913 > 4800@end example 4801 4802@noindent 4803 4804@node Other forms of ahead-of-time-compilation,,Compiling a context to a file,Tutorial part 5 Implementing an Ahead-of-Time compiler 4805@anchor{intro/tutorial05 other-forms-of-ahead-of-time-compilation}@anchor{4e} 4806@subsection Other forms of ahead-of-time-compilation 4807 4808 4809The above demonstrates compiling a @pxref{8,,gcc_jit_context *} directly 4810to an executable. It's also possible to compile it to an object file, 4811and to a dynamic library. See the documentation of 4812@pxref{4a,,gcc_jit_context_compile_to_file()} for more information. 4813 4814@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 4815@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 4816@c 4817@c This is free software: you can redistribute it and/or modify it 4818@c under the terms of the GNU General Public License as published by 4819@c the Free Software Foundation, either version 3 of the License, or 4820@c (at your option) any later version. 4821@c 4822@c This program is distributed in the hope that it will be useful, but 4823@c WITHOUT ANY WARRANTY; without even the implied warranty of 4824@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4825@c General Public License for more details. 4826@c 4827@c You should have received a copy of the GNU General Public License 4828@c along with this program. If not, see 4829@c <http://www.gnu.org/licenses/>. 4830 4831@node Topic Reference,C++ bindings for libgccjit,Tutorial,Top 4832@anchor{topics/index doc}@anchor{4f}@anchor{topics/index topic-reference}@anchor{50} 4833@chapter Topic Reference 4834 4835 4836@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 4837@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 4838@c 4839@c This is free software: you can redistribute it and/or modify it 4840@c under the terms of the GNU General Public License as published by 4841@c the Free Software Foundation, either version 3 of the License, or 4842@c (at your option) any later version. 4843@c 4844@c This program is distributed in the hope that it will be useful, but 4845@c WITHOUT ANY WARRANTY; without even the implied warranty of 4846@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 4847@c General Public License for more details. 4848@c 4849@c You should have received a copy of the GNU General Public License 4850@c along with this program. If not, see 4851@c <http://www.gnu.org/licenses/>. 4852 4853@menu 4854* Compilation contexts:: 4855* Objects:: 4856* Types:: 4857* Expressions:: 4858* Creating and using functions:: 4859* Source Locations:: 4860* Compiling a context:: 4861* ABI and API compatibility:: 4862* Performance:: 4863 4864Compilation contexts 4865 4866* Lifetime-management:: 4867* Thread-safety:: 4868* Error-handling: Error-handling<2>. 4869* Debugging:: 4870* Options: Options<2>. 4871 4872Options 4873 4874* String Options:: 4875* Boolean options:: 4876* Integer options:: 4877* Additional command-line options:: 4878 4879Types 4880 4881* Standard types:: 4882* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 4883* Structures and unions:: 4884 4885Expressions 4886 4887* Rvalues:: 4888* Lvalues:: 4889* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 4890 4891Rvalues 4892 4893* Simple expressions:: 4894* Unary Operations:: 4895* Binary Operations:: 4896* Comparisons:: 4897* Function calls:: 4898* Type-coercion:: 4899 4900Lvalues 4901 4902* Global variables:: 4903 4904Creating and using functions 4905 4906* Params:: 4907* Functions:: 4908* Blocks:: 4909* Statements:: 4910 4911Source Locations 4912 4913* Faking it:: 4914 4915Compiling a context 4916 4917* In-memory compilation:: 4918* Ahead-of-time compilation:: 4919 4920ABI and API compatibility 4921 4922* ABI symbol tags:: 4923 4924ABI symbol tags 4925 4926* LIBGCCJIT_ABI_0:: 4927* LIBGCCJIT_ABI_1:: 4928* LIBGCCJIT_ABI_2:: 4929* LIBGCCJIT_ABI_3:: 4930* LIBGCCJIT_ABI_4:: 4931* LIBGCCJIT_ABI_5:: 4932 4933Performance 4934 4935* The timing API:: 4936 4937@end menu 4938 4939 4940@node Compilation contexts,Objects,,Topic Reference 4941@anchor{topics/contexts compilation-contexts}@anchor{51}@anchor{topics/contexts doc}@anchor{52} 4942@section Compilation contexts 4943 4944 4945@geindex gcc_jit_context (C type) 4946@anchor{topics/contexts gcc_jit_context}@anchor{8} 4947@deffn {C Type} gcc_jit_context 4948@end deffn 4949 4950The top-level of the API is the @pxref{8,,gcc_jit_context} type. 4951 4952A @pxref{8,,gcc_jit_context} instance encapsulates the state of a 4953compilation. 4954 4955You can set up options on it, and add types, functions and code. 4956Invoking @pxref{15,,gcc_jit_context_compile()} on it gives you a 4957@pxref{16,,gcc_jit_result}. 4958 4959@menu 4960* Lifetime-management:: 4961* Thread-safety:: 4962* Error-handling: Error-handling<2>. 4963* Debugging:: 4964* Options: Options<2>. 4965 4966@end menu 4967 4968@node Lifetime-management,Thread-safety,,Compilation contexts 4969@anchor{topics/contexts lifetime-management}@anchor{53} 4970@subsection Lifetime-management 4971 4972 4973Contexts are the unit of lifetime-management within the API: objects 4974have their lifetime bounded by the context they are created within, and 4975cleanup of such objects is done for you when the context is released. 4976 4977@geindex gcc_jit_context_acquire (C function) 4978@anchor{topics/contexts gcc_jit_context_acquire}@anchor{9} 4979@deffn {C Function} gcc_jit_context *gcc_jit_context_acquire (void) 4980 4981This function acquires a new @pxref{8,,gcc_jit_context *} instance, 4982which is independent of any others that may be present within this 4983process. 4984@end deffn 4985 4986@geindex gcc_jit_context_release (C function) 4987@anchor{topics/contexts gcc_jit_context_release}@anchor{c} 4988@deffn {C Function} void gcc_jit_context_release (gcc_jit_context@w{ }*ctxt) 4989 4990This function releases all resources associated with the given context. 4991Both the context itself and all of its @pxref{e,,gcc_jit_object *} 4992instances are cleaned up. It should be called exactly once on a given 4993context. 4994 4995It is invalid to use the context or any of its "contextual" objects 4996after calling this. 4997 4998@example 4999gcc_jit_context_release (ctxt); 5000@end example 5001 5002@noindent 5003@end deffn 5004 5005@geindex gcc_jit_context_new_child_context (C function) 5006@anchor{topics/contexts gcc_jit_context_new_child_context}@anchor{54} 5007@deffn {C Function} gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context@w{ }*parent_ctxt) 5008 5009Given an existing JIT context, create a child context. 5010 5011The child inherits a copy of all option-settings from the parent. 5012 5013The child can reference objects created within the parent, but not 5014vice-versa. 5015 5016The lifetime of the child context must be bounded by that of the 5017parent: you should release a child context before releasing the parent 5018context. 5019 5020If you use a function from a parent context within a child context, 5021you have to compile the parent context before you can compile the 5022child context, and the gcc_jit_result of the parent context must 5023outlive the gcc_jit_result of the child context. 5024 5025This allows caching of shared initializations. For example, you could 5026create types and declarations of global functions in a parent context 5027once within a process, and then create child contexts whenever a 5028function or loop becomes hot. Each such child context can be used for 5029JIT-compiling just one function or loop, but can reference types 5030and helper functions created within the parent context. 5031 5032Contexts can be arbitrarily nested, provided the above rules are 5033followed, but it's probably not worth going above 2 or 3 levels, and 5034there will likely be a performance hit for such nesting. 5035@end deffn 5036 5037@node Thread-safety,Error-handling<2>,Lifetime-management,Compilation contexts 5038@anchor{topics/contexts thread-safety}@anchor{55} 5039@subsection Thread-safety 5040 5041 5042Instances of @pxref{8,,gcc_jit_context *} created via 5043@pxref{9,,gcc_jit_context_acquire()} are independent from each other: 5044only one thread may use a given context at once, but multiple threads 5045could each have their own contexts without needing locks. 5046 5047Contexts created via @pxref{54,,gcc_jit_context_new_child_context()} are 5048related to their parent context. They can be partitioned by their 5049ultimate ancestor into independent "family trees". Only one thread 5050within a process may use a given "family tree" of such contexts at once, 5051and if you're using multiple threads you should provide your own locking 5052around entire such context partitions. 5053 5054@node Error-handling<2>,Debugging,Thread-safety,Compilation contexts 5055@anchor{topics/contexts error-handling}@anchor{19}@anchor{topics/contexts id1}@anchor{56} 5056@subsection Error-handling 5057 5058 5059Various kinds of errors are possible when using the API, such as 5060mismatched types in an assignment. You can only compile and get code from 5061a context if no errors occur. 5062 5063Errors are printed on stderr and can be queried using 5064@pxref{57,,gcc_jit_context_get_first_error()}. 5065 5066They typically contain the name of the API entrypoint where the error 5067occurred, and pertinent information on the problem: 5068 5069@example 5070./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *) 5071@end example 5072 5073@noindent 5074 5075In general, if an error occurs when using an API entrypoint, the 5076entrypoint returns NULL. You don't have to check everywhere for NULL 5077results, since the API handles a NULL being passed in for any 5078argument by issuing another error. This typically leads to a cascade of 5079followup error messages, but is safe (albeit verbose). The first error 5080message is usually the one to pay attention to, since it is likely to 5081be responsible for all of the rest: 5082 5083@geindex gcc_jit_context_get_first_error (C function) 5084@anchor{topics/contexts gcc_jit_context_get_first_error}@anchor{57} 5085@deffn {C Function} const char * gcc_jit_context_get_first_error (gcc_jit_context@w{ }*ctxt) 5086 5087Returns the first error message that occurred on the context. 5088 5089The returned string is valid for the rest of the lifetime of the 5090context. 5091 5092If no errors occurred, this will be NULL. 5093@end deffn 5094 5095If you are wrapping the C API for a higher-level language that supports 5096exception-handling, you may instead be interested in the last error that 5097occurred on the context, so that you can embed this in an exception: 5098 5099@geindex gcc_jit_context_get_last_error (C function) 5100@anchor{topics/contexts gcc_jit_context_get_last_error}@anchor{58} 5101@deffn {C Function} const char * gcc_jit_context_get_last_error (gcc_jit_context@w{ }*ctxt) 5102 5103Returns the last error message that occurred on the context. 5104 5105If no errors occurred, this will be NULL. 5106 5107If non-NULL, the returned string is only guaranteed to be valid until 5108the next call to libgccjit relating to this context. 5109@end deffn 5110 5111@node Debugging,Options<2>,Error-handling<2>,Compilation contexts 5112@anchor{topics/contexts debugging}@anchor{59} 5113@subsection Debugging 5114 5115 5116@geindex gcc_jit_context_dump_to_file (C function) 5117@anchor{topics/contexts gcc_jit_context_dump_to_file}@anchor{5a} 5118@deffn {C Function} void gcc_jit_context_dump_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path, int@w{ }update_locations) 5119 5120To help with debugging: dump a C-like representation to the given path, 5121describing what's been set up on the context. 5122 5123If "update_locations" is true, then also set up @pxref{3b,,gcc_jit_location} 5124information throughout the context, pointing at the dump file as if it 5125were a source file. This may be of use in conjunction with 5126@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to allow stepping through the 5127code in a debugger. 5128@end deffn 5129 5130@geindex gcc_jit_context_set_logfile (C function) 5131@anchor{topics/contexts gcc_jit_context_set_logfile}@anchor{5b} 5132@deffn {C Function} void gcc_jit_context_set_logfile (gcc_jit_context@w{ }*ctxt, FILE@w{ }*logfile, int@w{ }flags, int@w{ }verbosity) 5133 5134To help with debugging; enable ongoing logging of the context's 5135activity to the given file. 5136 5137For example, the following will enable logging to stderr. 5138 5139@example 5140gcc_jit_context_set_logfile (ctxt, stderr, 0, 0); 5141@end example 5142 5143@noindent 5144 5145Examples of information logged include: 5146 5147 5148@itemize * 5149 5150@item 5151API calls 5152 5153@item 5154the various steps involved within compilation 5155 5156@item 5157activity on any @pxref{16,,gcc_jit_result} instances created by 5158the context 5159 5160@item 5161activity within any child contexts 5162@end itemize 5163 5164An example of a log can be seen @pxref{5c,,here}, 5165though the precise format and kinds of information logged is subject 5166to change. 5167 5168The caller remains responsible for closing @cite{logfile}, and it must not 5169be closed until all users are released. In particular, note that 5170child contexts and @pxref{16,,gcc_jit_result} instances created by 5171the context will use the logfile. 5172 5173There may a performance cost for logging. 5174 5175You can turn off logging on @cite{ctxt} by passing @cite{NULL} for @cite{logfile}. 5176Doing so only affects the context; it does not affect child contexts 5177or @pxref{16,,gcc_jit_result} instances already created by 5178the context. 5179 5180The parameters "flags" and "verbosity" are reserved for future 5181expansion, and must be zero for now. 5182@end deffn 5183 5184To contrast the above: @pxref{5a,,gcc_jit_context_dump_to_file()} dumps the 5185current state of a context to the given path, whereas 5186@pxref{5b,,gcc_jit_context_set_logfile()} enables on-going logging of 5187future activies on a context to the given @cite{FILE *}. 5188 5189@geindex gcc_jit_context_dump_reproducer_to_file (C function) 5190@anchor{topics/contexts gcc_jit_context_dump_reproducer_to_file}@anchor{5d} 5191@deffn {C Function} void gcc_jit_context_dump_reproducer_to_file (gcc_jit_context@w{ }*ctxt, const char@w{ }*path) 5192 5193Write C source code into @cite{path} that can be compiled into a 5194self-contained executable (i.e. with libgccjit as the only dependency). 5195The generated code will attempt to replay the API calls that have been 5196made into the given context. 5197 5198This may be useful when debugging the library or client code, for 5199reducing a complicated recipe for reproducing a bug into a simpler 5200form. For example, consider client code that parses some source file 5201into some internal representation, and then walks this IR, calling into 5202libgccjit. If this encounters a bug, a call to 5203@cite{gcc_jit_context_dump_reproducer_to_file} will write out C code for 5204a much simpler executable that performs the equivalent calls into 5205libgccjit, without needing the client code and its data. 5206 5207Typically you need to supply @code{-Wno-unused-variable} when 5208compiling the generated file (since the result of each API call is 5209assigned to a unique variable within the generated C source, and not 5210all are necessarily then used). 5211@end deffn 5212 5213@geindex gcc_jit_context_enable_dump (C function) 5214@anchor{topics/contexts gcc_jit_context_enable_dump}@anchor{5e} 5215@deffn {C Function} void gcc_jit_context_enable_dump (gcc_jit_context@w{ }*ctxt, const char@w{ }*dumpname, char@w{ }**out_ptr) 5216 5217Enable the dumping of a specific set of internal state from the 5218compilation, capturing the result in-memory as a buffer. 5219 5220Parameter "dumpname" corresponds to the equivalent gcc command-line 5221option, without the "-fdump-" prefix. 5222For example, to get the equivalent of @code{-fdump-tree-vrp1}, 5223supply @code{"tree-vrp1"}: 5224 5225@example 5226static char *dump_vrp1; 5227 5228void 5229create_code (gcc_jit_context *ctxt) 5230@{ 5231 gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1); 5232 /* (other API calls omitted for brevity) */ 5233@} 5234@end example 5235 5236@noindent 5237 5238The context directly stores the dumpname as a @code{(const char *)}, so 5239the passed string must outlive the context. 5240 5241@pxref{15,,gcc_jit_context_compile()} will capture the dump as a 5242dynamically-allocated buffer, writing it to @code{*out_ptr}. 5243 5244The caller becomes responsible for calling: 5245 5246@example 5247free (*out_ptr) 5248@end example 5249 5250@noindent 5251 5252each time that @pxref{15,,gcc_jit_context_compile()} is called. 5253@code{*out_ptr} will be written to, either with the address of a buffer, 5254or with @code{NULL} if an error occurred. 5255 5256@cartouche 5257@quotation Warning 5258This API entrypoint is likely to be less stable than the others. 5259In particular, both the precise dumpnames, and the format and content 5260of the dumps are subject to change. 5261 5262It exists primarily for writing the library's own test suite. 5263@end quotation 5264@end cartouche 5265@end deffn 5266 5267@node Options<2>,,Debugging,Compilation contexts 5268@anchor{topics/contexts options}@anchor{5f} 5269@subsection Options 5270 5271 5272Options present in the initial release of libgccjit were handled using 5273enums, whereas those added subsequently have their own per-option API 5274entrypoints. 5275 5276Adding entrypoints for each new option means that client code that use 5277the new options can be identified directly from binary metadata, which 5278would not be possible if we instead extended the various 5279@code{enum gcc_jit_*_option}. 5280 5281@menu 5282* String Options:: 5283* Boolean options:: 5284* Integer options:: 5285* Additional command-line options:: 5286 5287@end menu 5288 5289@node String Options,Boolean options,,Options<2> 5290@anchor{topics/contexts string-options}@anchor{60} 5291@subsubsection String Options 5292 5293 5294@geindex gcc_jit_context_set_str_option (C function) 5295@anchor{topics/contexts gcc_jit_context_set_str_option}@anchor{61} 5296@deffn {C Function} void gcc_jit_context_set_str_option (gcc_jit_context@w{ }*ctxt, enum gcc_jit_str_option@w{ }opt, const char@w{ }*value) 5297 5298Set a string option of the context. 5299 5300@geindex gcc_jit_str_option (C type) 5301@anchor{topics/contexts gcc_jit_str_option}@anchor{62} 5302@deffn {C Type} enum gcc_jit_str_option 5303@end deffn 5304 5305The parameter @code{value} can be NULL. If non-NULL, the call takes a 5306copy of the underlying string, so it is valid to pass in a pointer to 5307an on-stack buffer. 5308 5309There is just one string option specified this way: 5310 5311@geindex GCC_JIT_STR_OPTION_PROGNAME (C macro) 5312@anchor{topics/contexts GCC_JIT_STR_OPTION_PROGNAME}@anchor{63} 5313@deffn {C Macro} GCC_JIT_STR_OPTION_PROGNAME 5314 5315The name of the program, for use as a prefix when printing error 5316messages to stderr. If @cite{NULL}, or default, "libgccjit.so" is used. 5317@end deffn 5318@end deffn 5319 5320@node Boolean options,Integer options,String Options,Options<2> 5321@anchor{topics/contexts boolean-options}@anchor{64} 5322@subsubsection Boolean options 5323 5324 5325@geindex gcc_jit_context_set_bool_option (C function) 5326@anchor{topics/contexts gcc_jit_context_set_bool_option}@anchor{1b} 5327@deffn {C Function} void gcc_jit_context_set_bool_option (gcc_jit_context@w{ }*ctxt, enum gcc_jit_bool_option@w{ }opt, int@w{ }value) 5328 5329Set a boolean option of the context. 5330Zero is "false" (the default), non-zero is "true". 5331 5332@geindex gcc_jit_bool_option (C type) 5333@anchor{topics/contexts gcc_jit_bool_option}@anchor{65} 5334@deffn {C Type} enum gcc_jit_bool_option 5335@end deffn 5336 5337@geindex GCC_JIT_BOOL_OPTION_DEBUGINFO (C macro) 5338@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DEBUGINFO}@anchor{42} 5339@deffn {C Macro} GCC_JIT_BOOL_OPTION_DEBUGINFO 5340 5341If true, @pxref{15,,gcc_jit_context_compile()} will attempt to do the right 5342thing so that if you attach a debugger to the process, it will 5343be able to inspect variables and step through your code. 5344 5345Note that you can't step through code unless you set up source 5346location information for the code (by creating and passing in 5347@pxref{3b,,gcc_jit_location} instances). 5348@end deffn 5349 5350@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE (C macro) 5351@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE}@anchor{66} 5352@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE 5353 5354If true, @pxref{15,,gcc_jit_context_compile()} will dump its initial 5355"tree" representation of your code to stderr (before any 5356optimizations). 5357 5358Here's some sample output (from the @cite{square} example): 5359 5360@example 5361<statement_list 0x7f4875a62cc0 5362 type <void_type 0x7f4875a64bd0 VOID 5363 align 8 symtab 0 alias set -1 canonical type 0x7f4875a64bd0 5364 pointer_to_this <pointer_type 0x7f4875a64c78>> 5365 side-effects head 0x7f4875a761e0 tail 0x7f4875a761f8 stmts 0x7f4875a62d20 0x7f4875a62d00 5366 5367 stmt <label_expr 0x7f4875a62d20 type <void_type 0x7f4875a64bd0> 5368 side-effects 5369 arg 0 <label_decl 0x7f4875a79080 entry type <void_type 0x7f4875a64bd0> 5370 VOID file (null) line 0 col 0 5371 align 1 context <function_decl 0x7f4875a77500 square>>> 5372 stmt <return_expr 0x7f4875a62d00 5373 type <integer_type 0x7f4875a645e8 public SI 5374 size <integer_cst 0x7f4875a623a0 constant 32> 5375 unit size <integer_cst 0x7f4875a623c0 constant 4> 5376 align 32 symtab 0 alias set -1 canonical type 0x7f4875a645e8 precision 32 min <integer_cst 0x7f4875a62340 -2147483648> max <integer_cst 0x7f4875a62360 2147483647> 5377 pointer_to_this <pointer_type 0x7f4875a6b348>> 5378 side-effects 5379 arg 0 <modify_expr 0x7f4875a72a78 type <integer_type 0x7f4875a645e8> 5380 side-effects arg 0 <result_decl 0x7f4875a7a000 D.54> 5381 arg 1 <mult_expr 0x7f4875a72a50 type <integer_type 0x7f4875a645e8> 5382 arg 0 <parm_decl 0x7f4875a79000 i> arg 1 <parm_decl 0x7f4875a79000 i>>>>> 5383@end example 5384 5385@noindent 5386@end deffn 5387 5388@geindex GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE (C macro) 5389@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}@anchor{1c} 5390@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE 5391 5392If true, @pxref{15,,gcc_jit_context_compile()} will dump the "gimple" 5393representation of your code to stderr, before any optimizations 5394are performed. The dump resembles C code: 5395 5396@example 5397square (signed int i) 5398@{ 5399 signed int D.56; 5400 5401 entry: 5402 D.56 = i * i; 5403 return D.56; 5404@} 5405@end example 5406 5407@noindent 5408@end deffn 5409 5410@geindex GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE (C macro) 5411@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE}@anchor{1d} 5412@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE 5413 5414If true, @pxref{15,,gcc_jit_context_compile()} will dump the final 5415generated code to stderr, in the form of assembly language: 5416 5417@example 5418 .file "fake.c" 5419 .text 5420 .globl square 5421 .type square, @@function 5422square: 5423.LFB0: 5424 .cfi_startproc 5425 pushq %rbp 5426 .cfi_def_cfa_offset 16 5427 .cfi_offset 6, -16 5428 movq %rsp, %rbp 5429 .cfi_def_cfa_register 6 5430 movl %edi, -4(%rbp) 5431.L2: 5432 movl -4(%rbp), %eax 5433 imull -4(%rbp), %eax 5434 popq %rbp 5435 .cfi_def_cfa 7, 8 5436 ret 5437 .cfi_endproc 5438.LFE0: 5439 .size square, .-square 5440 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.1-%@{gcc_release@})" 5441 .section .note.GNU-stack,"",@@progbits 5442@end example 5443 5444@noindent 5445@end deffn 5446 5447@geindex GCC_JIT_BOOL_OPTION_DUMP_SUMMARY (C macro) 5448@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_SUMMARY}@anchor{67} 5449@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_SUMMARY 5450 5451If true, @pxref{15,,gcc_jit_context_compile()} will print information to stderr 5452on the actions it is performing. 5453@end deffn 5454 5455@geindex GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING (C macro) 5456@anchor{topics/contexts GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING}@anchor{68} 5457@deffn {C Macro} GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING 5458 5459If true, @pxref{15,,gcc_jit_context_compile()} will dump copious 5460amount of information on what it's doing to various 5461files within a temporary directory. Use 5462@pxref{69,,GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES} (see below) to 5463see the results. The files are intended to be human-readable, 5464but the exact files and their formats are subject to change. 5465@end deffn 5466 5467@geindex GCC_JIT_BOOL_OPTION_SELFCHECK_GC (C macro) 5468@anchor{topics/contexts GCC_JIT_BOOL_OPTION_SELFCHECK_GC}@anchor{6a} 5469@deffn {C Macro} GCC_JIT_BOOL_OPTION_SELFCHECK_GC 5470 5471If true, libgccjit will aggressively run its garbage collector, to 5472shake out bugs (greatly slowing down the compile). This is likely 5473to only be of interest to developers @emph{of} the library. It is 5474used when running the selftest suite. 5475@end deffn 5476 5477@geindex GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES (C macro) 5478@anchor{topics/contexts GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES}@anchor{69} 5479@deffn {C Macro} GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES 5480 5481If true, the @pxref{8,,gcc_jit_context} will not clean up intermediate files 5482written to the filesystem, and will display their location on stderr. 5483@end deffn 5484@end deffn 5485 5486@geindex gcc_jit_context_set_bool_allow_unreachable_blocks (C function) 5487@anchor{topics/contexts gcc_jit_context_set_bool_allow_unreachable_blocks}@anchor{6b} 5488@deffn {C Function} void gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value) 5489 5490By default, libgccjit will issue an error about unreachable blocks 5491within a function. 5492 5493This entrypoint can be used to disable that error. 5494 5495This entrypoint was added in @pxref{6c,,LIBGCCJIT_ABI_2}; you can test for 5496its presence using 5497 5498@example 5499#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 5500@end example 5501 5502@noindent 5503@end deffn 5504 5505@geindex gcc_jit_context_set_bool_use_external_driver (C function) 5506@anchor{topics/contexts gcc_jit_context_set_bool_use_external_driver}@anchor{6d} 5507@deffn {C Function} void gcc_jit_context_set_bool_use_external_driver (gcc_jit_context@w{ }*ctxt, int@w{ }bool_value) 5508 5509libgccjit internally generates assembler, and uses "driver" code 5510for converting it to other formats (e.g. shared libraries). 5511 5512By default, libgccjit will use an embedded copy of the driver 5513code. 5514 5515This option can be used to instead invoke an external driver executable 5516as a subprocess. 5517 5518This entrypoint was added in @pxref{6e,,LIBGCCJIT_ABI_5}; you can test for 5519its presence using 5520 5521@example 5522#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver 5523@end example 5524 5525@noindent 5526@end deffn 5527 5528@node Integer options,Additional command-line options,Boolean options,Options<2> 5529@anchor{topics/contexts integer-options}@anchor{6f} 5530@subsubsection Integer options 5531 5532 5533@geindex gcc_jit_context_set_int_option (C function) 5534@anchor{topics/contexts gcc_jit_context_set_int_option}@anchor{1e} 5535@deffn {C Function} void gcc_jit_context_set_int_option (gcc_jit_context@w{ }*ctxt, enum gcc_jit_int_option@w{ }opt, int@w{ }value) 5536 5537Set an integer option of the context. 5538 5539@geindex gcc_jit_int_option (C type) 5540@anchor{topics/contexts gcc_jit_int_option}@anchor{70} 5541@deffn {C Type} enum gcc_jit_int_option 5542@end deffn 5543 5544There is just one integer option specified this way: 5545 5546@geindex GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL (C macro) 5547@anchor{topics/contexts GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}@anchor{1f} 5548@deffn {C Macro} GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL 5549 5550How much to optimize the code. 5551 5552Valid values are 0-3, corresponding to GCC's command-line options 5553-O0 through -O3. 5554 5555The default value is 0 (unoptimized). 5556@end deffn 5557@end deffn 5558 5559@node Additional command-line options,,Integer options,Options<2> 5560@anchor{topics/contexts additional-command-line-options}@anchor{71} 5561@subsubsection Additional command-line options 5562 5563 5564@geindex gcc_jit_context_add_command_line_option (C function) 5565@anchor{topics/contexts gcc_jit_context_add_command_line_option}@anchor{72} 5566@deffn {C Function} void gcc_jit_context_add_command_line_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname) 5567 5568Add an arbitrary gcc command-line option to the context, for use 5569by @pxref{15,,gcc_jit_context_compile()} and 5570@pxref{4a,,gcc_jit_context_compile_to_file()}. 5571 5572The parameter @code{optname} must be non-NULL. The underlying buffer is 5573copied, so that it does not need to outlive the call. 5574 5575Extra options added by @cite{gcc_jit_context_add_command_line_option} are 5576applied @emph{after} the regular options above, potentially overriding them. 5577Options from parent contexts are inherited by child contexts; options 5578from the parent are applied @emph{before} those from the child. 5579 5580For example: 5581 5582@example 5583gcc_jit_context_add_command_line_option (ctxt, "-ffast-math"); 5584gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm"); 5585@end example 5586 5587@noindent 5588 5589Note that only some options are likely to be meaningful; there is no 5590"frontend" within libgccjit, so typically only those affecting 5591optimization and code-generation are likely to be useful. 5592 5593This entrypoint was added in @pxref{73,,LIBGCCJIT_ABI_1}; you can test for 5594its presence using 5595 5596@example 5597#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 5598@end example 5599 5600@noindent 5601@end deffn 5602 5603@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 5604@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 5605@c 5606@c This is free software: you can redistribute it and/or modify it 5607@c under the terms of the GNU General Public License as published by 5608@c the Free Software Foundation, either version 3 of the License, or 5609@c (at your option) any later version. 5610@c 5611@c This program is distributed in the hope that it will be useful, but 5612@c WITHOUT ANY WARRANTY; without even the implied warranty of 5613@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5614@c General Public License for more details. 5615@c 5616@c You should have received a copy of the GNU General Public License 5617@c along with this program. If not, see 5618@c <http://www.gnu.org/licenses/>. 5619 5620@node Objects,Types,Compilation contexts,Topic Reference 5621@anchor{topics/objects objects}@anchor{74}@anchor{topics/objects doc}@anchor{75} 5622@section Objects 5623 5624 5625@geindex gcc_jit_object (C type) 5626@anchor{topics/objects gcc_jit_object}@anchor{e} 5627@deffn {C Type} gcc_jit_object 5628@end deffn 5629 5630Almost every entity in the API (with the exception of 5631@pxref{8,,gcc_jit_context *} and @pxref{16,,gcc_jit_result *}) is a 5632"contextual" object, a @pxref{e,,gcc_jit_object *} 5633 5634A JIT object: 5635 5636@quotation 5637 5638 5639@itemize * 5640 5641@item 5642is associated with a @pxref{8,,gcc_jit_context *}. 5643 5644@item 5645is automatically cleaned up for you when its context is released so 5646you don't need to manually track and cleanup all objects, just the 5647contexts. 5648@end itemize 5649@end quotation 5650 5651Although the API is C-based, there is a form of class hierarchy, which 5652looks like this: 5653 5654@example 5655+- gcc_jit_object 5656 +- gcc_jit_location 5657 +- gcc_jit_type 5658 +- gcc_jit_struct 5659 +- gcc_jit_field 5660 +- gcc_jit_function 5661 +- gcc_jit_block 5662 +- gcc_jit_rvalue 5663 +- gcc_jit_lvalue 5664 +- gcc_jit_param 5665 +- gcc_jit_case 5666@end example 5667 5668@noindent 5669 5670There are casting methods for upcasting from subclasses to parent classes. 5671For example, @pxref{d,,gcc_jit_type_as_object()}: 5672 5673@example 5674gcc_jit_object *obj = gcc_jit_type_as_object (int_type); 5675@end example 5676 5677@noindent 5678 5679The object "base class" has the following operations: 5680 5681@geindex gcc_jit_object_get_context (C function) 5682@anchor{topics/objects gcc_jit_object_get_context}@anchor{76} 5683@deffn {C Function} gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object@w{ }*obj) 5684 5685Which context is "obj" within? 5686@end deffn 5687 5688@geindex gcc_jit_object_get_debug_string (C function) 5689@anchor{topics/objects gcc_jit_object_get_debug_string}@anchor{f} 5690@deffn {C Function} const char *gcc_jit_object_get_debug_string (gcc_jit_object@w{ }*obj) 5691 5692Generate a human-readable description for the given object. 5693 5694For example, 5695 5696@example 5697printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj)); 5698@end example 5699 5700@noindent 5701 5702might give this text on stdout: 5703 5704@example 5705obj: 4.0 * (float)i 5706@end example 5707 5708@noindent 5709 5710@cartouche 5711@quotation Note 5712If you call this on an object, the @cite{const char *} buffer is allocated 5713and generated on the first call for that object, and the buffer will 5714have the same lifetime as the object i.e. it will exist until the 5715object's context is released. 5716@end quotation 5717@end cartouche 5718@end deffn 5719 5720@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 5721@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 5722@c 5723@c This is free software: you can redistribute it and/or modify it 5724@c under the terms of the GNU General Public License as published by 5725@c the Free Software Foundation, either version 3 of the License, or 5726@c (at your option) any later version. 5727@c 5728@c This program is distributed in the hope that it will be useful, but 5729@c WITHOUT ANY WARRANTY; without even the implied warranty of 5730@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5731@c General Public License for more details. 5732@c 5733@c You should have received a copy of the GNU General Public License 5734@c along with this program. If not, see 5735@c <http://www.gnu.org/licenses/>. 5736 5737@node Types,Expressions,Objects,Topic Reference 5738@anchor{topics/types doc}@anchor{77}@anchor{topics/types types}@anchor{78} 5739@section Types 5740 5741 5742@geindex gcc_jit_type (C type) 5743@anchor{topics/types gcc_jit_type}@anchor{a} 5744@deffn {C Type} gcc_jit_type 5745 5746gcc_jit_type represents a type within the library. 5747@end deffn 5748 5749@geindex gcc_jit_type_as_object (C function) 5750@anchor{topics/types gcc_jit_type_as_object}@anchor{d} 5751@deffn {C Function} gcc_jit_object *gcc_jit_type_as_object (gcc_jit_type@w{ }*type) 5752 5753Upcast a type to an object. 5754@end deffn 5755 5756Types can be created in several ways: 5757 5758 5759@itemize * 5760 5761@item 5762fundamental types can be accessed using 5763@pxref{b,,gcc_jit_context_get_type()}: 5764 5765@example 5766gcc_jit_type *int_type = gcc_jit_context_get_type (GCC_JIT_TYPE_INT); 5767@end example 5768 5769@noindent 5770 5771See @pxref{b,,gcc_jit_context_get_type()} for the available types. 5772 5773@item 5774derived types can be accessed by using functions such as 5775@pxref{79,,gcc_jit_type_get_pointer()} and @pxref{7a,,gcc_jit_type_get_const()}: 5776 5777@example 5778gcc_jit_type *const_int_star = gcc_jit_type_get_pointer (gcc_jit_type_get_const (int_type)); 5779gcc_jit_type *int_const_star = gcc_jit_type_get_const (gcc_jit_type_get_pointer (int_type)); 5780@end example 5781 5782@noindent 5783 5784@item 5785by creating structures (see below). 5786@end itemize 5787 5788@menu 5789* Standard types:: 5790* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile. 5791* Structures and unions:: 5792 5793@end menu 5794 5795@node Standard types,Pointers const and volatile,,Types 5796@anchor{topics/types standard-types}@anchor{7b} 5797@subsection Standard types 5798 5799 5800@geindex gcc_jit_context_get_type (C function) 5801@anchor{topics/types gcc_jit_context_get_type}@anchor{b} 5802@deffn {C Function} gcc_jit_type *gcc_jit_context_get_type (gcc_jit_context@w{ }*ctxt, enum gcc_jit_types@w{ }type_) 5803 5804Access a specific type. The available types are: 5805 5806 5807@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} 5808@headitem 5809 5810@cite{enum gcc_jit_types} value 5811 5812@tab 5813 5814Meaning 5815 5816@item 5817 5818@code{GCC_JIT_TYPE_VOID} 5819 5820@tab 5821 5822C's @code{void} type. 5823 5824@item 5825 5826@code{GCC_JIT_TYPE_VOID_PTR} 5827 5828@tab 5829 5830C's @code{void *}. 5831 5832@item 5833 5834@code{GCC_JIT_TYPE_BOOL} 5835 5836@tab 5837 5838C++'s @code{bool} type; also C99's 5839@code{_Bool} type, aka @code{bool} if 5840using stdbool.h. 5841 5842@item 5843 5844@code{GCC_JIT_TYPE_CHAR} 5845 5846@tab 5847 5848C's @code{char} (of some signedness) 5849 5850@item 5851 5852@code{GCC_JIT_TYPE_SIGNED_CHAR} 5853 5854@tab 5855 5856C's @code{signed char} 5857 5858@item 5859 5860@code{GCC_JIT_TYPE_UNSIGNED_CHAR} 5861 5862@tab 5863 5864C's @code{unsigned char} 5865 5866@item 5867 5868@code{GCC_JIT_TYPE_SHORT} 5869 5870@tab 5871 5872C's @code{short} (signed) 5873 5874@item 5875 5876@code{GCC_JIT_TYPE_UNSIGNED_SHORT} 5877 5878@tab 5879 5880C's @code{unsigned short} 5881 5882@item 5883 5884@code{GCC_JIT_TYPE_INT} 5885 5886@tab 5887 5888C's @code{int} (signed) 5889 5890@item 5891 5892@code{GCC_JIT_TYPE_UNSIGNED_INT} 5893 5894@tab 5895 5896C's @code{unsigned int} 5897 5898@item 5899 5900@code{GCC_JIT_TYPE_LONG} 5901 5902@tab 5903 5904C's @code{long} (signed) 5905 5906@item 5907 5908@code{GCC_JIT_TYPE_UNSIGNED_LONG} 5909 5910@tab 5911 5912C's @code{unsigned long} 5913 5914@item 5915 5916@code{GCC_JIT_TYPE_LONG_LONG} 5917 5918@tab 5919 5920C99's @code{long long} (signed) 5921 5922@item 5923 5924@code{GCC_JIT_TYPE_UNSIGNED_LONG_LONG} 5925 5926@tab 5927 5928C99's @code{unsigned long long} 5929 5930@item 5931 5932@code{GCC_JIT_TYPE_FLOAT} 5933 5934@tab 5935 5936@item 5937 5938@code{GCC_JIT_TYPE_DOUBLE} 5939 5940@tab 5941 5942@item 5943 5944@code{GCC_JIT_TYPE_LONG_DOUBLE} 5945 5946@tab 5947 5948@item 5949 5950@code{GCC_JIT_TYPE_CONST_CHAR_PTR} 5951 5952@tab 5953 5954C type: @code{(const char *)} 5955 5956@item 5957 5958@code{GCC_JIT_TYPE_SIZE_T} 5959 5960@tab 5961 5962C's @code{size_t} type 5963 5964@item 5965 5966@code{GCC_JIT_TYPE_FILE_PTR} 5967 5968@tab 5969 5970C type: @code{(FILE *)} 5971 5972@item 5973 5974@code{GCC_JIT_TYPE_COMPLEX_FLOAT} 5975 5976@tab 5977 5978C99's @code{_Complex float} 5979 5980@item 5981 5982@code{GCC_JIT_TYPE_COMPLEX_DOUBLE} 5983 5984@tab 5985 5986C99's @code{_Complex double} 5987 5988@item 5989 5990@code{GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE} 5991 5992@tab 5993 5994C99's @code{_Complex long double} 5995 5996@end multitable 5997 5998@end deffn 5999 6000@geindex gcc_jit_context_get_int_type (C function) 6001@anchor{topics/types gcc_jit_context_get_int_type}@anchor{7c} 6002@deffn {C Function} gcc_jit_type * gcc_jit_context_get_int_type (gcc_jit_context@w{ }*ctxt, int@w{ }num_bytes, int@w{ }is_signed) 6003 6004Access the integer type of the given size. 6005@end deffn 6006 6007@node Pointers const and volatile,Structures and unions,Standard types,Types 6008@anchor{topics/types pointers-const-and-volatile}@anchor{7d} 6009@subsection Pointers, @cite{const}, and @cite{volatile} 6010 6011 6012@geindex gcc_jit_type_get_pointer (C function) 6013@anchor{topics/types gcc_jit_type_get_pointer}@anchor{79} 6014@deffn {C Function} gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type@w{ }*type) 6015 6016Given type "T", get type "T*". 6017@end deffn 6018 6019@geindex gcc_jit_type_get_const (C function) 6020@anchor{topics/types gcc_jit_type_get_const}@anchor{7a} 6021@deffn {C Function} gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type@w{ }*type) 6022 6023Given type "T", get type "const T". 6024@end deffn 6025 6026@geindex gcc_jit_type_get_volatile (C function) 6027@anchor{topics/types gcc_jit_type_get_volatile}@anchor{7e} 6028@deffn {C Function} gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type@w{ }*type) 6029 6030Given type "T", get type "volatile T". 6031@end deffn 6032 6033@geindex gcc_jit_context_new_array_type (C function) 6034@anchor{topics/types gcc_jit_context_new_array_type}@anchor{7f} 6035@deffn {C Function} gcc_jit_type * gcc_jit_context_new_array_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*element_type, int@w{ }num_elements) 6036 6037Given type "T", get type "T[N]" (for a constant N). 6038@end deffn 6039 6040@node Structures and unions,,Pointers const and volatile,Types 6041@anchor{topics/types structures-and-unions}@anchor{80} 6042@subsection Structures and unions 6043 6044 6045@geindex gcc_jit_struct (C type) 6046@anchor{topics/types gcc_jit_struct}@anchor{81} 6047@deffn {C Type} gcc_jit_struct 6048@end deffn 6049 6050A compound type analagous to a C @cite{struct}. 6051 6052@geindex gcc_jit_field (C type) 6053@anchor{topics/types gcc_jit_field}@anchor{82} 6054@deffn {C Type} gcc_jit_field 6055@end deffn 6056 6057A field within a @pxref{81,,gcc_jit_struct}. 6058 6059You can model C @cite{struct} types by creating @pxref{81,,gcc_jit_struct *} and 6060@pxref{82,,gcc_jit_field} instances, in either order: 6061 6062 6063@itemize * 6064 6065@item 6066by creating the fields, then the structure. For example, to model: 6067 6068@example 6069struct coord @{double x; double y; @}; 6070@end example 6071 6072@noindent 6073 6074you could call: 6075 6076@example 6077gcc_jit_field *field_x = 6078 gcc_jit_context_new_field (ctxt, NULL, double_type, "x"); 6079gcc_jit_field *field_y = 6080 gcc_jit_context_new_field (ctxt, NULL, double_type, "y"); 6081gcc_jit_field *fields[2] = @{field_x, field_y@}; 6082gcc_jit_struct *coord = 6083 gcc_jit_context_new_struct_type (ctxt, NULL, "coord", 2, fields); 6084@end example 6085 6086@noindent 6087 6088@item 6089by creating the structure, then populating it with fields, typically 6090to allow modelling self-referential structs such as: 6091 6092@example 6093struct node @{ int m_hash; struct node *m_next; @}; 6094@end example 6095 6096@noindent 6097 6098like this: 6099 6100@example 6101gcc_jit_type *node = 6102 gcc_jit_context_new_opaque_struct (ctxt, NULL, "node"); 6103gcc_jit_type *node_ptr = 6104 gcc_jit_type_get_pointer (node); 6105gcc_jit_field *field_hash = 6106 gcc_jit_context_new_field (ctxt, NULL, int_type, "m_hash"); 6107gcc_jit_field *field_next = 6108 gcc_jit_context_new_field (ctxt, NULL, node_ptr, "m_next"); 6109gcc_jit_field *fields[2] = @{field_hash, field_next@}; 6110gcc_jit_struct_set_fields (node, NULL, 2, fields); 6111@end example 6112 6113@noindent 6114@end itemize 6115 6116@geindex gcc_jit_context_new_field (C function) 6117@anchor{topics/types gcc_jit_context_new_field}@anchor{83} 6118@deffn {C Function} gcc_jit_field * gcc_jit_context_new_field (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, const char@w{ }*name) 6119 6120Construct a new field, with the given type and name. 6121 6122The parameter @code{name} must be non-NULL. The call takes a copy of the 6123underlying string, so it is valid to pass in a pointer to an on-stack 6124buffer. 6125@end deffn 6126 6127@geindex gcc_jit_field_as_object (C function) 6128@anchor{topics/types gcc_jit_field_as_object}@anchor{84} 6129@deffn {C Function} gcc_jit_object * gcc_jit_field_as_object (gcc_jit_field@w{ }*field) 6130 6131Upcast from field to object. 6132@end deffn 6133 6134@geindex gcc_jit_context_new_struct_type (C function) 6135@anchor{topics/types gcc_jit_context_new_struct_type}@anchor{85} 6136@deffn {C Function} gcc_jit_struct *gcc_jit_context_new_struct_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name, int@w{ }num_fields, gcc_jit_field@w{ }**fields) 6137 6138@quotation 6139 6140Construct a new struct type, with the given name and fields. 6141 6142The parameter @code{name} must be non-NULL. The call takes a copy of 6143the underlying string, so it is valid to pass in a pointer to an 6144on-stack buffer. 6145@end quotation 6146@end deffn 6147 6148@geindex gcc_jit_context_new_opaque_struct (C function) 6149@anchor{topics/types gcc_jit_context_new_opaque_struct}@anchor{86} 6150@deffn {C Function} gcc_jit_struct * gcc_jit_context_new_opaque_struct (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name) 6151 6152Construct a new struct type, with the given name, but without 6153specifying the fields. The fields can be omitted (in which case the 6154size of the struct is not known), or later specified using 6155@pxref{87,,gcc_jit_struct_set_fields()}. 6156 6157The parameter @code{name} must be non-NULL. The call takes a copy of 6158the underlying string, so it is valid to pass in a pointer to an 6159on-stack buffer. 6160@end deffn 6161 6162@geindex gcc_jit_struct_as_type (C function) 6163@anchor{topics/types gcc_jit_struct_as_type}@anchor{88} 6164@deffn {C Function} gcc_jit_type * gcc_jit_struct_as_type (gcc_jit_struct@w{ }*struct_type) 6165 6166Upcast from struct to type. 6167@end deffn 6168 6169@geindex gcc_jit_struct_set_fields (C function) 6170@anchor{topics/types gcc_jit_struct_set_fields}@anchor{87} 6171@deffn {C Function} void gcc_jit_struct_set_fields (gcc_jit_struct@w{ }*struct_type, gcc_jit_location@w{ }*loc, int@w{ }num_fields, gcc_jit_field@w{ }**fields) 6172 6173Populate the fields of a formerly-opaque struct type. 6174 6175This can only be called once on a given struct type. 6176@end deffn 6177 6178@geindex gcc_jit_context_new_union_type (C function) 6179@anchor{topics/types gcc_jit_context_new_union_type}@anchor{89} 6180@deffn {C Function} gcc_jit_type * gcc_jit_context_new_union_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name, int@w{ }num_fields, gcc_jit_field@w{ }**fields) 6181 6182Construct a new union type, with the given name and fields. 6183 6184The parameter @code{name} must be non-NULL. It is copied, so the input 6185buffer does not need to outlive the call. 6186 6187Example of use: 6188 6189@example 6190 6191union int_or_float 6192@{ 6193 int as_int; 6194 float as_float; 6195@}; 6196 6197void 6198create_code (gcc_jit_context *ctxt, void *user_data) 6199@{ 6200 /* Let's try to inject the equivalent of: 6201 float 6202 test_union (int i) 6203 @{ 6204 union int_or_float u; 6205 u.as_int = i; 6206 return u.as_float; 6207 @} 6208 */ 6209 gcc_jit_type *int_type = 6210 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 6211 gcc_jit_type *float_type = 6212 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); 6213 gcc_jit_field *as_int = 6214 gcc_jit_context_new_field (ctxt, 6215 NULL, 6216 int_type, 6217 "as_int"); 6218 gcc_jit_field *as_float = 6219 gcc_jit_context_new_field (ctxt, 6220 NULL, 6221 float_type, 6222 "as_float"); 6223 gcc_jit_field *fields[] = @{as_int, as_float@}; 6224 gcc_jit_type *union_type = 6225 gcc_jit_context_new_union_type (ctxt, NULL, 6226 "int_or_float", 2, fields); 6227 6228 /* Build the test function. */ 6229 gcc_jit_param *param_i = 6230 gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); 6231 gcc_jit_function *test_fn = 6232 gcc_jit_context_new_function (ctxt, NULL, 6233 GCC_JIT_FUNCTION_EXPORTED, 6234 float_type, 6235 "test_union", 6236 1, ¶m_i, 6237 0); 6238 6239 gcc_jit_lvalue *u = 6240 gcc_jit_function_new_local (test_fn, NULL, 6241 union_type, "u"); 6242 6243 gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); 6244 6245 /* u.as_int = i; */ 6246 gcc_jit_block_add_assignment ( 6247 block, 6248 NULL, 6249 /* "u.as_int = ..." */ 6250 gcc_jit_lvalue_access_field (u, 6251 NULL, 6252 as_int), 6253 gcc_jit_param_as_rvalue (param_i)); 6254 6255 /* return u.as_float; */ 6256 gcc_jit_block_end_with_return ( 6257 block, NULL, 6258 gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (u), 6259 NULL, 6260 as_float)); 6261@} 6262 6263 6264@end example 6265 6266@noindent 6267@end deffn 6268 6269@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 6270@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 6271@c 6272@c This is free software: you can redistribute it and/or modify it 6273@c under the terms of the GNU General Public License as published by 6274@c the Free Software Foundation, either version 3 of the License, or 6275@c (at your option) any later version. 6276@c 6277@c This program is distributed in the hope that it will be useful, but 6278@c WITHOUT ANY WARRANTY; without even the implied warranty of 6279@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 6280@c General Public License for more details. 6281@c 6282@c You should have received a copy of the GNU General Public License 6283@c along with this program. If not, see 6284@c <http://www.gnu.org/licenses/>. 6285 6286@node Expressions,Creating and using functions,Types,Topic Reference 6287@anchor{topics/expressions expressions}@anchor{8a}@anchor{topics/expressions doc}@anchor{8b} 6288@section Expressions 6289 6290 6291@menu 6292* Rvalues:: 6293* Lvalues:: 6294* Working with pointers@comma{} structs and unions: Working with pointers structs and unions. 6295 6296Rvalues 6297 6298* Simple expressions:: 6299* Unary Operations:: 6300* Binary Operations:: 6301* Comparisons:: 6302* Function calls:: 6303* Type-coercion:: 6304 6305Lvalues 6306 6307* Global variables:: 6308 6309@end menu 6310 6311 6312@node Rvalues,Lvalues,,Expressions 6313@anchor{topics/expressions rvalues}@anchor{8c} 6314@subsection Rvalues 6315 6316 6317@geindex gcc_jit_rvalue (C type) 6318@anchor{topics/expressions gcc_jit_rvalue}@anchor{13} 6319@deffn {C Type} gcc_jit_rvalue 6320@end deffn 6321 6322A @pxref{13,,gcc_jit_rvalue *} is an expression that can be computed. 6323 6324It can be simple, e.g.: 6325 6326@quotation 6327 6328 6329@itemize * 6330 6331@item 6332an integer value e.g. @cite{0} or @cite{42} 6333 6334@item 6335a string literal e.g. @cite{"Hello world"} 6336 6337@item 6338a variable e.g. @cite{i}. These are also lvalues (see below). 6339@end itemize 6340@end quotation 6341 6342or compound e.g.: 6343 6344@quotation 6345 6346 6347@itemize * 6348 6349@item 6350a unary expression e.g. @cite{!cond} 6351 6352@item 6353a binary expression e.g. @cite{(a + b)} 6354 6355@item 6356a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} 6357 6358@item 6359etc. 6360@end itemize 6361@end quotation 6362 6363Every rvalue has an associated type, and the API will check to ensure 6364that types match up correctly (otherwise the context will emit an error). 6365 6366@geindex gcc_jit_rvalue_get_type (C function) 6367@anchor{topics/expressions gcc_jit_rvalue_get_type}@anchor{8d} 6368@deffn {C Function} gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue@w{ }*rvalue) 6369 6370Get the type of this rvalue. 6371@end deffn 6372 6373@geindex gcc_jit_rvalue_as_object (C function) 6374@anchor{topics/expressions gcc_jit_rvalue_as_object}@anchor{14} 6375@deffn {C Function} gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue@w{ }*rvalue) 6376 6377Upcast the given rvalue to be an object. 6378@end deffn 6379 6380@menu 6381* Simple expressions:: 6382* Unary Operations:: 6383* Binary Operations:: 6384* Comparisons:: 6385* Function calls:: 6386* Type-coercion:: 6387 6388@end menu 6389 6390@node Simple expressions,Unary Operations,,Rvalues 6391@anchor{topics/expressions simple-expressions}@anchor{8e} 6392@subsubsection Simple expressions 6393 6394 6395@geindex gcc_jit_context_new_rvalue_from_int (C function) 6396@anchor{topics/expressions gcc_jit_context_new_rvalue_from_int}@anchor{30} 6397@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_int (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type, int@w{ }value) 6398 6399Given a numeric type (integer or floating point), build an rvalue for 6400the given constant @code{int} value. 6401@end deffn 6402 6403@geindex gcc_jit_context_new_rvalue_from_long (C function) 6404@anchor{topics/expressions gcc_jit_context_new_rvalue_from_long}@anchor{8f} 6405@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_long (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type, long@w{ }value) 6406 6407Given a numeric type (integer or floating point), build an rvalue for 6408the given constant @code{long} value. 6409@end deffn 6410 6411@geindex gcc_jit_context_zero (C function) 6412@anchor{topics/expressions gcc_jit_context_zero}@anchor{2b} 6413@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) 6414 6415Given a numeric type (integer or floating point), get the rvalue for 6416zero. Essentially this is just a shortcut for: 6417 6418@example 6419gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0) 6420@end example 6421 6422@noindent 6423@end deffn 6424 6425@geindex gcc_jit_context_one (C function) 6426@anchor{topics/expressions gcc_jit_context_one}@anchor{2f} 6427@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_one (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type) 6428 6429Given a numeric type (integer or floating point), get the rvalue for 6430one. Essentially this is just a shortcut for: 6431 6432@example 6433gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1) 6434@end example 6435 6436@noindent 6437@end deffn 6438 6439@geindex gcc_jit_context_new_rvalue_from_double (C function) 6440@anchor{topics/expressions gcc_jit_context_new_rvalue_from_double}@anchor{31} 6441@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_double (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type, double@w{ }value) 6442 6443Given a numeric type (integer or floating point), build an rvalue for 6444the given constant @code{double} value. 6445@end deffn 6446 6447@geindex gcc_jit_context_new_rvalue_from_ptr (C function) 6448@anchor{topics/expressions gcc_jit_context_new_rvalue_from_ptr}@anchor{90} 6449@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type, void@w{ }*value) 6450 6451Given a pointer type, build an rvalue for the given address. 6452@end deffn 6453 6454@geindex gcc_jit_context_null (C function) 6455@anchor{topics/expressions gcc_jit_context_null}@anchor{91} 6456@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type) 6457 6458Given a pointer type, build an rvalue for @code{NULL}. Essentially this 6459is just a shortcut for: 6460 6461@example 6462gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL) 6463@end example 6464 6465@noindent 6466@end deffn 6467 6468@geindex gcc_jit_context_new_string_literal (C function) 6469@anchor{topics/expressions gcc_jit_context_new_string_literal}@anchor{92} 6470@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_string_literal (gcc_jit_context@w{ }*ctxt, const char@w{ }*value) 6471 6472Generate an rvalue for the given NIL-terminated string, of type 6473@code{GCC_JIT_TYPE_CONST_CHAR_PTR}. 6474 6475The parameter @code{value} must be non-NULL. The call takes a copy of the 6476underlying string, so it is valid to pass in a pointer to an on-stack 6477buffer. 6478@end deffn 6479 6480@node Unary Operations,Binary Operations,Simple expressions,Rvalues 6481@anchor{topics/expressions unary-operations}@anchor{93} 6482@subsubsection Unary Operations 6483 6484 6485@geindex gcc_jit_context_new_unary_op (C function) 6486@anchor{topics/expressions gcc_jit_context_new_unary_op}@anchor{94} 6487@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_unary_op (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_unary_op@w{ }op, gcc_jit_type@w{ }*result_type, gcc_jit_rvalue@w{ }*rvalue) 6488 6489Build a unary operation out of an input rvalue. 6490@end deffn 6491 6492@geindex gcc_jit_unary_op (C type) 6493@anchor{topics/expressions gcc_jit_unary_op}@anchor{95} 6494@deffn {C Type} enum gcc_jit_unary_op 6495@end deffn 6496 6497The available unary operations are: 6498 6499 6500@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6501@headitem 6502 6503Unary Operation 6504 6505@tab 6506 6507C equivalent 6508 6509@item 6510 6511@pxref{96,,GCC_JIT_UNARY_OP_MINUS} 6512 6513@tab 6514 6515@cite{-(EXPR)} 6516 6517@item 6518 6519@pxref{97,,GCC_JIT_UNARY_OP_BITWISE_NEGATE} 6520 6521@tab 6522 6523@cite{~(EXPR)} 6524 6525@item 6526 6527@pxref{98,,GCC_JIT_UNARY_OP_LOGICAL_NEGATE} 6528 6529@tab 6530 6531@cite{!(EXPR)} 6532 6533@item 6534 6535@pxref{99,,GCC_JIT_UNARY_OP_ABS} 6536 6537@tab 6538 6539@cite{abs (EXPR)} 6540 6541@end multitable 6542 6543 6544@geindex GCC_JIT_UNARY_OP_MINUS (C macro) 6545@anchor{topics/expressions GCC_JIT_UNARY_OP_MINUS}@anchor{96} 6546@deffn {C Macro} GCC_JIT_UNARY_OP_MINUS 6547 6548Negate an arithmetic value; analogous to: 6549 6550@example 6551-(EXPR) 6552@end example 6553 6554@noindent 6555 6556in C. 6557@end deffn 6558 6559@geindex GCC_JIT_UNARY_OP_BITWISE_NEGATE (C macro) 6560@anchor{topics/expressions GCC_JIT_UNARY_OP_BITWISE_NEGATE}@anchor{97} 6561@deffn {C Macro} GCC_JIT_UNARY_OP_BITWISE_NEGATE 6562 6563Bitwise negation of an integer value (one's complement); analogous 6564to: 6565 6566@example 6567~(EXPR) 6568@end example 6569 6570@noindent 6571 6572in C. 6573@end deffn 6574 6575@geindex GCC_JIT_UNARY_OP_LOGICAL_NEGATE (C macro) 6576@anchor{topics/expressions GCC_JIT_UNARY_OP_LOGICAL_NEGATE}@anchor{98} 6577@deffn {C Macro} GCC_JIT_UNARY_OP_LOGICAL_NEGATE 6578 6579Logical negation of an arithmetic or pointer value; analogous to: 6580 6581@example 6582!(EXPR) 6583@end example 6584 6585@noindent 6586 6587in C. 6588@end deffn 6589 6590@geindex GCC_JIT_UNARY_OP_ABS (C macro) 6591@anchor{topics/expressions GCC_JIT_UNARY_OP_ABS}@anchor{99} 6592@deffn {C Macro} GCC_JIT_UNARY_OP_ABS 6593 6594Absolute value of an arithmetic expression; analogous to: 6595 6596@example 6597abs (EXPR) 6598@end example 6599 6600@noindent 6601 6602in C. 6603@end deffn 6604 6605@node Binary Operations,Comparisons,Unary Operations,Rvalues 6606@anchor{topics/expressions binary-operations}@anchor{9a} 6607@subsubsection Binary Operations 6608 6609 6610@geindex gcc_jit_context_new_binary_op (C function) 6611@anchor{topics/expressions gcc_jit_context_new_binary_op}@anchor{12} 6612@deffn {C Function} gcc_jit_rvalue *gcc_jit_context_new_binary_op (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_binary_op@w{ }op, gcc_jit_type@w{ }*result_type, gcc_jit_rvalue@w{ }*a, gcc_jit_rvalue@w{ }*b) 6613 6614Build a binary operation out of two constituent rvalues. 6615@end deffn 6616 6617@geindex gcc_jit_binary_op (C type) 6618@anchor{topics/expressions gcc_jit_binary_op}@anchor{9b} 6619@deffn {C Type} enum gcc_jit_binary_op 6620@end deffn 6621 6622The available binary operations are: 6623 6624 6625@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6626@headitem 6627 6628Binary Operation 6629 6630@tab 6631 6632C equivalent 6633 6634@item 6635 6636@pxref{9c,,GCC_JIT_BINARY_OP_PLUS} 6637 6638@tab 6639 6640@cite{x + y} 6641 6642@item 6643 6644@pxref{9d,,GCC_JIT_BINARY_OP_MINUS} 6645 6646@tab 6647 6648@cite{x - y} 6649 6650@item 6651 6652@pxref{9e,,GCC_JIT_BINARY_OP_MULT} 6653 6654@tab 6655 6656@cite{x * y} 6657 6658@item 6659 6660@pxref{9f,,GCC_JIT_BINARY_OP_DIVIDE} 6661 6662@tab 6663 6664@cite{x / y} 6665 6666@item 6667 6668@pxref{a0,,GCC_JIT_BINARY_OP_MODULO} 6669 6670@tab 6671 6672@cite{x % y} 6673 6674@item 6675 6676@pxref{a1,,GCC_JIT_BINARY_OP_BITWISE_AND} 6677 6678@tab 6679 6680@cite{x & y} 6681 6682@item 6683 6684@pxref{a2,,GCC_JIT_BINARY_OP_BITWISE_XOR} 6685 6686@tab 6687 6688@cite{x ^ y} 6689 6690@item 6691 6692@pxref{a3,,GCC_JIT_BINARY_OP_BITWISE_OR} 6693 6694@tab 6695 6696@cite{x | y} 6697 6698@item 6699 6700@pxref{a4,,GCC_JIT_BINARY_OP_LOGICAL_AND} 6701 6702@tab 6703 6704@cite{x && y} 6705 6706@item 6707 6708@pxref{a5,,GCC_JIT_BINARY_OP_LOGICAL_OR} 6709 6710@tab 6711 6712@cite{x || y} 6713 6714@item 6715 6716@pxref{a6,,GCC_JIT_BINARY_OP_LSHIFT} 6717 6718@tab 6719 6720@cite{x << y} 6721 6722@item 6723 6724@pxref{a7,,GCC_JIT_BINARY_OP_RSHIFT} 6725 6726@tab 6727 6728@cite{x >> y} 6729 6730@end multitable 6731 6732 6733@geindex GCC_JIT_BINARY_OP_PLUS (C macro) 6734@anchor{topics/expressions GCC_JIT_BINARY_OP_PLUS}@anchor{9c} 6735@deffn {C Macro} GCC_JIT_BINARY_OP_PLUS 6736 6737Addition of arithmetic values; analogous to: 6738 6739@example 6740(EXPR_A) + (EXPR_B) 6741@end example 6742 6743@noindent 6744 6745in C. 6746 6747For pointer addition, use @pxref{a8,,gcc_jit_context_new_array_access()}. 6748@end deffn 6749 6750@geindex GCC_JIT_BINARY_OP_MINUS (C macro) 6751@anchor{topics/expressions GCC_JIT_BINARY_OP_MINUS}@anchor{9d} 6752@deffn {C Macro} GCC_JIT_BINARY_OP_MINUS 6753 6754Subtraction of arithmetic values; analogous to: 6755 6756@example 6757(EXPR_A) - (EXPR_B) 6758@end example 6759 6760@noindent 6761 6762in C. 6763@end deffn 6764 6765@geindex GCC_JIT_BINARY_OP_MULT (C macro) 6766@anchor{topics/expressions GCC_JIT_BINARY_OP_MULT}@anchor{9e} 6767@deffn {C Macro} GCC_JIT_BINARY_OP_MULT 6768 6769Multiplication of a pair of arithmetic values; analogous to: 6770 6771@example 6772(EXPR_A) * (EXPR_B) 6773@end example 6774 6775@noindent 6776 6777in C. 6778@end deffn 6779 6780@geindex GCC_JIT_BINARY_OP_DIVIDE (C macro) 6781@anchor{topics/expressions GCC_JIT_BINARY_OP_DIVIDE}@anchor{9f} 6782@deffn {C Macro} GCC_JIT_BINARY_OP_DIVIDE 6783 6784Quotient of division of arithmetic values; analogous to: 6785 6786@example 6787(EXPR_A) / (EXPR_B) 6788@end example 6789 6790@noindent 6791 6792in C. 6793 6794The result type affects the kind of division: if the result type is 6795integer-based, then the result is truncated towards zero, whereas 6796a floating-point result type indicates floating-point division. 6797@end deffn 6798 6799@geindex GCC_JIT_BINARY_OP_MODULO (C macro) 6800@anchor{topics/expressions GCC_JIT_BINARY_OP_MODULO}@anchor{a0} 6801@deffn {C Macro} GCC_JIT_BINARY_OP_MODULO 6802 6803Remainder of division of arithmetic values; analogous to: 6804 6805@example 6806(EXPR_A) % (EXPR_B) 6807@end example 6808 6809@noindent 6810 6811in C. 6812@end deffn 6813 6814@geindex GCC_JIT_BINARY_OP_BITWISE_AND (C macro) 6815@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_AND}@anchor{a1} 6816@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_AND 6817 6818Bitwise AND; analogous to: 6819 6820@example 6821(EXPR_A) & (EXPR_B) 6822@end example 6823 6824@noindent 6825 6826in C. 6827@end deffn 6828 6829@geindex GCC_JIT_BINARY_OP_BITWISE_XOR (C macro) 6830@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_XOR}@anchor{a2} 6831@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_XOR 6832 6833Bitwise exclusive OR; analogous to: 6834 6835@example 6836(EXPR_A) ^ (EXPR_B) 6837@end example 6838 6839@noindent 6840 6841in C. 6842@end deffn 6843 6844@geindex GCC_JIT_BINARY_OP_BITWISE_OR (C macro) 6845@anchor{topics/expressions GCC_JIT_BINARY_OP_BITWISE_OR}@anchor{a3} 6846@deffn {C Macro} GCC_JIT_BINARY_OP_BITWISE_OR 6847 6848Bitwise inclusive OR; analogous to: 6849 6850@example 6851(EXPR_A) | (EXPR_B) 6852@end example 6853 6854@noindent 6855 6856in C. 6857@end deffn 6858 6859@geindex GCC_JIT_BINARY_OP_LOGICAL_AND (C macro) 6860@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_AND}@anchor{a4} 6861@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_AND 6862 6863Logical AND; analogous to: 6864 6865@example 6866(EXPR_A) && (EXPR_B) 6867@end example 6868 6869@noindent 6870 6871in C. 6872@end deffn 6873 6874@geindex GCC_JIT_BINARY_OP_LOGICAL_OR (C macro) 6875@anchor{topics/expressions GCC_JIT_BINARY_OP_LOGICAL_OR}@anchor{a5} 6876@deffn {C Macro} GCC_JIT_BINARY_OP_LOGICAL_OR 6877 6878Logical OR; analogous to: 6879 6880@example 6881(EXPR_A) || (EXPR_B) 6882@end example 6883 6884@noindent 6885 6886in C. 6887@end deffn 6888 6889@geindex GCC_JIT_BINARY_OP_LSHIFT (C macro) 6890@anchor{topics/expressions GCC_JIT_BINARY_OP_LSHIFT}@anchor{a6} 6891@deffn {C Macro} GCC_JIT_BINARY_OP_LSHIFT 6892 6893Left shift; analogous to: 6894 6895@example 6896(EXPR_A) << (EXPR_B) 6897@end example 6898 6899@noindent 6900 6901in C. 6902@end deffn 6903 6904@geindex GCC_JIT_BINARY_OP_RSHIFT (C macro) 6905@anchor{topics/expressions GCC_JIT_BINARY_OP_RSHIFT}@anchor{a7} 6906@deffn {C Macro} GCC_JIT_BINARY_OP_RSHIFT 6907 6908Right shift; analogous to: 6909 6910@example 6911(EXPR_A) >> (EXPR_B) 6912@end example 6913 6914@noindent 6915 6916in C. 6917@end deffn 6918 6919@node Comparisons,Function calls,Binary Operations,Rvalues 6920@anchor{topics/expressions comparisons}@anchor{a9} 6921@subsubsection Comparisons 6922 6923 6924@geindex gcc_jit_context_new_comparison (C function) 6925@anchor{topics/expressions gcc_jit_context_new_comparison}@anchor{2c} 6926@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_comparison (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_comparison@w{ }op, gcc_jit_rvalue@w{ }*a, gcc_jit_rvalue@w{ }*b) 6927 6928Build a boolean rvalue out of the comparison of two other rvalues. 6929@end deffn 6930 6931@geindex gcc_jit_comparison (C type) 6932@anchor{topics/expressions gcc_jit_comparison}@anchor{aa} 6933@deffn {C Type} enum gcc_jit_comparison 6934@end deffn 6935 6936 6937@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxx} 6938@headitem 6939 6940Comparison 6941 6942@tab 6943 6944C equivalent 6945 6946@item 6947 6948@code{GCC_JIT_COMPARISON_EQ} 6949 6950@tab 6951 6952@cite{x == y} 6953 6954@item 6955 6956@code{GCC_JIT_COMPARISON_NE} 6957 6958@tab 6959 6960@cite{x != y} 6961 6962@item 6963 6964@code{GCC_JIT_COMPARISON_LT} 6965 6966@tab 6967 6968@cite{x < y} 6969 6970@item 6971 6972@code{GCC_JIT_COMPARISON_LE} 6973 6974@tab 6975 6976@cite{x <= y} 6977 6978@item 6979 6980@code{GCC_JIT_COMPARISON_GT} 6981 6982@tab 6983 6984@cite{x > y} 6985 6986@item 6987 6988@code{GCC_JIT_COMPARISON_GE} 6989 6990@tab 6991 6992@cite{x >= y} 6993 6994@end multitable 6995 6996 6997@node Function calls,Type-coercion,Comparisons,Rvalues 6998@anchor{topics/expressions function-calls}@anchor{ab} 6999@subsubsection Function calls 7000 7001 7002@geindex gcc_jit_context_new_call (C function) 7003@anchor{topics/expressions gcc_jit_context_new_call}@anchor{ac} 7004@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_call (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_function@w{ }*func, int@w{ }numargs, gcc_jit_rvalue@w{ }**args) 7005 7006Given a function and the given table of argument rvalues, construct a 7007call to the function, with the result as an rvalue. 7008 7009@cartouche 7010@quotation Note 7011@pxref{ac,,gcc_jit_context_new_call()} merely builds a 7012@pxref{13,,gcc_jit_rvalue} i.e. an expression that can be evaluated, 7013perhaps as part of a more complicated expression. 7014The call @emph{won't} happen unless you add a statement to a function 7015that evaluates the expression. 7016 7017For example, if you want to call a function and discard the result 7018(or to call a function with @code{void} return type), use 7019@pxref{ad,,gcc_jit_block_add_eval()}: 7020 7021@example 7022/* Add "(void)printf (arg0, arg1);". */ 7023gcc_jit_block_add_eval ( 7024 block, NULL, 7025 gcc_jit_context_new_call ( 7026 ctxt, 7027 NULL, 7028 printf_func, 7029 2, args)); 7030@end example 7031 7032@noindent 7033@end quotation 7034@end cartouche 7035@end deffn 7036 7037@node Type-coercion,,Function calls,Rvalues 7038@anchor{topics/expressions type-coercion}@anchor{ae} 7039@subsubsection Type-coercion 7040 7041 7042@geindex gcc_jit_context_new_cast (C function) 7043@anchor{topics/expressions gcc_jit_context_new_cast}@anchor{af} 7044@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) 7045 7046Given an rvalue of T, construct another rvalue of another type. 7047 7048Currently only a limited set of conversions are possible: 7049 7050@quotation 7051 7052 7053@itemize * 7054 7055@item 7056int <-> float 7057 7058@item 7059int <-> bool 7060 7061@item 7062P* <-> Q*, for pointer types P and Q 7063@end itemize 7064@end quotation 7065@end deffn 7066 7067@node Lvalues,Working with pointers structs and unions,Rvalues,Expressions 7068@anchor{topics/expressions lvalues}@anchor{b0} 7069@subsection Lvalues 7070 7071 7072@geindex gcc_jit_lvalue (C type) 7073@anchor{topics/expressions gcc_jit_lvalue}@anchor{24} 7074@deffn {C Type} gcc_jit_lvalue 7075@end deffn 7076 7077An lvalue is something that can of the @emph{left}-hand side of an assignment: 7078a storage area (such as a variable). It is also usable as an rvalue, 7079where the rvalue is computed by reading from the storage area. 7080 7081@geindex gcc_jit_lvalue_as_object (C function) 7082@anchor{topics/expressions gcc_jit_lvalue_as_object}@anchor{b1} 7083@deffn {C Function} gcc_jit_object * gcc_jit_lvalue_as_object (gcc_jit_lvalue@w{ }*lvalue) 7084 7085Upcast an lvalue to be an object. 7086@end deffn 7087 7088@geindex gcc_jit_lvalue_as_rvalue (C function) 7089@anchor{topics/expressions gcc_jit_lvalue_as_rvalue}@anchor{b2} 7090@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue@w{ }*lvalue) 7091 7092Upcast an lvalue to be an rvalue. 7093@end deffn 7094 7095@geindex gcc_jit_lvalue_get_address (C function) 7096@anchor{topics/expressions gcc_jit_lvalue_get_address}@anchor{b3} 7097@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_get_address (gcc_jit_lvalue@w{ }*lvalue, gcc_jit_location@w{ }*loc) 7098 7099Take the address of an lvalue; analogous to: 7100 7101@example 7102&(EXPR) 7103@end example 7104 7105@noindent 7106 7107in C. 7108@end deffn 7109 7110@menu 7111* Global variables:: 7112 7113@end menu 7114 7115@node Global variables,,,Lvalues 7116@anchor{topics/expressions global-variables}@anchor{b4} 7117@subsubsection Global variables 7118 7119 7120@geindex gcc_jit_context_new_global (C function) 7121@anchor{topics/expressions gcc_jit_context_new_global}@anchor{b5} 7122@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) 7123 7124Add a new global variable of the given type and name to the context. 7125 7126The parameter @code{name} must be non-NULL. The call takes a copy of the 7127underlying string, so it is valid to pass in a pointer to an on-stack 7128buffer. 7129 7130The "kind" parameter determines the visibility of the "global" outside 7131of the @pxref{16,,gcc_jit_result}: 7132 7133@geindex gcc_jit_global_kind (C type) 7134@anchor{topics/expressions gcc_jit_global_kind}@anchor{b6} 7135@deffn {C Type} enum gcc_jit_global_kind 7136@end deffn 7137 7138@geindex GCC_JIT_GLOBAL_EXPORTED (C macro) 7139@anchor{topics/expressions GCC_JIT_GLOBAL_EXPORTED}@anchor{b7} 7140@deffn {C Macro} GCC_JIT_GLOBAL_EXPORTED 7141 7142Global is defined by the client code and is visible 7143by name outside of this JIT context via 7144@pxref{b8,,gcc_jit_result_get_global()} (and this value is required for 7145the global to be accessible via that entrypoint). 7146@end deffn 7147 7148@geindex GCC_JIT_GLOBAL_INTERNAL (C macro) 7149@anchor{topics/expressions GCC_JIT_GLOBAL_INTERNAL}@anchor{b9} 7150@deffn {C Macro} GCC_JIT_GLOBAL_INTERNAL 7151 7152Global is defined by the client code, but is invisible 7153outside of it. Analogous to a "static" global within a .c file. 7154Specifically, the variable will only be visible within this 7155context and within child contexts. 7156@end deffn 7157 7158@geindex GCC_JIT_GLOBAL_IMPORTED (C macro) 7159@anchor{topics/expressions GCC_JIT_GLOBAL_IMPORTED}@anchor{ba} 7160@deffn {C Macro} GCC_JIT_GLOBAL_IMPORTED 7161 7162Global is not defined by the client code; we're merely 7163referring to it. Analogous to using an "extern" global from a 7164header file. 7165@end deffn 7166@end deffn 7167 7168@node Working with pointers structs and unions,,Lvalues,Expressions 7169@anchor{topics/expressions working-with-pointers-structs-and-unions}@anchor{bb} 7170@subsection Working with pointers, structs and unions 7171 7172 7173@geindex gcc_jit_rvalue_dereference (C function) 7174@anchor{topics/expressions gcc_jit_rvalue_dereference}@anchor{bc} 7175@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference (gcc_jit_rvalue@w{ }*rvalue, gcc_jit_location@w{ }*loc) 7176 7177Given an rvalue of pointer type @code{T *}, dereferencing the pointer, 7178getting an lvalue of type @code{T}. Analogous to: 7179 7180@example 7181*(EXPR) 7182@end example 7183 7184@noindent 7185 7186in C. 7187@end deffn 7188 7189Field access is provided separately for both lvalues and rvalues. 7190 7191@geindex gcc_jit_lvalue_access_field (C function) 7192@anchor{topics/expressions gcc_jit_lvalue_access_field}@anchor{bd} 7193@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) 7194 7195Given an lvalue of struct or union type, access the given field, 7196getting an lvalue of the field's type. Analogous to: 7197 7198@example 7199(EXPR).field = ...; 7200@end example 7201 7202@noindent 7203 7204in C. 7205@end deffn 7206 7207@geindex gcc_jit_rvalue_access_field (C function) 7208@anchor{topics/expressions gcc_jit_rvalue_access_field}@anchor{be} 7209@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) 7210 7211Given an rvalue of struct or union type, access the given field 7212as an rvalue. Analogous to: 7213 7214@example 7215(EXPR).field 7216@end example 7217 7218@noindent 7219 7220in C. 7221@end deffn 7222 7223@geindex gcc_jit_rvalue_dereference_field (C function) 7224@anchor{topics/expressions gcc_jit_rvalue_dereference_field}@anchor{bf} 7225@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) 7226 7227Given an rvalue of pointer type @code{T *} where T is of struct or union 7228type, access the given field as an lvalue. Analogous to: 7229 7230@example 7231(EXPR)->field 7232@end example 7233 7234@noindent 7235 7236in C, itself equivalent to @code{(*EXPR).FIELD}. 7237@end deffn 7238 7239@geindex gcc_jit_context_new_array_access (C function) 7240@anchor{topics/expressions gcc_jit_context_new_array_access}@anchor{a8} 7241@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) 7242 7243Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at 7244the given index, using standard C array indexing rules i.e. each 7245increment of @code{index} corresponds to @code{sizeof(T)} bytes. 7246Analogous to: 7247 7248@example 7249PTR[INDEX] 7250@end example 7251 7252@noindent 7253 7254in C (or, indeed, to @code{PTR + INDEX}). 7255@end deffn 7256 7257@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 7258@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7259@c 7260@c This is free software: you can redistribute it and/or modify it 7261@c under the terms of the GNU General Public License as published by 7262@c the Free Software Foundation, either version 3 of the License, or 7263@c (at your option) any later version. 7264@c 7265@c This program is distributed in the hope that it will be useful, but 7266@c WITHOUT ANY WARRANTY; without even the implied warranty of 7267@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7268@c General Public License for more details. 7269@c 7270@c You should have received a copy of the GNU General Public License 7271@c along with this program. If not, see 7272@c <http://www.gnu.org/licenses/>. 7273 7274@node Creating and using functions,Source Locations,Expressions,Topic Reference 7275@anchor{topics/functions doc}@anchor{c0}@anchor{topics/functions creating-and-using-functions}@anchor{c1} 7276@section Creating and using functions 7277 7278 7279@menu 7280* Params:: 7281* Functions:: 7282* Blocks:: 7283* Statements:: 7284 7285@end menu 7286 7287@node Params,Functions,,Creating and using functions 7288@anchor{topics/functions params}@anchor{c2} 7289@subsection Params 7290 7291 7292@geindex gcc_jit_param (C type) 7293@anchor{topics/functions gcc_jit_param}@anchor{25} 7294@deffn {C Type} gcc_jit_param 7295 7296A @cite{gcc_jit_param} represents a parameter to a function. 7297@end deffn 7298 7299@geindex gcc_jit_context_new_param (C function) 7300@anchor{topics/functions gcc_jit_context_new_param}@anchor{10} 7301@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) 7302 7303In preparation for creating a function, create a new parameter of the 7304given type and name. 7305 7306The parameter @code{name} must be non-NULL. The call takes a copy of the 7307underlying string, so it is valid to pass in a pointer to an on-stack 7308buffer. 7309@end deffn 7310 7311Parameters are lvalues, and thus are also rvalues (and objects), so the 7312following upcasts are available: 7313 7314@geindex gcc_jit_param_as_lvalue (C function) 7315@anchor{topics/functions gcc_jit_param_as_lvalue}@anchor{c3} 7316@deffn {C Function} gcc_jit_lvalue * gcc_jit_param_as_lvalue (gcc_jit_param@w{ }*param) 7317 7318Upcasting from param to lvalue. 7319@end deffn 7320 7321@geindex gcc_jit_param_as_rvalue (C function) 7322@anchor{topics/functions gcc_jit_param_as_rvalue}@anchor{c4} 7323@deffn {C Function} gcc_jit_rvalue * gcc_jit_param_as_rvalue (gcc_jit_param@w{ }*param) 7324 7325Upcasting from param to rvalue. 7326@end deffn 7327 7328@geindex gcc_jit_param_as_object (C function) 7329@anchor{topics/functions gcc_jit_param_as_object}@anchor{c5} 7330@deffn {C Function} gcc_jit_object * gcc_jit_param_as_object (gcc_jit_param@w{ }*param) 7331 7332Upcasting from param to object. 7333@end deffn 7334 7335@node Functions,Blocks,Params,Creating and using functions 7336@anchor{topics/functions functions}@anchor{c6} 7337@subsection Functions 7338 7339 7340@geindex gcc_jit_function (C type) 7341@anchor{topics/functions gcc_jit_function}@anchor{29} 7342@deffn {C Type} gcc_jit_function 7343 7344A @cite{gcc_jit_function} represents a function - either one that we're 7345creating ourselves, or one that we're referencing. 7346@end deffn 7347 7348@geindex gcc_jit_context_new_function (C function) 7349@anchor{topics/functions gcc_jit_context_new_function}@anchor{11} 7350@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) 7351 7352Create a gcc_jit_function with the given name and parameters. 7353 7354@geindex gcc_jit_function_kind (C type) 7355@anchor{topics/functions gcc_jit_function_kind}@anchor{c7} 7356@deffn {C Type} enum gcc_jit_function_kind 7357@end deffn 7358 7359This enum controls the kind of function created, and has the following 7360values: 7361 7362@quotation 7363 7364@geindex GCC_JIT_FUNCTION_EXPORTED (C macro) 7365@anchor{topics/functions GCC_JIT_FUNCTION_EXPORTED}@anchor{c8} 7366@deffn {C Macro} GCC_JIT_FUNCTION_EXPORTED 7367 7368Function is defined by the client code and visible 7369by name outside of the JIT. 7370 7371This value is required if you want to extract machine code 7372for this function from a @pxref{16,,gcc_jit_result} via 7373@pxref{17,,gcc_jit_result_get_code()}. 7374@end deffn 7375 7376@geindex GCC_JIT_FUNCTION_INTERNAL (C macro) 7377@anchor{topics/functions GCC_JIT_FUNCTION_INTERNAL}@anchor{c9} 7378@deffn {C Macro} GCC_JIT_FUNCTION_INTERNAL 7379 7380Function is defined by the client code, but is invisible 7381outside of the JIT. Analogous to a "static" function. 7382@end deffn 7383 7384@geindex GCC_JIT_FUNCTION_IMPORTED (C macro) 7385@anchor{topics/functions GCC_JIT_FUNCTION_IMPORTED}@anchor{ca} 7386@deffn {C Macro} GCC_JIT_FUNCTION_IMPORTED 7387 7388Function is not defined by the client code; we're merely 7389referring to it. Analogous to using an "extern" function from a 7390header file. 7391@end deffn 7392 7393@geindex GCC_JIT_FUNCTION_ALWAYS_INLINE (C macro) 7394@anchor{topics/functions GCC_JIT_FUNCTION_ALWAYS_INLINE}@anchor{cb} 7395@deffn {C Macro} GCC_JIT_FUNCTION_ALWAYS_INLINE 7396 7397Function is only ever inlined into other functions, and is 7398invisible outside of the JIT. 7399 7400Analogous to prefixing with @code{inline} and adding 7401@code{__attribute__((always_inline))} 7402 7403Inlining will only occur when the optimization level is 7404above 0; when optimization is off, this is essentially the 7405same as GCC_JIT_FUNCTION_INTERNAL. 7406@end deffn 7407@end quotation 7408 7409The parameter @code{name} must be non-NULL. The call takes a copy of the 7410underlying string, so it is valid to pass in a pointer to an on-stack 7411buffer. 7412@end deffn 7413 7414@geindex gcc_jit_context_get_builtin_function (C function) 7415@anchor{topics/functions gcc_jit_context_get_builtin_function}@anchor{cc} 7416@deffn {C Function} gcc_jit_function *gcc_jit_context_get_builtin_function (gcc_jit_context@w{ }*ctxt, const char@w{ }*name) 7417@end deffn 7418 7419@geindex gcc_jit_function_as_object (C function) 7420@anchor{topics/functions gcc_jit_function_as_object}@anchor{cd} 7421@deffn {C Function} gcc_jit_object * gcc_jit_function_as_object (gcc_jit_function@w{ }*func) 7422 7423Upcasting from function to object. 7424@end deffn 7425 7426@geindex gcc_jit_function_get_param (C function) 7427@anchor{topics/functions gcc_jit_function_get_param}@anchor{ce} 7428@deffn {C Function} gcc_jit_param * gcc_jit_function_get_param (gcc_jit_function@w{ }*func, int@w{ }index) 7429 7430Get the param of the given index (0-based). 7431@end deffn 7432 7433@geindex gcc_jit_function_dump_to_dot (C function) 7434@anchor{topics/functions gcc_jit_function_dump_to_dot}@anchor{33} 7435@deffn {C Function} void gcc_jit_function_dump_to_dot (gcc_jit_function@w{ }*func, const char@w{ }*path) 7436 7437Emit the function in graphviz format to the given path. 7438@end deffn 7439 7440@geindex gcc_jit_function_new_local (C function) 7441@anchor{topics/functions gcc_jit_function_new_local}@anchor{26} 7442@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) 7443 7444Create a new local variable within the function, of the given type and 7445name. 7446 7447The parameter @code{name} must be non-NULL. The call takes a copy of the 7448underlying string, so it is valid to pass in a pointer to an on-stack 7449buffer. 7450@end deffn 7451 7452@node Blocks,Statements,Functions,Creating and using functions 7453@anchor{topics/functions blocks}@anchor{cf} 7454@subsection Blocks 7455 7456 7457@geindex gcc_jit_block (C type) 7458@anchor{topics/functions gcc_jit_block}@anchor{28} 7459@deffn {C Type} gcc_jit_block 7460 7461A @cite{gcc_jit_block} represents a basic block within a function i.e. a 7462sequence of statements with a single entry point and a single exit 7463point. 7464 7465The first basic block that you create within a function will 7466be the entrypoint. 7467 7468Each basic block that you create within a function must be 7469terminated, either with a conditional, a jump, a return, or a 7470switch. 7471 7472It's legal to have multiple basic blocks that return within 7473one function. 7474@end deffn 7475 7476@geindex gcc_jit_function_new_block (C function) 7477@anchor{topics/functions gcc_jit_function_new_block}@anchor{d0} 7478@deffn {C Function} gcc_jit_block * gcc_jit_function_new_block (gcc_jit_function@w{ }*func, const char@w{ }*name) 7479 7480Create a basic block of the given name. The name may be NULL, but 7481providing meaningful names is often helpful when debugging: it may 7482show up in dumps of the internal representation, and in error 7483messages. It is copied, so the input buffer does not need to outlive 7484the call; you can pass in a pointer to an on-stack buffer, e.g.: 7485 7486@example 7487for (pc = 0; pc < fn->fn_num_ops; pc++) 7488 @{ 7489 char buf[16]; 7490 sprintf (buf, "instr%i", pc); 7491 state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf); 7492 @} 7493@end example 7494 7495@noindent 7496@end deffn 7497 7498@geindex gcc_jit_block_as_object (C function) 7499@anchor{topics/functions gcc_jit_block_as_object}@anchor{d1} 7500@deffn {C Function} gcc_jit_object * gcc_jit_block_as_object (gcc_jit_block@w{ }*block) 7501 7502Upcast from block to object. 7503@end deffn 7504 7505@geindex gcc_jit_block_get_function (C function) 7506@anchor{topics/functions gcc_jit_block_get_function}@anchor{d2} 7507@deffn {C Function} gcc_jit_function * gcc_jit_block_get_function (gcc_jit_block@w{ }*block) 7508 7509Which function is this block within? 7510@end deffn 7511 7512@node Statements,,Blocks,Creating and using functions 7513@anchor{topics/functions statements}@anchor{d3} 7514@subsection Statements 7515 7516 7517@geindex gcc_jit_block_add_eval (C function) 7518@anchor{topics/functions gcc_jit_block_add_eval}@anchor{ad} 7519@deffn {C Function} void gcc_jit_block_add_eval (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue) 7520 7521Add evaluation of an rvalue, discarding the result 7522(e.g. a function call that "returns" void). 7523 7524This is equivalent to this C code: 7525 7526@example 7527(void)expression; 7528@end example 7529 7530@noindent 7531@end deffn 7532 7533@geindex gcc_jit_block_add_assignment (C function) 7534@anchor{topics/functions gcc_jit_block_add_assignment}@anchor{2a} 7535@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) 7536 7537Add evaluation of an rvalue, assigning the result to the given 7538lvalue. 7539 7540This is roughly equivalent to this C code: 7541 7542@example 7543lvalue = rvalue; 7544@end example 7545 7546@noindent 7547@end deffn 7548 7549@geindex gcc_jit_block_add_assignment_op (C function) 7550@anchor{topics/functions gcc_jit_block_add_assignment_op}@anchor{2e} 7551@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) 7552 7553Add evaluation of an rvalue, using the result to modify an 7554lvalue. 7555 7556This is analogous to "+=" and friends: 7557 7558@example 7559lvalue += rvalue; 7560lvalue *= rvalue; 7561lvalue /= rvalue; 7562@end example 7563 7564@noindent 7565 7566etc. For example: 7567 7568@example 7569/* "i++" */ 7570gcc_jit_block_add_assignment_op ( 7571 loop_body, NULL, 7572 i, 7573 GCC_JIT_BINARY_OP_PLUS, 7574 gcc_jit_context_one (ctxt, int_type)); 7575@end example 7576 7577@noindent 7578@end deffn 7579 7580@geindex gcc_jit_block_add_comment (C function) 7581@anchor{topics/functions gcc_jit_block_add_comment}@anchor{3d} 7582@deffn {C Function} void gcc_jit_block_add_comment (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, const char@w{ }*text) 7583 7584Add a no-op textual comment to the internal representation of the 7585code. It will be optimized away, but will be visible in the dumps 7586seen via @pxref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} 7587and @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, 7588and thus may be of use when debugging how your project's internal 7589representation gets converted to the libgccjit IR. 7590 7591The parameter @code{text} must be non-NULL. It is copied, so the input 7592buffer does not need to outlive the call. For example: 7593 7594@example 7595char buf[100]; 7596snprintf (buf, sizeof (buf), 7597 "op%i: %s", 7598 pc, opcode_names[op->op_opcode]); 7599gcc_jit_block_add_comment (block, loc, buf); 7600@end example 7601 7602@noindent 7603@end deffn 7604 7605@geindex gcc_jit_block_end_with_conditional (C function) 7606@anchor{topics/functions gcc_jit_block_end_with_conditional}@anchor{2d} 7607@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) 7608 7609Terminate a block by adding evaluation of an rvalue, branching on the 7610result to the appropriate successor block. 7611 7612This is roughly equivalent to this C code: 7613 7614@example 7615if (boolval) 7616 goto on_true; 7617else 7618 goto on_false; 7619@end example 7620 7621@noindent 7622 7623block, boolval, on_true, and on_false must be non-NULL. 7624@end deffn 7625 7626@geindex gcc_jit_block_end_with_jump (C function) 7627@anchor{topics/functions gcc_jit_block_end_with_jump}@anchor{d4} 7628@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) 7629 7630Terminate a block by adding a jump to the given target block. 7631 7632This is roughly equivalent to this C code: 7633 7634@example 7635goto target; 7636@end example 7637 7638@noindent 7639@end deffn 7640 7641@geindex gcc_jit_block_end_with_return (C function) 7642@anchor{topics/functions gcc_jit_block_end_with_return}@anchor{d5} 7643@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) 7644 7645Terminate a block by adding evaluation of an rvalue, returning the value. 7646 7647This is roughly equivalent to this C code: 7648 7649@example 7650return expression; 7651@end example 7652 7653@noindent 7654@end deffn 7655 7656@geindex gcc_jit_block_end_with_void_return (C function) 7657@anchor{topics/functions gcc_jit_block_end_with_void_return}@anchor{d6} 7658@deffn {C Function} void gcc_jit_block_end_with_void_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc) 7659 7660Terminate a block by adding a valueless return, for use within a function 7661with "void" return type. 7662 7663This is equivalent to this C code: 7664 7665@example 7666return; 7667@end example 7668 7669@noindent 7670@end deffn 7671 7672@geindex gcc_jit_block_end_with_switch (C function) 7673@anchor{topics/functions gcc_jit_block_end_with_switch}@anchor{d7} 7674@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) 7675 7676Terminate a block by adding evalation of an rvalue, then performing 7677a multiway branch. 7678 7679This is roughly equivalent to this C code: 7680 7681@example 7682switch (expr) 7683 @{ 7684 default: 7685 goto default_block; 7686 7687 case C0.min_value ... C0.max_value: 7688 goto C0.dest_block; 7689 7690 case C1.min_value ... C1.max_value: 7691 goto C1.dest_block; 7692 7693 ...etc... 7694 7695 case C[N - 1].min_value ... C[N - 1].max_value: 7696 goto C[N - 1].dest_block; 7697@} 7698@end example 7699 7700@noindent 7701 7702@code{block}, @code{expr}, @code{default_block} and @code{cases} must all be 7703non-NULL. 7704 7705@code{expr} must be of the same integer type as all of the @code{min_value} 7706and @code{max_value} within the cases. 7707 7708@code{num_cases} must be >= 0. 7709 7710The ranges of the cases must not overlap (or have duplicate 7711values). 7712 7713The API entrypoints relating to switch statements and cases: 7714 7715@quotation 7716 7717 7718@itemize * 7719 7720@item 7721@pxref{d7,,gcc_jit_block_end_with_switch()} 7722 7723@item 7724@pxref{d8,,gcc_jit_case_as_object()} 7725 7726@item 7727@pxref{d9,,gcc_jit_context_new_case()} 7728@end itemize 7729@end quotation 7730 7731were added in @pxref{da,,LIBGCCJIT_ABI_3}; you can test for their presence 7732using 7733 7734@example 7735#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 7736@end example 7737 7738@noindent 7739 7740@geindex gcc_jit_case (C type) 7741@anchor{topics/functions gcc_jit_case}@anchor{db} 7742@deffn {C Type} gcc_jit_case 7743@end deffn 7744 7745A @cite{gcc_jit_case} represents a case within a switch statement, and 7746is created within a particular @pxref{8,,gcc_jit_context} using 7747@pxref{d9,,gcc_jit_context_new_case()}. 7748 7749Each case expresses a multivalued range of integer values. You 7750can express single-valued cases by passing in the same value for 7751both @cite{min_value} and @cite{max_value}. 7752 7753@geindex gcc_jit_context_new_case (C function) 7754@anchor{topics/functions gcc_jit_context_new_case}@anchor{d9} 7755@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) 7756 7757Create a new gcc_jit_case instance for use in a switch statement. 7758@cite{min_value} and @cite{max_value} must be constants of an integer type, 7759which must match that of the expression of the switch statement. 7760 7761@cite{dest_block} must be within the same function as the switch 7762statement. 7763@end deffn 7764 7765@geindex gcc_jit_case_as_object (C function) 7766@anchor{topics/functions gcc_jit_case_as_object}@anchor{d8} 7767@deffn {C Function} gcc_jit_object * gcc_jit_case_as_object (gcc_jit_case@w{ }*case_) 7768 7769Upcast from a case to an object. 7770@end deffn 7771 7772Here's an example of creating a switch statement: 7773 7774@quotation 7775 7776@example 7777 7778void 7779create_code (gcc_jit_context *ctxt, void *user_data) 7780@{ 7781 /* Let's try to inject the equivalent of: 7782 int 7783 test_switch (int x) 7784 @{ 7785 switch (x) 7786 @{ 7787 case 0 ... 5: 7788 return 3; 7789 7790 case 25 ... 27: 7791 return 4; 7792 7793 case -42 ... -17: 7794 return 83; 7795 7796 case 40: 7797 return 8; 7798 7799 default: 7800 return 10; 7801 @} 7802 @} 7803 */ 7804 gcc_jit_type *t_int = 7805 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); 7806 gcc_jit_type *return_type = t_int; 7807 gcc_jit_param *x = 7808 gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); 7809 gcc_jit_param *params[1] = @{x@}; 7810 gcc_jit_function *func = 7811 gcc_jit_context_new_function (ctxt, NULL, 7812 GCC_JIT_FUNCTION_EXPORTED, 7813 return_type, 7814 "test_switch", 7815 1, params, 0); 7816 7817 gcc_jit_block *b_initial = 7818 gcc_jit_function_new_block (func, "initial"); 7819 7820 gcc_jit_block *b_default = 7821 gcc_jit_function_new_block (func, "default"); 7822 gcc_jit_block *b_case_0_5 = 7823 gcc_jit_function_new_block (func, "case_0_5"); 7824 gcc_jit_block *b_case_25_27 = 7825 gcc_jit_function_new_block (func, "case_25_27"); 7826 gcc_jit_block *b_case_m42_m17 = 7827 gcc_jit_function_new_block (func, "case_m42_m17"); 7828 gcc_jit_block *b_case_40 = 7829 gcc_jit_function_new_block (func, "case_40"); 7830 7831 gcc_jit_case *cases[4] = @{ 7832 gcc_jit_context_new_case ( 7833 ctxt, 7834 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0), 7835 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5), 7836 b_case_0_5), 7837 gcc_jit_context_new_case ( 7838 ctxt, 7839 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 25), 7840 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 27), 7841 b_case_25_27), 7842 gcc_jit_context_new_case ( 7843 ctxt, 7844 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -42), 7845 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -17), 7846 b_case_m42_m17), 7847 gcc_jit_context_new_case ( 7848 ctxt, 7849 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), 7850 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), 7851 b_case_40) 7852 @}; 7853 gcc_jit_block_end_with_switch ( 7854 b_initial, NULL, 7855 gcc_jit_param_as_rvalue (x), 7856 b_default, 7857 4, cases); 7858 7859 gcc_jit_block_end_with_return ( 7860 b_case_0_5, NULL, 7861 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); 7862 gcc_jit_block_end_with_return ( 7863 b_case_25_27, NULL, 7864 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4)); 7865 gcc_jit_block_end_with_return ( 7866 b_case_m42_m17, NULL, 7867 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 83)); 7868 gcc_jit_block_end_with_return ( 7869 b_case_40, NULL, 7870 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 8)); 7871 gcc_jit_block_end_with_return ( 7872 b_default, NULL, 7873 gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); 7874@} 7875 7876 7877@end example 7878 7879@noindent 7880@end quotation 7881@end deffn 7882 7883@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 7884@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7885@c 7886@c This is free software: you can redistribute it and/or modify it 7887@c under the terms of the GNU General Public License as published by 7888@c the Free Software Foundation, either version 3 of the License, or 7889@c (at your option) any later version. 7890@c 7891@c This program is distributed in the hope that it will be useful, but 7892@c WITHOUT ANY WARRANTY; without even the implied warranty of 7893@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7894@c General Public License for more details. 7895@c 7896@c You should have received a copy of the GNU General Public License 7897@c along with this program. If not, see 7898@c <http://www.gnu.org/licenses/>. 7899 7900@node Source Locations,Compiling a context,Creating and using functions,Topic Reference 7901@anchor{topics/locations source-locations}@anchor{dc}@anchor{topics/locations doc}@anchor{dd} 7902@section Source Locations 7903 7904 7905@geindex gcc_jit_location (C type) 7906@anchor{topics/locations gcc_jit_location}@anchor{3b} 7907@deffn {C Type} gcc_jit_location 7908 7909A @cite{gcc_jit_location} encapsulates a source code location, so that 7910you can (optionally) associate locations in your language with 7911statements in the JIT-compiled code, allowing the debugger to 7912single-step through your language. 7913 7914@cite{gcc_jit_location} instances are optional: you can always pass NULL to 7915any API entrypoint accepting one. 7916 7917You can construct them using @pxref{41,,gcc_jit_context_new_location()}. 7918 7919You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 7920@pxref{8,,gcc_jit_context} for these locations to actually be usable by 7921the debugger: 7922 7923@example 7924gcc_jit_context_set_bool_option ( 7925 ctxt, 7926 GCC_JIT_BOOL_OPTION_DEBUGINFO, 7927 1); 7928@end example 7929 7930@noindent 7931@end deffn 7932 7933@geindex gcc_jit_context_new_location (C function) 7934@anchor{topics/locations gcc_jit_context_new_location}@anchor{41} 7935@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) 7936 7937Create a @cite{gcc_jit_location} instance representing the given source 7938location. 7939 7940The parameter @code{filename} must be non-NULL. The call takes a copy of 7941the underlying string, so it is valid to pass in a pointer to an 7942on-stack buffer. 7943@end deffn 7944 7945@menu 7946* Faking it:: 7947 7948@end menu 7949 7950@node Faking it,,,Source Locations 7951@anchor{topics/locations faking-it}@anchor{de} 7952@subsection Faking it 7953 7954 7955If you don't have source code for your internal representation, but need 7956to debug, you can generate a C-like representation of the functions in 7957your context using @pxref{5a,,gcc_jit_context_dump_to_file()}: 7958 7959@example 7960gcc_jit_context_dump_to_file (ctxt, "/tmp/something.c", 7961 1 /* update_locations */); 7962@end example 7963 7964@noindent 7965 7966This will dump C-like code to the given path. If the @cite{update_locations} 7967argument is true, this will also set up @cite{gcc_jit_location} information 7968throughout the context, pointing at the dump file as if it were a source 7969file, giving you @emph{something} you can step through in the debugger. 7970 7971@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 7972@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 7973@c 7974@c This is free software: you can redistribute it and/or modify it 7975@c under the terms of the GNU General Public License as published by 7976@c the Free Software Foundation, either version 3 of the License, or 7977@c (at your option) any later version. 7978@c 7979@c This program is distributed in the hope that it will be useful, but 7980@c WITHOUT ANY WARRANTY; without even the implied warranty of 7981@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 7982@c General Public License for more details. 7983@c 7984@c You should have received a copy of the GNU General Public License 7985@c along with this program. If not, see 7986@c <http://www.gnu.org/licenses/>. 7987 7988@node Compiling a context,ABI and API compatibility,Source Locations,Topic Reference 7989@anchor{topics/compilation compiling-a-context}@anchor{df}@anchor{topics/compilation doc}@anchor{e0} 7990@section Compiling a context 7991 7992 7993Once populated, a @pxref{8,,gcc_jit_context *} can be compiled to 7994machine code, either in-memory via @pxref{15,,gcc_jit_context_compile()} or 7995to disk via @pxref{4a,,gcc_jit_context_compile_to_file()}. 7996 7997You can compile a context multiple times (using either form of 7998compilation), although any errors that occur on the context will 7999prevent any future compilation of that context. 8000 8001@menu 8002* In-memory compilation:: 8003* Ahead-of-time compilation:: 8004 8005@end menu 8006 8007@node In-memory compilation,Ahead-of-time compilation,,Compiling a context 8008@anchor{topics/compilation in-memory-compilation}@anchor{e1} 8009@subsection In-memory compilation 8010 8011 8012@geindex gcc_jit_context_compile (C function) 8013@anchor{topics/compilation gcc_jit_context_compile}@anchor{15} 8014@deffn {C Function} gcc_jit_result * gcc_jit_context_compile (gcc_jit_context@w{ }*ctxt) 8015 8016This calls into GCC and builds the code, returning a 8017@cite{gcc_jit_result *}. 8018 8019If the result is non-NULL, the caller becomes responsible for 8020calling @pxref{39,,gcc_jit_result_release()} on it once they're done 8021with it. 8022@end deffn 8023 8024@geindex gcc_jit_result (C type) 8025@anchor{topics/compilation gcc_jit_result}@anchor{16} 8026@deffn {C Type} gcc_jit_result 8027 8028A @cite{gcc_jit_result} encapsulates the result of compiling a context 8029in-memory, and the lifetimes of any machine code functions or globals 8030that are within the result. 8031@end deffn 8032 8033@geindex gcc_jit_result_get_code (C function) 8034@anchor{topics/compilation gcc_jit_result_get_code}@anchor{17} 8035@deffn {C Function} void * gcc_jit_result_get_code (gcc_jit_result@w{ }*result, const char@w{ }*funcname) 8036 8037Locate a given function within the built machine code. 8038 8039Functions are looked up by name. For this to succeed, a function 8040with a name matching @cite{funcname} must have been created on 8041@cite{result}'s context (or a parent context) via a call to 8042@pxref{11,,gcc_jit_context_new_function()} with @cite{kind} 8043@pxref{c8,,GCC_JIT_FUNCTION_EXPORTED}: 8044 8045@example 8046gcc_jit_context_new_function (ctxt, 8047 any_location, /* or NULL */ 8048 /* Required for func to be visible to 8049 gcc_jit_result_get_code: */ 8050 GCC_JIT_FUNCTION_EXPORTED, 8051 any_return_type, 8052 /* Must string-compare equal: */ 8053 funcname, 8054 /* etc */); 8055@end example 8056 8057@noindent 8058 8059If such a function is not found (or @cite{result} or @cite{funcname} are 8060@code{NULL}), an error message will be emitted on stderr and 8061@code{NULL} will be returned. 8062 8063If the function is found, the result will need to be cast to a 8064function pointer of the correct type before it can be called. 8065 8066Note that the resulting machine code becomes invalid after 8067@pxref{39,,gcc_jit_result_release()} is called on the 8068@pxref{16,,gcc_jit_result *}; attempting to call it after that may lead 8069to a segmentation fault. 8070@end deffn 8071 8072@geindex gcc_jit_result_get_global (C function) 8073@anchor{topics/compilation gcc_jit_result_get_global}@anchor{b8} 8074@deffn {C Function} void * gcc_jit_result_get_global (gcc_jit_result@w{ }*result, const char@w{ }*name) 8075 8076Locate a given global within the built machine code. 8077 8078Globals are looked up by name. For this to succeed, a global 8079with a name matching @cite{name} must have been created on 8080@cite{result}'s context (or a parent context) via a call to 8081@pxref{b5,,gcc_jit_context_new_global()} with @cite{kind} 8082@pxref{b7,,GCC_JIT_GLOBAL_EXPORTED}. 8083 8084If the global is found, the result will need to be cast to a 8085pointer of the correct type before it can be called. 8086 8087This is a @emph{pointer} to the global, so e.g. for an @code{int} this is 8088an @code{int *}. 8089 8090For example, given an @code{int foo;} created this way: 8091 8092@example 8093gcc_jit_lvalue *exported_global = 8094 gcc_jit_context_new_global (ctxt, 8095 any_location, /* or NULL */ 8096 GCC_JIT_GLOBAL_EXPORTED, 8097 int_type, 8098 "foo"); 8099@end example 8100 8101@noindent 8102 8103we can access it like this: 8104 8105@example 8106int *ptr_to_foo = 8107 (int *)gcc_jit_result_get_global (result, "foo"); 8108@end example 8109 8110@noindent 8111 8112If such a global is not found (or @cite{result} or @cite{name} are 8113@code{NULL}), an error message will be emitted on stderr and 8114@code{NULL} will be returned. 8115 8116Note that the resulting address becomes invalid after 8117@pxref{39,,gcc_jit_result_release()} is called on the 8118@pxref{16,,gcc_jit_result *}; attempting to use it after that may lead 8119to a segmentation fault. 8120@end deffn 8121 8122@geindex gcc_jit_result_release (C function) 8123@anchor{topics/compilation gcc_jit_result_release}@anchor{39} 8124@deffn {C Function} void gcc_jit_result_release (gcc_jit_result@w{ }*result) 8125 8126Once we're done with the code, this unloads the built .so file. 8127This cleans up the result; after calling this, it's no longer 8128valid to use the result, or any code or globals that were obtained 8129by calling @pxref{17,,gcc_jit_result_get_code()} or 8130@pxref{b8,,gcc_jit_result_get_global()} on it. 8131@end deffn 8132 8133@node Ahead-of-time compilation,,In-memory compilation,Compiling a context 8134@anchor{topics/compilation ahead-of-time-compilation}@anchor{e2} 8135@subsection Ahead-of-time compilation 8136 8137 8138Although libgccjit is primarily aimed at just-in-time compilation, it 8139can also be used for implementing more traditional ahead-of-time 8140compilers, via the @pxref{4a,,gcc_jit_context_compile_to_file()} 8141API entrypoint. 8142 8143@geindex gcc_jit_context_compile_to_file (C function) 8144@anchor{topics/compilation gcc_jit_context_compile_to_file}@anchor{4a} 8145@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) 8146 8147Compile the @pxref{8,,gcc_jit_context *} to a file of the given 8148kind. 8149@end deffn 8150 8151@pxref{4a,,gcc_jit_context_compile_to_file()} ignores the suffix of 8152@code{output_path}, and insteads uses the given 8153@code{enum gcc_jit_output_kind} to decide what to do. 8154 8155@cartouche 8156@quotation Note 8157This is different from the @code{gcc} program, which does make use of the 8158suffix of the output file when determining what to do. 8159@end quotation 8160@end cartouche 8161 8162@geindex gcc_jit_output_kind (C type) 8163@anchor{topics/compilation gcc_jit_output_kind}@anchor{e3} 8164@deffn {C Type} enum gcc_jit_output_kind 8165@end deffn 8166 8167The available kinds of output are: 8168 8169 8170@multitable {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxx} 8171@headitem 8172 8173Output kind 8174 8175@tab 8176 8177Typical suffix 8178 8179@item 8180 8181@pxref{e4,,GCC_JIT_OUTPUT_KIND_ASSEMBLER} 8182 8183@tab 8184 8185.s 8186 8187@item 8188 8189@pxref{e5,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE} 8190 8191@tab 8192 8193.o 8194 8195@item 8196 8197@pxref{e6,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY} 8198 8199@tab 8200 8201.so or .dll 8202 8203@item 8204 8205@pxref{e7,,GCC_JIT_OUTPUT_KIND_EXECUTABLE} 8206 8207@tab 8208 8209None, or .exe 8210 8211@end multitable 8212 8213 8214@geindex GCC_JIT_OUTPUT_KIND_ASSEMBLER (C macro) 8215@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{e4} 8216@deffn {C Macro} GCC_JIT_OUTPUT_KIND_ASSEMBLER 8217 8218Compile the context to an assembler file. 8219@end deffn 8220 8221@geindex GCC_JIT_OUTPUT_KIND_OBJECT_FILE (C macro) 8222@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{e5} 8223@deffn {C Macro} GCC_JIT_OUTPUT_KIND_OBJECT_FILE 8224 8225Compile the context to an object file. 8226@end deffn 8227 8228@geindex GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY (C macro) 8229@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{e6} 8230@deffn {C Macro} GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY 8231 8232Compile the context to a dynamic library. 8233 8234There is currently no support for specifying other libraries to link 8235against. 8236@end deffn 8237 8238@geindex GCC_JIT_OUTPUT_KIND_EXECUTABLE (C macro) 8239@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{e7} 8240@deffn {C Macro} GCC_JIT_OUTPUT_KIND_EXECUTABLE 8241 8242Compile the context to an executable. 8243 8244There is currently no support for specifying libraries to link 8245against. 8246@end deffn 8247 8248@c Copyright (C) 2015-2016 Free Software Foundation, Inc. 8249@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8250@c 8251@c This is free software: you can redistribute it and/or modify it 8252@c under the terms of the GNU General Public License as published by 8253@c the Free Software Foundation, either version 3 of the License, or 8254@c (at your option) any later version. 8255@c 8256@c This program is distributed in the hope that it will be useful, but 8257@c WITHOUT ANY WARRANTY; without even the implied warranty of 8258@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8259@c General Public License for more details. 8260@c 8261@c You should have received a copy of the GNU General Public License 8262@c along with this program. If not, see 8263@c <http://www.gnu.org/licenses/>. 8264 8265@node ABI and API compatibility,Performance,Compiling a context,Topic Reference 8266@anchor{topics/compatibility abi-and-api-compatibility}@anchor{e8}@anchor{topics/compatibility doc}@anchor{e9} 8267@section ABI and API compatibility 8268 8269 8270The libgccjit developers strive for ABI and API backward-compatibility: 8271programs built against libgccjit.so stand a good chance of running 8272without recompilation against newer versions of libgccjit.so, and 8273ought to recompile without modification against newer versions of 8274libgccjit.h. 8275 8276@cartouche 8277@quotation Note 8278The libgccjit++.h C++ API is more experimental, and less 8279locked-down at this time. 8280@end quotation 8281@end cartouche 8282 8283API compatibility is achieved by extending the API rather than changing 8284it. For ABI compatiblity, we avoid bumping the SONAME, and instead use 8285symbol versioning to tag each symbol, so that a binary linked against 8286libgccjit.so is tagged according to the symbols that it uses. 8287 8288For example, @pxref{72,,gcc_jit_context_add_command_line_option()} was added in 8289@code{LIBGCCJIT_ABI_1}. If a client program uses it, this can be detected 8290from metadata by using @code{objdump}: 8291 8292@example 8293$ objdump -p testsuite/jit/test-extra-options.c.exe | tail -n 8 8294 8295Version References: 8296 required from libgccjit.so.0: 8297 0x00824161 0x00 04 LIBGCCJIT_ABI_1 8298 0x00824160 0x00 03 LIBGCCJIT_ABI_0 8299 required from libc.so.6: 8300@end example 8301 8302@noindent 8303 8304You can see the symbol tags provided by libgccjit.so using @code{objdump}: 8305 8306@example 8307$ objdump -p libgccjit.so | less 8308[...snip...] 8309Version definitions: 83101 0x01 0x0ff81f20 libgccjit.so.0 83112 0x00 0x00824160 LIBGCCJIT_ABI_0 83123 0x00 0x00824161 LIBGCCJIT_ABI_1 8313 LIBGCCJIT_ABI_0 8314[...snip...] 8315@end example 8316 8317@noindent 8318 8319@menu 8320* ABI symbol tags:: 8321 8322ABI symbol tags 8323 8324* LIBGCCJIT_ABI_0:: 8325* LIBGCCJIT_ABI_1:: 8326* LIBGCCJIT_ABI_2:: 8327* LIBGCCJIT_ABI_3:: 8328* LIBGCCJIT_ABI_4:: 8329* LIBGCCJIT_ABI_5:: 8330 8331@end menu 8332 8333 8334@node ABI symbol tags,,,ABI and API compatibility 8335@anchor{topics/compatibility abi-symbol-tags}@anchor{ea} 8336@subsection ABI symbol tags 8337 8338 8339The initial release of libgccjit (in gcc 5.1) did not use symbol versioning. 8340 8341Newer releases use the following tags. 8342 8343@menu 8344* LIBGCCJIT_ABI_0:: 8345* LIBGCCJIT_ABI_1:: 8346* LIBGCCJIT_ABI_2:: 8347* LIBGCCJIT_ABI_3:: 8348* LIBGCCJIT_ABI_4:: 8349* LIBGCCJIT_ABI_5:: 8350 8351@end menu 8352 8353@node LIBGCCJIT_ABI_0,LIBGCCJIT_ABI_1,,ABI symbol tags 8354@anchor{topics/compatibility libgccjit-abi-0}@anchor{eb}@anchor{topics/compatibility id1}@anchor{ec} 8355@subsubsection @code{LIBGCCJIT_ABI_0} 8356 8357 8358All entrypoints in the initial release of libgccjit are tagged with 8359@code{LIBGCCJIT_ABI_0}, to signify the transition to symbol versioning. 8360 8361Binaries built against older copies of @code{libgccjit.so} should 8362continue to work, with this being handled transparently by the linker 8363(see this post@footnote{https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html}) 8364 8365@node LIBGCCJIT_ABI_1,LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_0,ABI symbol tags 8366@anchor{topics/compatibility libgccjit-abi-1}@anchor{73}@anchor{topics/compatibility id2}@anchor{ed} 8367@subsubsection @code{LIBGCCJIT_ABI_1} 8368 8369 8370@code{LIBGCCJIT_ABI_1} covers the addition of 8371@pxref{72,,gcc_jit_context_add_command_line_option()} 8372 8373@node LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_1,ABI symbol tags 8374@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c}@anchor{topics/compatibility id3}@anchor{ee} 8375@subsubsection @code{LIBGCCJIT_ABI_2} 8376 8377 8378@code{LIBGCCJIT_ABI_2} covers the addition of 8379@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()} 8380 8381@node LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_2,ABI symbol tags 8382@anchor{topics/compatibility libgccjit-abi-3}@anchor{da}@anchor{topics/compatibility id4}@anchor{ef} 8383@subsubsection @code{LIBGCCJIT_ABI_3} 8384 8385 8386@code{LIBGCCJIT_ABI_3} covers the addition of switch statements via API 8387entrypoints: 8388 8389@quotation 8390 8391 8392@itemize * 8393 8394@item 8395@pxref{d7,,gcc_jit_block_end_with_switch()} 8396 8397@item 8398@pxref{d8,,gcc_jit_case_as_object()} 8399 8400@item 8401@pxref{d9,,gcc_jit_context_new_case()} 8402@end itemize 8403@end quotation 8404 8405@node LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_3,ABI symbol tags 8406@anchor{topics/compatibility id5}@anchor{f0}@anchor{topics/compatibility libgccjit-abi-4}@anchor{f1} 8407@subsubsection @code{LIBGCCJIT_ABI_4} 8408 8409 8410@code{LIBGCCJIT_ABI_4} covers the addition of timers via API 8411entrypoints: 8412 8413@quotation 8414 8415 8416@itemize * 8417 8418@item 8419@pxref{f2,,gcc_jit_context_get_timer()} 8420 8421@item 8422@pxref{f3,,gcc_jit_context_set_timer()} 8423 8424@item 8425@pxref{f4,,gcc_jit_timer_new()} 8426 8427@item 8428@pxref{f5,,gcc_jit_timer_release()} 8429 8430@item 8431@pxref{f6,,gcc_jit_timer_push()} 8432 8433@item 8434@pxref{f7,,gcc_jit_timer_pop()} 8435 8436@item 8437@pxref{f8,,gcc_jit_timer_print()} 8438@end itemize 8439@end quotation 8440 8441@node LIBGCCJIT_ABI_5,,LIBGCCJIT_ABI_4,ABI symbol tags 8442@anchor{topics/compatibility id6}@anchor{f9}@anchor{topics/compatibility libgccjit-abi-5}@anchor{6e} 8443@subsubsection @code{LIBGCCJIT_ABI_5} 8444 8445 8446@code{LIBGCCJIT_ABI_5} covers the addition of 8447@pxref{6d,,gcc_jit_context_set_bool_use_external_driver()} 8448 8449@c Copyright (C) 2015-2016 Free Software Foundation, Inc. 8450@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8451@c 8452@c This is free software: you can redistribute it and/or modify it 8453@c under the terms of the GNU General Public License as published by 8454@c the Free Software Foundation, either version 3 of the License, or 8455@c (at your option) any later version. 8456@c 8457@c This program is distributed in the hope that it will be useful, but 8458@c WITHOUT ANY WARRANTY; without even the implied warranty of 8459@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8460@c General Public License for more details. 8461@c 8462@c You should have received a copy of the GNU General Public License 8463@c along with this program. If not, see 8464@c <http://www.gnu.org/licenses/>. 8465 8466@node Performance,,ABI and API compatibility,Topic Reference 8467@anchor{topics/performance performance}@anchor{fa}@anchor{topics/performance doc}@anchor{fb} 8468@section Performance 8469 8470 8471@menu 8472* The timing API:: 8473 8474@end menu 8475 8476@node The timing API,,,Performance 8477@anchor{topics/performance the-timing-api}@anchor{fc} 8478@subsection The timing API 8479 8480 8481As of GCC 6, libgccjit exposes a timing API, for printing reports on 8482how long was spent in different parts of code. 8483 8484You can create a @pxref{fd,,gcc_jit_timer} instance, which will 8485measure time spent since its creation. The timer maintains a stack 8486of "timer items": as control flow moves through your code, you can push 8487and pop named items relating to your code onto the stack, and the timer 8488will account the time spent accordingly. 8489 8490You can also asssociate a timer with a @pxref{8,,gcc_jit_context}, in 8491which case the time spent inside compilation will be subdivided. 8492 8493For example, the following code uses a timer, recording client items 8494"create_code", "compile", and "running code": 8495 8496@example 8497/* Create a timer. */ 8498gcc_jit_timer *timer = gcc_jit_timer_new (); 8499if (!timer) 8500 @{ 8501 error ("gcc_jit_timer_new failed"); 8502 return -1; 8503 @} 8504 8505/* Let's repeatedly compile and run some code, accumulating it 8506 all into the timer. */ 8507for (int i = 0; i < num_iterations; i++) 8508 @{ 8509 /* Create a context and associate it with the timer. */ 8510 gcc_jit_context *ctxt = gcc_jit_context_acquire (); 8511 if (!ctxt) 8512 @{ 8513 error ("gcc_jit_context_acquire failed"); 8514 return -1; 8515 @} 8516 gcc_jit_context_set_timer (ctxt, timer); 8517 8518 /* Populate the context, timing it as client item "create_code". */ 8519 gcc_jit_timer_push (timer, "create_code"); 8520 create_code (ctxt); 8521 gcc_jit_timer_pop (timer, "create_code"); 8522 8523 /* Compile the context, timing it as client item "compile". */ 8524 gcc_jit_timer_push (timer, "compile"); 8525 result = gcc_jit_context_compile (ctxt); 8526 gcc_jit_timer_pop (timer, "compile"); 8527 8528 /* Run the generated code, timing it as client item "running code". */ 8529 gcc_jit_timer_push (timer, "running code"); 8530 run_the_code (ctxt, result); 8531 gcc_jit_timer_pop (timer, "running code"); 8532 8533 /* Clean up. */ 8534 gcc_jit_context_release (ctxt); 8535 gcc_jit_result_release (result); 8536@} 8537 8538/* Print the accumulated timings. */ 8539gcc_jit_timer_print (timer, stderr); 8540gcc_jit_timer_release (timer); 8541@end example 8542 8543@noindent 8544 8545giving output like this, showing the internal GCC items at the top, then 8546client items, then the total: 8547 8548@example 8549Execution times (seconds) 8550GCC items: 8551 phase setup : 0.29 (14%) usr 0.00 ( 0%) sys 0.32 ( 5%) wall 10661 kB (50%) ggc 8552 phase parsing : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 653 kB ( 3%) ggc 8553 phase finalize : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8554 dump files : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc 8555 callgraph construction : 0.02 ( 1%) usr 0.01 ( 6%) sys 0.01 ( 0%) wall 242 kB ( 1%) ggc 8556 callgraph optimization : 0.03 ( 2%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 142 kB ( 1%) ggc 8557 trivially dead code : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8558 df scan insns : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 9 kB ( 0%) ggc 8559 df live regs : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc 8560 inline parameters : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 82 kB ( 0%) ggc 8561 tree CFG cleanup : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8562 tree PHI insertion : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 64 kB ( 0%) ggc 8563 tree SSA other : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 18 kB ( 0%) ggc 8564 expand : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 398 kB ( 2%) ggc 8565 jump : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8566 loop init : 0.01 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 67 kB ( 0%) ggc 8567 integrated RA : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 2468 kB (12%) ggc 8568 thread pro- & epilogue : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 162 kB ( 1%) ggc 8569 final : 0.01 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 216 kB ( 1%) ggc 8570 rest of compilation : 1.37 (69%) usr 0.00 ( 0%) sys 1.13 (18%) wall 1391 kB ( 6%) ggc 8571 assemble JIT code : 0.01 ( 1%) usr 0.00 ( 0%) sys 4.04 (66%) wall 0 kB ( 0%) ggc 8572 load JIT result : 0.02 ( 1%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8573 JIT client code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8574Client items: 8575 create_code : 0.00 ( 0%) usr 0.01 ( 6%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8576 compile : 0.36 (18%) usr 0.15 (83%) sys 0.86 (14%) wall 14939 kB (70%) ggc 8577 running code : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 0 kB ( 0%) ggc 8578 TOTAL : 2.00 0.18 6.12 21444 kB 8579@end example 8580 8581@noindent 8582 8583The exact format is intended to be human-readable, and is subject to change. 8584 8585@geindex LIBGCCJIT_HAVE_TIMING_API (C macro) 8586@anchor{topics/performance LIBGCCJIT_HAVE_TIMING_API}@anchor{fe} 8587@deffn {C Macro} LIBGCCJIT_HAVE_TIMING_API 8588 8589The timer API was added to libgccjit in GCC 6. 8590This macro is only defined in versions of libgccjit.h which have the 8591timer API, and so can be used to guard code that may need to compile 8592against earlier releases: 8593 8594@example 8595#ifdef LIBGCCJIT_HAVE_TIMING_API 8596gcc_jit_timer *t = gcc_jit_timer_new (); 8597gcc_jit_context_set_timer (ctxt, t); 8598#endif 8599@end example 8600 8601@noindent 8602@end deffn 8603 8604@geindex gcc_jit_timer (C type) 8605@anchor{topics/performance gcc_jit_timer}@anchor{fd} 8606@deffn {C Type} gcc_jit_timer 8607@end deffn 8608 8609@geindex gcc_jit_timer_new (C function) 8610@anchor{topics/performance gcc_jit_timer_new}@anchor{f4} 8611@deffn {C Function} gcc_jit_timer * gcc_jit_timer_new (void) 8612 8613Create a @pxref{fd,,gcc_jit_timer} instance, and start timing: 8614 8615@example 8616gcc_jit_timer *t = gcc_jit_timer_new (); 8617@end example 8618 8619@noindent 8620 8621This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test 8622for its presence using 8623 8624@example 8625#ifdef LIBGCCJIT_HAVE_TIMING_API 8626@end example 8627 8628@noindent 8629@end deffn 8630 8631@geindex gcc_jit_timer_release (C function) 8632@anchor{topics/performance gcc_jit_timer_release}@anchor{f5} 8633@deffn {C Function} void gcc_jit_timer_release (gcc_jit_timer@w{ }*timer) 8634 8635Release a @pxref{fd,,gcc_jit_timer} instance: 8636 8637@example 8638gcc_jit_timer_release (t); 8639@end example 8640 8641@noindent 8642 8643This should be called exactly once on a timer. 8644 8645This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test 8646for its presence using 8647 8648@example 8649#ifdef LIBGCCJIT_HAVE_TIMING_API 8650@end example 8651 8652@noindent 8653@end deffn 8654 8655@geindex gcc_jit_context_set_timer (C function) 8656@anchor{topics/performance gcc_jit_context_set_timer}@anchor{f3} 8657@deffn {C Function} void gcc_jit_context_set_timer (gcc_jit_context@w{ }*ctxt, gcc_jit_timer@w{ }*timer) 8658 8659Associate a @pxref{fd,,gcc_jit_timer} instance with a context: 8660 8661@example 8662gcc_jit_context_set_timer (ctxt, t); 8663@end example 8664 8665@noindent 8666 8667A timer instance can be shared between multiple 8668@pxref{8,,gcc_jit_context} instances. 8669 8670Timers have no locking, so if you have a multithreaded program, you 8671must provide your own locks if more than one thread could be working 8672with the same timer via timer-associated contexts. 8673 8674This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test 8675for its presence using 8676 8677@example 8678#ifdef LIBGCCJIT_HAVE_TIMING_API 8679@end example 8680 8681@noindent 8682@end deffn 8683 8684@geindex gcc_jit_context_get_timer (C function) 8685@anchor{topics/performance gcc_jit_context_get_timer}@anchor{f2} 8686@deffn {C Function} gcc_jit_timer *gcc_jit_context_get_timer (gcc_jit_context@w{ }*ctxt) 8687 8688Get the timer associated with a context (if any). 8689 8690This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test 8691for its presence using 8692 8693@example 8694#ifdef LIBGCCJIT_HAVE_TIMING_API 8695@end example 8696 8697@noindent 8698@end deffn 8699 8700@geindex gcc_jit_timer_push (C function) 8701@anchor{topics/performance gcc_jit_timer_push}@anchor{f6} 8702@deffn {C Function} void gcc_jit_timer_push (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name) 8703 8704Push the given item onto the timer's stack: 8705 8706@example 8707gcc_jit_timer_push (t, "running code"); 8708run_the_code (ctxt, result); 8709gcc_jit_timer_pop (t, "running code"); 8710@end example 8711 8712@noindent 8713 8714This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test 8715for its presence using 8716 8717@example 8718#ifdef LIBGCCJIT_HAVE_TIMING_API 8719@end example 8720 8721@noindent 8722@end deffn 8723 8724@geindex gcc_jit_timer_pop (C function) 8725@anchor{topics/performance gcc_jit_timer_pop}@anchor{f7} 8726@deffn {C Function} void gcc_jit_timer_pop (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name) 8727 8728Pop the top item from the timer's stack. 8729 8730If "item_name" is provided, it must match that of the top item. 8731Alternatively, @code{NULL} can be passed in, to suppress checking. 8732 8733This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test 8734for its presence using 8735 8736@example 8737#ifdef LIBGCCJIT_HAVE_TIMING_API 8738@end example 8739 8740@noindent 8741@end deffn 8742 8743@geindex gcc_jit_timer_print (C function) 8744@anchor{topics/performance gcc_jit_timer_print}@anchor{f8} 8745@deffn {C Function} void gcc_jit_timer_print (gcc_jit_timer@w{ }*timer, FILE@w{ }*f_out) 8746 8747Print timing information to the given stream about activity since 8748the timer was started. 8749 8750This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test 8751for its presence using 8752 8753@example 8754#ifdef LIBGCCJIT_HAVE_TIMING_API 8755@end example 8756 8757@noindent 8758@end deffn 8759 8760@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 8761@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8762@c 8763@c This is free software: you can redistribute it and/or modify it 8764@c under the terms of the GNU General Public License as published by 8765@c the Free Software Foundation, either version 3 of the License, or 8766@c (at your option) any later version. 8767@c 8768@c This program is distributed in the hope that it will be useful, but 8769@c WITHOUT ANY WARRANTY; without even the implied warranty of 8770@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8771@c General Public License for more details. 8772@c 8773@c You should have received a copy of the GNU General Public License 8774@c along with this program. If not, see 8775@c <http://www.gnu.org/licenses/>. 8776 8777@node C++ bindings for libgccjit,Internals,Topic Reference,Top 8778@anchor{cp/index c-bindings-for-libgccjit}@anchor{ff}@anchor{cp/index doc}@anchor{100} 8779@chapter C++ bindings for libgccjit 8780 8781 8782This document describes the C++ bindings to 8783libgccjit@footnote{http://gcc.gnu.org/wiki/JIT}, an API for embedding GCC 8784inside programs and libraries. 8785 8786The C++ bindings consist of a single header file @code{libgccjit++.h}. 8787 8788This is a collection of "thin" wrapper classes around the C API. 8789Everything is an inline function, implemented in terms of the C API, 8790so there is nothing extra to link against. 8791 8792Note that libgccjit is currently of "Alpha" quality; 8793the APIs are not yet set in stone, and they shouldn't be used in 8794production yet. 8795 8796Contents: 8797 8798@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 8799@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8800@c 8801@c This is free software: you can redistribute it and/or modify it 8802@c under the terms of the GNU General Public License as published by 8803@c the Free Software Foundation, either version 3 of the License, or 8804@c (at your option) any later version. 8805@c 8806@c This program is distributed in the hope that it will be useful, but 8807@c WITHOUT ANY WARRANTY; without even the implied warranty of 8808@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8809@c General Public License for more details. 8810@c 8811@c You should have received a copy of the GNU General Public License 8812@c along with this program. If not, see 8813@c <http://www.gnu.org/licenses/>. 8814 8815@menu 8816* Tutorial: Tutorial<2>. 8817* Topic Reference: Topic Reference<2>. 8818 8819Tutorial 8820 8821* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 8822* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 8823* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 8824* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 8825 8826Tutorial part 2: Creating a trivial machine code function 8827 8828* Options: Options<3>. 8829* Full example: Full example<3>. 8830 8831Tutorial part 3: Loops and variables 8832 8833* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 8834* Control flow: Control flow<2>. 8835* Visualizing the control flow graph: Visualizing the control flow graph<2>. 8836* Full example: Full example<4>. 8837 8838Tutorial part 4: Adding JIT-compilation to a toy interpreter 8839 8840* Our toy interpreter: Our toy interpreter<2>. 8841* Compiling to machine code: Compiling to machine code<2>. 8842* Setting things up: Setting things up<2>. 8843* Populating the function: Populating the function<2>. 8844* Verifying the control flow graph: Verifying the control flow graph<2>. 8845* Compiling the context: Compiling the context<2>. 8846* Single-stepping through the generated code: Single-stepping through the generated code<2>. 8847* Examining the generated code: Examining the generated code<2>. 8848* Putting it all together: Putting it all together<2>. 8849* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 8850 8851Behind the curtain: How does our code get optimized? 8852 8853* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 8854* Elimination of tail recursion: Elimination of tail recursion<2>. 8855 8856Topic Reference 8857 8858* Compilation contexts: Compilation contexts<2>. 8859* Objects: Objects<2>. 8860* Types: Types<2>. 8861* Expressions: Expressions<2>. 8862* Creating and using functions: Creating and using functions<2>. 8863* Source Locations: Source Locations<2>. 8864* Compiling a context: Compiling a context<2>. 8865 8866Compilation contexts 8867 8868* Lifetime-management: Lifetime-management<2>. 8869* Thread-safety: Thread-safety<2>. 8870* Error-handling: Error-handling<3>. 8871* Debugging: Debugging<2>. 8872* Options: Options<4>. 8873 8874Options 8875 8876* String Options: String Options<2>. 8877* Boolean options: Boolean options<2>. 8878* Integer options: Integer options<2>. 8879* Additional command-line options: Additional command-line options<2>. 8880 8881Types 8882 8883* Standard types: Standard types<2>. 8884* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 8885* Structures and unions: Structures and unions<2>. 8886 8887Expressions 8888 8889* Rvalues: Rvalues<2>. 8890* Lvalues: Lvalues<2>. 8891* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 8892 8893Rvalues 8894 8895* Simple expressions: Simple expressions<2>. 8896* Unary Operations: Unary Operations<2>. 8897* Binary Operations: Binary Operations<2>. 8898* Comparisons: Comparisons<2>. 8899* Function calls: Function calls<2>. 8900* Type-coercion: Type-coercion<2>. 8901 8902Lvalues 8903 8904* Global variables: Global variables<2>. 8905 8906Creating and using functions 8907 8908* Params: Params<2>. 8909* Functions: Functions<2>. 8910* Blocks: Blocks<2>. 8911* Statements: Statements<2>. 8912 8913Source Locations 8914 8915* Faking it: Faking it<2>. 8916 8917Compiling a context 8918 8919* In-memory compilation: In-memory compilation<2>. 8920* Ahead-of-time compilation: Ahead-of-time compilation<2>. 8921 8922@end menu 8923 8924 8925@node Tutorial<2>,Topic Reference<2>,,C++ bindings for libgccjit 8926@anchor{cp/intro/index doc}@anchor{101}@anchor{cp/intro/index tutorial}@anchor{102} 8927@section Tutorial 8928 8929 8930@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 8931@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 8932@c 8933@c This is free software: you can redistribute it and/or modify it 8934@c under the terms of the GNU General Public License as published by 8935@c the Free Software Foundation, either version 3 of the License, or 8936@c (at your option) any later version. 8937@c 8938@c This program is distributed in the hope that it will be useful, but 8939@c WITHOUT ANY WARRANTY; without even the implied warranty of 8940@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8941@c General Public License for more details. 8942@c 8943@c You should have received a copy of the GNU General Public License 8944@c along with this program. If not, see 8945@c <http://www.gnu.org/licenses/>. 8946 8947@menu 8948* Tutorial part 1; "Hello world": Tutorial part 1 "Hello world"<2>. 8949* Tutorial part 2; Creating a trivial machine code function: Tutorial part 2 Creating a trivial machine code function<2>. 8950* Tutorial part 3; Loops and variables: Tutorial part 3 Loops and variables<2>. 8951* Tutorial part 4; Adding JIT-compilation to a toy interpreter: Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>. 8952 8953@end menu 8954 8955@node Tutorial part 1 "Hello world"<2>,Tutorial part 2 Creating a trivial machine code function<2>,,Tutorial<2> 8956@anchor{cp/intro/tutorial01 doc}@anchor{103}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{104} 8957@subsection Tutorial part 1: "Hello world" 8958 8959 8960Before we look at the details of the API, let's look at building and 8961running programs that use the library. 8962 8963Here's a toy "hello world" program that uses the library's C++ API to 8964synthesize a call to @cite{printf} and uses it to write a message to stdout. 8965 8966Don't worry about the content of the program for now; we'll cover 8967the details in later parts of this tutorial. 8968 8969@quotation 8970 8971@example 8972/* Smoketest example for libgccjit.so C++ API 8973 Copyright (C) 2014-2016 Free Software Foundation, Inc. 8974 8975This file is part of GCC. 8976 8977GCC is free software; you can redistribute it and/or modify it 8978under the terms of the GNU General Public License as published by 8979the Free Software Foundation; either version 3, or (at your option) 8980any later version. 8981 8982GCC is distributed in the hope that it will be useful, but 8983WITHOUT ANY WARRANTY; without even the implied warranty of 8984MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 8985General Public License for more details. 8986 8987You should have received a copy of the GNU General Public License 8988along with GCC; see the file COPYING3. If not see 8989<http://www.gnu.org/licenses/>. */ 8990 8991#include <libgccjit++.h> 8992 8993#include <stdlib.h> 8994#include <stdio.h> 8995 8996static void 8997create_code (gccjit::context ctxt) 8998@{ 8999 /* Let's try to inject the equivalent of this C code: 9000 void 9001 greet (const char *name) 9002 @{ 9003 printf ("hello %s\n", name); 9004 @} 9005 */ 9006 gccjit::type void_type = ctxt.get_type (GCC_JIT_TYPE_VOID); 9007 gccjit::type const_char_ptr_type = 9008 ctxt.get_type (GCC_JIT_TYPE_CONST_CHAR_PTR); 9009 gccjit::param param_name = 9010 ctxt.new_param (const_char_ptr_type, "name"); 9011 std::vector<gccjit::param> func_params; 9012 func_params.push_back (param_name); 9013 gccjit::function func = 9014 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9015 void_type, 9016 "greet", 9017 func_params, 0); 9018 9019 gccjit::param param_format = 9020 ctxt.new_param (const_char_ptr_type, "format"); 9021 std::vector<gccjit::param> printf_params; 9022 printf_params.push_back (param_format); 9023 gccjit::function printf_func = 9024 ctxt.new_function (GCC_JIT_FUNCTION_IMPORTED, 9025 ctxt.get_type (GCC_JIT_TYPE_INT), 9026 "printf", 9027 printf_params, 1); 9028 9029 gccjit::block block = func.new_block (); 9030 block.add_eval (ctxt.new_call (printf_func, 9031 ctxt.new_rvalue ("hello %s\n"), 9032 param_name)); 9033 block.end_with_return (); 9034@} 9035 9036int 9037main (int argc, char **argv) 9038@{ 9039 gccjit::context ctxt; 9040 gcc_jit_result *result; 9041 9042 /* Get a "context" object for working with the library. */ 9043 ctxt = gccjit::context::acquire (); 9044 9045 /* Set some options on the context. 9046 Turn this on to see the code being generated, in assembler form. */ 9047 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 0); 9048 9049 /* Populate the context. */ 9050 create_code (ctxt); 9051 9052 /* Compile the code. */ 9053 result = ctxt.compile (); 9054 if (!result) 9055 @{ 9056 fprintf (stderr, "NULL result"); 9057 exit (1); 9058 @} 9059 9060 ctxt.release (); 9061 9062 /* Extract the generated code from "result". */ 9063 typedef void (*fn_type) (const char *); 9064 fn_type greet = 9065 (fn_type)gcc_jit_result_get_code (result, "greet"); 9066 if (!greet) 9067 @{ 9068 fprintf (stderr, "NULL greet"); 9069 exit (1); 9070 @} 9071 9072 /* Now call the generated function: */ 9073 greet ("world"); 9074 fflush (stdout); 9075 9076 gcc_jit_result_release (result); 9077 return 0; 9078@} 9079 9080@end example 9081 9082@noindent 9083@end quotation 9084 9085Copy the above to @cite{tut01-hello-world.cc}. 9086 9087Assuming you have the jit library installed, build the test program 9088using: 9089 9090@example 9091$ gcc \ 9092 tut01-hello-world.cc \ 9093 -o tut01-hello-world \ 9094 -lgccjit 9095@end example 9096 9097@noindent 9098 9099You should then be able to run the built program: 9100 9101@example 9102$ ./tut01-hello-world 9103hello world 9104@end example 9105 9106@noindent 9107 9108@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 9109@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9110@c 9111@c This is free software: you can redistribute it and/or modify it 9112@c under the terms of the GNU General Public License as published by 9113@c the Free Software Foundation, either version 3 of the License, or 9114@c (at your option) any later version. 9115@c 9116@c This program is distributed in the hope that it will be useful, but 9117@c WITHOUT ANY WARRANTY; without even the implied warranty of 9118@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9119@c General Public License for more details. 9120@c 9121@c You should have received a copy of the GNU General Public License 9122@c along with this program. If not, see 9123@c <http://www.gnu.org/licenses/>. 9124 9125@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> 9126@anchor{cp/intro/tutorial02 doc}@anchor{105}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{106} 9127@subsection Tutorial part 2: Creating a trivial machine code function 9128 9129 9130Consider this C function: 9131 9132@example 9133int square (int i) 9134@{ 9135 return i * i; 9136@} 9137@end example 9138 9139@noindent 9140 9141How can we construct this at run-time using libgccjit's C++ API? 9142 9143First we need to include the relevant header: 9144 9145@example 9146#include <libgccjit++.h> 9147@end example 9148 9149@noindent 9150 9151All state associated with compilation is associated with a 9152@code{gccjit::context}, which is a thin C++ wrapper around the C API's 9153@pxref{8,,gcc_jit_context *}. 9154 9155Create one using @pxref{107,,gccjit;;context;;acquire()}: 9156 9157@example 9158gccjit::context ctxt; 9159ctxt = gccjit::context::acquire (); 9160@end example 9161 9162@noindent 9163 9164The JIT library has a system of types. It is statically-typed: every 9165expression is of a specific type, fixed at compile-time. In our example, 9166all of the expressions are of the C @cite{int} type, so let's obtain this from 9167the context, as a @code{gccjit::type}, using 9168@pxref{108,,gccjit;;context;;get_type()}: 9169 9170@example 9171gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 9172@end example 9173 9174@noindent 9175 9176@code{gccjit::type} is an example of a "contextual" object: every 9177entity in the API is associated with a @code{gccjit::context}. 9178 9179Memory management is easy: all such "contextual" objects are automatically 9180cleaned up for you when the context is released, using 9181@pxref{109,,gccjit;;context;;release()}: 9182 9183@example 9184ctxt.release (); 9185@end example 9186 9187@noindent 9188 9189so you don't need to manually track and cleanup all objects, just the 9190contexts. 9191 9192All of the C++ classes in the API are thin wrappers around pointers to 9193types in the C API. 9194 9195The C++ class hierarchy within the @code{gccjit} namespace looks like this: 9196 9197@example 9198+- object 9199 +- location 9200 +- type 9201 +- struct 9202 +- field 9203 +- function 9204 +- block 9205 +- rvalue 9206 +- lvalue 9207 +- param 9208@end example 9209 9210@noindent 9211 9212One thing you can do with a @code{gccjit::object} is 9213to ask it for a human-readable description as a @code{std::string}, using 9214@pxref{10a,,gccjit;;object;;get_debug_string()}: 9215 9216@example 9217printf ("obj: %s\n", obj.get_debug_string ().c_str ()); 9218@end example 9219 9220@noindent 9221 9222giving this text on stdout: 9223 9224@example 9225obj: int 9226@end example 9227 9228@noindent 9229 9230This is invaluable when debugging. 9231 9232Let's create the function. To do so, we first need to construct 9233its single parameter, specifying its type and giving it a name, 9234using @pxref{10b,,gccjit;;context;;new_param()}: 9235 9236@example 9237gccjit::param param_i = ctxt.new_param (int_type, "i"); 9238@end example 9239 9240@noindent 9241 9242and we can then make a vector of all of the params of the function, 9243in this case just one: 9244 9245@example 9246std::vector<gccjit::param> params; 9247params.push_back (param_i); 9248@end example 9249 9250@noindent 9251 9252Now we can create the function, using 9253@code{gccjit::context::new_function()}: 9254 9255@example 9256gccjit::function func = 9257 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9258 int_type, 9259 "square", 9260 params, 9261 0); 9262@end example 9263 9264@noindent 9265 9266To define the code within the function, we must create basic blocks 9267containing statements. 9268 9269Every basic block contains a list of statements, eventually terminated 9270by a statement that either returns, or jumps to another basic block. 9271 9272Our function has no control-flow, so we just need one basic block: 9273 9274@example 9275gccjit::block block = func.new_block (); 9276@end example 9277 9278@noindent 9279 9280Our basic block is relatively simple: it immediately terminates by 9281returning the value of an expression. 9282 9283We can build the expression using @pxref{10c,,gccjit;;context;;new_binary_op()}: 9284 9285@example 9286gccjit::rvalue expr = 9287 ctxt.new_binary_op ( 9288 GCC_JIT_BINARY_OP_MULT, int_type, 9289 param_i, param_i); 9290@end example 9291 9292@noindent 9293 9294A @code{gccjit::rvalue} is another example of a 9295@code{gccjit::object} subclass. As before, we can print it with 9296@pxref{10a,,gccjit;;object;;get_debug_string()}. 9297 9298@example 9299printf ("expr: %s\n", expr.get_debug_string ().c_str ()); 9300@end example 9301 9302@noindent 9303 9304giving this output: 9305 9306@example 9307expr: i * i 9308@end example 9309 9310@noindent 9311 9312Note that @code{gccjit::rvalue} provides numerous overloaded operators 9313which can be used to dramatically reduce the amount of typing needed. 9314We can build the above binary operation more directly with this one-liner: 9315 9316@example 9317gccjit::rvalue expr = param_i * param_i; 9318@end example 9319 9320@noindent 9321 9322Creating the expression in itself doesn't do anything; we have to add 9323this expression to a statement within the block. In this case, we use it 9324to build a return statement, which terminates the basic block: 9325 9326@example 9327block.end_with_return (expr); 9328@end example 9329 9330@noindent 9331 9332OK, we've populated the context. We can now compile it using 9333@pxref{10d,,gccjit;;context;;compile()}: 9334 9335@example 9336gcc_jit_result *result; 9337result = ctxt.compile (); 9338@end example 9339 9340@noindent 9341 9342and get a @pxref{16,,gcc_jit_result *}. 9343 9344We can now use @pxref{17,,gcc_jit_result_get_code()} to look up a specific 9345machine code routine within the result, in this case, the function we 9346created above. 9347 9348@example 9349void *fn_ptr = gcc_jit_result_get_code (result, "square"); 9350if (!fn_ptr) 9351 @{ 9352 fprintf (stderr, "NULL fn_ptr"); 9353 goto error; 9354 @} 9355@end example 9356 9357@noindent 9358 9359We can now cast the pointer to an appropriate function pointer type, and 9360then call it: 9361 9362@example 9363typedef int (*fn_type) (int); 9364fn_type square = (fn_type)fn_ptr; 9365printf ("result: %d", square (5)); 9366@end example 9367 9368@noindent 9369 9370@example 9371result: 25 9372@end example 9373 9374@noindent 9375 9376@menu 9377* Options: Options<3>. 9378* Full example: Full example<3>. 9379 9380@end menu 9381 9382@node Options<3>,Full example<3>,,Tutorial part 2 Creating a trivial machine code function<2> 9383@anchor{cp/intro/tutorial02 options}@anchor{10e} 9384@subsubsection Options 9385 9386 9387To get more information on what's going on, you can set debugging flags 9388on the context using @pxref{10f,,gccjit;;context;;set_bool_option()}. 9389 9390@c (I'm deliberately not mentioning 9391@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think 9392@c it's probably more of use to implementors than to users) 9393 9394Setting @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE} will dump a 9395C-like representation to stderr when you compile (GCC's "GIMPLE" 9396representation): 9397 9398@example 9399ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); 9400result = ctxt.compile (); 9401@end example 9402 9403@noindent 9404 9405@example 9406square (signed int i) 9407@{ 9408 signed int D.260; 9409 9410 entry: 9411 D.260 = i * i; 9412 return D.260; 9413@} 9414@end example 9415 9416@noindent 9417 9418We can see the generated machine code in assembler form (on stderr) by 9419setting @pxref{1d,,GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE} on the context 9420before compiling: 9421 9422@example 9423ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); 9424result = ctxt.compile (); 9425@end example 9426 9427@noindent 9428 9429@example 9430 .file "fake.c" 9431 .text 9432 .globl square 9433 .type square, @@function 9434square: 9435.LFB6: 9436 .cfi_startproc 9437 pushq %rbp 9438 .cfi_def_cfa_offset 16 9439 .cfi_offset 6, -16 9440 movq %rsp, %rbp 9441 .cfi_def_cfa_register 6 9442 movl %edi, -4(%rbp) 9443.L14: 9444 movl -4(%rbp), %eax 9445 imull -4(%rbp), %eax 9446 popq %rbp 9447 .cfi_def_cfa 7, 8 9448 ret 9449 .cfi_endproc 9450.LFE6: 9451 .size square, .-square 9452 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 9453 .section .note.GNU-stack,"",@@progbits 9454@end example 9455 9456@noindent 9457 9458By default, no optimizations are performed, the equivalent of GCC's 9459@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling 9460@pxref{110,,gccjit;;context;;set_int_option()} with 9461@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 9462 9463@example 9464ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); 9465@end example 9466 9467@noindent 9468 9469@example 9470 .file "fake.c" 9471 .text 9472 .p2align 4,,15 9473 .globl square 9474 .type square, @@function 9475square: 9476.LFB7: 9477 .cfi_startproc 9478.L16: 9479 movl %edi, %eax 9480 imull %edi, %eax 9481 ret 9482 .cfi_endproc 9483.LFE7: 9484 .size square, .-square 9485 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-0.5.1920c315ff984892399893b380305ab36e07b455.fc20)" 9486 .section .note.GNU-stack,"",@@progbits 9487@end example 9488 9489@noindent 9490 9491Naturally this has only a small effect on such a trivial function. 9492 9493@node Full example<3>,,Options<3>,Tutorial part 2 Creating a trivial machine code function<2> 9494@anchor{cp/intro/tutorial02 full-example}@anchor{111} 9495@subsubsection Full example 9496 9497 9498Here's what the above looks like as a complete program: 9499 9500@quotation 9501 9502@example 9503/* Usage example for libgccjit.so's C++ API 9504 Copyright (C) 2014-2016 Free Software Foundation, Inc. 9505 9506This file is part of GCC. 9507 9508GCC is free software; you can redistribute it and/or modify it 9509under the terms of the GNU General Public License as published by 9510the Free Software Foundation; either version 3, or (at your option) 9511any later version. 9512 9513GCC is distributed in the hope that it will be useful, but 9514WITHOUT ANY WARRANTY; without even the implied warranty of 9515MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9516General Public License for more details. 9517 9518You should have received a copy of the GNU General Public License 9519along with GCC; see the file COPYING3. If not see 9520<http://www.gnu.org/licenses/>. */ 9521 9522#include <libgccjit++.h> 9523 9524#include <stdlib.h> 9525#include <stdio.h> 9526 9527void 9528create_code (gccjit::context ctxt) 9529@{ 9530 /* Let's try to inject the equivalent of this C code: 9531 9532 int square (int i) 9533 @{ 9534 return i * i; 9535 @} 9536 */ 9537 gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 9538 gccjit::param param_i = ctxt.new_param (int_type, "i"); 9539 std::vector<gccjit::param> params; 9540 params.push_back (param_i); 9541 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9542 int_type, 9543 "square", 9544 params, 0); 9545 9546 gccjit::block block = func.new_block (); 9547 9548 gccjit::rvalue expr = 9549 ctxt.new_binary_op (GCC_JIT_BINARY_OP_MULT, int_type, 9550 param_i, param_i); 9551 9552 block.end_with_return (expr); 9553@} 9554 9555int 9556main (int argc, char **argv) 9557@{ 9558 /* Get a "context" object for working with the library. */ 9559 gccjit::context ctxt = gccjit::context::acquire (); 9560 9561 /* Set some options on the context. 9562 Turn this on to see the code being generated, in assembler form. */ 9563 ctxt.set_bool_option ( 9564 GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 9565 0); 9566 9567 /* Populate the context. */ 9568 create_code (ctxt); 9569 9570 /* Compile the code. */ 9571 gcc_jit_result *result = ctxt.compile (); 9572 9573 /* We're done with the context; we can release it: */ 9574 ctxt.release (); 9575 9576 if (!result) 9577 @{ 9578 fprintf (stderr, "NULL result"); 9579 return 1; 9580 @} 9581 9582 /* Extract the generated code from "result". */ 9583 void *fn_ptr = gcc_jit_result_get_code (result, "square"); 9584 if (!fn_ptr) 9585 @{ 9586 fprintf (stderr, "NULL fn_ptr"); 9587 gcc_jit_result_release (result); 9588 return 1; 9589 @} 9590 9591 typedef int (*fn_type) (int); 9592 fn_type square = (fn_type)fn_ptr; 9593 printf ("result: %d\n", square (5)); 9594 9595 gcc_jit_result_release (result); 9596 return 0; 9597@} 9598 9599@end example 9600 9601@noindent 9602@end quotation 9603 9604Building and running it: 9605 9606@example 9607$ gcc \ 9608 tut02-square.cc \ 9609 -o tut02-square \ 9610 -lgccjit 9611 9612# Run the built program: 9613$ ./tut02-square 9614result: 25 9615@end example 9616 9617@noindent 9618 9619@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 9620@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 9621@c 9622@c This is free software: you can redistribute it and/or modify it 9623@c under the terms of the GNU General Public License as published by 9624@c the Free Software Foundation, either version 3 of the License, or 9625@c (at your option) any later version. 9626@c 9627@c This program is distributed in the hope that it will be useful, but 9628@c WITHOUT ANY WARRANTY; without even the implied warranty of 9629@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9630@c General Public License for more details. 9631@c 9632@c You should have received a copy of the GNU General Public License 9633@c along with this program. If not, see 9634@c <http://www.gnu.org/licenses/>. 9635 9636@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> 9637@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{112}@anchor{cp/intro/tutorial03 doc}@anchor{113} 9638@subsection Tutorial part 3: Loops and variables 9639 9640 9641Consider this C function: 9642 9643@quotation 9644 9645@example 9646int loop_test (int n) 9647@{ 9648 int sum = 0; 9649 for (int i = 0; i < n; i++) 9650 sum += i * i; 9651 return sum; 9652@} 9653@end example 9654 9655@noindent 9656@end quotation 9657 9658This example demonstrates some more features of libgccjit, with local 9659variables and a loop. 9660 9661To break this down into libgccjit terms, it's usually easier to reword 9662the @cite{for} loop as a @cite{while} loop, giving: 9663 9664@quotation 9665 9666@example 9667int loop_test (int n) 9668@{ 9669 int sum = 0; 9670 int i = 0; 9671 while (i < n) 9672 @{ 9673 sum += i * i; 9674 i++; 9675 @} 9676 return sum; 9677@} 9678@end example 9679 9680@noindent 9681@end quotation 9682 9683Here's what the final control flow graph will look like: 9684 9685@quotation 9686 9687 9688@float Figure 9689 9690@image{sum-of-squares,,,image of a control flow graph,png} 9691 9692@end float 9693 9694@end quotation 9695 9696As before, we include the libgccjit++ header and make a 9697@code{gccjit::context}. 9698 9699@example 9700#include <libgccjit++.h> 9701 9702void test (void) 9703@{ 9704 gccjit::context ctxt; 9705 ctxt = gccjit::context::acquire (); 9706@end example 9707 9708@noindent 9709 9710The function works with the C @cite{int} type. 9711 9712In the previous tutorial we acquired this via 9713 9714@example 9715gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_INT); 9716@end example 9717 9718@noindent 9719 9720though we could equally well make it work on, say, @cite{double}: 9721 9722@example 9723gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_DOUBLE); 9724@end example 9725 9726@noindent 9727 9728For integer types we can use @code{gccjit::context::get_int_type} 9729to directly bind a specific type: 9730 9731@example 9732gccjit::type the_type = ctxt.get_int_type <int> (); 9733@end example 9734 9735@noindent 9736 9737Let's build the function: 9738 9739@example 9740gcc_jit_param n = ctxt.new_param (the_type, "n"); 9741std::vector<gccjit::param> params; 9742params.push_back (n); 9743gccjit::function func = 9744 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 9745 return_type, 9746 "loop_test", 9747 params, 0); 9748@end example 9749 9750@noindent 9751 9752@menu 9753* Expressions; lvalues and rvalues: Expressions lvalues and rvalues<2>. 9754* Control flow: Control flow<2>. 9755* Visualizing the control flow graph: Visualizing the control flow graph<2>. 9756* Full example: Full example<4>. 9757 9758@end menu 9759 9760@node Expressions lvalues and rvalues<2>,Control flow<2>,,Tutorial part 3 Loops and variables<2> 9761@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{114} 9762@subsubsection Expressions: lvalues and rvalues 9763 9764 9765The base class of expression is the @code{gccjit::rvalue}, 9766representing an expression that can be on the @emph{right}-hand side of 9767an assignment: a value that can be computed somehow, and assigned 9768@emph{to} a storage area (such as a variable). It has a specific 9769@code{gccjit::type}. 9770 9771Anothe important class is @code{gccjit::lvalue}. 9772A @code{gccjit::lvalue}. is something that can of the @emph{left}-hand 9773side of an assignment: a storage area (such as a variable). 9774 9775In other words, every assignment can be thought of as: 9776 9777@example 9778LVALUE = RVALUE; 9779@end example 9780 9781@noindent 9782 9783Note that @code{gccjit::lvalue} is a subclass of 9784@code{gccjit::rvalue}, where in an assignment of the form: 9785 9786@example 9787LVALUE_A = LVALUE_B; 9788@end example 9789 9790@noindent 9791 9792the @cite{LVALUE_B} implies reading the current value of that storage 9793area, assigning it into the @cite{LVALUE_A}. 9794 9795So far the only expressions we've seen are from the previous tutorial: 9796 9797 9798@enumerate 9799 9800@item 9801the multiplication @cite{i * i}: 9802@end enumerate 9803 9804@quotation 9805 9806@example 9807gccjit::rvalue expr = 9808 ctxt.new_binary_op ( 9809 GCC_JIT_BINARY_OP_MULT, int_type, 9810 param_i, param_i); 9811 9812/* Alternatively, using operator-overloading: */ 9813gccjit::rvalue expr = param_i * param_i; 9814@end example 9815 9816@noindent 9817 9818which is a @code{gccjit::rvalue}, and 9819@end quotation 9820 9821 9822@enumerate 2 9823 9824@item 9825the various function parameters: @cite{param_i} and @cite{param_n}, instances of 9826@code{gccjit::param}, which is a subclass of @code{gccjit::lvalue} 9827(and, in turn, of @code{gccjit::rvalue}): 9828we can both read from and write to function parameters within the 9829body of a function. 9830@end enumerate 9831 9832Our new example has a new kind of expression: we have two local 9833variables. We create them by calling 9834@pxref{115,,gccjit;;function;;new_local()}, supplying a type and a name: 9835 9836@example 9837/* Build locals: */ 9838gccjit::lvalue i = func.new_local (the_type, "i"); 9839gccjit::lvalue sum = func.new_local (the_type, "sum"); 9840@end example 9841 9842@noindent 9843 9844These are instances of @code{gccjit::lvalue} - they can be read from 9845and written to. 9846 9847Note that there is no precanned way to create @emph{and} initialize a variable 9848like in C: 9849 9850@example 9851int i = 0; 9852@end example 9853 9854@noindent 9855 9856Instead, having added the local to the function, we have to separately add 9857an assignment of @cite{0} to @cite{local_i} at the beginning of the function. 9858 9859@node Control flow<2>,Visualizing the control flow graph<2>,Expressions lvalues and rvalues<2>,Tutorial part 3 Loops and variables<2> 9860@anchor{cp/intro/tutorial03 control-flow}@anchor{116} 9861@subsubsection Control flow 9862 9863 9864This function has a loop, so we need to build some basic blocks to 9865handle the control flow. In this case, we need 4 blocks: 9866 9867 9868@enumerate 9869 9870@item 9871before the loop (initializing the locals) 9872 9873@item 9874the conditional at the top of the loop (comparing @cite{i < n}) 9875 9876@item 9877the body of the loop 9878 9879@item 9880after the loop terminates (@cite{return sum}) 9881@end enumerate 9882 9883so we create these as @code{gccjit::block} instances within the 9884@code{gccjit::function}: 9885 9886@example 9887gccjit::block b_initial = func.new_block ("initial"); 9888gccjit::block b_loop_cond = func.new_block ("loop_cond"); 9889gccjit::block b_loop_body = func.new_block ("loop_body"); 9890gccjit::block b_after_loop = func.new_block ("after_loop"); 9891@end example 9892 9893@noindent 9894 9895We now populate each block with statements. 9896 9897The entry block @cite{b_initial} consists of initializations followed by a jump 9898to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using 9899@pxref{117,,gccjit;;block;;add_assignment()} to add 9900an assignment statement, and using @pxref{118,,gccjit;;context;;zero()} to get 9901the constant value @cite{0} for the relevant type for the right-hand side of 9902the assignment: 9903 9904@example 9905/* sum = 0; */ 9906b_initial.add_assignment (sum, ctxt.zero (the_type)); 9907 9908/* i = 0; */ 9909b_initial.add_assignment (i, ctxt.zero (the_type)); 9910@end example 9911 9912@noindent 9913 9914We can then terminate the entry block by jumping to the conditional: 9915 9916@example 9917b_initial.end_with_jump (b_loop_cond); 9918@end example 9919 9920@noindent 9921 9922The conditional block is equivalent to the line @cite{while (i < n)} from our 9923C example. It contains a single statement: a conditional, which jumps to 9924one of two destination blocks depending on a boolean 9925@code{gccjit::rvalue}, in this case the comparison of @cite{i} and @cite{n}. 9926 9927We could build the comparison using @pxref{119,,gccjit;;context;;new_comparison()}: 9928 9929@example 9930gccjit::rvalue guard = 9931 ctxt.new_comparison (GCC_JIT_COMPARISON_GE, 9932 i, n); 9933@end example 9934 9935@noindent 9936 9937and can then use this to add @cite{b_loop_cond}'s sole statement, via 9938@pxref{11a,,gccjit;;block;;end_with_conditional()}: 9939 9940@example 9941b_loop_cond.end_with_conditional (guard, 9942 b_after_loop, // on_true 9943 b_loop_body); // on_false 9944@end example 9945 9946@noindent 9947 9948However @code{gccjit::rvalue} has overloaded operators for this, so we 9949express the conditional as 9950 9951@example 9952gccjit::rvalue guard = (i >= n); 9953@end example 9954 9955@noindent 9956 9957and hence we can write the block more concisely as: 9958 9959@example 9960b_loop_cond.end_with_conditional ( 9961 i >= n, 9962 b_after_loop, // on_true 9963 b_loop_body); // on_false 9964@end example 9965 9966@noindent 9967 9968Next, we populate the body of the loop. 9969 9970The C statement @cite{sum += i * i;} is an assignment operation, where an 9971lvalue is modified "in-place". We use 9972@pxref{11b,,gccjit;;block;;add_assignment_op()} to handle these operations: 9973 9974@example 9975/* sum += i * i */ 9976b_loop_body.add_assignment_op (sum, 9977 GCC_JIT_BINARY_OP_PLUS, 9978 i * i); 9979@end example 9980 9981@noindent 9982 9983The @cite{i++} can be thought of as @cite{i += 1}, and can thus be handled in 9984a similar way. We use @pxref{2f,,gcc_jit_context_one()} to get the constant 9985value @cite{1} (for the relevant type) for the right-hand side 9986of the assignment. 9987 9988@example 9989/* i++ */ 9990b_loop_body.add_assignment_op (i, 9991 GCC_JIT_BINARY_OP_PLUS, 9992 ctxt.one (the_type)); 9993@end example 9994 9995@noindent 9996 9997@cartouche 9998@quotation Note 9999For numeric constants other than 0 or 1, we could use 10000@pxref{11c,,gccjit;;context;;new_rvalue()}, which has overloads 10001for both @code{int} and @code{double}. 10002@end quotation 10003@end cartouche 10004 10005The loop body completes by jumping back to the conditional: 10006 10007@example 10008b_loop_body.end_with_jump (b_loop_cond); 10009@end example 10010 10011@noindent 10012 10013Finally, we populate the @cite{b_after_loop} block, reached when the loop 10014conditional is false. We want to generate the equivalent of: 10015 10016@example 10017return sum; 10018@end example 10019 10020@noindent 10021 10022so the block is just one statement: 10023 10024@example 10025/* return sum */ 10026b_after_loop.end_with_return (sum); 10027@end example 10028 10029@noindent 10030 10031@cartouche 10032@quotation Note 10033You can intermingle block creation with statement creation, 10034but given that the terminator statements generally include references 10035to other blocks, I find it's clearer to create all the blocks, 10036@emph{then} all the statements. 10037@end quotation 10038@end cartouche 10039 10040We've finished populating the function. As before, we can now compile it 10041to machine code: 10042 10043@example 10044gcc_jit_result *result; 10045result = ctxt.compile (); 10046 10047ctxt.release (); 10048 10049if (!result) 10050 @{ 10051 fprintf (stderr, "NULL result"); 10052 return 1; 10053 @} 10054 10055typedef int (*loop_test_fn_type) (int); 10056loop_test_fn_type loop_test = 10057 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 10058if (!loop_test) 10059 @{ 10060 fprintf (stderr, "NULL loop_test"); 10061 gcc_jit_result_release (result); 10062 return 1; 10063 @} 10064printf ("result: %d", loop_test (10)); 10065@end example 10066 10067@noindent 10068 10069@example 10070result: 285 10071@end example 10072 10073@noindent 10074 10075@node Visualizing the control flow graph<2>,Full example<4>,Control flow<2>,Tutorial part 3 Loops and variables<2> 10076@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{11d} 10077@subsubsection Visualizing the control flow graph 10078 10079 10080You can see the control flow graph of a function using 10081@pxref{11e,,gccjit;;function;;dump_to_dot()}: 10082 10083@example 10084func.dump_to_dot ("/tmp/sum-of-squares.dot"); 10085@end example 10086 10087@noindent 10088 10089giving a .dot file in GraphViz format. 10090 10091You can convert this to an image using @cite{dot}: 10092 10093@example 10094$ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png 10095@end example 10096 10097@noindent 10098 10099or use a viewer (my preferred one is xdot.py; see 10100@indicateurl{https://github.com/jrfonseca/xdot.py}; on Fedora you can 10101install it with @cite{yum install python-xdot}): 10102 10103@quotation 10104 10105 10106@float Figure 10107 10108@image{sum-of-squares,,,image of a control flow graph,png} 10109 10110@end float 10111 10112@end quotation 10113 10114@node Full example<4>,,Visualizing the control flow graph<2>,Tutorial part 3 Loops and variables<2> 10115@anchor{cp/intro/tutorial03 full-example}@anchor{11f} 10116@subsubsection Full example 10117 10118 10119@quotation 10120 10121@example 10122/* Usage example for libgccjit.so's C++ API 10123 Copyright (C) 2014-2016 Free Software Foundation, Inc. 10124 10125This file is part of GCC. 10126 10127GCC is free software; you can redistribute it and/or modify it 10128under the terms of the GNU General Public License as published by 10129the Free Software Foundation; either version 3, or (at your option) 10130any later version. 10131 10132GCC is distributed in the hope that it will be useful, but 10133WITHOUT ANY WARRANTY; without even the implied warranty of 10134MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10135General Public License for more details. 10136 10137You should have received a copy of the GNU General Public License 10138along with GCC; see the file COPYING3. If not see 10139<http://www.gnu.org/licenses/>. */ 10140 10141#include <libgccjit++.h> 10142 10143#include <stdlib.h> 10144#include <stdio.h> 10145 10146void 10147create_code (gccjit::context ctxt) 10148@{ 10149 /* 10150 Simple sum-of-squares, to test conditionals and looping 10151 10152 int loop_test (int n) 10153 @{ 10154 int i; 10155 int sum = 0; 10156 for (i = 0; i < n ; i ++) 10157 @{ 10158 sum += i * i; 10159 @} 10160 return sum; 10161 */ 10162 gccjit::type the_type = ctxt.get_int_type <int> (); 10163 gccjit::type return_type = the_type; 10164 10165 gccjit::param n = ctxt.new_param (the_type, "n"); 10166 std::vector<gccjit::param> params; 10167 params.push_back (n); 10168 gccjit::function func = 10169 ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10170 return_type, 10171 "loop_test", 10172 params, 0); 10173 10174 /* Build locals: */ 10175 gccjit::lvalue i = func.new_local (the_type, "i"); 10176 gccjit::lvalue sum = func.new_local (the_type, "sum"); 10177 10178 gccjit::block b_initial = func.new_block ("initial"); 10179 gccjit::block b_loop_cond = func.new_block ("loop_cond"); 10180 gccjit::block b_loop_body = func.new_block ("loop_body"); 10181 gccjit::block b_after_loop = func.new_block ("after_loop"); 10182 10183 /* sum = 0; */ 10184 b_initial.add_assignment (sum, ctxt.zero (the_type)); 10185 10186 /* i = 0; */ 10187 b_initial.add_assignment (i, ctxt.zero (the_type)); 10188 10189 b_initial.end_with_jump (b_loop_cond); 10190 10191 /* if (i >= n) */ 10192 b_loop_cond.end_with_conditional ( 10193 i >= n, 10194 b_after_loop, 10195 b_loop_body); 10196 10197 /* sum += i * i */ 10198 b_loop_body.add_assignment_op (sum, 10199 GCC_JIT_BINARY_OP_PLUS, 10200 i * i); 10201 10202 /* i++ */ 10203 b_loop_body.add_assignment_op (i, 10204 GCC_JIT_BINARY_OP_PLUS, 10205 ctxt.one (the_type)); 10206 10207 b_loop_body.end_with_jump (b_loop_cond); 10208 10209 /* return sum */ 10210 b_after_loop.end_with_return (sum); 10211@} 10212 10213int 10214main (int argc, char **argv) 10215@{ 10216 gccjit::context ctxt; 10217 gcc_jit_result *result = NULL; 10218 10219 /* Get a "context" object for working with the library. */ 10220 ctxt = gccjit::context::acquire (); 10221 10222 /* Set some options on the context. 10223 Turn this on to see the code being generated, in assembler form. */ 10224 ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 10225 0); 10226 10227 /* Populate the context. */ 10228 create_code (ctxt); 10229 10230 /* Compile the code. */ 10231 result = ctxt.compile (); 10232 10233 ctxt.release (); 10234 10235 if (!result) 10236 @{ 10237 fprintf (stderr, "NULL result"); 10238 return 1; 10239 @} 10240 10241 /* Extract the generated code from "result". */ 10242 typedef int (*loop_test_fn_type) (int); 10243 loop_test_fn_type loop_test = 10244 (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); 10245 if (!loop_test) 10246 @{ 10247 fprintf (stderr, "NULL loop_test"); 10248 gcc_jit_result_release (result); 10249 return 1; 10250 @} 10251 10252 /* Run the generated code. */ 10253 int val = loop_test (10); 10254 printf("loop_test returned: %d\n", val); 10255 10256 gcc_jit_result_release (result); 10257 return 0; 10258@} 10259 10260@end example 10261 10262@noindent 10263@end quotation 10264 10265Building and running it: 10266 10267@example 10268$ gcc \ 10269 tut03-sum-of-squares.cc \ 10270 -o tut03-sum-of-squares \ 10271 -lgccjit 10272 10273# Run the built program: 10274$ ./tut03-sum-of-squares 10275loop_test returned: 285 10276@end example 10277 10278@noindent 10279 10280@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 10281@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 10282@c 10283@c This is free software: you can redistribute it and/or modify it 10284@c under the terms of the GNU General Public License as published by 10285@c the Free Software Foundation, either version 3 of the License, or 10286@c (at your option) any later version. 10287@c 10288@c This program is distributed in the hope that it will be useful, but 10289@c WITHOUT ANY WARRANTY; without even the implied warranty of 10290@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10291@c General Public License for more details. 10292@c 10293@c You should have received a copy of the GNU General Public License 10294@c along with this program. If not, see 10295@c <http://www.gnu.org/licenses/>. 10296 10297@node Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,,Tutorial part 3 Loops and variables<2>,Tutorial<2> 10298@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{120}@anchor{cp/intro/tutorial04 doc}@anchor{121} 10299@subsection Tutorial part 4: Adding JIT-compilation to a toy interpreter 10300 10301 10302In this example we construct a "toy" interpreter, and add JIT-compilation 10303to it. 10304 10305@menu 10306* Our toy interpreter: Our toy interpreter<2>. 10307* Compiling to machine code: Compiling to machine code<2>. 10308* Setting things up: Setting things up<2>. 10309* Populating the function: Populating the function<2>. 10310* Verifying the control flow graph: Verifying the control flow graph<2>. 10311* Compiling the context: Compiling the context<2>. 10312* Single-stepping through the generated code: Single-stepping through the generated code<2>. 10313* Examining the generated code: Examining the generated code<2>. 10314* Putting it all together: Putting it all together<2>. 10315* Behind the curtain; How does our code get optimized?: Behind the curtain How does our code get optimized?<2>. 10316 10317@end menu 10318 10319@node Our toy interpreter<2>,Compiling to machine code<2>,,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2> 10320@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{122} 10321@subsubsection Our toy interpreter 10322 10323 10324It's a stack-based interpreter, and is intended as a (very simple) example 10325of the kind of bytecode interpreter seen in dynamic languages such as 10326Python, Ruby etc. 10327 10328For the sake of simplicity, our toy virtual machine is very limited: 10329 10330@quotation 10331 10332 10333@itemize * 10334 10335@item 10336The only data type is @cite{int} 10337 10338@item 10339It can only work on one function at a time (so that the only 10340function call that can be made is to recurse). 10341 10342@item 10343Functions can only take one parameter. 10344 10345@item 10346Functions have a stack of @cite{int} values. 10347 10348@item 10349We'll implement function call within the interpreter by calling a 10350function in our implementation, rather than implementing our own 10351frame stack. 10352 10353@item 10354The parser is only good enough to get the examples to work. 10355@end itemize 10356@end quotation 10357 10358Naturally, a real interpreter would be much more complicated that this. 10359 10360The following operations are supported: 10361 10362 10363@multitable {xxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxx} {xxxxxxxxxxxxxxxxxx} 10364@headitem 10365 10366Operation 10367 10368@tab 10369 10370Meaning 10371 10372@tab 10373 10374Old Stack 10375 10376@tab 10377 10378New Stack 10379 10380@item 10381 10382DUP 10383 10384@tab 10385 10386Duplicate top of stack. 10387 10388@tab 10389 10390@code{[..., x]} 10391 10392@tab 10393 10394@code{[..., x, x]} 10395 10396@item 10397 10398ROT 10399 10400@tab 10401 10402Swap top two elements 10403of stack. 10404 10405@tab 10406 10407@code{[..., x, y]} 10408 10409@tab 10410 10411@code{[..., y, x]} 10412 10413@item 10414 10415BINARY_ADD 10416 10417@tab 10418 10419Add the top two elements 10420on the stack. 10421 10422@tab 10423 10424@code{[..., x, y]} 10425 10426@tab 10427 10428@code{[..., (x+y)]} 10429 10430@item 10431 10432BINARY_SUBTRACT 10433 10434@tab 10435 10436Likewise, but subtract. 10437 10438@tab 10439 10440@code{[..., x, y]} 10441 10442@tab 10443 10444@code{[..., (x-y)]} 10445 10446@item 10447 10448BINARY_MULT 10449 10450@tab 10451 10452Likewise, but multiply. 10453 10454@tab 10455 10456@code{[..., x, y]} 10457 10458@tab 10459 10460@code{[..., (x*y)]} 10461 10462@item 10463 10464BINARY_COMPARE_LT 10465 10466@tab 10467 10468Compare the top two 10469elements on the stack 10470and push a nonzero/zero 10471if (x<y). 10472 10473@tab 10474 10475@code{[..., x, y]} 10476 10477@tab 10478 10479@code{[..., (x<y)]} 10480 10481@item 10482 10483RECURSE 10484 10485@tab 10486 10487Recurse, passing the top 10488of the stack, and 10489popping the result. 10490 10491@tab 10492 10493@code{[..., x]} 10494 10495@tab 10496 10497@code{[..., fn(x)]} 10498 10499@item 10500 10501RETURN 10502 10503@tab 10504 10505Return the top of the 10506stack. 10507 10508@tab 10509 10510@code{[x]} 10511 10512@tab 10513 10514@code{[]} 10515 10516@item 10517 10518PUSH_CONST @cite{arg} 10519 10520@tab 10521 10522Push an int const. 10523 10524@tab 10525 10526@code{[...]} 10527 10528@tab 10529 10530@code{[..., arg]} 10531 10532@item 10533 10534JUMP_ABS_IF_TRUE @cite{arg} 10535 10536@tab 10537 10538Pop; if top of stack was 10539nonzero, jump to 10540@code{arg}. 10541 10542@tab 10543 10544@code{[..., x]} 10545 10546@tab 10547 10548@code{[...]} 10549 10550@end multitable 10551 10552 10553Programs can be interpreted, disassembled, and compiled to machine code. 10554 10555The interpreter reads @code{.toy} scripts. Here's what a simple recursive 10556factorial program looks like, the script @code{factorial.toy}. 10557The parser ignores lines beginning with a @cite{#}. 10558 10559@quotation 10560 10561@example 10562# Simple recursive factorial implementation, roughly equivalent to: 10563# 10564# int factorial (int arg) 10565# @{ 10566# if (arg < 2) 10567# return arg 10568# return arg * factorial (arg - 1) 10569# @} 10570 10571# Initial state: 10572# stack: [arg] 10573 10574# 0: 10575DUP 10576# stack: [arg, arg] 10577 10578# 1: 10579PUSH_CONST 2 10580# stack: [arg, arg, 2] 10581 10582# 2: 10583BINARY_COMPARE_LT 10584# stack: [arg, (arg < 2)] 10585 10586# 3: 10587JUMP_ABS_IF_TRUE 9 10588# stack: [arg] 10589 10590# 4: 10591DUP 10592# stack: [arg, arg] 10593 10594# 5: 10595PUSH_CONST 1 10596# stack: [arg, arg, 1] 10597 10598# 6: 10599BINARY_SUBTRACT 10600# stack: [arg, (arg - 1) 10601 10602# 7: 10603RECURSE 10604# stack: [arg, factorial(arg - 1)] 10605 10606# 8: 10607BINARY_MULT 10608# stack: [arg * factorial(arg - 1)] 10609 10610# 9: 10611RETURN 10612 10613@end example 10614 10615@noindent 10616@end quotation 10617 10618The interpreter is a simple infinite loop with a big @code{switch} statement 10619based on what the next opcode is: 10620 10621@quotation 10622 10623@example 10624 10625int 10626toyvm_function::interpret (int arg, FILE *trace) 10627@{ 10628 toyvm_frame frame; 10629#define PUSH(ARG) (frame.push (ARG)) 10630#define POP(ARG) (frame.pop ()) 10631 10632 frame.frm_function = this; 10633 frame.frm_pc = 0; 10634 frame.frm_cur_depth = 0; 10635 10636 PUSH (arg); 10637 10638 while (1) 10639 @{ 10640 toyvm_op *op; 10641 int x, y; 10642 assert (frame.frm_pc < fn_num_ops); 10643 op = &fn_ops[frame.frm_pc++]; 10644 10645 if (trace) 10646 @{ 10647 frame.dump_stack (trace); 10648 disassemble_op (op, frame.frm_pc, trace); 10649 @} 10650 10651 switch (op->op_opcode) 10652 @{ 10653 /* Ops taking no operand. */ 10654 case DUP: 10655 x = POP (); 10656 PUSH (x); 10657 PUSH (x); 10658 break; 10659 10660 case ROT: 10661 y = POP (); 10662 x = POP (); 10663 PUSH (y); 10664 PUSH (x); 10665 break; 10666 10667 case BINARY_ADD: 10668 y = POP (); 10669 x = POP (); 10670 PUSH (x + y); 10671 break; 10672 10673 case BINARY_SUBTRACT: 10674 y = POP (); 10675 x = POP (); 10676 PUSH (x - y); 10677 break; 10678 10679 case BINARY_MULT: 10680 y = POP (); 10681 x = POP (); 10682 PUSH (x * y); 10683 break; 10684 10685 case BINARY_COMPARE_LT: 10686 y = POP (); 10687 x = POP (); 10688 PUSH (x < y); 10689 break; 10690 10691 case RECURSE: 10692 x = POP (); 10693 x = interpret (x, trace); 10694 PUSH (x); 10695 break; 10696 10697 case RETURN: 10698 return POP (); 10699 10700 /* Ops taking an operand. */ 10701 case PUSH_CONST: 10702 PUSH (op->op_operand); 10703 break; 10704 10705 case JUMP_ABS_IF_TRUE: 10706 x = POP (); 10707 if (x) 10708 frame.frm_pc = op->op_operand; 10709 break; 10710 10711 default: 10712 assert (0); /* unknown opcode */ 10713 10714 @} /* end of switch on opcode */ 10715 @} /* end of while loop */ 10716 10717#undef PUSH 10718#undef POP 10719@} 10720 10721 10722@end example 10723 10724@noindent 10725@end quotation 10726 10727@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> 10728@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{123} 10729@subsubsection Compiling to machine code 10730 10731 10732We want to generate machine code that can be cast to this type and 10733then directly executed in-process: 10734 10735@quotation 10736 10737@example 10738typedef int (*toyvm_compiled_func) (int); 10739 10740 10741@end example 10742 10743@noindent 10744@end quotation 10745 10746Our compiler isn't very sophisticated; it takes the implementation of 10747each opcode above, and maps it directly to the operations supported by 10748the libgccjit API. 10749 10750How should we handle the stack? In theory we could calculate what the 10751stack depth will be at each opcode, and optimize away the stack 10752manipulation "by hand". We'll see below that libgccjit is able to do 10753this for us, so we'll implement stack manipulation 10754in a direct way, by creating a @code{stack} array and @code{stack_depth} 10755variables, local within the generated function, equivalent to this C code: 10756 10757@example 10758int stack_depth; 10759int stack[MAX_STACK_DEPTH]; 10760@end example 10761 10762@noindent 10763 10764We'll also have local variables @code{x} and @code{y} for use when implementing 10765the opcodes, equivalent to this: 10766 10767@example 10768int x; 10769int y; 10770@end example 10771 10772@noindent 10773 10774This means our compiler has the following state: 10775 10776@quotation 10777 10778@example 10779 10780 toyvm_function &toyvmfn; 10781 10782 gccjit::context ctxt; 10783 10784 gccjit::type int_type; 10785 gccjit::type bool_type; 10786 gccjit::type stack_type; /* int[MAX_STACK_DEPTH] */ 10787 10788 gccjit::rvalue const_one; 10789 10790 gccjit::function fn; 10791 gccjit::param param_arg; 10792 gccjit::lvalue stack; 10793 gccjit::lvalue stack_depth; 10794 gccjit::lvalue x; 10795 gccjit::lvalue y; 10796 10797 gccjit::location op_locs[MAX_OPS]; 10798 gccjit::block initial_block; 10799 gccjit::block op_blocks[MAX_OPS]; 10800 10801 10802@end example 10803 10804@noindent 10805@end quotation 10806 10807@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> 10808@anchor{cp/intro/tutorial04 setting-things-up}@anchor{124} 10809@subsubsection Setting things up 10810 10811 10812First we create our types: 10813 10814@quotation 10815 10816@example 10817 10818void 10819compilation_state::create_types () 10820@{ 10821 /* Create types. */ 10822 int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 10823 bool_type = ctxt.get_type (GCC_JIT_TYPE_BOOL); 10824 stack_type = ctxt.new_array_type (int_type, MAX_STACK_DEPTH); 10825 10826 10827@end example 10828 10829@noindent 10830@end quotation 10831 10832along with extracting a useful @cite{int} constant: 10833 10834@quotation 10835 10836@example 10837 const_one = ctxt.one (int_type); 10838 10839@} 10840 10841 10842@end example 10843 10844@noindent 10845@end quotation 10846 10847We'll implement push and pop in terms of the @code{stack} array and 10848@code{stack_depth}. Here are helper functions for adding statements to 10849a block, implementing pushing and popping values: 10850 10851@quotation 10852 10853@example 10854 10855void 10856compilation_state::add_push (gccjit::block block, 10857 gccjit::rvalue rvalue, 10858 gccjit::location loc) 10859@{ 10860 /* stack[stack_depth] = RVALUE */ 10861 block.add_assignment ( 10862 /* stack[stack_depth] */ 10863 ctxt.new_array_access ( 10864 stack, 10865 stack_depth, 10866 loc), 10867 rvalue, 10868 loc); 10869 10870 /* "stack_depth++;". */ 10871 block.add_assignment_op ( 10872 stack_depth, 10873 GCC_JIT_BINARY_OP_PLUS, 10874 const_one, 10875 loc); 10876@} 10877 10878void 10879compilation_state::add_pop (gccjit::block block, 10880 gccjit::lvalue lvalue, 10881 gccjit::location loc) 10882@{ 10883 /* "--stack_depth;". */ 10884 block.add_assignment_op ( 10885 stack_depth, 10886 GCC_JIT_BINARY_OP_MINUS, 10887 const_one, 10888 loc); 10889 10890 /* "LVALUE = stack[stack_depth];". */ 10891 block.add_assignment ( 10892 lvalue, 10893 /* stack[stack_depth] */ 10894 ctxt.new_array_access (stack, 10895 stack_depth, 10896 loc), 10897 loc); 10898@} 10899 10900 10901@end example 10902 10903@noindent 10904@end quotation 10905 10906We will support single-stepping through the generated code in the 10907debugger, so we need to create @code{gccjit::location} instances, one 10908per operation in the source code. These will reference the lines of 10909e.g. @code{factorial.toy}. 10910 10911@quotation 10912 10913@example 10914 10915void 10916compilation_state::create_locations () 10917@{ 10918 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 10919 @{ 10920 toyvm_op *op = &toyvmfn.fn_ops[pc]; 10921 10922 op_locs[pc] = ctxt.new_location (toyvmfn.fn_filename, 10923 op->op_linenum, 10924 0); /* column */ 10925 @} 10926@} 10927 10928 10929@end example 10930 10931@noindent 10932@end quotation 10933 10934Let's create the function itself. As usual, we create its parameter 10935first, then use the parameter to create the function: 10936 10937@quotation 10938 10939@example 10940 10941void 10942compilation_state::create_function (const char *funcname) 10943@{ 10944 std::vector <gccjit::param> params; 10945 param_arg = ctxt.new_param (int_type, "arg", op_locs[0]); 10946 params.push_back (param_arg); 10947 fn = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 10948 int_type, 10949 funcname, 10950 params, 0, 10951 op_locs[0]); 10952 10953 10954@end example 10955 10956@noindent 10957@end quotation 10958 10959We create the locals within the function. 10960 10961@quotation 10962 10963@example 10964 stack = fn.new_local (stack_type, "stack"); 10965 stack_depth = fn.new_local (int_type, "stack_depth"); 10966 x = fn.new_local (int_type, "x"); 10967 y = fn.new_local (int_type, "y"); 10968 10969 10970@end example 10971 10972@noindent 10973@end quotation 10974 10975@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> 10976@anchor{cp/intro/tutorial04 populating-the-function}@anchor{125} 10977@subsubsection Populating the function 10978 10979 10980There's some one-time initialization, and the API treats the first block 10981you create as the entrypoint of the function, so we need to create that 10982block first: 10983 10984@quotation 10985 10986@example 10987 initial_block = fn.new_block ("initial"); 10988 10989 10990@end example 10991 10992@noindent 10993@end quotation 10994 10995We can now create blocks for each of the operations. Most of these will 10996be consolidated into larger blocks when the optimizer runs. 10997 10998@quotation 10999 11000@example 11001 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 11002 @{ 11003 char buf[16]; 11004 sprintf (buf, "instr%i", pc); 11005 op_blocks[pc] = fn.new_block (buf); 11006 @} 11007 11008 11009@end example 11010 11011@noindent 11012@end quotation 11013 11014Now that we have a block it can jump to when it's done, we can populate 11015the initial block: 11016 11017@quotation 11018 11019@example 11020 11021 /* "stack_depth = 0;". */ 11022 initial_block.add_assignment (stack_depth, 11023 ctxt.zero (int_type), 11024 op_locs[0]); 11025 11026 /* "PUSH (arg);". */ 11027 add_push (initial_block, 11028 param_arg, 11029 op_locs[0]); 11030 11031 /* ...and jump to insn 0. */ 11032 initial_block.end_with_jump (op_blocks[0], 11033 op_locs[0]); 11034 11035 11036@end example 11037 11038@noindent 11039@end quotation 11040 11041We can now populate the blocks for the individual operations. We loop 11042through them, adding instructions to their blocks: 11043 11044@quotation 11045 11046@example 11047 for (int pc = 0; pc < toyvmfn.fn_num_ops; pc++) 11048 @{ 11049 gccjit::location loc = op_locs[pc]; 11050 11051 gccjit::block block = op_blocks[pc]; 11052 gccjit::block next_block = (pc < toyvmfn.fn_num_ops 11053 ? op_blocks[pc + 1] 11054 : NULL); 11055 11056 toyvm_op *op; 11057 op = &toyvmfn.fn_ops[pc]; 11058 11059 11060@end example 11061 11062@noindent 11063@end quotation 11064 11065We're going to have another big @code{switch} statement for implementing 11066the opcodes, this time for compiling them, rather than interpreting 11067them. It's helpful to have macros for implementing push and pop, so that 11068we can make the @code{switch} statement that's coming up look as much as 11069possible like the one above within the interpreter: 11070 11071@example 11072 11073#define X_EQUALS_POP()\ 11074 add_pop (block, x, loc) 11075#define Y_EQUALS_POP()\ 11076 add_pop (block, y, loc) 11077#define PUSH_RVALUE(RVALUE)\ 11078 add_push (block, (RVALUE), loc) 11079#define PUSH_X()\ 11080 PUSH_RVALUE (x) 11081#define PUSH_Y() \ 11082 PUSH_RVALUE (y) 11083 11084 11085@end example 11086 11087@noindent 11088 11089@cartouche 11090@quotation Note 11091A particularly clever implementation would have an @emph{identical} 11092@code{switch} statement shared by the interpreter and the compiler, with 11093some preprocessor "magic". We're not doing that here, for the sake 11094of simplicity. 11095@end quotation 11096@end cartouche 11097 11098When I first implemented this compiler, I accidentally missed an edit 11099when copying and pasting the @code{Y_EQUALS_POP} macro, so that popping the 11100stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y} 11101uninitialized. 11102 11103To track this kind of thing down, we can use 11104@pxref{126,,gccjit;;block;;add_comment()} to add descriptive comments 11105to the internal representation. This is invaluable when looking through 11106the generated IR for, say @code{factorial}: 11107 11108@quotation 11109 11110@example 11111 11112 block.add_comment (opcode_names[op->op_opcode], loc); 11113 11114 11115@end example 11116 11117@noindent 11118@end quotation 11119 11120We can now write the big @code{switch} statement that implements the 11121individual opcodes, populating the relevant block with statements: 11122 11123@quotation 11124 11125@example 11126 11127 switch (op->op_opcode) 11128 @{ 11129 case DUP: 11130 X_EQUALS_POP (); 11131 PUSH_X (); 11132 PUSH_X (); 11133 break; 11134 11135 case ROT: 11136 Y_EQUALS_POP (); 11137 X_EQUALS_POP (); 11138 PUSH_Y (); 11139 PUSH_X (); 11140 break; 11141 11142 case BINARY_ADD: 11143 Y_EQUALS_POP (); 11144 X_EQUALS_POP (); 11145 PUSH_RVALUE ( 11146 ctxt.new_binary_op ( 11147 GCC_JIT_BINARY_OP_PLUS, 11148 int_type, 11149 x, y, 11150 loc)); 11151 break; 11152 11153 case BINARY_SUBTRACT: 11154 Y_EQUALS_POP (); 11155 X_EQUALS_POP (); 11156 PUSH_RVALUE ( 11157 ctxt.new_binary_op ( 11158 GCC_JIT_BINARY_OP_MINUS, 11159 int_type, 11160 x, y, 11161 loc)); 11162 break; 11163 11164 case BINARY_MULT: 11165 Y_EQUALS_POP (); 11166 X_EQUALS_POP (); 11167 PUSH_RVALUE ( 11168 ctxt.new_binary_op ( 11169 GCC_JIT_BINARY_OP_MULT, 11170 int_type, 11171 x, y, 11172 loc)); 11173 break; 11174 11175 case BINARY_COMPARE_LT: 11176 Y_EQUALS_POP (); 11177 X_EQUALS_POP (); 11178 PUSH_RVALUE ( 11179 /* cast of bool to int */ 11180 ctxt.new_cast ( 11181 /* (x < y) as a bool */ 11182 ctxt.new_comparison ( 11183 GCC_JIT_COMPARISON_LT, 11184 x, y, 11185 loc), 11186 int_type, 11187 loc)); 11188 break; 11189 11190 case RECURSE: 11191 @{ 11192 X_EQUALS_POP (); 11193 PUSH_RVALUE ( 11194 ctxt.new_call ( 11195 fn, 11196 x, 11197 loc)); 11198 break; 11199 @} 11200 11201 case RETURN: 11202 X_EQUALS_POP (); 11203 block.end_with_return (x, loc); 11204 break; 11205 11206 /* Ops taking an operand. */ 11207 case PUSH_CONST: 11208 PUSH_RVALUE ( 11209 ctxt.new_rvalue (int_type, op->op_operand)); 11210 break; 11211 11212 case JUMP_ABS_IF_TRUE: 11213 X_EQUALS_POP (); 11214 block.end_with_conditional ( 11215 /* "(bool)x". */ 11216 ctxt.new_cast (x, bool_type, loc), 11217 op_blocks[op->op_operand], /* on_true */ 11218 next_block, /* on_false */ 11219 loc); 11220 break; 11221 11222 default: 11223 assert(0); 11224 @} /* end of switch on opcode */ 11225 11226 11227@end example 11228 11229@noindent 11230@end quotation 11231 11232Every block must be terminated, via a call to one of the 11233@code{gccjit::block::end_with_} entrypoints. This has been done for two 11234of the opcodes, but we need to do it for the other ones, by jumping 11235to the next block. 11236 11237@quotation 11238 11239@example 11240 if (op->op_opcode != JUMP_ABS_IF_TRUE 11241 && op->op_opcode != RETURN) 11242 block.end_with_jump (next_block, loc); 11243 11244 11245@end example 11246 11247@noindent 11248@end quotation 11249 11250This is analogous to simply incrementing the program counter. 11251 11252@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> 11253@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{127} 11254@subsubsection Verifying the control flow graph 11255 11256 11257Having finished looping over the blocks, the context is complete. 11258 11259As before, we can verify that the control flow and statements are sane by 11260using @pxref{11e,,gccjit;;function;;dump_to_dot()}: 11261 11262@example 11263fn.dump_to_dot ("/tmp/factorial.dot"); 11264@end example 11265 11266@noindent 11267 11268and viewing the result. Note how the label names, comments, and 11269variable names show up in the dump, to make it easier to spot 11270errors in our compiler. 11271 11272@quotation 11273 11274 11275@float Figure 11276 11277@image{factorial,,,image of a control flow graph,png} 11278 11279@end float 11280 11281@end quotation 11282 11283@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> 11284@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{128} 11285@subsubsection Compiling the context 11286 11287 11288Having finished looping over the blocks and populating them with 11289statements, the context is complete. 11290 11291We can now compile it, extract machine code from the result, and 11292run it: 11293 11294@quotation 11295 11296@example 11297 11298class compilation_result 11299@{ 11300public: 11301 compilation_result (gcc_jit_result *result) : 11302 m_result (result) 11303 @{ 11304 @} 11305 ~compilation_result () 11306 @{ 11307 gcc_jit_result_release (m_result); 11308 @} 11309 11310 void *get_code (const char *funcname) 11311 @{ 11312 return gcc_jit_result_get_code (m_result, funcname); 11313 @} 11314 11315private: 11316 gcc_jit_result *m_result; 11317@}; 11318 11319 11320@end example 11321 11322@noindent 11323 11324@example 11325 compilation_result compiler_result = fn->compile (); 11326 11327 const char *funcname = fn->get_function_name (); 11328 toyvm_compiled_func code 11329 = (toyvm_compiled_func)compiler_result.get_code (funcname); 11330 11331 printf ("compiler result: %d\n", 11332 code (atoi (argv[2]))); 11333 11334 11335@end example 11336 11337@noindent 11338@end quotation 11339 11340@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> 11341@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{129} 11342@subsubsection Single-stepping through the generated code 11343 11344 11345It's possible to debug the generated code. To do this we need to both: 11346 11347@quotation 11348 11349 11350@itemize * 11351 11352@item 11353Set up source code locations for our statements, so that we can 11354meaningfully step through the code. We did this above by 11355calling @pxref{12a,,gccjit;;context;;new_location()} and using the 11356results. 11357 11358@item 11359Enable the generation of debugging information, by setting 11360@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 11361@code{gccjit::context} via 11362@pxref{10f,,gccjit;;context;;set_bool_option()}: 11363 11364@example 11365ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1); 11366@end example 11367 11368@noindent 11369@end itemize 11370@end quotation 11371 11372Having done this, we can put a breakpoint on the generated function: 11373 11374@example 11375$ gdb --args ./toyvm factorial.toy 10 11376(gdb) break factorial 11377Function "factorial" not defined. 11378Make breakpoint pending on future shared library load? (y or [n]) y 11379Breakpoint 1 (factorial) pending. 11380(gdb) run 11381Breakpoint 1, factorial (arg=10) at factorial.toy:14 1138214 DUP 11383@end example 11384 11385@noindent 11386 11387We've set up location information, which references @code{factorial.toy}. 11388This allows us to use e.g. @code{list} to see where we are in the script: 11389 11390@example 11391(gdb) list 113929 1139310 # Initial state: 1139411 # stack: [arg] 1139512 1139613 # 0: 1139714 DUP 1139815 # stack: [arg, arg] 1139916 1140017 # 1: 1140118 PUSH_CONST 2 11402@end example 11403 11404@noindent 11405 11406and to step through the function, examining the data: 11407 11408@example 11409(gdb) n 1141018 PUSH_CONST 2 11411(gdb) n 1141222 BINARY_COMPARE_LT 11413(gdb) print stack 11414$5 = @{10, 10, 2, 0, -7152, 32767, 0, 0@} 11415(gdb) print stack_depth 11416$6 = 3 11417@end example 11418 11419@noindent 11420 11421You'll see that the parts of the @code{stack} array that haven't been 11422touched yet are uninitialized. 11423 11424@cartouche 11425@quotation Note 11426Turning on optimizations may lead to unpredictable results when 11427stepping through the generated code: the execution may appear to 11428"jump around" the source code. This is analogous to turning up the 11429optimization level in a regular compiler. 11430@end quotation 11431@end cartouche 11432 11433@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> 11434@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{12b} 11435@subsubsection Examining the generated code 11436 11437 11438How good is the optimized code? 11439 11440We can turn up optimizations, by calling 11441@pxref{110,,gccjit;;context;;set_int_option()} with 11442@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}: 11443 11444@example 11445ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); 11446@end example 11447 11448@noindent 11449 11450One of GCC's internal representations is called "gimple". A dump of the 11451initial gimple representation of the code can be seen by setting: 11452 11453@example 11454ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); 11455@end example 11456 11457@noindent 11458 11459With optimization on and source locations displayed, this gives: 11460 11461@c We'll use "c" for gimple dumps 11462 11463@example 11464factorial (signed int arg) 11465@{ 11466 <unnamed type> D.80; 11467 signed int D.81; 11468 signed int D.82; 11469 signed int D.83; 11470 signed int D.84; 11471 signed int D.85; 11472 signed int y; 11473 signed int x; 11474 signed int stack_depth; 11475 signed int stack[8]; 11476 11477 try 11478 @{ 11479 initial: 11480 stack_depth = 0; 11481 stack[stack_depth] = arg; 11482 stack_depth = stack_depth + 1; 11483 goto instr0; 11484 instr0: 11485 /* DUP */: 11486 stack_depth = stack_depth + -1; 11487 x = stack[stack_depth]; 11488 stack[stack_depth] = x; 11489 stack_depth = stack_depth + 1; 11490 stack[stack_depth] = x; 11491 stack_depth = stack_depth + 1; 11492 goto instr1; 11493 instr1: 11494 /* PUSH_CONST */: 11495 stack[stack_depth] = 2; 11496 stack_depth = stack_depth + 1; 11497 goto instr2; 11498 11499 /* etc */ 11500@end example 11501 11502@noindent 11503 11504You can see the generated machine code in assembly form via: 11505 11506@example 11507ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1); 11508result = ctxt.compile (); 11509@end example 11510 11511@noindent 11512 11513which shows that (on this x86_64 box) the compiler has unrolled the loop 11514and is using MMX instructions to perform several multiplications 11515simultaneously: 11516 11517@example 11518 .file "fake.c" 11519 .text 11520.Ltext0: 11521 .p2align 4,,15 11522 .globl factorial 11523 .type factorial, @@function 11524factorial: 11525.LFB0: 11526 .file 1 "factorial.toy" 11527 .loc 1 14 0 11528 .cfi_startproc 11529.LVL0: 11530.L2: 11531 .loc 1 26 0 11532 cmpl $1, %edi 11533 jle .L13 11534 leal -1(%rdi), %edx 11535 movl %edx, %ecx 11536 shrl $2, %ecx 11537 leal 0(,%rcx,4), %esi 11538 testl %esi, %esi 11539 je .L14 11540 cmpl $9, %edx 11541 jbe .L14 11542 leal -2(%rdi), %eax 11543 movl %eax, -16(%rsp) 11544 leal -3(%rdi), %eax 11545 movd -16(%rsp), %xmm0 11546 movl %edi, -16(%rsp) 11547 movl %eax, -12(%rsp) 11548 movd -16(%rsp), %xmm1 11549 xorl %eax, %eax 11550 movl %edx, -16(%rsp) 11551 movd -12(%rsp), %xmm4 11552 movd -16(%rsp), %xmm6 11553 punpckldq %xmm4, %xmm0 11554 movdqa .LC1(%rip), %xmm4 11555 punpckldq %xmm6, %xmm1 11556 punpcklqdq %xmm0, %xmm1 11557 movdqa .LC0(%rip), %xmm0 11558 jmp .L5 11559 # etc - edited for brevity 11560@end example 11561 11562@noindent 11563 11564This is clearly overkill for a function that will likely overflow the 11565@code{int} type before the vectorization is worthwhile - but then again, this 11566is a toy example. 11567 11568Turning down the optimization level to 2: 11569 11570@example 11571ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2); 11572@end example 11573 11574@noindent 11575 11576yields this code, which is simple enough to quote in its entirety: 11577 11578@example 11579 .file "fake.c" 11580 .text 11581 .p2align 4,,15 11582 .globl factorial 11583 .type factorial, @@function 11584factorial: 11585.LFB0: 11586 .cfi_startproc 11587.L2: 11588 cmpl $1, %edi 11589 jle .L8 11590 movl $1, %edx 11591 jmp .L4 11592 .p2align 4,,10 11593 .p2align 3 11594.L6: 11595 movl %eax, %edi 11596.L4: 11597.L5: 11598 leal -1(%rdi), %eax 11599 imull %edi, %edx 11600 cmpl $1, %eax 11601 jne .L6 11602.L3: 11603.L7: 11604 imull %edx, %eax 11605 ret 11606.L8: 11607 movl %edi, %eax 11608 movl $1, %edx 11609 jmp .L7 11610 .cfi_endproc 11611.LFE0: 11612 .size factorial, .-factorial 11613 .ident "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2-%@{gcc_release@})" 11614 .section .note.GNU-stack,"",@@progbits 11615@end example 11616 11617@noindent 11618 11619Note that the stack pushing and popping have been eliminated, as has the 11620recursive call (in favor of an iteration). 11621 11622@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> 11623@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{12c} 11624@subsubsection Putting it all together 11625 11626 11627The complete example can be seen in the source tree at 11628@code{gcc/jit/docs/examples/tut04-toyvm/toyvm.cc} 11629 11630along with a Makefile and a couple of sample .toy scripts: 11631 11632@example 11633$ ls -al 11634drwxrwxr-x. 2 david david 4096 Sep 19 17:46 . 11635drwxrwxr-x. 3 david david 4096 Sep 19 15:26 .. 11636-rw-rw-r--. 1 david david 615 Sep 19 12:43 factorial.toy 11637-rw-rw-r--. 1 david david 834 Sep 19 13:08 fibonacci.toy 11638-rw-rw-r--. 1 david david 238 Sep 19 14:22 Makefile 11639-rw-rw-r--. 1 david david 16457 Sep 19 17:07 toyvm.cc 11640 11641$ make toyvm 11642g++ -Wall -g -o toyvm toyvm.cc -lgccjit 11643 11644$ ./toyvm factorial.toy 10 11645interpreter result: 3628800 11646compiler result: 3628800 11647 11648$ ./toyvm fibonacci.toy 10 11649interpreter result: 55 11650compiler result: 55 11651@end example 11652 11653@noindent 11654 11655@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> 11656@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{12d} 11657@subsubsection Behind the curtain: How does our code get optimized? 11658 11659 11660Our example is done, but you may be wondering about exactly how the 11661compiler turned what we gave it into the machine code seen above. 11662 11663We can examine what the compiler is doing in detail by setting: 11664 11665@example 11666state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 1); 11667state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 1); 11668@end example 11669 11670@noindent 11671 11672This will dump detailed information about the compiler's state to a 11673directory under @code{/tmp}, and keep it from being cleaned up. 11674 11675The precise names and their formats of these files is subject to change. 11676Higher optimization levels lead to more files. 11677Here's what I saw (edited for brevity; there were almost 200 files): 11678 11679@example 11680intermediate files written to /tmp/libgccjit-KPQbGw 11681$ ls /tmp/libgccjit-KPQbGw/ 11682fake.c.000i.cgraph 11683fake.c.000i.type-inheritance 11684fake.c.004t.gimple 11685fake.c.007t.omplower 11686fake.c.008t.lower 11687fake.c.011t.eh 11688fake.c.012t.cfg 11689fake.c.014i.visibility 11690fake.c.015i.early_local_cleanups 11691fake.c.016t.ssa 11692# etc 11693@end example 11694 11695@noindent 11696 11697The gimple code is converted into Static Single Assignment form, 11698with annotations for use when generating the debuginfo: 11699 11700@example 11701$ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa 11702@end example 11703 11704@noindent 11705 11706@example 11707;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11708 11709factorial (signed int arg) 11710@{ 11711 signed int stack[8]; 11712 signed int stack_depth; 11713 signed int x; 11714 signed int y; 11715 <unnamed type> _20; 11716 signed int _21; 11717 signed int _38; 11718 signed int _44; 11719 signed int _51; 11720 signed int _56; 11721 11722initial: 11723 stack_depth_3 = 0; 11724 # DEBUG stack_depth => stack_depth_3 11725 stack[stack_depth_3] = arg_5(D); 11726 stack_depth_7 = stack_depth_3 + 1; 11727 # DEBUG stack_depth => stack_depth_7 11728 # DEBUG instr0 => NULL 11729 # DEBUG /* DUP */ => NULL 11730 stack_depth_8 = stack_depth_7 + -1; 11731 # DEBUG stack_depth => stack_depth_8 11732 x_9 = stack[stack_depth_8]; 11733 # DEBUG x => x_9 11734 stack[stack_depth_8] = x_9; 11735 stack_depth_11 = stack_depth_8 + 1; 11736 # DEBUG stack_depth => stack_depth_11 11737 stack[stack_depth_11] = x_9; 11738 stack_depth_13 = stack_depth_11 + 1; 11739 # DEBUG stack_depth => stack_depth_13 11740 # DEBUG instr1 => NULL 11741 # DEBUG /* PUSH_CONST */ => NULL 11742 stack[stack_depth_13] = 2; 11743 11744 /* etc; edited for brevity */ 11745@end example 11746 11747@noindent 11748 11749We can perhaps better see the code by turning off 11750@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} to suppress all those @code{DEBUG} 11751statements, giving: 11752 11753@example 11754$ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa 11755@end example 11756 11757@noindent 11758 11759@example 11760;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11761 11762factorial (signed int arg) 11763@{ 11764 signed int stack[8]; 11765 signed int stack_depth; 11766 signed int x; 11767 signed int y; 11768 <unnamed type> _20; 11769 signed int _21; 11770 signed int _38; 11771 signed int _44; 11772 signed int _51; 11773 signed int _56; 11774 11775initial: 11776 stack_depth_3 = 0; 11777 stack[stack_depth_3] = arg_5(D); 11778 stack_depth_7 = stack_depth_3 + 1; 11779 stack_depth_8 = stack_depth_7 + -1; 11780 x_9 = stack[stack_depth_8]; 11781 stack[stack_depth_8] = x_9; 11782 stack_depth_11 = stack_depth_8 + 1; 11783 stack[stack_depth_11] = x_9; 11784 stack_depth_13 = stack_depth_11 + 1; 11785 stack[stack_depth_13] = 2; 11786 stack_depth_15 = stack_depth_13 + 1; 11787 stack_depth_16 = stack_depth_15 + -1; 11788 y_17 = stack[stack_depth_16]; 11789 stack_depth_18 = stack_depth_16 + -1; 11790 x_19 = stack[stack_depth_18]; 11791 _20 = x_19 < y_17; 11792 _21 = (signed int) _20; 11793 stack[stack_depth_18] = _21; 11794 stack_depth_23 = stack_depth_18 + 1; 11795 stack_depth_24 = stack_depth_23 + -1; 11796 x_25 = stack[stack_depth_24]; 11797 if (x_25 != 0) 11798 goto <bb 4> (instr9); 11799 else 11800 goto <bb 3> (instr4); 11801 11802instr4: 11803/* DUP */: 11804 stack_depth_26 = stack_depth_24 + -1; 11805 x_27 = stack[stack_depth_26]; 11806 stack[stack_depth_26] = x_27; 11807 stack_depth_29 = stack_depth_26 + 1; 11808 stack[stack_depth_29] = x_27; 11809 stack_depth_31 = stack_depth_29 + 1; 11810 stack[stack_depth_31] = 1; 11811 stack_depth_33 = stack_depth_31 + 1; 11812 stack_depth_34 = stack_depth_33 + -1; 11813 y_35 = stack[stack_depth_34]; 11814 stack_depth_36 = stack_depth_34 + -1; 11815 x_37 = stack[stack_depth_36]; 11816 _38 = x_37 - y_35; 11817 stack[stack_depth_36] = _38; 11818 stack_depth_40 = stack_depth_36 + 1; 11819 stack_depth_41 = stack_depth_40 + -1; 11820 x_42 = stack[stack_depth_41]; 11821 _44 = factorial (x_42); 11822 stack[stack_depth_41] = _44; 11823 stack_depth_46 = stack_depth_41 + 1; 11824 stack_depth_47 = stack_depth_46 + -1; 11825 y_48 = stack[stack_depth_47]; 11826 stack_depth_49 = stack_depth_47 + -1; 11827 x_50 = stack[stack_depth_49]; 11828 _51 = x_50 * y_48; 11829 stack[stack_depth_49] = _51; 11830 stack_depth_53 = stack_depth_49 + 1; 11831 11832 # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)> 11833instr9: 11834/* RETURN */: 11835 stack_depth_54 = stack_depth_1 + -1; 11836 x_55 = stack[stack_depth_54]; 11837 _56 = x_55; 11838 stack =@{v@} @{CLOBBER@}; 11839 return _56; 11840 11841@} 11842@end example 11843 11844@noindent 11845 11846Note in the above how all the @code{gccjit::block} instances we 11847created have been consolidated into just 3 blocks in GCC's internal 11848representation: @code{initial}, @code{instr4} and @code{instr9}. 11849 11850@menu 11851* Optimizing away stack manipulation: Optimizing away stack manipulation<2>. 11852* Elimination of tail recursion: Elimination of tail recursion<2>. 11853 11854@end menu 11855 11856@node Optimizing away stack manipulation<2>,Elimination of tail recursion<2>,,Behind the curtain How does our code get optimized?<2> 11857@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{12e} 11858@subsubsection Optimizing away stack manipulation 11859 11860 11861Recall our simple implementation of stack operations. Let's examine 11862how the stack operations are optimized away. 11863 11864After a pass of constant-propagation, the depth of the stack at each 11865opcode can be determined at compile-time: 11866 11867@example 11868$ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1 11869@end example 11870 11871@noindent 11872 11873@example 11874;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11875 11876factorial (signed int arg) 11877@{ 11878 signed int stack[8]; 11879 signed int stack_depth; 11880 signed int x; 11881 signed int y; 11882 <unnamed type> _20; 11883 signed int _21; 11884 signed int _38; 11885 signed int _44; 11886 signed int _51; 11887 11888initial: 11889 stack[0] = arg_5(D); 11890 x_9 = stack[0]; 11891 stack[0] = x_9; 11892 stack[1] = x_9; 11893 stack[2] = 2; 11894 y_17 = stack[2]; 11895 x_19 = stack[1]; 11896 _20 = x_19 < y_17; 11897 _21 = (signed int) _20; 11898 stack[1] = _21; 11899 x_25 = stack[1]; 11900 if (x_25 != 0) 11901 goto <bb 4> (instr9); 11902 else 11903 goto <bb 3> (instr4); 11904 11905instr4: 11906/* DUP */: 11907 x_27 = stack[0]; 11908 stack[0] = x_27; 11909 stack[1] = x_27; 11910 stack[2] = 1; 11911 y_35 = stack[2]; 11912 x_37 = stack[1]; 11913 _38 = x_37 - y_35; 11914 stack[1] = _38; 11915 x_42 = stack[1]; 11916 _44 = factorial (x_42); 11917 stack[1] = _44; 11918 y_48 = stack[1]; 11919 x_50 = stack[0]; 11920 _51 = x_50 * y_48; 11921 stack[0] = _51; 11922 11923instr9: 11924/* RETURN */: 11925 x_55 = stack[0]; 11926 x_56 = x_55; 11927 stack =@{v@} @{CLOBBER@}; 11928 return x_56; 11929 11930@} 11931@end example 11932 11933@noindent 11934 11935Note how, in the above, all those @code{stack_depth} values are now just 11936constants: we're accessing specific stack locations at each opcode. 11937 11938The "esra" pass ("Early Scalar Replacement of Aggregates") breaks 11939out our "stack" array into individual elements: 11940 11941@example 11942$ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra 11943@end example 11944 11945@noindent 11946 11947@example 11948;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 11949 11950Created a replacement for stack offset: 0, size: 32: stack$0 11951Created a replacement for stack offset: 32, size: 32: stack$1 11952Created a replacement for stack offset: 64, size: 32: stack$2 11953 11954Symbols to be put in SSA form 11955@{ D.89 D.90 D.91 @} 11956Incremental SSA update started at block: 0 11957Number of blocks in CFG: 5 11958Number of blocks to update: 4 ( 80%) 11959 11960 11961factorial (signed int arg) 11962@{ 11963 signed int stack$2; 11964 signed int stack$1; 11965 signed int stack$0; 11966 signed int stack[8]; 11967 signed int stack_depth; 11968 signed int x; 11969 signed int y; 11970 <unnamed type> _20; 11971 signed int _21; 11972 signed int _38; 11973 signed int _44; 11974 signed int _51; 11975 11976initial: 11977 stack$0_45 = arg_5(D); 11978 x_9 = stack$0_45; 11979 stack$0_39 = x_9; 11980 stack$1_32 = x_9; 11981 stack$2_30 = 2; 11982 y_17 = stack$2_30; 11983 x_19 = stack$1_32; 11984 _20 = x_19 < y_17; 11985 _21 = (signed int) _20; 11986 stack$1_28 = _21; 11987 x_25 = stack$1_28; 11988 if (x_25 != 0) 11989 goto <bb 4> (instr9); 11990 else 11991 goto <bb 3> (instr4); 11992 11993instr4: 11994/* DUP */: 11995 x_27 = stack$0_39; 11996 stack$0_22 = x_27; 11997 stack$1_14 = x_27; 11998 stack$2_12 = 1; 11999 y_35 = stack$2_12; 12000 x_37 = stack$1_14; 12001 _38 = x_37 - y_35; 12002 stack$1_10 = _38; 12003 x_42 = stack$1_10; 12004 _44 = factorial (x_42); 12005 stack$1_6 = _44; 12006 y_48 = stack$1_6; 12007 x_50 = stack$0_22; 12008 _51 = x_50 * y_48; 12009 stack$0_1 = _51; 12010 12011 # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)> 12012instr9: 12013/* RETURN */: 12014 x_55 = stack$0_52; 12015 x_56 = x_55; 12016 stack =@{v@} @{CLOBBER@}; 12017 return x_56; 12018 12019@} 12020@end example 12021 12022@noindent 12023 12024Hence at this point, all those pushes and pops of the stack are now 12025simply assignments to specific temporary variables. 12026 12027After some copy propagation, the stack manipulation has been completely 12028optimized away: 12029 12030@example 12031$ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1 12032@end example 12033 12034@noindent 12035 12036@example 12037;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12038 12039factorial (signed int arg) 12040@{ 12041 signed int stack$2; 12042 signed int stack$1; 12043 signed int stack$0; 12044 signed int stack[8]; 12045 signed int stack_depth; 12046 signed int x; 12047 signed int y; 12048 <unnamed type> _20; 12049 signed int _21; 12050 signed int _38; 12051 signed int _44; 12052 signed int _51; 12053 12054initial: 12055 stack$0_39 = arg_5(D); 12056 _20 = arg_5(D) <= 1; 12057 _21 = (signed int) _20; 12058 if (_21 != 0) 12059 goto <bb 4> (instr9); 12060 else 12061 goto <bb 3> (instr4); 12062 12063instr4: 12064/* DUP */: 12065 _38 = arg_5(D) + -1; 12066 _44 = factorial (_38); 12067 _51 = arg_5(D) * _44; 12068 stack$0_1 = _51; 12069 12070 # stack$0_52 = PHI <arg_5(D)(2), _51(3)> 12071instr9: 12072/* RETURN */: 12073 stack =@{v@} @{CLOBBER@}; 12074 return stack$0_52; 12075 12076@} 12077@end example 12078 12079@noindent 12080 12081Later on, another pass finally eliminated @code{stack_depth} local and the 12082unused parts of the @cite{stack`} array altogether: 12083 12084@example 12085$ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa 12086@end example 12087 12088@noindent 12089 12090@example 12091;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12092 12093Released 44 names, 314.29%, removed 44 holes 12094factorial (signed int arg) 12095@{ 12096 signed int stack$0; 12097 signed int mult_acc_1; 12098 <unnamed type> _5; 12099 signed int _6; 12100 signed int _7; 12101 signed int mul_tmp_10; 12102 signed int mult_acc_11; 12103 signed int mult_acc_13; 12104 12105 # arg_9 = PHI <arg_8(D)(0)> 12106 # mult_acc_13 = PHI <1(0)> 12107initial: 12108 12109 <bb 5>: 12110 # arg_4 = PHI <arg_9(2), _7(3)> 12111 # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)> 12112 _5 = arg_4 <= 1; 12113 _6 = (signed int) _5; 12114 if (_6 != 0) 12115 goto <bb 4> (instr9); 12116 else 12117 goto <bb 3> (instr4); 12118 12119instr4: 12120/* DUP */: 12121 _7 = arg_4 + -1; 12122 mult_acc_11 = mult_acc_1 * arg_4; 12123 goto <bb 5>; 12124 12125 # stack$0_12 = PHI <arg_4(5)> 12126instr9: 12127/* RETURN */: 12128 mul_tmp_10 = mult_acc_1 * stack$0_12; 12129 return mul_tmp_10; 12130 12131@} 12132@end example 12133 12134@noindent 12135 12136@node Elimination of tail recursion<2>,,Optimizing away stack manipulation<2>,Behind the curtain How does our code get optimized?<2> 12137@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{12f} 12138@subsubsection Elimination of tail recursion 12139 12140 12141Another significant optimization is the detection that the call to 12142@code{factorial} is tail recursion, which can be eliminated in favor of 12143an iteration: 12144 12145@example 12146$ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1 12147@end example 12148 12149@noindent 12150 12151@example 12152;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0) 12153 12154 12155Symbols to be put in SSA form 12156@{ D.88 @} 12157Incremental SSA update started at block: 0 12158Number of blocks in CFG: 5 12159Number of blocks to update: 4 ( 80%) 12160 12161 12162factorial (signed int arg) 12163@{ 12164 signed int stack$2; 12165 signed int stack$1; 12166 signed int stack$0; 12167 signed int stack[8]; 12168 signed int stack_depth; 12169 signed int x; 12170 signed int y; 12171 signed int mult_acc_1; 12172 <unnamed type> _20; 12173 signed int _21; 12174 signed int _38; 12175 signed int mul_tmp_44; 12176 signed int mult_acc_51; 12177 12178 # arg_5 = PHI <arg_39(D)(0), _38(3)> 12179 # mult_acc_1 = PHI <1(0), mult_acc_51(3)> 12180initial: 12181 _20 = arg_5 <= 1; 12182 _21 = (signed int) _20; 12183 if (_21 != 0) 12184 goto <bb 4> (instr9); 12185 else 12186 goto <bb 3> (instr4); 12187 12188instr4: 12189/* DUP */: 12190 _38 = arg_5 + -1; 12191 mult_acc_51 = mult_acc_1 * arg_5; 12192 goto <bb 2> (initial); 12193 12194 # stack$0_52 = PHI <arg_5(2)> 12195instr9: 12196/* RETURN */: 12197 stack =@{v@} @{CLOBBER@}; 12198 mul_tmp_44 = mult_acc_1 * stack$0_52; 12199 return mul_tmp_44; 12200 12201@} 12202@end example 12203 12204@noindent 12205 12206@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 12207@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12208@c 12209@c This is free software: you can redistribute it and/or modify it 12210@c under the terms of the GNU General Public License as published by 12211@c the Free Software Foundation, either version 3 of the License, or 12212@c (at your option) any later version. 12213@c 12214@c This program is distributed in the hope that it will be useful, but 12215@c WITHOUT ANY WARRANTY; without even the implied warranty of 12216@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12217@c General Public License for more details. 12218@c 12219@c You should have received a copy of the GNU General Public License 12220@c along with this program. If not, see 12221@c <http://www.gnu.org/licenses/>. 12222 12223@node Topic Reference<2>,,Tutorial<2>,C++ bindings for libgccjit 12224@anchor{cp/topics/index doc}@anchor{130}@anchor{cp/topics/index topic-reference}@anchor{131} 12225@section Topic Reference 12226 12227 12228@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 12229@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12230@c 12231@c This is free software: you can redistribute it and/or modify it 12232@c under the terms of the GNU General Public License as published by 12233@c the Free Software Foundation, either version 3 of the License, or 12234@c (at your option) any later version. 12235@c 12236@c This program is distributed in the hope that it will be useful, but 12237@c WITHOUT ANY WARRANTY; without even the implied warranty of 12238@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12239@c General Public License for more details. 12240@c 12241@c You should have received a copy of the GNU General Public License 12242@c along with this program. If not, see 12243@c <http://www.gnu.org/licenses/>. 12244 12245@menu 12246* Compilation contexts: Compilation contexts<2>. 12247* Objects: Objects<2>. 12248* Types: Types<2>. 12249* Expressions: Expressions<2>. 12250* Creating and using functions: Creating and using functions<2>. 12251* Source Locations: Source Locations<2>. 12252* Compiling a context: Compiling a context<2>. 12253 12254Compilation contexts 12255 12256* Lifetime-management: Lifetime-management<2>. 12257* Thread-safety: Thread-safety<2>. 12258* Error-handling: Error-handling<3>. 12259* Debugging: Debugging<2>. 12260* Options: Options<4>. 12261 12262Options 12263 12264* String Options: String Options<2>. 12265* Boolean options: Boolean options<2>. 12266* Integer options: Integer options<2>. 12267* Additional command-line options: Additional command-line options<2>. 12268 12269Types 12270 12271* Standard types: Standard types<2>. 12272* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 12273* Structures and unions: Structures and unions<2>. 12274 12275Expressions 12276 12277* Rvalues: Rvalues<2>. 12278* Lvalues: Lvalues<2>. 12279* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 12280 12281Rvalues 12282 12283* Simple expressions: Simple expressions<2>. 12284* Unary Operations: Unary Operations<2>. 12285* Binary Operations: Binary Operations<2>. 12286* Comparisons: Comparisons<2>. 12287* Function calls: Function calls<2>. 12288* Type-coercion: Type-coercion<2>. 12289 12290Lvalues 12291 12292* Global variables: Global variables<2>. 12293 12294Creating and using functions 12295 12296* Params: Params<2>. 12297* Functions: Functions<2>. 12298* Blocks: Blocks<2>. 12299* Statements: Statements<2>. 12300 12301Source Locations 12302 12303* Faking it: Faking it<2>. 12304 12305Compiling a context 12306 12307* In-memory compilation: In-memory compilation<2>. 12308* Ahead-of-time compilation: Ahead-of-time compilation<2>. 12309 12310@end menu 12311 12312 12313@node Compilation contexts<2>,Objects<2>,,Topic Reference<2> 12314@anchor{cp/topics/contexts compilation-contexts}@anchor{132}@anchor{cp/topics/contexts doc}@anchor{133} 12315@subsection Compilation contexts 12316 12317 12318@geindex gccjit;;context (C++ class) 12319@anchor{cp/topics/contexts gccjit context}@anchor{134} 12320@deffn {C++ Class} gccjit::context 12321@end deffn 12322 12323The top-level of the C++ API is the @pxref{134,,gccjit;;context} type. 12324 12325A @pxref{134,,gccjit;;context} instance encapsulates the state of a 12326compilation. 12327 12328You can set up options on it, and add types, functions and code. 12329Invoking @pxref{10d,,gccjit;;context;;compile()} on it gives you a 12330@pxref{16,,gcc_jit_result *}. 12331 12332It is a thin wrapper around the C API's @pxref{8,,gcc_jit_context *}. 12333 12334@menu 12335* Lifetime-management: Lifetime-management<2>. 12336* Thread-safety: Thread-safety<2>. 12337* Error-handling: Error-handling<3>. 12338* Debugging: Debugging<2>. 12339* Options: Options<4>. 12340 12341@end menu 12342 12343@node Lifetime-management<2>,Thread-safety<2>,,Compilation contexts<2> 12344@anchor{cp/topics/contexts lifetime-management}@anchor{135} 12345@subsubsection Lifetime-management 12346 12347 12348Contexts are the unit of lifetime-management within the API: objects 12349have their lifetime bounded by the context they are created within, and 12350cleanup of such objects is done for you when the context is released. 12351 12352@geindex gccjit;;context;;acquire (C++ function) 12353@anchor{cp/topics/contexts gccjit context acquire}@anchor{107} 12354@deffn {C++ Function} gccjit::context gccjit::context::acquire () 12355 12356This function acquires a new @pxref{134,,gccjit;;context} instance, 12357which is independent of any others that may be present within this 12358process. 12359@end deffn 12360 12361@geindex gccjit;;context;;release (C++ function) 12362@anchor{cp/topics/contexts gccjit context release}@anchor{109} 12363@deffn {C++ Function} void gccjit::context::release () 12364 12365This function releases all resources associated with the given context. 12366Both the context itself and all of its @code{gccjit::object *} 12367instances are cleaned up. It should be called exactly once on a given 12368context. 12369 12370It is invalid to use the context or any of its "contextual" objects 12371after calling this. 12372 12373@example 12374ctxt.release (); 12375@end example 12376 12377@noindent 12378@end deffn 12379 12380@geindex gccjit;;context;;new_child_context (C++ function) 12381@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{136} 12382@deffn {C++ Function} gccjit::context gccjit::context::new_child_context () 12383 12384Given an existing JIT context, create a child context. 12385 12386The child inherits a copy of all option-settings from the parent. 12387 12388The child can reference objects created within the parent, but not 12389vice-versa. 12390 12391The lifetime of the child context must be bounded by that of the 12392parent: you should release a child context before releasing the parent 12393context. 12394 12395If you use a function from a parent context within a child context, 12396you have to compile the parent context before you can compile the 12397child context, and the gccjit::result of the parent context must 12398outlive the gccjit::result of the child context. 12399 12400This allows caching of shared initializations. For example, you could 12401create types and declarations of global functions in a parent context 12402once within a process, and then create child contexts whenever a 12403function or loop becomes hot. Each such child context can be used for 12404JIT-compiling just one function or loop, but can reference types 12405and helper functions created within the parent context. 12406 12407Contexts can be arbitrarily nested, provided the above rules are 12408followed, but it's probably not worth going above 2 or 3 levels, and 12409there will likely be a performance hit for such nesting. 12410@end deffn 12411 12412@node Thread-safety<2>,Error-handling<3>,Lifetime-management<2>,Compilation contexts<2> 12413@anchor{cp/topics/contexts thread-safety}@anchor{137} 12414@subsubsection Thread-safety 12415 12416 12417Instances of @pxref{134,,gccjit;;context} created via 12418@pxref{107,,gccjit;;context;;acquire()} are independent from each other: 12419only one thread may use a given context at once, but multiple threads 12420could each have their own contexts without needing locks. 12421 12422Contexts created via @pxref{136,,gccjit;;context;;new_child_context()} are 12423related to their parent context. They can be partitioned by their 12424ultimate ancestor into independent "family trees". Only one thread 12425within a process may use a given "family tree" of such contexts at once, 12426and if you're using multiple threads you should provide your own locking 12427around entire such context partitions. 12428 12429@node Error-handling<3>,Debugging<2>,Thread-safety<2>,Compilation contexts<2> 12430@anchor{cp/topics/contexts error-handling}@anchor{138} 12431@subsubsection Error-handling 12432 12433 12434@c FIXME: How does error-handling work for C++ API? 12435 12436You can only compile and get code from a context if no errors occur. 12437 12438In general, if an error occurs when using an API entrypoint, it returns 12439NULL. You don't have to check everywhere for NULL results, since the 12440API gracefully handles a NULL being passed in for any argument. 12441 12442Errors are printed on stderr and can be queried using 12443@pxref{139,,gccjit;;context;;get_first_error()}. 12444 12445@geindex gccjit;;context;;get_first_error (C++ function) 12446@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{139} 12447@deffn {C++ Function} const char* gccjit::context::get_first_error (gccjit::context* ctxt) 12448 12449Returns the first error message that occurred on the context. 12450 12451The returned string is valid for the rest of the lifetime of the 12452context. 12453 12454If no errors occurred, this will be NULL. 12455@end deffn 12456 12457@node Debugging<2>,Options<4>,Error-handling<3>,Compilation contexts<2> 12458@anchor{cp/topics/contexts debugging}@anchor{13a} 12459@subsubsection Debugging 12460 12461 12462@geindex gccjit;;context;;dump_to_file (C++ function) 12463@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{13b} 12464@deffn {C++ Function} void gccjit::context::dump_to_file (const std::string& path, int update_locations) 12465 12466To help with debugging: dump a C-like representation to the given path, 12467describing what's been set up on the context. 12468 12469If "update_locations" is true, then also set up @pxref{13c,,gccjit;;location} 12470information throughout the context, pointing at the dump file as if it 12471were a source file. This may be of use in conjunction with 12472@code{GCCJIT::BOOL_OPTION_DEBUGINFO} to allow stepping through the 12473code in a debugger. 12474@end deffn 12475 12476@geindex gccjit;;context;;dump_reproducer_to_file (C++ function) 12477@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{13d} 12478@deffn {C++ Function} void gccjit::context::dump_reproducer_to_file (gcc_jit_context* ctxt, const char* path) 12479 12480This is a thin wrapper around the C API 12481@pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}, and hence works the 12482same way. 12483 12484Note that the generated source is C code, not C++; this might be of use 12485for seeing what the C++ bindings are doing at the C level. 12486@end deffn 12487 12488@node Options<4>,,Debugging<2>,Compilation contexts<2> 12489@anchor{cp/topics/contexts options}@anchor{13e} 12490@subsubsection Options 12491 12492 12493@menu 12494* String Options: String Options<2>. 12495* Boolean options: Boolean options<2>. 12496* Integer options: Integer options<2>. 12497* Additional command-line options: Additional command-line options<2>. 12498 12499@end menu 12500 12501@node String Options<2>,Boolean options<2>,,Options<4> 12502@anchor{cp/topics/contexts string-options}@anchor{13f} 12503@subsubsection String Options 12504 12505 12506@geindex gccjit;;context;;set_str_option (C++ function) 12507@anchor{cp/topics/contexts gccjit context set_str_option__enum cCP}@anchor{140} 12508@deffn {C++ Function} void gccjit::context::set_str_option (enum gcc_jit_str_option, const char* value) 12509 12510Set a string option of the context. 12511 12512This is a thin wrapper around the C API 12513@pxref{61,,gcc_jit_context_set_str_option()}; the options have the same 12514meaning. 12515@end deffn 12516 12517@node Boolean options<2>,Integer options<2>,String Options<2>,Options<4> 12518@anchor{cp/topics/contexts boolean-options}@anchor{141} 12519@subsubsection Boolean options 12520 12521 12522@geindex gccjit;;context;;set_bool_option (C++ function) 12523@anchor{cp/topics/contexts gccjit context set_bool_option__enum i}@anchor{10f} 12524@deffn {C++ Function} void gccjit::context::set_bool_option (enum gcc_jit_bool_option, int value) 12525 12526Set a boolean option of the context. 12527 12528This is a thin wrapper around the C API 12529@pxref{1b,,gcc_jit_context_set_bool_option()}; the options have the same 12530meaning. 12531@end deffn 12532 12533@geindex gccjit;;context;;set_bool_allow_unreachable_blocks (C++ function) 12534@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{142} 12535@deffn {C++ Function} void gccjit::context::set_bool_allow_unreachable_blocks (int bool_value) 12536 12537By default, libgccjit will issue an error about unreachable blocks 12538within a function. 12539 12540This entrypoint can be used to disable that error; it is a thin wrapper 12541around the C API 12542@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}. 12543 12544This entrypoint was added in @pxref{6c,,LIBGCCJIT_ABI_2}; you can test for 12545its presence using 12546 12547@example 12548#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 12549@end example 12550 12551@noindent 12552@end deffn 12553 12554@geindex gccjit;;context;;set_bool_use_external_driver (C++ function) 12555@anchor{cp/topics/contexts gccjit context set_bool_use_external_driver__i}@anchor{143} 12556@deffn {C++ Function} void gccjit::context::set_bool_use_external_driver (int bool_value) 12557 12558libgccjit internally generates assembler, and uses "driver" code 12559for converting it to other formats (e.g. shared libraries). 12560 12561By default, libgccjit will use an embedded copy of the driver 12562code. 12563 12564This option can be used to instead invoke an external driver executable 12565as a subprocess; it is a thin wrapper around the C API 12566@pxref{6d,,gcc_jit_context_set_bool_use_external_driver()}. 12567 12568This entrypoint was added in @pxref{6e,,LIBGCCJIT_ABI_5}; you can test for 12569its presence using 12570 12571@example 12572#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver 12573@end example 12574 12575@noindent 12576@end deffn 12577 12578@node Integer options<2>,Additional command-line options<2>,Boolean options<2>,Options<4> 12579@anchor{cp/topics/contexts integer-options}@anchor{144} 12580@subsubsection Integer options 12581 12582 12583@geindex gccjit;;context;;set_int_option (C++ function) 12584@anchor{cp/topics/contexts gccjit context set_int_option__enum i}@anchor{110} 12585@deffn {C++ Function} void gccjit::context::set_int_option (enum gcc_jit_int_option, int value) 12586 12587Set an integer option of the context. 12588 12589This is a thin wrapper around the C API 12590@pxref{1e,,gcc_jit_context_set_int_option()}; the options have the same 12591meaning. 12592@end deffn 12593 12594@node Additional command-line options<2>,,Integer options<2>,Options<4> 12595@anchor{cp/topics/contexts additional-command-line-options}@anchor{145} 12596@subsubsection Additional command-line options 12597 12598 12599@geindex gccjit;;context;;add_command_line_option (C++ function) 12600@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{146} 12601@deffn {C++ Function} void gccjit::context::add_command_line_option (const char* optname) 12602 12603Add an arbitrary gcc command-line option to the context for use 12604when compiling. 12605 12606This is a thin wrapper around the C API 12607@pxref{72,,gcc_jit_context_add_command_line_option()}. 12608 12609This entrypoint was added in @pxref{73,,LIBGCCJIT_ABI_1}; you can test for 12610its presence using 12611 12612@example 12613#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 12614@end example 12615 12616@noindent 12617@end deffn 12618 12619@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 12620@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12621@c 12622@c This is free software: you can redistribute it and/or modify it 12623@c under the terms of the GNU General Public License as published by 12624@c the Free Software Foundation, either version 3 of the License, or 12625@c (at your option) any later version. 12626@c 12627@c This program is distributed in the hope that it will be useful, but 12628@c WITHOUT ANY WARRANTY; without even the implied warranty of 12629@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12630@c General Public License for more details. 12631@c 12632@c You should have received a copy of the GNU General Public License 12633@c along with this program. If not, see 12634@c <http://www.gnu.org/licenses/>. 12635 12636@node Objects<2>,Types<2>,Compilation contexts<2>,Topic Reference<2> 12637@anchor{cp/topics/objects objects}@anchor{147}@anchor{cp/topics/objects doc}@anchor{148} 12638@subsection Objects 12639 12640 12641@geindex gccjit;;object (C++ class) 12642@anchor{cp/topics/objects gccjit object}@anchor{149} 12643@deffn {C++ Class} gccjit::object 12644@end deffn 12645 12646Almost every entity in the API (with the exception of 12647@pxref{134,,gccjit;;context} and @pxref{16,,gcc_jit_result *}) is a 12648"contextual" object, a @pxref{149,,gccjit;;object}. 12649 12650A JIT object: 12651 12652@quotation 12653 12654 12655@itemize * 12656 12657@item 12658is associated with a @pxref{134,,gccjit;;context}. 12659 12660@item 12661is automatically cleaned up for you when its context is released so 12662you don't need to manually track and cleanup all objects, just the 12663contexts. 12664@end itemize 12665@end quotation 12666 12667The C++ class hierarchy within the @code{gccjit} namespace looks like this: 12668 12669@example 12670+- object 12671 +- location 12672 +- type 12673 +- struct 12674 +- field 12675 +- function 12676 +- block 12677 +- rvalue 12678 +- lvalue 12679 +- param 12680 +- case_ 12681@end example 12682 12683@noindent 12684 12685The @pxref{149,,gccjit;;object} base class has the following operations: 12686 12687@geindex gccjit;;object;;get_context (C++ function) 12688@anchor{cp/topics/objects gccjit object get_contextC}@anchor{14a} 12689@deffn {C++ Function} gccjit::context gccjit::object::get_context () const 12690 12691Which context is the obj within? 12692@end deffn 12693 12694@geindex gccjit;;object;;get_debug_string (C++ function) 12695@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{10a} 12696@deffn {C++ Function} std::string gccjit::object::get_debug_string () const 12697 12698Generate a human-readable description for the given object. 12699 12700For example, 12701 12702@example 12703printf ("obj: %s\n", obj.get_debug_string ().c_str ()); 12704@end example 12705 12706@noindent 12707 12708might give this text on stdout: 12709 12710@example 12711obj: 4.0 * (float)i 12712@end example 12713 12714@noindent 12715@end deffn 12716 12717@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 12718@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12719@c 12720@c This is free software: you can redistribute it and/or modify it 12721@c under the terms of the GNU General Public License as published by 12722@c the Free Software Foundation, either version 3 of the License, or 12723@c (at your option) any later version. 12724@c 12725@c This program is distributed in the hope that it will be useful, but 12726@c WITHOUT ANY WARRANTY; without even the implied warranty of 12727@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12728@c General Public License for more details. 12729@c 12730@c You should have received a copy of the GNU General Public License 12731@c along with this program. If not, see 12732@c <http://www.gnu.org/licenses/>. 12733 12734@node Types<2>,Expressions<2>,Objects<2>,Topic Reference<2> 12735@anchor{cp/topics/types doc}@anchor{14b}@anchor{cp/topics/types types}@anchor{14c} 12736@subsection Types 12737 12738 12739@geindex gccjit;;type (C++ class) 12740@anchor{cp/topics/types gccjit type}@anchor{14d} 12741@deffn {C++ Class} gccjit::type 12742 12743gccjit::type represents a type within the library. It is a subclass 12744of @pxref{149,,gccjit;;object}. 12745@end deffn 12746 12747Types can be created in several ways: 12748 12749 12750@itemize * 12751 12752@item 12753fundamental types can be accessed using 12754@pxref{108,,gccjit;;context;;get_type()}: 12755 12756@example 12757gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT); 12758@end example 12759 12760@noindent 12761 12762or using the @code{gccjit::context::get_int_type} template: 12763 12764@example 12765gccjit::type t = ctxt.get_int_type <unsigned short> (); 12766@end example 12767 12768@noindent 12769 12770See @pxref{b,,gcc_jit_context_get_type()} for the available types. 12771 12772@item 12773derived types can be accessed by using functions such as 12774@pxref{14e,,gccjit;;type;;get_pointer()} and @pxref{14f,,gccjit;;type;;get_const()}: 12775 12776@example 12777gccjit::type const_int_star = int_type.get_const ().get_pointer (); 12778gccjit::type int_const_star = int_type.get_pointer ().get_const (); 12779@end example 12780 12781@noindent 12782 12783@item 12784by creating structures (see below). 12785@end itemize 12786 12787@menu 12788* Standard types: Standard types<2>. 12789* Pointers@comma{} const@comma{} and volatile: Pointers const and volatile<2>. 12790* Structures and unions: Structures and unions<2>. 12791 12792@end menu 12793 12794@node Standard types<2>,Pointers const and volatile<2>,,Types<2> 12795@anchor{cp/topics/types standard-types}@anchor{150} 12796@subsubsection Standard types 12797 12798 12799@geindex gccjit;;context;;get_type (C++ function) 12800@anchor{cp/topics/types gccjit context get_type__enum}@anchor{108} 12801@deffn {C++ Function} gccjit::type gccjit::context::get_type (enum gcc_jit_types) 12802 12803Access a specific type. This is a thin wrapper around 12804@pxref{b,,gcc_jit_context_get_type()}; the parameter has the same meaning. 12805@end deffn 12806 12807@geindex gccjit;;context;;get_int_type (C++ function) 12808@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{151} 12809@deffn {C++ Function} gccjit::type gccjit::context::get_int_type (size_t num_bytes, int is_signed) 12810 12811Access the integer type of the given size. 12812@end deffn 12813 12814@geindex gccjit;;context;;get_int_type<T> (C++ function) 12815@anchor{cp/topics/types gccjit context get_int_type T}@anchor{152} 12816@deffn {C++ Function} gccjit::type gccjit::context::get_int_type<T> () 12817 12818Access the given integer type. For example, you could map the 12819@code{unsigned short} type into a gccjit::type via: 12820 12821@example 12822gccjit::type t = ctxt.get_int_type <unsigned short> (); 12823@end example 12824 12825@noindent 12826@end deffn 12827 12828@node Pointers const and volatile<2>,Structures and unions<2>,Standard types<2>,Types<2> 12829@anchor{cp/topics/types pointers-const-and-volatile}@anchor{153} 12830@subsubsection Pointers, @cite{const}, and @cite{volatile} 12831 12832 12833@geindex gccjit;;type;;get_pointer (C++ function) 12834@anchor{cp/topics/types gccjit type get_pointer}@anchor{14e} 12835@deffn {C++ Function} gccjit::type gccjit::type::get_pointer () 12836 12837Given type "T", get type "T*". 12838@end deffn 12839 12840@c FIXME: get_const doesn't seem to exist 12841 12842@geindex gccjit;;type;;get_const (C++ function) 12843@anchor{cp/topics/types gccjit type get_const}@anchor{14f} 12844@deffn {C++ Function} gccjit::type gccjit::type::get_const () 12845 12846Given type "T", get type "const T". 12847@end deffn 12848 12849@geindex gccjit;;type;;get_volatile (C++ function) 12850@anchor{cp/topics/types gccjit type get_volatile}@anchor{154} 12851@deffn {C++ Function} gccjit::type gccjit::type::get_volatile () 12852 12853Given type "T", get type "volatile T". 12854@end deffn 12855 12856@geindex gccjit;;context;;new_array_type (C++ function) 12857@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{155} 12858@deffn {C++ Function} gccjit::type gccjit::context::new_array_type (gccjit::type element_type, int num_elements, gccjit::location loc) 12859 12860Given type "T", get type "T[N]" (for a constant N). 12861Param "loc" is optional. 12862@end deffn 12863 12864@node Structures and unions<2>,,Pointers const and volatile<2>,Types<2> 12865@anchor{cp/topics/types structures-and-unions}@anchor{156} 12866@subsubsection Structures and unions 12867 12868 12869@geindex gccjit;;struct_ (C++ class) 12870@anchor{cp/topics/types gccjit struct_}@anchor{157} 12871@deffn {C++ Class} gccjit::struct_ 12872@end deffn 12873 12874A compound type analagous to a C @cite{struct}. 12875 12876@pxref{157,,gccjit;;struct_} is a subclass of @pxref{14d,,gccjit;;type} (and thus 12877of @pxref{149,,gccjit;;object} in turn). 12878 12879@geindex gccjit;;field (C++ class) 12880@anchor{cp/topics/types gccjit field}@anchor{158} 12881@deffn {C++ Class} gccjit::field 12882@end deffn 12883 12884A field within a @pxref{157,,gccjit;;struct_}. 12885 12886@pxref{158,,gccjit;;field} is a subclass of @pxref{149,,gccjit;;object}. 12887 12888You can model C @cite{struct} types by creating @pxref{157,,gccjit;;struct_} and 12889@pxref{158,,gccjit;;field} instances, in either order: 12890 12891 12892@itemize * 12893 12894@item 12895by creating the fields, then the structure. For example, to model: 12896 12897@example 12898struct coord @{double x; double y; @}; 12899@end example 12900 12901@noindent 12902 12903you could call: 12904 12905@example 12906gccjit::field field_x = ctxt.new_field (double_type, "x"); 12907gccjit::field field_y = ctxt.new_field (double_type, "y"); 12908std::vector fields; 12909fields.push_back (field_x); 12910fields.push_back (field_y); 12911gccjit::struct_ coord = ctxt.new_struct_type ("coord", fields); 12912@end example 12913 12914@noindent 12915 12916@item 12917by creating the structure, then populating it with fields, typically 12918to allow modelling self-referential structs such as: 12919 12920@example 12921struct node @{ int m_hash; struct node *m_next; @}; 12922@end example 12923 12924@noindent 12925 12926like this: 12927 12928@example 12929gccjit::struct_ node = ctxt.new_opaque_struct_type ("node"); 12930gccjit::type node_ptr = node.get_pointer (); 12931gccjit::field field_hash = ctxt.new_field (int_type, "m_hash"); 12932gccjit::field field_next = ctxt.new_field (node_ptr, "m_next"); 12933std::vector fields; 12934fields.push_back (field_hash); 12935fields.push_back (field_next); 12936node.set_fields (fields); 12937@end example 12938 12939@noindent 12940@end itemize 12941 12942@c FIXME: the above API doesn't seem to exist yet 12943 12944@geindex gccjit;;context;;new_field (C++ function) 12945@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{159} 12946@deffn {C++ Function} gccjit::field gccjit::context::new_field (gccjit::type type, const char* name, gccjit::location loc) 12947 12948Construct a new field, with the given type and name. 12949@end deffn 12950 12951@geindex gccjit;;context;;new_struct_type (C++ function) 12952@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{15a} 12953@deffn {C++ Function} gccjit::struct_ gccjit::context::new_struct_type (const std::string& name, std::vector<field>& fields, gccjit::location loc) 12954 12955@quotation 12956 12957Construct a new struct type, with the given name and fields. 12958@end quotation 12959@end deffn 12960 12961@geindex gccjit;;context;;new_opaque_struct (C++ function) 12962@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{15b} 12963@deffn {C++ Function} gccjit::struct_ gccjit::context::new_opaque_struct (const std::string& name, gccjit::location loc) 12964 12965Construct a new struct type, with the given name, but without 12966specifying the fields. The fields can be omitted (in which case the 12967size of the struct is not known), or later specified using 12968@pxref{87,,gcc_jit_struct_set_fields()}. 12969@end deffn 12970 12971@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 12972@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 12973@c 12974@c This is free software: you can redistribute it and/or modify it 12975@c under the terms of the GNU General Public License as published by 12976@c the Free Software Foundation, either version 3 of the License, or 12977@c (at your option) any later version. 12978@c 12979@c This program is distributed in the hope that it will be useful, but 12980@c WITHOUT ANY WARRANTY; without even the implied warranty of 12981@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12982@c General Public License for more details. 12983@c 12984@c You should have received a copy of the GNU General Public License 12985@c along with this program. If not, see 12986@c <http://www.gnu.org/licenses/>. 12987 12988@node Expressions<2>,Creating and using functions<2>,Types<2>,Topic Reference<2> 12989@anchor{cp/topics/expressions expressions}@anchor{15c}@anchor{cp/topics/expressions doc}@anchor{15d} 12990@subsection Expressions 12991 12992 12993@menu 12994* Rvalues: Rvalues<2>. 12995* Lvalues: Lvalues<2>. 12996* Working with pointers@comma{} structs and unions: Working with pointers structs and unions<2>. 12997 12998Rvalues 12999 13000* Simple expressions: Simple expressions<2>. 13001* Unary Operations: Unary Operations<2>. 13002* Binary Operations: Binary Operations<2>. 13003* Comparisons: Comparisons<2>. 13004* Function calls: Function calls<2>. 13005* Type-coercion: Type-coercion<2>. 13006 13007Lvalues 13008 13009* Global variables: Global variables<2>. 13010 13011@end menu 13012 13013 13014@node Rvalues<2>,Lvalues<2>,,Expressions<2> 13015@anchor{cp/topics/expressions rvalues}@anchor{15e} 13016@subsubsection Rvalues 13017 13018 13019@geindex gccjit;;rvalue (C++ class) 13020@anchor{cp/topics/expressions gccjit rvalue}@anchor{15f} 13021@deffn {C++ Class} gccjit::rvalue 13022@end deffn 13023 13024A @pxref{15f,,gccjit;;rvalue} is an expression that can be computed. It is a 13025subclass of @pxref{149,,gccjit;;object}, and is a thin wrapper around 13026@pxref{13,,gcc_jit_rvalue *} from the C API. 13027 13028It can be simple, e.g.: 13029 13030@quotation 13031 13032 13033@itemize * 13034 13035@item 13036an integer value e.g. @cite{0} or @cite{42} 13037 13038@item 13039a string literal e.g. @cite{"Hello world"} 13040 13041@item 13042a variable e.g. @cite{i}. These are also lvalues (see below). 13043@end itemize 13044@end quotation 13045 13046or compound e.g.: 13047 13048@quotation 13049 13050 13051@itemize * 13052 13053@item 13054a unary expression e.g. @cite{!cond} 13055 13056@item 13057a binary expression e.g. @cite{(a + b)} 13058 13059@item 13060a function call e.g. @cite{get_distance (&player_ship@comma{} &target)} 13061 13062@item 13063etc. 13064@end itemize 13065@end quotation 13066 13067Every rvalue has an associated type, and the API will check to ensure 13068that types match up correctly (otherwise the context will emit an error). 13069 13070@geindex gccjit;;rvalue;;get_type (C++ function) 13071@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{160} 13072@deffn {C++ Function} gccjit::type gccjit::rvalue::get_type () 13073 13074Get the type of this rvalue. 13075@end deffn 13076 13077@menu 13078* Simple expressions: Simple expressions<2>. 13079* Unary Operations: Unary Operations<2>. 13080* Binary Operations: Binary Operations<2>. 13081* Comparisons: Comparisons<2>. 13082* Function calls: Function calls<2>. 13083* Type-coercion: Type-coercion<2>. 13084 13085@end menu 13086 13087@node Simple expressions<2>,Unary Operations<2>,,Rvalues<2> 13088@anchor{cp/topics/expressions simple-expressions}@anchor{161} 13089@subsubsection Simple expressions 13090 13091 13092@geindex gccjit;;context;;new_rvalue (C++ function) 13093@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{11c} 13094@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, int value) const 13095 13096Given a numeric type (integer or floating point), build an rvalue for 13097the given constant @code{int} value. 13098@end deffn 13099 13100@geindex gccjit;;context;;new_rvalue (C++ function) 13101@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{162} 13102@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, long value) const 13103 13104Given a numeric type (integer or floating point), build an rvalue for 13105the given constant @code{long} value. 13106@end deffn 13107 13108@geindex gccjit;;context;;zero (C++ function) 13109@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{118} 13110@deffn {C++ Function} gccjit::rvalue gccjit::context::zero (gccjit::type numeric_type) const 13111 13112Given a numeric type (integer or floating point), get the rvalue for 13113zero. Essentially this is just a shortcut for: 13114 13115@example 13116ctxt.new_rvalue (numeric_type, 0) 13117@end example 13118 13119@noindent 13120@end deffn 13121 13122@geindex gccjit;;context;;one (C++ function) 13123@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{163} 13124@deffn {C++ Function} gccjit::rvalue gccjit::context::one (gccjit::type numeric_type) const 13125 13126Given a numeric type (integer or floating point), get the rvalue for 13127one. Essentially this is just a shortcut for: 13128 13129@example 13130ctxt.new_rvalue (numeric_type, 1) 13131@end example 13132 13133@noindent 13134@end deffn 13135 13136@geindex gccjit;;context;;new_rvalue (C++ function) 13137@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{164} 13138@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, double value) const 13139 13140Given a numeric type (integer or floating point), build an rvalue for 13141the given constant @code{double} value. 13142@end deffn 13143 13144@geindex gccjit;;context;;new_rvalue (C++ function) 13145@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{165} 13146@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type pointer_type, void* value) const 13147 13148Given a pointer type, build an rvalue for the given address. 13149@end deffn 13150 13151@geindex gccjit;;context;;new_rvalue (C++ function) 13152@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{166} 13153@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (const std::string& value) const 13154 13155Generate an rvalue of type @code{GCC_JIT_TYPE_CONST_CHAR_PTR} for 13156the given string. This is akin to a string literal. 13157@end deffn 13158 13159@node Unary Operations<2>,Binary Operations<2>,Simple expressions<2>,Rvalues<2> 13160@anchor{cp/topics/expressions unary-operations}@anchor{167} 13161@subsubsection Unary Operations 13162 13163 13164@geindex gccjit;;context;;new_unary_op (C++ function) 13165@anchor{cp/topics/expressions gccjit context new_unary_op__enum gccjit type gccjit rvalue gccjit location}@anchor{168} 13166@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) 13167 13168Build a unary operation out of an input rvalue. 13169 13170Parameter @code{loc} is optional. 13171 13172This is a thin wrapper around the C API's 13173@pxref{94,,gcc_jit_context_new_unary_op()} and the available unary 13174operations are documented there. 13175@end deffn 13176 13177There are shorter ways to spell the various specific kinds of unary 13178operation: 13179 13180@geindex gccjit;;context;;new_minus (C++ function) 13181@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{169} 13182@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 13183 13184Negate an arithmetic value; for example: 13185 13186@example 13187gccjit::rvalue negpi = ctxt.new_minus (t_double, pi); 13188@end example 13189 13190@noindent 13191 13192builds the equivalent of this C expression: 13193 13194@example 13195-pi 13196@end example 13197 13198@noindent 13199@end deffn 13200 13201@geindex new_bitwise_negate (C++ function) 13202@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{16a} 13203@deffn {C++ Function} gccjit::rvalue new_bitwise_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 13204 13205Bitwise negation of an integer value (one's complement); for example: 13206 13207@example 13208gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a); 13209@end example 13210 13211@noindent 13212 13213builds the equivalent of this C expression: 13214 13215@example 13216~a 13217@end example 13218 13219@noindent 13220@end deffn 13221 13222@geindex new_logical_negate (C++ function) 13223@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{16b} 13224@deffn {C++ Function} gccjit::rvalue new_logical_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc) 13225 13226Logical negation of an arithmetic or pointer value; for example: 13227 13228@example 13229gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond); 13230@end example 13231 13232@noindent 13233 13234builds the equivalent of this C expression: 13235 13236@example 13237!cond 13238@end example 13239 13240@noindent 13241@end deffn 13242 13243The most concise way to spell them is with overloaded operators: 13244 13245@geindex operator- (C++ function) 13246@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{16c} 13247@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a) 13248 13249@example 13250gccjit::rvalue negpi = -pi; 13251@end example 13252 13253@noindent 13254@end deffn 13255 13256@geindex operator~ (C++ function) 13257@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{16d} 13258@deffn {C++ Function} gccjit::rvalue operator~ (gccjit::rvalue a) 13259 13260@example 13261gccjit::rvalue mask = ~a; 13262@end example 13263 13264@noindent 13265@end deffn 13266 13267@geindex operator! (C++ function) 13268@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{16e} 13269@deffn {C++ Function} gccjit::rvalue operator! (gccjit::rvalue a) 13270 13271@example 13272gccjit::rvalue guard = !cond; 13273@end example 13274 13275@noindent 13276@end deffn 13277 13278@node Binary Operations<2>,Comparisons<2>,Unary Operations<2>,Rvalues<2> 13279@anchor{cp/topics/expressions binary-operations}@anchor{16f} 13280@subsubsection Binary Operations 13281 13282 13283@geindex gccjit;;context;;new_binary_op (C++ function) 13284@anchor{cp/topics/expressions gccjit context new_binary_op__enum gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{10c} 13285@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) 13286 13287Build a binary operation out of two constituent rvalues. 13288 13289Parameter @code{loc} is optional. 13290 13291This is a thin wrapper around the C API's 13292@pxref{12,,gcc_jit_context_new_binary_op()} and the available binary 13293operations are documented there. 13294@end deffn 13295 13296There are shorter ways to spell the various specific kinds of binary 13297operation: 13298 13299@geindex gccjit;;context;;new_plus (C++ function) 13300@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{170} 13301@deffn {C++ Function} gccjit::rvalue gccjit::context::new_plus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13302@end deffn 13303 13304@geindex gccjit;;context;;new_minus (C++ function) 13305@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{171} 13306@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13307@end deffn 13308 13309@geindex gccjit;;context;;new_mult (C++ function) 13310@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{172} 13311@deffn {C++ Function} gccjit::rvalue gccjit::context::new_mult (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13312@end deffn 13313 13314@geindex gccjit;;context;;new_divide (C++ function) 13315@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{173} 13316@deffn {C++ Function} gccjit::rvalue gccjit::context::new_divide (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13317@end deffn 13318 13319@geindex gccjit;;context;;new_modulo (C++ function) 13320@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{174} 13321@deffn {C++ Function} gccjit::rvalue gccjit::context::new_modulo (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13322@end deffn 13323 13324@geindex gccjit;;context;;new_bitwise_and (C++ function) 13325@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{175} 13326@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13327@end deffn 13328 13329@geindex gccjit;;context;;new_bitwise_xor (C++ function) 13330@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{176} 13331@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_xor (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13332@end deffn 13333 13334@geindex gccjit;;context;;new_bitwise_or (C++ function) 13335@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{177} 13336@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13337@end deffn 13338 13339@geindex gccjit;;context;;new_logical_and (C++ function) 13340@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{178} 13341@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13342@end deffn 13343 13344@geindex gccjit;;context;;new_logical_or (C++ function) 13345@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{179} 13346@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13347@end deffn 13348 13349The most concise way to spell them is with overloaded operators: 13350 13351@geindex operator+ (C++ function) 13352@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{17a} 13353@deffn {C++ Function} gccjit::rvalue operator+ (gccjit::rvalue a, gccjit::rvalue b) 13354 13355@example 13356gccjit::rvalue sum = a + b; 13357@end example 13358 13359@noindent 13360@end deffn 13361 13362@geindex operator- (C++ function) 13363@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{17b} 13364@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a, gccjit::rvalue b) 13365 13366@example 13367gccjit::rvalue diff = a - b; 13368@end example 13369 13370@noindent 13371@end deffn 13372 13373@geindex operator* (C++ function) 13374@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{17c} 13375@deffn {C++ Function} gccjit::rvalue operator* (gccjit::rvalue a, gccjit::rvalue b) 13376 13377@example 13378gccjit::rvalue prod = a * b; 13379@end example 13380 13381@noindent 13382@end deffn 13383 13384@geindex operator/ (C++ function) 13385@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{17d} 13386@deffn {C++ Function} gccjit::rvalue operator/ (gccjit::rvalue a, gccjit::rvalue b) 13387 13388@example 13389gccjit::rvalue result = a / b; 13390@end example 13391 13392@noindent 13393@end deffn 13394 13395@geindex operator% (C++ function) 13396@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{17e} 13397@deffn {C++ Function} gccjit::rvalue operator% (gccjit::rvalue a, gccjit::rvalue b) 13398 13399@example 13400gccjit::rvalue mod = a % b; 13401@end example 13402 13403@noindent 13404@end deffn 13405 13406@geindex operator& (C++ function) 13407@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{17f} 13408@deffn {C++ Function} gccjit::rvalue operator& (gccjit::rvalue a, gccjit::rvalue b) 13409 13410@example 13411gccjit::rvalue x = a & b; 13412@end example 13413 13414@noindent 13415@end deffn 13416 13417@geindex operator^ (C++ function) 13418@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{180} 13419@deffn {C++ Function} gccjit::rvalue operator^ (gccjit::rvalue a, gccjit::rvalue b) 13420 13421@example 13422gccjit::rvalue x = a ^ b; 13423@end example 13424 13425@noindent 13426@end deffn 13427 13428@geindex operator| (C++ function) 13429@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{181} 13430@deffn {C++ Function} gccjit::rvalue operator| (gccjit::rvalue a, gccjit::rvalue b) 13431 13432@example 13433gccjit::rvalue x = a | b; 13434@end example 13435 13436@noindent 13437@end deffn 13438 13439@geindex operator&& (C++ function) 13440@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{182} 13441@deffn {C++ Function} gccjit::rvalue operator&& (gccjit::rvalue a, gccjit::rvalue b) 13442 13443@example 13444gccjit::rvalue cond = a && b; 13445@end example 13446 13447@noindent 13448@end deffn 13449 13450@geindex operator|| (C++ function) 13451@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{183} 13452@deffn {C++ Function} gccjit::rvalue operator|| (gccjit::rvalue a, gccjit::rvalue b) 13453 13454@example 13455gccjit::rvalue cond = a || b; 13456@end example 13457 13458@noindent 13459@end deffn 13460 13461These can of course be combined, giving a terse way to build compound 13462expressions: 13463 13464@quotation 13465 13466@example 13467gccjit::rvalue discriminant = (b * b) - (four * a * c); 13468@end example 13469 13470@noindent 13471@end quotation 13472 13473@node Comparisons<2>,Function calls<2>,Binary Operations<2>,Rvalues<2> 13474@anchor{cp/topics/expressions comparisons}@anchor{184} 13475@subsubsection Comparisons 13476 13477 13478@geindex gccjit;;context;;new_comparison (C++ function) 13479@anchor{cp/topics/expressions gccjit context new_comparison__enum gccjit rvalue gccjit rvalue gccjit location}@anchor{119} 13480@deffn {C++ Function} gccjit::rvalue gccjit::context::new_comparison (enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13481 13482Build a boolean rvalue out of the comparison of two other rvalues. 13483 13484Parameter @code{loc} is optional. 13485 13486This is a thin wrapper around the C API's 13487@pxref{2c,,gcc_jit_context_new_comparison()} and the available kinds 13488of comparison are documented there. 13489@end deffn 13490 13491There are shorter ways to spell the various specific kinds of binary 13492operation: 13493 13494@geindex gccjit;;context;;new_eq (C++ function) 13495@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{185} 13496@deffn {C++ Function} gccjit::rvalue gccjit::context::new_eq (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13497@end deffn 13498 13499@geindex gccjit;;context;;new_ne (C++ function) 13500@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{186} 13501@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ne (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13502@end deffn 13503 13504@geindex gccjit;;context;;new_lt (C++ function) 13505@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{187} 13506@deffn {C++ Function} gccjit::rvalue gccjit::context::new_lt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13507@end deffn 13508 13509@geindex gccjit;;context;;new_le (C++ function) 13510@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{188} 13511@deffn {C++ Function} gccjit::rvalue gccjit::context::new_le (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13512@end deffn 13513 13514@geindex gccjit;;context;;new_gt (C++ function) 13515@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{189} 13516@deffn {C++ Function} gccjit::rvalue gccjit::context::new_gt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13517@end deffn 13518 13519@geindex gccjit;;context;;new_ge (C++ function) 13520@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{18a} 13521@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ge (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc) 13522@end deffn 13523 13524The most concise way to spell them is with overloaded operators: 13525 13526@geindex operator== (C++ function) 13527@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{18b} 13528@deffn {C++ Function} gccjit::rvalue operator== (gccjit::rvalue a, gccjit::rvalue b) 13529 13530@example 13531gccjit::rvalue cond = (a == ctxt.zero (t_int)); 13532@end example 13533 13534@noindent 13535@end deffn 13536 13537@geindex operator!= (C++ function) 13538@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{18c} 13539@deffn {C++ Function} gccjit::rvalue operator!= (gccjit::rvalue a, gccjit::rvalue b) 13540 13541@example 13542gccjit::rvalue cond = (i != j); 13543@end example 13544 13545@noindent 13546@end deffn 13547 13548@geindex operator< (C++ function) 13549@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{18d} 13550@deffn {C++ Function} gccjit::rvalue operator< (gccjit::rvalue a, gccjit::rvalue b) 13551 13552@example 13553gccjit::rvalue cond = i < n; 13554@end example 13555 13556@noindent 13557@end deffn 13558 13559@geindex operator<= (C++ function) 13560@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{18e} 13561@deffn {C++ Function} gccjit::rvalue operator<= (gccjit::rvalue a, gccjit::rvalue b) 13562 13563@example 13564gccjit::rvalue cond = i <= n; 13565@end example 13566 13567@noindent 13568@end deffn 13569 13570@geindex operator> (C++ function) 13571@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{18f} 13572@deffn {C++ Function} gccjit::rvalue operator> (gccjit::rvalue a, gccjit::rvalue b) 13573 13574@example 13575gccjit::rvalue cond = (ch > limit); 13576@end example 13577 13578@noindent 13579@end deffn 13580 13581@geindex operator>= (C++ function) 13582@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{190} 13583@deffn {C++ Function} gccjit::rvalue operator>= (gccjit::rvalue a, gccjit::rvalue b) 13584 13585@example 13586gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100)); 13587@end example 13588 13589@noindent 13590@end deffn 13591 13592@c TODO: beyond this point 13593 13594@node Function calls<2>,Type-coercion<2>,Comparisons<2>,Rvalues<2> 13595@anchor{cp/topics/expressions function-calls}@anchor{191} 13596@subsubsection Function calls 13597 13598 13599@geindex gcc_jit_context_new_call (C++ function) 13600@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{192} 13601@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) 13602 13603Given a function and the given table of argument rvalues, construct a 13604call to the function, with the result as an rvalue. 13605 13606@cartouche 13607@quotation Note 13608@code{gccjit::context::new_call()} merely builds a 13609@pxref{15f,,gccjit;;rvalue} i.e. an expression that can be evaluated, 13610perhaps as part of a more complicated expression. 13611The call @emph{won't} happen unless you add a statement to a function 13612that evaluates the expression. 13613 13614For example, if you want to call a function and discard the result 13615(or to call a function with @code{void} return type), use 13616@pxref{193,,gccjit;;block;;add_eval()}: 13617 13618@example 13619/* Add "(void)printf (arg0, arg1);". */ 13620block.add_eval (ctxt.new_call (printf_func, arg0, arg1)); 13621@end example 13622 13623@noindent 13624@end quotation 13625@end cartouche 13626@end deffn 13627 13628@node Type-coercion<2>,,Function calls<2>,Rvalues<2> 13629@anchor{cp/topics/expressions type-coercion}@anchor{194} 13630@subsubsection Type-coercion 13631 13632 13633@geindex gccjit;;context;;new_cast (C++ function) 13634@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{195} 13635@deffn {C++ Function} gccjit::rvalue gccjit::context::new_cast (gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc) 13636 13637Given an rvalue of T, construct another rvalue of another type. 13638 13639Currently only a limited set of conversions are possible: 13640 13641@quotation 13642 13643 13644@itemize * 13645 13646@item 13647int <-> float 13648 13649@item 13650int <-> bool 13651 13652@item 13653P* <-> Q*, for pointer types P and Q 13654@end itemize 13655@end quotation 13656@end deffn 13657 13658@node Lvalues<2>,Working with pointers structs and unions<2>,Rvalues<2>,Expressions<2> 13659@anchor{cp/topics/expressions lvalues}@anchor{196} 13660@subsubsection Lvalues 13661 13662 13663@geindex gccjit;;lvalue (C++ class) 13664@anchor{cp/topics/expressions gccjit lvalue}@anchor{197} 13665@deffn {C++ Class} gccjit::lvalue 13666@end deffn 13667 13668An lvalue is something that can of the @emph{left}-hand side of an assignment: 13669a storage area (such as a variable). It is a subclass of 13670@pxref{15f,,gccjit;;rvalue}, where the rvalue is computed by reading from the 13671storage area. 13672 13673It iss a thin wrapper around @pxref{24,,gcc_jit_lvalue *} from the C API. 13674 13675@geindex gccjit;;lvalue;;get_address (C++ function) 13676@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{198} 13677@deffn {C++ Function} gccjit::rvalue gccjit::lvalue::get_address (gccjit::location loc) 13678 13679Take the address of an lvalue; analogous to: 13680 13681@example 13682&(EXPR) 13683@end example 13684 13685@noindent 13686 13687in C. 13688 13689Parameter "loc" is optional. 13690@end deffn 13691 13692@menu 13693* Global variables: Global variables<2>. 13694 13695@end menu 13696 13697@node Global variables<2>,,,Lvalues<2> 13698@anchor{cp/topics/expressions global-variables}@anchor{199} 13699@subsubsection Global variables 13700 13701 13702@geindex gccjit;;context;;new_global (C++ function) 13703@anchor{cp/topics/expressions gccjit context new_global__enum gccjit type cCP gccjit location}@anchor{19a} 13704@deffn {C++ Function} gccjit::lvalue gccjit::context::new_global (enum gcc_jit_global_kind, gccjit::type type, const char* name, gccjit::location loc) 13705 13706Add a new global variable of the given type and name to the context. 13707 13708This is a thin wrapper around @pxref{b5,,gcc_jit_context_new_global()} from 13709the C API; the "kind" parameter has the same meaning as there. 13710@end deffn 13711 13712@node Working with pointers structs and unions<2>,,Lvalues<2>,Expressions<2> 13713@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{19b} 13714@subsubsection Working with pointers, structs and unions 13715 13716 13717@geindex gccjit;;rvalue;;dereference (C++ function) 13718@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{19c} 13719@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference (gccjit::location loc) 13720 13721Given an rvalue of pointer type @code{T *}, dereferencing the pointer, 13722getting an lvalue of type @code{T}. Analogous to: 13723 13724@example 13725*(EXPR) 13726@end example 13727 13728@noindent 13729 13730in C. 13731 13732Parameter "loc" is optional. 13733@end deffn 13734 13735If you don't need to specify the location, this can also be expressed using 13736an overloaded operator: 13737 13738@geindex gccjit;;rvalue;;operator* (C++ function) 13739@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{19d} 13740@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::operator* () 13741 13742@example 13743gccjit::lvalue content = *ptr; 13744@end example 13745 13746@noindent 13747@end deffn 13748 13749Field access is provided separately for both lvalues and rvalues: 13750 13751@geindex gccjit;;lvalue;;access_field (C++ function) 13752@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{19e} 13753@deffn {C++ Function} gccjit::lvalue gccjit::lvalue::access_field (gccjit::field field, gccjit::location loc) 13754 13755Given an lvalue of struct or union type, access the given field, 13756getting an lvalue of the field's type. Analogous to: 13757 13758@example 13759(EXPR).field = ...; 13760@end example 13761 13762@noindent 13763 13764in C. 13765@end deffn 13766 13767@geindex gccjit;;rvalue;;access_field (C++ function) 13768@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{19f} 13769@deffn {C++ Function} gccjit::rvalue gccjit::rvalue::access_field (gccjit::field field, gccjit::location loc) 13770 13771Given an rvalue of struct or union type, access the given field 13772as an rvalue. Analogous to: 13773 13774@example 13775(EXPR).field 13776@end example 13777 13778@noindent 13779 13780in C. 13781@end deffn 13782 13783@geindex gccjit;;rvalue;;dereference_field (C++ function) 13784@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{1a0} 13785@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference_field (gccjit::field field, gccjit::location loc) 13786 13787Given an rvalue of pointer type @code{T *} where T is of struct or union 13788type, access the given field as an lvalue. Analogous to: 13789 13790@example 13791(EXPR)->field 13792@end example 13793 13794@noindent 13795 13796in C, itself equivalent to @code{(*EXPR).FIELD}. 13797@end deffn 13798 13799@geindex gccjit;;context;;new_array_access (C++ function) 13800@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{1a1} 13801@deffn {C++ Function} gccjit::lvalue gccjit::context::new_array_access (gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc) 13802 13803Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at 13804the given index, using standard C array indexing rules i.e. each 13805increment of @code{index} corresponds to @code{sizeof(T)} bytes. 13806Analogous to: 13807 13808@example 13809PTR[INDEX] 13810@end example 13811 13812@noindent 13813 13814in C (or, indeed, to @code{PTR + INDEX}). 13815 13816Parameter "loc" is optional. 13817@end deffn 13818 13819For array accesses where you don't need to specify a @pxref{13c,,gccjit;;location}, 13820two overloaded operators are available: 13821 13822@quotation 13823 13824gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index) 13825 13826@example 13827gccjit::lvalue element = array[idx]; 13828@end example 13829 13830@noindent 13831 13832gccjit::lvalue gccjit::rvalue::operator[] (int index) 13833 13834@example 13835gccjit::lvalue element = array[0]; 13836@end example 13837 13838@noindent 13839@end quotation 13840 13841@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 13842@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 13843@c 13844@c This is free software: you can redistribute it and/or modify it 13845@c under the terms of the GNU General Public License as published by 13846@c the Free Software Foundation, either version 3 of the License, or 13847@c (at your option) any later version. 13848@c 13849@c This program is distributed in the hope that it will be useful, but 13850@c WITHOUT ANY WARRANTY; without even the implied warranty of 13851@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13852@c General Public License for more details. 13853@c 13854@c You should have received a copy of the GNU General Public License 13855@c along with this program. If not, see 13856@c <http://www.gnu.org/licenses/>. 13857 13858@node Creating and using functions<2>,Source Locations<2>,Expressions<2>,Topic Reference<2> 13859@anchor{cp/topics/functions doc}@anchor{1a2}@anchor{cp/topics/functions creating-and-using-functions}@anchor{1a3} 13860@subsection Creating and using functions 13861 13862 13863@menu 13864* Params: Params<2>. 13865* Functions: Functions<2>. 13866* Blocks: Blocks<2>. 13867* Statements: Statements<2>. 13868 13869@end menu 13870 13871@node Params<2>,Functions<2>,,Creating and using functions<2> 13872@anchor{cp/topics/functions params}@anchor{1a4} 13873@subsubsection Params 13874 13875 13876@geindex gccjit;;param (C++ class) 13877@anchor{cp/topics/functions gccjit param}@anchor{1a5} 13878@deffn {C++ Class} gccjit::param 13879 13880A @cite{gccjit::param} represents a parameter to a function. 13881@end deffn 13882 13883@geindex gccjit;;context;;new_param (C++ function) 13884@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{10b} 13885@deffn {C++ Function} gccjit::param gccjit::context::new_param (gccjit::type type, const char* name, gccjit::location loc) 13886 13887In preparation for creating a function, create a new parameter of the 13888given type and name. 13889@end deffn 13890 13891@pxref{1a5,,gccjit;;param} is a subclass of @pxref{197,,gccjit;;lvalue} (and thus 13892of @pxref{15f,,gccjit;;rvalue} and @pxref{149,,gccjit;;object}). It is a thin 13893wrapper around the C API's @pxref{25,,gcc_jit_param *}. 13894 13895@node Functions<2>,Blocks<2>,Params<2>,Creating and using functions<2> 13896@anchor{cp/topics/functions functions}@anchor{1a6} 13897@subsubsection Functions 13898 13899 13900@geindex gccjit;;function (C++ class) 13901@anchor{cp/topics/functions gccjit function}@anchor{1a7} 13902@deffn {C++ Class} gccjit::function 13903 13904A @cite{gccjit::function} represents a function - either one that we're 13905creating ourselves, or one that we're referencing. 13906@end deffn 13907 13908@geindex gccjit;;context;;new_function (C++ function) 13909@anchor{cp/topics/functions gccjit context new_function__enum gccjit type cCP std vector param R i gccjit location}@anchor{1a8} 13910@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) 13911 13912Create a gcc_jit_function with the given name and parameters. 13913 13914Parameters "is_variadic" and "loc" are optional. 13915 13916This is a wrapper around the C API's @pxref{11,,gcc_jit_context_new_function()}. 13917@end deffn 13918 13919@geindex gccjit;;context;;get_builtin_function (C++ function) 13920@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{1a9} 13921@deffn {C++ Function} gccjit::function gccjit::context::get_builtin_function (const char* name) 13922 13923This is a wrapper around the C API's 13924@pxref{cc,,gcc_jit_context_get_builtin_function()}. 13925@end deffn 13926 13927@geindex gccjit;;function;;get_param (C++ function) 13928@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{1aa} 13929@deffn {C++ Function} gccjit::param gccjit::function::get_param (int index) const 13930 13931Get the param of the given index (0-based). 13932@end deffn 13933 13934@geindex gccjit;;function;;dump_to_dot (C++ function) 13935@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{11e} 13936@deffn {C++ Function} void gccjit::function::dump_to_dot (const char* path) 13937 13938Emit the function in graphviz format to the given path. 13939@end deffn 13940 13941@geindex gccjit;;function;;new_local (C++ function) 13942@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{115} 13943@deffn {C++ Function} gccjit::lvalue gccjit::function::new_local (gccjit::type type, const char* name, gccjit::location loc) 13944 13945Create a new local variable within the function, of the given type and 13946name. 13947@end deffn 13948 13949@node Blocks<2>,Statements<2>,Functions<2>,Creating and using functions<2> 13950@anchor{cp/topics/functions blocks}@anchor{1ab} 13951@subsubsection Blocks 13952 13953 13954@geindex gccjit;;block (C++ class) 13955@anchor{cp/topics/functions gccjit block}@anchor{1ac} 13956@deffn {C++ Class} gccjit::block 13957 13958A @cite{gccjit::block} represents a basic block within a function i.e. a 13959sequence of statements with a single entry point and a single exit 13960point. 13961 13962@pxref{1ac,,gccjit;;block} is a subclass of @pxref{149,,gccjit;;object}. 13963 13964The first basic block that you create within a function will 13965be the entrypoint. 13966 13967Each basic block that you create within a function must be 13968terminated, either with a conditional, a jump, a return, or 13969a switch. 13970 13971It's legal to have multiple basic blocks that return within 13972one function. 13973@end deffn 13974 13975@geindex gccjit;;function;;new_block (C++ function) 13976@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{1ad} 13977@deffn {C++ Function} gccjit::block gccjit::function::new_block (const char* name) 13978 13979Create a basic block of the given name. The name may be NULL, but 13980providing meaningful names is often helpful when debugging: it may 13981show up in dumps of the internal representation, and in error 13982messages. 13983@end deffn 13984 13985@node Statements<2>,,Blocks<2>,Creating and using functions<2> 13986@anchor{cp/topics/functions statements}@anchor{1ae} 13987@subsubsection Statements 13988 13989 13990@geindex gccjit;;block;;add_eval (C++ function) 13991@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{193} 13992@deffn {C++ Function} void gccjit::block::add_eval (gccjit::rvalue rvalue, gccjit::location loc) 13993 13994Add evaluation of an rvalue, discarding the result 13995(e.g. a function call that "returns" void). 13996 13997This is equivalent to this C code: 13998 13999@example 14000(void)expression; 14001@end example 14002 14003@noindent 14004@end deffn 14005 14006@geindex gccjit;;block;;add_assignment (C++ function) 14007@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{117} 14008@deffn {C++ Function} void gccjit::block::add_assignment (gccjit::lvalue lvalue, gccjit::rvalue rvalue, gccjit::location loc) 14009 14010Add evaluation of an rvalue, assigning the result to the given 14011lvalue. 14012 14013This is roughly equivalent to this C code: 14014 14015@example 14016lvalue = rvalue; 14017@end example 14018 14019@noindent 14020@end deffn 14021 14022@geindex gccjit;;block;;add_assignment_op (C++ function) 14023@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue enum gccjit rvalue gccjit location}@anchor{11b} 14024@deffn {C++ Function} void gccjit::block::add_assignment_op (gccjit::lvalue lvalue, enum gcc_jit_binary_op, gccjit::rvalue rvalue, gccjit::location loc) 14025 14026Add evaluation of an rvalue, using the result to modify an 14027lvalue. 14028 14029This is analogous to "+=" and friends: 14030 14031@example 14032lvalue += rvalue; 14033lvalue *= rvalue; 14034lvalue /= rvalue; 14035@end example 14036 14037@noindent 14038 14039etc. For example: 14040 14041@example 14042/* "i++" */ 14043loop_body.add_assignment_op ( 14044 i, 14045 GCC_JIT_BINARY_OP_PLUS, 14046 ctxt.one (int_type)); 14047@end example 14048 14049@noindent 14050@end deffn 14051 14052@geindex gccjit;;block;;add_comment (C++ function) 14053@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{126} 14054@deffn {C++ Function} void gccjit::block::add_comment (const char* text, gccjit::location loc) 14055 14056Add a no-op textual comment to the internal representation of the 14057code. It will be optimized away, but will be visible in the dumps 14058seen via @pxref{66,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE} 14059and @pxref{1c,,GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE}, 14060and thus may be of use when debugging how your project's internal 14061representation gets converted to the libgccjit IR. 14062 14063Parameter "loc" is optional. 14064@end deffn 14065 14066@geindex gccjit;;block;;end_with_conditional (C++ function) 14067@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{11a} 14068@deffn {C++ Function} void gccjit::block::end_with_conditional (gccjit::rvalue boolval, gccjit::block on_true, gccjit::block on_false, gccjit::location loc) 14069 14070Terminate a block by adding evaluation of an rvalue, branching on the 14071result to the appropriate successor block. 14072 14073This is roughly equivalent to this C code: 14074 14075@example 14076if (boolval) 14077 goto on_true; 14078else 14079 goto on_false; 14080@end example 14081 14082@noindent 14083 14084block, boolval, on_true, and on_false must be non-NULL. 14085@end deffn 14086 14087@geindex gccjit;;block;;end_with_jump (C++ function) 14088@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{1af} 14089@deffn {C++ Function} void gccjit::block::end_with_jump (gccjit::block target, gccjit::location loc) 14090 14091Terminate a block by adding a jump to the given target block. 14092 14093This is roughly equivalent to this C code: 14094 14095@example 14096goto target; 14097@end example 14098 14099@noindent 14100@end deffn 14101 14102@geindex gccjit;;block;;end_with_return (C++ function) 14103@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{1b0} 14104@deffn {C++ Function} void gccjit::block::end_with_return (gccjit::rvalue rvalue, gccjit::location loc) 14105 14106Terminate a block. 14107 14108Both params are optional. 14109 14110An rvalue must be provided for a function returning non-void, and 14111must not be provided by a function "returning" @cite{void}. 14112 14113If an rvalue is provided, the block is terminated by evaluating the 14114rvalue and returning the value. 14115 14116This is roughly equivalent to this C code: 14117 14118@example 14119return expression; 14120@end example 14121 14122@noindent 14123 14124If an rvalue is not provided, the block is terminated by adding a 14125valueless return, for use within a function with "void" return type. 14126 14127This is equivalent to this C code: 14128 14129@example 14130return; 14131@end example 14132 14133@noindent 14134@end deffn 14135 14136@geindex gccjit;;block;;end_with_switch (C++ function) 14137@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{1b1} 14138@deffn {C++ Function} void gccjit::block::end_with_switch (gccjit::rvalue expr, gccjit::block default_block, std::vector<gccjit::case_> cases, gccjit::location loc) 14139 14140Terminate a block by adding evalation of an rvalue, then performing 14141a multiway branch. 14142 14143This is roughly equivalent to this C code: 14144 14145@example 14146switch (expr) 14147 @{ 14148 default: 14149 goto default_block; 14150 14151 case C0.min_value ... C0.max_value: 14152 goto C0.dest_block; 14153 14154 case C1.min_value ... C1.max_value: 14155 goto C1.dest_block; 14156 14157 ...etc... 14158 14159 case C[N - 1].min_value ... C[N - 1].max_value: 14160 goto C[N - 1].dest_block; 14161@} 14162@end example 14163 14164@noindent 14165 14166@code{expr} must be of the same integer type as all of the @code{min_value} 14167and @code{max_value} within the cases. 14168 14169The ranges of the cases must not overlap (or have duplicate 14170values). 14171 14172The API entrypoints relating to switch statements and cases: 14173 14174@quotation 14175 14176 14177@itemize * 14178 14179@item 14180@pxref{1b1,,gccjit;;block;;end_with_switch()} 14181 14182@item 14183@pxref{1b2,,gccjit;;context;;new_case()} 14184@end itemize 14185@end quotation 14186 14187were added in @pxref{da,,LIBGCCJIT_ABI_3}; you can test for their presence 14188using 14189 14190@example 14191#ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 14192@end example 14193 14194@noindent 14195 14196@geindex gccjit;;block;;end_with_switch;;gccjit;;case_ (C++ class) 14197@anchor{cp/topics/functions gccjit block end_with_switch gccjit case_}@anchor{1b3} 14198@deffn {C++ Class} gccjit::case_ 14199@end deffn 14200 14201A @cite{gccjit::case_} represents a case within a switch statement, and 14202is created within a particular @pxref{134,,gccjit;;context} using 14203@pxref{1b2,,gccjit;;context;;new_case()}. It is a subclass of 14204@pxref{149,,gccjit;;object}. 14205 14206Each case expresses a multivalued range of integer values. You 14207can express single-valued cases by passing in the same value for 14208both @cite{min_value} and @cite{max_value}. 14209 14210@geindex gccjit;;block;;end_with_switch;;gccjit;;context;;new_case (C++ function) 14211@anchor{cp/topics/functions gccjit block end_with_switch gccjit context new_case__gccjit rvalue gccjit rvalue gccjit block}@anchor{1b2} 14212@deffn {C++ Function} gccjit::case_* gccjit::context::new_case (gccjit::rvalue min_value, gccjit::rvalue max_value, gccjit::block dest_block) 14213 14214Create a new gccjit::case for use in a switch statement. 14215@cite{min_value} and @cite{max_value} must be constants of an integer type, 14216which must match that of the expression of the switch statement. 14217 14218@cite{dest_block} must be within the same function as the switch 14219statement. 14220@end deffn 14221 14222Here's an example of creating a switch statement: 14223 14224@quotation 14225 14226@example 14227 14228void 14229create_code (gcc_jit_context *c_ctxt, void *user_data) 14230@{ 14231 /* Let's try to inject the equivalent of: 14232 int 14233 test_switch (int x) 14234 @{ 14235 switch (x) 14236 @{ 14237 case 0 ... 5: 14238 return 3; 14239 14240 case 25 ... 27: 14241 return 4; 14242 14243 case -42 ... -17: 14244 return 83; 14245 14246 case 40: 14247 return 8; 14248 14249 default: 14250 return 10; 14251 @} 14252 @} 14253 */ 14254 gccjit::context ctxt (c_ctxt); 14255 gccjit::type t_int = ctxt.get_type (GCC_JIT_TYPE_INT); 14256 gccjit::type return_type = t_int; 14257 gccjit::param x = ctxt.new_param (t_int, "x"); 14258 std::vector <gccjit::param> params; 14259 params.push_back (x); 14260 gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, 14261 return_type, 14262 "test_switch", 14263 params, 0); 14264 14265 gccjit::block b_initial = func.new_block ("initial"); 14266 14267 gccjit::block b_default = func.new_block ("default"); 14268 gccjit::block b_case_0_5 = func.new_block ("case_0_5"); 14269 gccjit::block b_case_25_27 = func.new_block ("case_25_27"); 14270 gccjit::block b_case_m42_m17 = func.new_block ("case_m42_m17"); 14271 gccjit::block b_case_40 = func.new_block ("case_40"); 14272 14273 std::vector <gccjit::case_> cases; 14274 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 0), 14275 ctxt.new_rvalue (t_int, 5), 14276 b_case_0_5)); 14277 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 25), 14278 ctxt.new_rvalue (t_int, 27), 14279 b_case_25_27)); 14280 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, -42), 14281 ctxt.new_rvalue (t_int, -17), 14282 b_case_m42_m17)); 14283 cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 40), 14284 ctxt.new_rvalue (t_int, 40), 14285 b_case_40)); 14286 b_initial.end_with_switch (x, 14287 b_default, 14288 cases); 14289 14290 b_case_0_5.end_with_return (ctxt.new_rvalue (t_int, 3)); 14291 b_case_25_27.end_with_return (ctxt.new_rvalue (t_int, 4)); 14292 b_case_m42_m17.end_with_return (ctxt.new_rvalue (t_int, 83)); 14293 b_case_40.end_with_return (ctxt.new_rvalue (t_int, 8)); 14294 b_default.end_with_return (ctxt.new_rvalue (t_int, 10)); 14295@} 14296 14297 14298@end example 14299 14300@noindent 14301@end quotation 14302@end deffn 14303 14304@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 14305@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14306@c 14307@c This is free software: you can redistribute it and/or modify it 14308@c under the terms of the GNU General Public License as published by 14309@c the Free Software Foundation, either version 3 of the License, or 14310@c (at your option) any later version. 14311@c 14312@c This program is distributed in the hope that it will be useful, but 14313@c WITHOUT ANY WARRANTY; without even the implied warranty of 14314@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14315@c General Public License for more details. 14316@c 14317@c You should have received a copy of the GNU General Public License 14318@c along with this program. If not, see 14319@c <http://www.gnu.org/licenses/>. 14320 14321@node Source Locations<2>,Compiling a context<2>,Creating and using functions<2>,Topic Reference<2> 14322@anchor{cp/topics/locations source-locations}@anchor{1b4}@anchor{cp/topics/locations doc}@anchor{1b5} 14323@subsection Source Locations 14324 14325 14326@geindex gccjit;;location (C++ class) 14327@anchor{cp/topics/locations gccjit location}@anchor{13c} 14328@deffn {C++ Class} gccjit::location 14329 14330A @cite{gccjit::location} encapsulates a source code location, so that 14331you can (optionally) associate locations in your language with 14332statements in the JIT-compiled code, allowing the debugger to 14333single-step through your language. 14334 14335@cite{gccjit::location} instances are optional: you can always omit them 14336from any C++ API entrypoint accepting one. 14337 14338You can construct them using @pxref{12a,,gccjit;;context;;new_location()}. 14339 14340You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the 14341@pxref{134,,gccjit;;context} for these locations to actually be usable by 14342the debugger: 14343 14344@example 14345ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1); 14346@end example 14347 14348@noindent 14349@end deffn 14350 14351@geindex gccjit;;context;;new_location (C++ function) 14352@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{12a} 14353@deffn {C++ Function} gccjit::location gccjit::context::new_location (const char* filename, int line, int column) 14354 14355Create a @cite{gccjit::location} instance representing the given source 14356location. 14357@end deffn 14358 14359@menu 14360* Faking it: Faking it<2>. 14361 14362@end menu 14363 14364@node Faking it<2>,,,Source Locations<2> 14365@anchor{cp/topics/locations faking-it}@anchor{1b6} 14366@subsubsection Faking it 14367 14368 14369If you don't have source code for your internal representation, but need 14370to debug, you can generate a C-like representation of the functions in 14371your context using @pxref{13b,,gccjit;;context;;dump_to_file()}: 14372 14373@example 14374ctxt.dump_to_file ("/tmp/something.c", 14375 1 /* update_locations */); 14376@end example 14377 14378@noindent 14379 14380This will dump C-like code to the given path. If the @cite{update_locations} 14381argument is true, this will also set up @cite{gccjit::location} information 14382throughout the context, pointing at the dump file as if it were a source 14383file, giving you @emph{something} you can step through in the debugger. 14384 14385@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 14386@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14387@c 14388@c This is free software: you can redistribute it and/or modify it 14389@c under the terms of the GNU General Public License as published by 14390@c the Free Software Foundation, either version 3 of the License, or 14391@c (at your option) any later version. 14392@c 14393@c This program is distributed in the hope that it will be useful, but 14394@c WITHOUT ANY WARRANTY; without even the implied warranty of 14395@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14396@c General Public License for more details. 14397@c 14398@c You should have received a copy of the GNU General Public License 14399@c along with this program. If not, see 14400@c <http://www.gnu.org/licenses/>. 14401 14402@node Compiling a context<2>,,Source Locations<2>,Topic Reference<2> 14403@anchor{cp/topics/compilation compiling-a-context}@anchor{1b7}@anchor{cp/topics/compilation doc}@anchor{1b8} 14404@subsection Compiling a context 14405 14406 14407Once populated, a @pxref{134,,gccjit;;context} can be compiled to 14408machine code, either in-memory via @pxref{10d,,gccjit;;context;;compile()} or 14409to disk via @pxref{1b9,,gccjit;;context;;compile_to_file()}. 14410 14411You can compile a context multiple times (using either form of 14412compilation), although any errors that occur on the context will 14413prevent any future compilation of that context. 14414 14415@menu 14416* In-memory compilation: In-memory compilation<2>. 14417* Ahead-of-time compilation: Ahead-of-time compilation<2>. 14418 14419@end menu 14420 14421@node In-memory compilation<2>,Ahead-of-time compilation<2>,,Compiling a context<2> 14422@anchor{cp/topics/compilation in-memory-compilation}@anchor{1ba} 14423@subsubsection In-memory compilation 14424 14425 14426@geindex gccjit;;context;;compile (C++ function) 14427@anchor{cp/topics/compilation gccjit context compile}@anchor{10d} 14428@deffn {C++ Function} gcc_jit_result* gccjit::context::compile () 14429 14430This calls into GCC and builds the code, returning a 14431@cite{gcc_jit_result *}. 14432 14433This is a thin wrapper around the 14434@pxref{15,,gcc_jit_context_compile()} API entrypoint. 14435@end deffn 14436 14437@node Ahead-of-time compilation<2>,,In-memory compilation<2>,Compiling a context<2> 14438@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{1bb} 14439@subsubsection Ahead-of-time compilation 14440 14441 14442Although libgccjit is primarily aimed at just-in-time compilation, it 14443can also be used for implementing more traditional ahead-of-time 14444compilers, via the @pxref{1b9,,gccjit;;context;;compile_to_file()} method. 14445 14446@geindex gccjit;;context;;compile_to_file (C++ function) 14447@anchor{cp/topics/compilation gccjit context compile_to_file__enum cCP}@anchor{1b9} 14448@deffn {C++ Function} void gccjit::context::compile_to_file (enum gcc_jit_output_kind, const char* output_path) 14449 14450Compile the @pxref{134,,gccjit;;context} to a file of the given 14451kind. 14452 14453This is a thin wrapper around the 14454@pxref{4a,,gcc_jit_context_compile_to_file()} API entrypoint. 14455@end deffn 14456 14457@c Copyright (C) 2014-2016 Free Software Foundation, Inc. 14458@c Originally contributed by David Malcolm <dmalcolm@redhat.com> 14459@c 14460@c This is free software: you can redistribute it and/or modify it 14461@c under the terms of the GNU General Public License as published by 14462@c the Free Software Foundation, either version 3 of the License, or 14463@c (at your option) any later version. 14464@c 14465@c This program is distributed in the hope that it will be useful, but 14466@c WITHOUT ANY WARRANTY; without even the implied warranty of 14467@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14468@c General Public License for more details. 14469@c 14470@c You should have received a copy of the GNU General Public License 14471@c along with this program. If not, see 14472@c <http://www.gnu.org/licenses/>. 14473 14474@node Internals,Indices and tables,C++ bindings for libgccjit,Top 14475@anchor{internals/index internals}@anchor{1bc}@anchor{internals/index doc}@anchor{1bd} 14476@chapter Internals 14477 14478 14479@menu 14480* Working on the JIT library:: 14481* Running the test suite:: 14482* Environment variables:: 14483* Packaging notes:: 14484* Overview of code structure:: 14485* Design notes:: 14486* Submitting patches:: 14487 14488@end menu 14489 14490@node Working on the JIT library,Running the test suite,,Internals 14491@anchor{internals/index working-on-the-jit-library}@anchor{1be} 14492@section Working on the JIT library 14493 14494 14495Having checked out the source code (to "src"), you can configure and build 14496the JIT library like this: 14497 14498@example 14499mkdir build 14500mkdir install 14501PREFIX=$(pwd)/install 14502cd build 14503../src/configure \ 14504 --enable-host-shared \ 14505 --enable-languages=jit,c++ \ 14506 --disable-bootstrap \ 14507 --enable-checking=release \ 14508 --prefix=$PREFIX 14509nice make -j4 # altering the "4" to however many cores you have 14510@end example 14511 14512@noindent 14513 14514This should build a libgccjit.so within jit/build/gcc: 14515 14516@example 14517[build] $ file gcc/libgccjit.so* 14518gcc/libgccjit.so: symbolic link to `libgccjit.so.0' 14519gcc/libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' 14520gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped 14521@end example 14522 14523@noindent 14524 14525Here's what those configuration options mean: 14526 14527@geindex command line option; --enable-host-shared 14528@anchor{internals/index cmdoption--enable-host-shared}@anchor{1bf} 14529@deffn {Option} --enable-host-shared 14530 14531Configuring with this option means that the compiler is built as 14532position-independent code, which incurs a slight performance hit, 14533but it necessary for a shared library. 14534@end deffn 14535 14536@geindex command line option; --enable-languages=jit@comma{}c++ 14537@anchor{internals/index cmdoption--enable-languages}@anchor{1c0} 14538@deffn {Option} --enable-languages=jit,c++ 14539 14540This specifies which frontends to build. The JIT library looks like 14541a frontend to the rest of the code. 14542 14543The C++ portion of the JIT test suite requires the C++ frontend to be 14544enabled at configure-time, or you may see errors like this when 14545running the test suite: 14546 14547@example 14548xgcc: error: /home/david/jit/src/gcc/testsuite/jit.dg/test-quadratic.cc: C++ compiler not installed on this system 14549c++: error trying to exec 'cc1plus': execvp: No such file or directory 14550@end example 14551 14552@noindent 14553@end deffn 14554 14555@geindex command line option; --disable-bootstrap 14556@anchor{internals/index cmdoption--disable-bootstrap}@anchor{1c1} 14557@deffn {Option} --disable-bootstrap 14558 14559For hacking on the "jit" subdirectory, performing a full 14560bootstrap can be overkill, since it's unused by a bootstrap. However, 14561when submitting patches, you should remove this option, to ensure that 14562the compiler can still bootstrap itself. 14563@end deffn 14564 14565@geindex command line option; --enable-checking=release 14566@anchor{internals/index cmdoption--enable-checking}@anchor{1c2} 14567@deffn {Option} --enable-checking=release 14568 14569The compile can perform extensive self-checking as it runs, useful when 14570debugging, but slowing things down. 14571 14572For maximum speed, configure with @code{--enable-checking=release} to 14573disable this self-checking. 14574@end deffn 14575 14576@node Running the test suite,Environment variables,Working on the JIT library,Internals 14577@anchor{internals/index running-the-test-suite}@anchor{1c3} 14578@section Running the test suite 14579 14580 14581@example 14582[build] $ cd gcc 14583[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v" 14584@end example 14585 14586@noindent 14587 14588A summary of the tests can then be seen in: 14589 14590@example 14591jit/build/gcc/testsuite/jit/jit.sum 14592@end example 14593 14594@noindent 14595 14596and detailed logs in: 14597 14598@example 14599jit/build/gcc/testsuite/jit/jit.log 14600@end example 14601 14602@noindent 14603 14604The test executables can be seen as: 14605 14606@example 14607jit/build/gcc/testsuite/jit/*.exe 14608@end example 14609 14610@noindent 14611 14612which can be run independently. 14613 14614You can compile and run individual tests by passing "jit.exp=TESTNAME" to RUNTESTFLAGS e.g.: 14615 14616@example 14617[gcc] $ make check-jit RUNTESTFLAGS="-v -v -v jit.exp=test-factorial.c" 14618@end example 14619 14620@noindent 14621 14622and once a test has been compiled, you can debug it directly: 14623 14624@example 14625[gcc] $ PATH=.:$PATH \ 14626 LD_LIBRARY_PATH=. \ 14627 LIBRARY_PATH=. \ 14628 gdb --args \ 14629 testsuite/jit/test-factorial.c.exe 14630@end example 14631 14632@noindent 14633 14634@menu 14635* Running under valgrind:: 14636 14637@end menu 14638 14639@node Running under valgrind,,,Running the test suite 14640@anchor{internals/index running-under-valgrind}@anchor{1c4} 14641@subsection Running under valgrind 14642 14643 14644The jit testsuite detects if RUN_UNDER_VALGRIND is present in the 14645environment (with any value). If it is present, it runs the test client 14646code under valgrind@footnote{http://valgrind.org}, 14647specifcally, the default 14648memcheck@footnote{http://valgrind.org/docs/manual/mc-manual.html} 14649tool with 14650--leak-check=full@footnote{http://valgrind.org/docs/manual/mc-manual.html#opt.leak-check}. 14651 14652It automatically parses the output from valgrind, injecting XFAIL results if 14653any issues are found, or PASS results if the output is clean. The output 14654is saved to @code{TESTNAME.exe.valgrind.txt}. 14655 14656For example, the following invocation verbosely runs the testcase 14657@code{test-sum-of-squares.c} under valgrind, showing an issue: 14658 14659@example 14660$ RUN_UNDER_VALGRIND= \ 14661 make check-jit \ 14662 RUNTESTFLAGS="-v -v -v jit.exp=test-sum-of-squares.c" 14663 14664(...verbose log contains detailed valgrind errors, if any...) 14665 14666 === jit Summary === 14667 14668# of expected passes 28 14669# of expected failures 2 14670 14671$ less testsuite/jit/jit.sum 14672(...other results...) 14673XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: definitely lost: 8 bytes in 1 blocks 14674XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: unsuppressed errors: 1 14675(...other results...) 14676 14677$ less testsuite/jit/test-sum-of-squares.c.exe.valgrind.txt 14678(...shows full valgrind report for this test case...) 14679@end example 14680 14681@noindent 14682 14683When running under valgrind, it's best to have configured gcc with 14684@code{--enable-valgrind-annotations}, which automatically suppresses 14685various known false positives. 14686 14687@node Environment variables,Packaging notes,Running the test suite,Internals 14688@anchor{internals/index environment-variables}@anchor{1c5} 14689@section Environment variables 14690 14691 14692When running client code against a locally-built libgccjit, three 14693environment variables need to be set up: 14694 14695@geindex environment variable; LD_LIBRARY_PATH 14696@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{1c6} 14697@deffn {Environment Variable} LD_LIBRARY_PATH 14698 14699@quotation 14700 14701@cite{libgccjit.so} is dynamically linked into client code, so if running 14702against a locally-built library, @code{LD_LIBRARY_PATH} needs to be set 14703up appropriately. The library can be found within the "gcc" 14704subdirectory of the build tree: 14705@end quotation 14706 14707@example 14708$ file libgccjit.so* 14709libgccjit.so: symbolic link to `libgccjit.so.0' 14710libgccjit.so.0: symbolic link to `libgccjit.so.0.0.1' 14711libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, not stripped 14712@end example 14713 14714@noindent 14715@end deffn 14716 14717@geindex environment variable; PATH 14718@anchor{internals/index envvar-PATH}@anchor{1c7} 14719@deffn {Environment Variable} PATH 14720 14721The library uses a driver executable for converting from .s assembler 14722files to .so shared libraries. Specifically, it looks for a name 14723expanded from 14724@code{$@{target_noncanonical@}-gcc-$@{gcc_BASEVER@}$@{exeext@}} 14725such as @code{x86_64-unknown-linux-gnu-gcc-5.0.0}. 14726 14727Hence @code{PATH} needs to include a directory where the library can 14728locate this executable. 14729 14730The executable is normally installed to the installation bindir 14731(e.g. /usr/bin), but a copy is also created within the "gcc" 14732subdirectory of the build tree for running the testsuite, and for ease 14733of development. 14734@end deffn 14735 14736@geindex environment variable; LIBRARY_PATH 14737@anchor{internals/index envvar-LIBRARY_PATH}@anchor{1c8} 14738@deffn {Environment Variable} LIBRARY_PATH 14739 14740The driver executable invokes the linker, and the latter needs to locate 14741support libraries needed by the generated code, or you will see errors 14742like: 14743 14744@example 14745ld: cannot find crtbeginS.o: No such file or directory 14746ld: cannot find -lgcc 14747ld: cannot find -lgcc_s 14748@end example 14749 14750@noindent 14751 14752Hence if running directly from a locally-built copy (without installing), 14753@code{LIBRARY_PATH} needs to contain the "gcc" subdirectory of the build 14754tree. 14755@end deffn 14756 14757For example, to run a binary that uses the library against a non-installed 14758build of the library in LIBGCCJIT_BUILD_DIR you need an invocation of the 14759client code like this, to preprend the dir to each of the environment 14760variables: 14761 14762@example 14763$ LD_LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LD_LIBRARY_PATH) \ 14764 PATH=$(LIBGCCJIT_BUILD_DIR):$(PATH) \ 14765 LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LIBRARY_PATH) \ 14766 ./jit-hello-world 14767hello world 14768@end example 14769 14770@noindent 14771 14772@node Packaging notes,Overview of code structure,Environment variables,Internals 14773@anchor{internals/index packaging-notes}@anchor{1c9} 14774@section Packaging notes 14775 14776 14777The configure-time option @pxref{1bf,,--enable-host-shared} is needed when 14778building the jit in order to get position-independent code. This will 14779slow down the regular compiler by a few percent. Hence when packaging gcc 14780with libgccjit, please configure and build twice: 14781 14782@quotation 14783 14784 14785@itemize * 14786 14787@item 14788once without @pxref{1bf,,--enable-host-shared} for most languages, and 14789 14790@item 14791once with @pxref{1bf,,--enable-host-shared} for the jit 14792@end itemize 14793@end quotation 14794 14795For example: 14796 14797@example 14798# Configure and build with --enable-host-shared 14799# for the jit: 14800mkdir configuration-for-jit 14801pushd configuration-for-jit 14802$(SRCDIR)/configure \ 14803 --enable-host-shared \ 14804 --enable-languages=jit \ 14805 --prefix=$(DESTDIR) 14806make 14807popd 14808 14809# Configure and build *without* --enable-host-shared 14810# for maximum speed: 14811mkdir standard-configuration 14812pushd standard-configuration 14813$(SRCDIR)/configure \ 14814 --enable-languages=all \ 14815 --prefix=$(DESTDIR) 14816make 14817popd 14818 14819# Both of the above are configured to install to $(DESTDIR) 14820# Install the configuration with --enable-host-shared first 14821# *then* the one without, so that the faster build 14822# of "cc1" et al overwrites the slower build. 14823pushd configuration-for-jit 14824make install 14825popd 14826 14827pushd standard-configuration 14828make install 14829popd 14830@end example 14831 14832@noindent 14833 14834@node Overview of code structure,Design notes,Packaging notes,Internals 14835@anchor{internals/index overview-of-code-structure}@anchor{1ca} 14836@section Overview of code structure 14837 14838 14839The library is implemented in C++. The source files have the @code{.c} 14840extension for legacy reasons. 14841 14842 14843@itemize * 14844 14845@item 14846@code{libgccjit.c} implements the API entrypoints. It performs error 14847checking, then calls into classes of the gcc::jit::recording namespace 14848within @code{jit-recording.c} and @code{jit-recording.h}. 14849 14850@item 14851The gcc::jit::recording classes (within @code{jit-recording.c} and 14852@code{jit-recording.h}) record the API calls that are made: 14853 14854@quotation 14855 14856@example 14857 14858 /* Indentation indicates inheritance: */ 14859 class context; 14860 class memento; 14861 class string; 14862 class location; 14863 class type; 14864 class function_type; 14865 class compound_type; 14866 class struct_; 14867 class union_; 14868 class field; 14869 class fields; 14870 class function; 14871 class block; 14872 class rvalue; 14873 class lvalue; 14874 class local; 14875 class global; 14876 class param; 14877 class statement; 14878 class case_; 14879 14880 14881@end example 14882 14883@noindent 14884@end quotation 14885 14886@item 14887When the context is compiled, the gcc::jit::playback classes (within 14888@code{jit-playback.c} and @code{jit-playback.h}) replay the API calls 14889within langhook:parse_file: 14890 14891@quotation 14892 14893@example 14894 14895 /* Indentation indicates inheritance: */ 14896 class context; 14897 class wrapper; 14898 class type; 14899 class compound_type; 14900 class field; 14901 class function; 14902 class block; 14903 class rvalue; 14904 class lvalue; 14905 class param; 14906 class source_file; 14907 class source_line; 14908 class location; 14909 class case_; 14910 14911 14912@end example 14913 14914@noindent 14915 14916@example 14917Client Code . Generated . libgccjit.so 14918 . code . 14919 . . JIT API . JIT "Frontend". (libbackend.a) 14920.................................................................................... 14921 ��� . . . . 14922 ������������������������������������������������������������������������������> . . 14923 . . ��� . . 14924 . . V . . 14925 . . ������> libgccjit.c . 14926 . . ��� (error-checking). 14927 . . ��� . 14928 . . ������> jit-recording.c 14929 . . (record API calls) 14930 . . <��������������������� . 14931 . . ��� . . 14932 <��������������������������������������������������������������������������������� . . 14933 ��� . . . . 14934 ��� . . . . 14935 V . . gcc_jit_context_compile . 14936 ������������������������������������������������������������������������������> . . 14937 . . ��� start of recording::context::compile () 14938 . . ��� . . 14939 . . ��� start of playback::context::compile () 14940 . . ��� (create tempdir) . 14941 . . ��� . . 14942 . . ��� ACQUIRE MUTEX . 14943 . . ��� . . 14944 . . V���������������������������������������������������������������������> toplev::main (for now) 14945 . . . . ��� 14946 . . . . (various code) 14947 . . . . ��� 14948 . . . . V 14949 . . . <��������������������������������������������������� langhook:parse_file 14950 . . . ��� . 14951 . . . ��� (jit_langhook_parse_file) 14952 . . . ��� . 14953..........................................���..................VVVVVVVVVVVVV... 14954 . . . ��� . No GC in here 14955 . . . ��� jit-playback.c 14956 . . . ��� (playback of API calls) 14957 . . . ���������������������������������������������> creation of functions, 14958 . . . . types, expression trees 14959 . . . <������������������������������������������������ etc 14960 . . . ���(handle_locations: add locations to 14961 . . . ��� linemap and associate them with trees) 14962 . . . ��� . 14963 . . . ��� . No GC in here 14964..........................................���..................AAAAAAAAAAAAA... 14965 . . . ��� for each function 14966 . . . ������> postprocess 14967 . . . ��� . 14968 . . . ������������������������������������> cgraph_finalize_function 14969 . . . <������������������������������������ 14970 . . . <������ . 14971 . . . ��� . 14972 . . . ������������������������������������������������������> (end of 14973 . . . . ��� langhook_parse_file) 14974 . . . . ��� 14975 . . . . (various code) 14976 . . . . ��� 14977 . . . . ��� 14978 . . . <��������������������������������������������������� langhook:write_globals 14979 . . . ��� . 14980 . . . ��� (jit_langhook_write_globals) 14981 . . . ��� . 14982 . . . ��� . 14983 . . . ������������������������������������������������������> finalize_compilation_unit 14984 . . . . ��� 14985 . . . . (the middle���end and backend) 14986 . . . . ��� 14987 . . <��������������������������������������������������������������������������������������� end of toplev::main 14988 . . ��� . . 14989 . . V���������������������������������������������������������������������> toplev::finalize 14990 . . . . ��� (purge internal state) 14991 . . <������������������������������������������������������������������������ end of toplev::finalize 14992 . . ��� . . 14993 . . V���> playback::context::postprocess: 14994 . . ��� . . 14995 . . ��� (assuming an in-memory compile): 14996 . . ��� . . 14997 . . --> Convert assembler to DSO, via embedded 14998 . . copy of driver: 14999 . . driver::main () 15000 . . invocation of "as" 15001 . . invocation of "ld" 15002 . . driver::finalize () 15003 . . <---- 15004 . . ��� . . 15005 . . ��� . Load DSO (dlopen "fake.so") 15006 . . ��� . . 15007 . . ��� . Bundle it up in a jit::result 15008 . . <������ . . 15009 . . ��� . . 15010 . . ��� RELEASE MUTEX . 15011 . . ��� . . 15012 . . ��� end of playback::context::compile () 15013 . . ��� . . 15014 . . ��� playback::context dtor 15015 . . ������> . . 15016 . . ��� Normally we cleanup the tempdir here: 15017 . . ��� ("fake.so" is unlinked from the 15018 . . ��� filesystem at this point) 15019 . . ��� If the client code requested debuginfo, the 15020 . . ��� cleanup happens later (in gcc_jit_result_release) 15021 . . ��� to make it easier on the debugger (see PR jit/64206) 15022 . . <������ . . 15023 . . ��� . . 15024 . . ��� end of recording::context::compile () 15025 <��������������������������������������������������������������������������������� . . 15026 ��� . . . . 15027 V . . gcc_jit_result_get_code . 15028 ������������������������������������������������������������������������������> . . 15029 . . ��� dlsym () within loaded DSO 15030 <��������������������������������������������������������������������������������� . . 15031 Get (void*). . . . 15032 ��� . . . . 15033 ��� Call it . . . . 15034 ���������������������������������������������> . . . 15035 . ��� . . . 15036 . ��� . . . 15037 <��������������������������������������������� . . . 15038 ��� . . . . 15039etc��� . . . . 15040 ��� . . . . 15041 V . . gcc_jit_result_release . 15042 ������������������������������������������������������������������������������> . . 15043 . . ��� dlclose () the loaded DSO 15044 . . ��� (code becomes uncallable) 15045 . . ��� . . 15046 . . ��� If the client code requested debuginfo, then 15047 . . ��� cleanup of the tempdir was delayed. 15048 . . ��� If that was the case, clean it up now. 15049 <��������������������������������������������������������������������������������� . . 15050 ��� . . . . 15051 15052@end example 15053 15054@noindent 15055@end quotation 15056@end itemize 15057 15058Here is a high-level summary from @code{jit-common.h}: 15059 15060@quotation 15061 15062In order to allow jit objects to be usable outside of a compile 15063whilst working with the existing structure of GCC's code the 15064C API is implemented in terms of a gcc::jit::recording::context, 15065which records the calls made to it. 15066 15067When a gcc_jit_context is compiled, the recording context creates a 15068playback context. The playback context invokes the bulk of the GCC 15069code, and within the "frontend" parsing hook, plays back the recorded 15070API calls, creating GCC tree objects. 15071 15072So there are two parallel families of classes: those relating to 15073recording, and those relating to playback: 15074 15075 15076@itemize * 15077 15078@item 15079Visibility: recording objects are exposed back to client code, 15080whereas playback objects are internal to the library. 15081 15082@item 15083Lifetime: recording objects have a lifetime equal to that of the 15084recording context that created them, whereas playback objects only 15085exist within the frontend hook. 15086 15087@item 15088Memory allocation: recording objects are allocated by the recording 15089context, and automatically freed by it when the context is released, 15090whereas playback objects are allocated within the GC heap, and 15091garbage-collected; they can own GC-references. 15092 15093@item 15094Integration with rest of GCC: recording objects are unrelated to the 15095rest of GCC, whereas playback objects are wrappers around "tree" 15096instances. Hence you can't ask a recording rvalue or lvalue what its 15097type is, whereas you can for a playback rvalue of lvalue (since it 15098can work with the underlying GCC tree nodes). 15099 15100@item 15101Instancing: There can be multiple recording contexts "alive" at once 15102(albeit it only one compiling at once), whereas there can only be one 15103playback context alive at one time (since it interacts with the GC). 15104@end itemize 15105 15106Ultimately if GCC could support multiple GC heaps and contexts, and 15107finer-grained initialization, then this recording vs playback 15108distinction could be eliminated. 15109 15110During a playback, we associate objects from the recording with 15111their counterparts during this playback. For simplicity, we store this 15112within the recording objects, as @code{void *m_playback_obj}, casting it to 15113the appropriate playback object subclass. For these casts to make 15114sense, the two class hierarchies need to have the same structure. 15115 15116Note that the playback objects that @code{m_playback_obj} points to are 15117GC-allocated, but the recording objects don't own references: 15118these associations only exist within a part of the code where 15119the GC doesn't collect, and are set back to NULL before the GC can 15120run. 15121@end quotation 15122@anchor{internals/index example-of-log-file}@anchor{5c} 15123Another way to understand the structure of the code is to enable logging, 15124via @pxref{5b,,gcc_jit_context_set_logfile()}. Here is an example of a log 15125generated via this call: 15126 15127@example 15128JIT: libgccjit (GCC) version 6.0.0 20150803 (experimental) (x86_64-pc-linux-gnu) 15129JIT: 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 15130JIT: entering: gcc_jit_context_set_str_option 15131JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe" 15132JIT: exiting: gcc_jit_context_set_str_option 15133JIT: entering: gcc_jit_context_set_int_option 15134JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3 15135JIT: exiting: gcc_jit_context_set_int_option 15136JIT: entering: gcc_jit_context_set_bool_option 15137JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true 15138JIT: exiting: gcc_jit_context_set_bool_option 15139JIT: entering: gcc_jit_context_set_bool_option 15140JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false 15141JIT: exiting: gcc_jit_context_set_bool_option 15142JIT: entering: gcc_jit_context_set_bool_option 15143JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false 15144JIT: exiting: gcc_jit_context_set_bool_option 15145JIT: entering: gcc_jit_context_set_bool_option 15146JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true 15147JIT: exiting: gcc_jit_context_set_bool_option 15148JIT: entering: gcc_jit_context_set_bool_option 15149JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false 15150JIT: exiting: gcc_jit_context_set_bool_option 15151JIT: entering: gcc_jit_context_get_type 15152JIT: exiting: gcc_jit_context_get_type 15153JIT: entering: gcc_jit_context_get_type 15154JIT: exiting: gcc_jit_context_get_type 15155JIT: entering: gcc_jit_context_new_param 15156JIT: exiting: gcc_jit_context_new_param 15157JIT: entering: gcc_jit_context_new_function 15158JIT: exiting: gcc_jit_context_new_function 15159JIT: entering: gcc_jit_context_new_param 15160JIT: exiting: gcc_jit_context_new_param 15161JIT: entering: gcc_jit_context_get_type 15162JIT: exiting: gcc_jit_context_get_type 15163JIT: entering: gcc_jit_context_new_function 15164JIT: exiting: gcc_jit_context_new_function 15165JIT: entering: gcc_jit_context_new_string_literal 15166JIT: exiting: gcc_jit_context_new_string_literal 15167JIT: entering: gcc_jit_function_new_block 15168JIT: exiting: gcc_jit_function_new_block 15169JIT: entering: gcc_jit_block_add_comment 15170JIT: exiting: gcc_jit_block_add_comment 15171JIT: entering: gcc_jit_context_new_call 15172JIT: exiting: gcc_jit_context_new_call 15173JIT: entering: gcc_jit_block_add_eval 15174JIT: exiting: gcc_jit_block_add_eval 15175JIT: entering: gcc_jit_block_end_with_void_return 15176JIT: exiting: gcc_jit_block_end_with_void_return 15177JIT: entering: gcc_jit_context_dump_reproducer_to_file 15178JIT: entering: void gcc::jit::recording::context::dump_reproducer_to_file(const char*) 15179JIT: exiting: void gcc::jit::recording::context::dump_reproducer_to_file(const char*) 15180JIT: exiting: gcc_jit_context_dump_reproducer_to_file 15181JIT: entering: gcc_jit_context_compile 15182JIT: in-memory compile of ctxt: 0x1283e20 15183JIT: entering: gcc::jit::result* gcc::jit::recording::context::compile() 15184JIT: GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe" 15185JIT: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3 15186JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO: true 15187JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false 15188JIT: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false 15189JIT: GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE: false 15190JIT: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false 15191JIT: GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING: false 15192JIT: GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true 15193JIT: GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES: false 15194JIT: gcc_jit_context_set_bool_allow_unreachable_blocks: false 15195JIT: gcc_jit_context_set_bool_use_external_driver: false 15196JIT: entering: void gcc::jit::recording::context::validate() 15197JIT: exiting: void gcc::jit::recording::context::validate() 15198JIT: entering: gcc::jit::playback::context::context(gcc::jit::recording::context*) 15199JIT: exiting: gcc::jit::playback::context::context(gcc::jit::recording::context*) 15200JIT: entering: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*) 15201JIT: exiting: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*) 15202JIT: entering: void gcc::jit::playback::context::compile() 15203JIT: entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int) 15204JIT: exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int) 15205JIT: entering: bool gcc::jit::tempdir::create() 15206JIT: m_path_template: /tmp/libgccjit-XXXXXX 15207JIT: m_path_tempdir: /tmp/libgccjit-CKq1M9 15208JIT: exiting: bool gcc::jit::tempdir::create() 15209JIT: entering: void gcc::jit::playback::context::acquire_mutex() 15210JIT: exiting: void gcc::jit::playback::context::acquire_mutex() 15211JIT: entering: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*) 15212JIT: reusing cached configure-time options 15213JIT: configure_time_options[0]: -mtune=generic 15214JIT: configure_time_options[1]: -march=x86-64 15215JIT: exiting: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*) 15216JIT: entering: toplev::main 15217JIT: argv[0]: ./test-hello-world.c.exe 15218JIT: argv[1]: /tmp/libgccjit-CKq1M9/fake.c 15219JIT: argv[2]: -fPIC 15220JIT: argv[3]: -O3 15221JIT: argv[4]: -g 15222JIT: argv[5]: -quiet 15223JIT: argv[6]: --param 15224JIT: argv[7]: ggc-min-expand=0 15225JIT: argv[8]: --param 15226JIT: argv[9]: ggc-min-heapsize=0 15227JIT: argv[10]: -mtune=generic 15228JIT: argv[11]: -march=x86-64 15229JIT: entering: bool jit_langhook_init() 15230JIT: exiting: bool jit_langhook_init() 15231JIT: entering: void gcc::jit::playback::context::replay() 15232JIT: entering: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*) 15233JIT: exiting: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*) 15234JIT: entering: void gcc::jit::recording::context::disassociate_from_playback() 15235JIT: exiting: void gcc::jit::recording::context::disassociate_from_playback() 15236JIT: entering: void gcc::jit::playback::context::handle_locations() 15237JIT: exiting: void gcc::jit::playback::context::handle_locations() 15238JIT: entering: void gcc::jit::playback::function::build_stmt_list() 15239JIT: exiting: void gcc::jit::playback::function::build_stmt_list() 15240JIT: entering: void gcc::jit::playback::function::build_stmt_list() 15241JIT: exiting: void gcc::jit::playback::function::build_stmt_list() 15242JIT: entering: void gcc::jit::playback::function::postprocess() 15243JIT: exiting: void gcc::jit::playback::function::postprocess() 15244JIT: entering: void gcc::jit::playback::function::postprocess() 15245JIT: exiting: void gcc::jit::playback::function::postprocess() 15246JIT: exiting: void gcc::jit::playback::context::replay() 15247JIT: exiting: toplev::main 15248JIT: entering: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*) 15249JIT: exiting: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*) 15250JIT: entering: toplev::finalize 15251JIT: exiting: toplev::finalize 15252JIT: entering: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*) 15253JIT: entering: void gcc::jit::playback::context::convert_to_dso(const char*) 15254JIT: entering: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool) 15255JIT: entering: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*) 15256JIT: exiting: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*) 15257JIT: argv[0]: x86_64-unknown-linux-gnu-gcc-6.0.0 15258JIT: argv[1]: -m64 15259JIT: argv[2]: -shared 15260JIT: argv[3]: /tmp/libgccjit-CKq1M9/fake.s 15261JIT: argv[4]: -o 15262JIT: argv[5]: /tmp/libgccjit-CKq1M9/fake.so 15263JIT: argv[6]: -fno-use-linker-plugin 15264JIT: entering: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*) 15265JIT: exiting: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*) 15266JIT: exiting: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool) 15267JIT: exiting: void gcc::jit::playback::context::convert_to_dso(const char*) 15268JIT: entering: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso() 15269JIT: GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir to jit::result 15270JIT: entering: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*) 15271JIT: exiting: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*) 15272JIT: exiting: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso() 15273JIT: exiting: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*) 15274JIT: entering: void gcc::jit::playback::context::release_mutex() 15275JIT: exiting: void gcc::jit::playback::context::release_mutex() 15276JIT: exiting: void gcc::jit::playback::context::compile() 15277JIT: entering: gcc::jit::playback::context::~context() 15278JIT: exiting: gcc::jit::playback::context::~context() 15279JIT: exiting: gcc::jit::result* gcc::jit::recording::context::compile() 15280JIT: gcc_jit_context_compile: returning (gcc_jit_result *)0x12f75d0 15281JIT: exiting: gcc_jit_context_compile 15282JIT: entering: gcc_jit_result_get_code 15283JIT: locating fnname: hello_world 15284JIT: entering: void* gcc::jit::result::get_code(const char*) 15285JIT: exiting: void* gcc::jit::result::get_code(const char*) 15286JIT: gcc_jit_result_get_code: returning (void *)0x7ff6b8cd87f0 15287JIT: exiting: gcc_jit_result_get_code 15288JIT: entering: gcc_jit_context_release 15289JIT: deleting ctxt: 0x1283e20 15290JIT: entering: gcc::jit::recording::context::~context() 15291JIT: exiting: gcc::jit::recording::context::~context() 15292JIT: exiting: gcc_jit_context_release 15293JIT: entering: gcc_jit_result_release 15294JIT: deleting result: 0x12f75d0 15295JIT: entering: virtual gcc::jit::result::~result() 15296JIT: entering: gcc::jit::tempdir::~tempdir() 15297JIT: unlinking .s file: /tmp/libgccjit-CKq1M9/fake.s 15298JIT: unlinking .so file: /tmp/libgccjit-CKq1M9/fake.so 15299JIT: removing tempdir: /tmp/libgccjit-CKq1M9 15300JIT: exiting: gcc::jit::tempdir::~tempdir() 15301JIT: exiting: virtual gcc::jit::result::~result() 15302JIT: exiting: gcc_jit_result_release 15303JIT: gcc::jit::logger::~logger() 15304 15305@end example 15306 15307@noindent 15308 15309@node Design notes,Submitting patches,Overview of code structure,Internals 15310@anchor{internals/index design-notes}@anchor{1cb} 15311@section Design notes 15312 15313 15314It should not be possible for client code to cause an internal compiler 15315error. If this @emph{does} happen, the root cause should be isolated (perhaps 15316using @pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}) and the cause 15317should be rejected via additional checking. The checking ideally should 15318be within the libgccjit API entrypoints in libgccjit.c, since this is as 15319close as possible to the error; failing that, a good place is within 15320@code{recording::context::validate ()} in jit-recording.c. 15321 15322@node Submitting patches,,Design notes,Internals 15323@anchor{internals/index submitting-patches}@anchor{1cc} 15324@section Submitting patches 15325 15326 15327Please read the contribution guidelines for gcc at 15328@indicateurl{https://gcc.gnu.org/contribute.html}. 15329 15330Patches for the jit should be sent to both the 15331@email{gcc-patches@@gcc.gnu.org} and @email{jit@@gcc.gnu.org} mailing lists, 15332with "jit" and "PATCH" in the Subject line. 15333 15334You don't need to do a full bootstrap for code that just touches the 15335@code{jit} and @code{testsuite/jit.dg} subdirectories. However, please run 15336@code{make check-jit} before submitting the patch, and mention the results 15337in your email (along with the host triple that the tests were run on). 15338 15339A good patch should contain the information listed in the 15340gcc contribution guide linked to above; for a @code{jit} patch, the patch 15341shold contain: 15342 15343@quotation 15344 15345 15346@itemize * 15347 15348@item 15349the code itself (for example, a new API entrypoint will typically 15350touch @code{libgccjit.h} and @code{.c}, along with support code in 15351@code{jit-recording.[ch]} and @code{jit-playback.[ch]} as appropriate) 15352 15353@item 15354test coverage 15355 15356@item 15357documentation for the C API 15358 15359@item 15360documentation for the C++ API 15361@end itemize 15362@end quotation 15363 15364A patch that adds new API entrypoints should also contain: 15365 15366@quotation 15367 15368 15369@itemize * 15370 15371@item 15372a feature macro in @code{libgccjit.h} so that client code that doesn't 15373use a "configure" mechanism can still easily detect the presence of 15374the entrypoint. See e.g. @code{LIBGCCJIT_HAVE_SWITCH_STATEMENTS} (for 15375a category of entrypoints) and 15376@code{LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks} 15377(for an individual entrypoint). 15378 15379@item 15380a new ABI tag containing the new symbols (in @code{libgccjit.map}), so 15381that we can detect client code that uses them 15382 15383@item 15384Support for @pxref{5d,,gcc_jit_context_dump_reproducer_to_file()}. Most 15385jit testcases attempt to dump their contexts to a .c file; @code{jit.exp} 15386then sanity-checks the generated c by compiling them (though 15387not running them). A new API entrypoint 15388needs to "know" how to write itself back out to C (by implementing 15389@code{gcc::jit::recording::memento::write_reproducer} for the appropriate 15390@code{memento} subclass). 15391 15392@item 15393C++ bindings for the new entrypoints (see @code{libgccjit++.h}); ideally 15394with test coverage, though the C++ API test coverage is admittedly 15395spotty at the moment 15396 15397@item 15398documentation for the new C entrypoints 15399 15400@item 15401documentation for the new C++ entrypoints 15402 15403@item 15404documentation for the new ABI tag (see @code{topics/compatibility.rst}). 15405@end itemize 15406@end quotation 15407 15408Depending on the patch you can either extend an existing test case, or 15409add a new test case. If you add an entirely new testcase: @code{jit.exp} 15410expects jit testcases to begin with @code{test-}, or @code{test-error-} (for a 15411testcase that generates an error on a @pxref{8,,gcc_jit_context}). 15412 15413Every new testcase that doesn't generate errors should also touch 15414@code{gcc/testsuite/jit.dg/all-non-failing-tests.h}: 15415 15416@quotation 15417 15418 15419@itemize * 15420 15421@item 15422Testcases that don't generate errors should ideally be added to the 15423@code{testcases} array in that file; this means that, in addition 15424to being run standalone, they also get run within 15425@code{test-combination.c} (which runs all successful tests inside one 15426big @pxref{8,,gcc_jit_context}), and @code{test-threads.c} (which runs all 15427successful tests in one process, each one running in a different 15428thread on a different @pxref{8,,gcc_jit_context}). 15429 15430@cartouche 15431@quotation Note 15432Given that exported functions within a @pxref{8,,gcc_jit_context} 15433must have unique names, and most testcases are run within 15434@code{test-combination.c}, this means that every jit-compiled test 15435function typically needs a name that's unique across the entire 15436test suite. 15437@end quotation 15438@end cartouche 15439 15440@item 15441Testcases that aren't to be added to the @code{testcases} array should 15442instead add a comment to the file clarifying why they're not in that 15443array. See the file for examples. 15444@end itemize 15445@end quotation 15446 15447Typically a patch that touches the .rst documentation will also need the 15448texinfo to be regenerated. You can do this with 15449Sphinx 1.0@footnote{http://sphinx-doc.org/} or later by 15450running @code{make texinfo} within @code{SRCDIR/gcc/jit/docs}. Don't do this 15451within the patch sent to the mailing list; it can often be relatively 15452large and inconsequential (e.g. anchor renumbering), rather like generated 15453"configure" changes from configure.ac. You can regenerate it when 15454committing to svn. 15455 15456@node Indices and tables,Index,Internals,Top 15457@anchor{index indices-and-tables}@anchor{1cd} 15458@unnumbered Indices and tables 15459 15460 15461 15462@itemize * 15463 15464@item 15465@emph{genindex} 15466 15467@item 15468@emph{modindex} 15469 15470@item 15471@emph{search} 15472@end itemize 15473 15474@c Some notes: 15475@c 15476@c The Sphinx C domain appears to lack explicit support for enum values, 15477@c so I've been using :c:macro: for them. 15478@c 15479@c See http://sphinx-doc.org/domains.html#the-c-domain 15480 15481@node Index,,Indices and tables,Top 15482@unnumbered Index 15483 15484 15485@printindex ge 15486 15487@c %**end of body 15488@bye 15489