Generating and Using LLVM Bitcode

In the compiler build options, under the LLVM build options, the compiler can output LLVM bitcode by doing:

llvm_options.output_bitcode = true;

By default, the bitcode is outputted to the .build folder. However, one can change where the bitcode is outputted by changing the intermediate path of the compiler:

target_options.intermediate_path = #filepath;

By setting the intermediate path to whatever you want, you can change where the bitcode files end up at.

Here is a simple compiler message loop example of how to generate LLVM bitcode:

#import "Basic";
#import "Compiler";

#run {
  w := compiler_create_workspace("workspace_1");
  if !w {
    print("Workspace creation failed.\n");
    return;
  }
  target_options := get_build_options(w);
  target_options.output_executable_name = "executable";
  target_options.intermediate_path = #filepath;
  set_optimization_level(*target_options, 2, 0); 
  target_options.llvm_options.output_bitcode = true;
  set_build_options(target_options, w);

  compiler_begin_intercept(w);
  add_build_file("main.jai", w);  

  while true {
    message := compiler_wait_for_message();
    if !message break;
    if message.kind == {
    case .COMPLETE;
      break;
    }
  }
  compiler_end_intercept(w);
  set_build_options_dc(.{do_output=false});
}

Create a simple main.jai program that prints “Hello World!”. Now your build script can generate LLVM bitcode.

#import "Basic";
main :: () {
  print("Hello World\n");
}

Generating Assembly Language from LLVM

To install LLVM on your Linux Ubuntu machine, you can use the following Linux commands:

sudo apt install llvm

If you have LLVM installed on your Linux Ubuntu machine, you can use the commands:

llc < your_bitcode.bc > output.asm
as output.asm

to transform the program into assembly language. The llc command transforms your bitcode into the assembly language on your machine, and the as command compiles that assembly language into binary machine language.

@danieltan1517 Is this the valid first step for generating wasm? I.e. Jai → LLVM Bytecode → Wasm? Or not really.

Would be superuseful to have a wasm article in cookbook once it’s clear how to get it working.

Maybe? I did some LLVM work in graduate compilers class. I know commands to convert LLVM IR into ASM. Though because it is not directly supported by the compiler as a backend, converting LLVM IR into Wasm might be a bit hacky.

I decided to look more into LLVM to WASM, and it seems that you need to LLVM to generate IR compatible with WASM. See How do I generate LLVM bitcode for use by emscripten? - Stack Overflow and Using LLVM from Rust to generate WebAssembly binaries | by Jay Phelps | Medium.

Maybe I’ll look more into this if I have free time over the holidays.

1 Like

Thank you, this is super exciting!