To get the build options for the compiler, create a workspace with the function compiler_create_workspace
and call get_build_options
on the workspace created under compiler_create_workspace
. Here is an example build
function that demonstrates this:
#import "Basic";
#import "Compiler";
build :: () {
w := compiler_create_workspace();
if !w {
print("Workspace creation failed.\n");
return;
}
target_options := get_build_options(w);
//...other code
}
The Build_Options
struct contains many build options such as enabling/disabling array bounds check, setting the optimization level, switching the backend between LLVM and x64, changing the executable name, and setting the OS target.
Simple Build Options for highly optimized code
This snippet creates a highly optimized build. Optimized builds take a long time, but are around twice as fast as an unoptimized build. The build options included do things such as setting the compiler backend to LLVM, disabling array bounds check, disabling number cast checking, and enabling tail call recursion optimization.
set_optimization_level(target_options, 2, 0); // same as clang -O2
Target Build Options
The output type for target_options
can be specified between no output, executable, dynamic library, and static library. By default, the output type is an executable.
target_options.output_type = .NO_OUTPUT; // specifies no output for the compiler
target_options.output_type = .EXECUTABLE; // specifies executable as an output for the compiler
target_options.output_type = .DYNAMIC_LIBRARY; // specifies output to be a dynamic library
target_options.output_type = .STATIC_LIBRARY; // specifies output to be a static library
target_options.output_type = .OBJECT_FILE; // specifies output to be an object file
Optimization levels can be toggled between debug and release.
target_options.optimization_level = .DEBUG; // specifies the optimization level to be .DEBUG
target_options.optimization_level = .RELEASE; // specifies the optimization level to be .RELEASE
The different backend options can be toggled between -x64 and llvm as follows:
target_options.backend = .X64; // specifies the x64 backend
target_options.backend = .LLVM; // specifies the llvm backend
Array bounds check can be changed through the array_bounds_check
field.
target_options.array_bounds_check = .OFF; // turns off array bounds check
target_options.array_bounds_check = .ON; // turns on array bounds check
target_options.array_bounds_check = .ALWAYS;
The build options for the llvm and x64 backends can be be set through the x64_options
and llvm_options
fields respectively.
LLVM Options
The LLVM backend options contains many compiler options for optimizing code, turning features of LLVM on or off. Here is a list of some of the flags for the LLVM Options given the target_options.llvm_options
struct.
.enable_tail_calls = false;
.enable_loop_unrolling = false;
.enable_slp_vectorization = false;
.enable_loop_vectorization = false;
.reroll_loop = false;
.verify_input = false;
.verify_output = false;
.merge_functions = false;
.disable_inlining = true;
.disable_mem2reg = false;
The -O3
, -O2
, -O1
optimization levels for LLVM can be changed by setting the code_gen_optimization_level
field to 3, 2, 1 respectively. For example, target_options.llvm_options.code_gen_optimization_level = 2
will set the LLVM options to -O2
.
Debug Options can be passed directly to LLVM’s cl::ParseCommandLineOptions()
function through
the field debug_options
.
A more comprehensive set of compiler options and details can be found under Compiler.jai
.