Getting the application binary interface right – IR Generation for High-Level Language Constructs-2
By Reginald Bellamy / May 3, 2024 / No Comments / Handling the scope of names, IT Certifications, LLVM IR REFERENCE, Technical requirements
To set multiple attributes, you can use the llvm::AttrBuilder class.
The other way to provide additional information is to use type rewriting. With this approach, you disguise the original types. You can do the following:
- Split the parameter. For example, instead of passing one complex argument, you can pass two floating-point arguments.
- Cast the parameter into a different representation, such as passing a floating-point value through an integer register.
To cast between types without changing the bits of the value, you use the bitcast instruction. The bitcast instruction can operate on simple data types such as integers and floating-point values. When floating-point values are passed via an integer register, the floating-point value must be cast to an integer. In LLVM, a 32-bit floating-point value is expressed as float, and a 32-bit bit integer is expressed as i32. The floating point value can be bitcasted to an integer in the following way:
%intconv = bitcast float %fp to i32
Additionally, the bitcast instruction requires that both types have the same size.
Adding attributes to an argument or changing the type is not complicated. But how do you know what you need to implement? First of all, you should get an overview of the calling convention used on your target platform. For example, the ELF ABI on Linux is documented for each supported CPU platform, so you can look up the document and make yourself comfortable with it.
There is also documentation about the requirements of the LLVM code generators. The source of information is the clang implementation, which you can find at https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/TargetInfo.cpp. This single file contains the ABI-specific actions for all supported platforms, and it is also where all information is collected.
In this section, you learned to generate the IR for function calls to be compliant with the ABI of your platform. The next section covers the different ways to create IR for classes and virtual functions.
Creating IR code for classes and virtual functions
Many modern programming languages support object orientation using classes. A class is a high-level language construct, and in this section, we will explore how we can map a class construct into LLVM IR.