TC-L FAQ
- What is a PHI node?
LLVM instructions are represented in the SSA (Static Single Assignment) form.
Let’s take an example:
let var v := 10 var a := 1 var b := 0 in if (v < 10) then a := 2; b := a end
The whole point of The SSA form is to create a variable each time a variable is assigned more than once to enforce the single static assignment, so we cannot assign
2
toa
.In that case, LLVM is going to create two
a
’s, and the assignment has to pick the desired version.Using a PHI node, the assignment will depend on the original path of the code, and using that information, it can decide which version of
a
should be picked.You can use the
opt
tool in order to display the control-flow graph.opt -dot-cfg fact.ll
This generates two files:
cfg.tc_main.dot
andcfg.fact_18.dot
, corresponding to themain
function and thefact
function.- I don’t understand all the acronyms used in LLVM.
Where can I find their meaning? You can find it in The LLVM Lexicon.
- Can I output the LLVM IR of a C/C++ program?
Yes, you can. Clang, A C language family front end for LLVM allows you to do it using the flags
-S -emit-llvm
.int main(void) { int a = 1 + 2 * 3; return a; }
$ clang -m32 -S -emit-llvm -o - clang-example.c ; ModuleID = 'clang-example.c' source_filename = "clang-example.c" target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128" target triple = "i386-pc-linux-gnu" ; Function Attrs: noinline nounwind optnone uwtable define dso_local i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 0, i32* %1, align 4 store i32 7, i32* %2, align 4 %3 = load i32, i32* %2, align 4 ret i32 %3 } attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="i686" "target-features"="+cx8,+x87" "tune-cpu"="generic" } !llvm.module.flags = !{!0, !1, !2, !3, !4, !5} !llvm.ident = !{!6} !0 = !{i32 1, !"NumRegisterParameters", i32 0} !1 = !{i32 1, !"wchar_size", i32 4} !2 = !{i32 7, !"PIC Level", i32 2} !3 = !{i32 7, !"PIE Level", i32 2} !4 = !{i32 7, !"uwtable", i32 1} !5 = !{i32 7, !"frame-pointer", i32 2} !6 = !{!"Debian clang version 14.0.6"} $ echo $? 0
- The build failed on my machine
If the following error occurs:
CXXLD src/tc src/.libs/libtc.a(lt14-translator.o):(.rodata._ZTIN4llvm17GetElementPtrInstE[_ZTIN4llvm17GetElementPtrInstE]+0x10): undefined reference to `typeinfo for llvm::Instruction' src/.libs/libtc.a(lt14-translator.o):(.rodata._ZTIN4llvm8ICmpInstE[_ZTIN4llvm8ICmpInstE]+0x10): undefined reference to `typeinfo for llvm::CmpInst' src/.libs/libtc.a(lt14-translator.o):(.rodata._ZTIN4llvm7PHINodeE[_ZTIN4llvm7PHINodeE]+0x10): undefined reference to `typeinfo for llvm::Instruction' collect2: error: ld returned 1 exit status Makefile:2992: recipe for target 'src/tc' failed make: *** [src/tc] Error 1
then you are using an old version of LLVM. The version required is 3.8 or more.
If you still want to use LLVM 3.7, then the LLVM build you are using is compiled without RTTI.
In order to make it work, you have two choices:
If you are building LLVM 3.7 from the source code, apply this patch to fix the compilation.
Build LLVM with RTTI enabled. In order to build LLVM with RTTI enabled, follow these steps, assuming the current directory is the root of LLVM:
mkdir _build
cd _build
cmake .. -DLLVM_REQUIRES_RTTI=ON -DCMAKE_BUILD_TYPE=Release
make install
LLVM builds with RTTI disabled by default. They use their own RTTI-like system. Tiger is compiled using RTTI, and actually uses it quite a lot (
dynamic_cast
). In order to make them work together, LLVM has to emit thevtables
of its classes in their own translation unit.This regression appeared in LLVM 3.7 when a virtual destructor was inlined, so the
vtables
were emitted in every translation unit. It was the following classes:llvm::GetElementPtrInst
,llvm::ICmpInst
andllvm::PHINode
.In order to solve the problem, LLVM uses a dedicated member function called
anchor
, that is going to force the emission to happen in its own translation unit.As of today, here are some packages of LLVM 3.7 that work/don’t work: - ArchLinux (pacman) - RTTI enabled.
OS X (brew) - RTTI enabled.
OS X (macports) - RTTI disabled. Does not compile.
Ubuntu (apt) - RTTI enabled.
- Your compiler crashes when
llvm::Linker::linkModules
is called When using
--llvm-runtime-display
, this behavior can occur when the linker is asked to link two LLVM IR modules that may have been compiled with two different LLVM IR versions.Since the runtime is compiled with Clang, A C language family front end for LLVM, from C to LLVM IR, you have to make sure that the Clang, A C language family front end for LLVM version and the LLVM version are exactly the same.
This crash currently occurs with Clang, A C language family front end for LLVM 3.6 and LLVM 3.8.