Next: , Previous: , Up: TC-L   [Contents][Index]


4.21.5 TC-L FAQ

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:

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 the vtables 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 and llvm::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:

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 SSA is to forbid re-assignments, so we cannot assign 2 to a.

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 and cfg.fact_18.dot, corresponding to the main function and the fact 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 allows you to do it using the flags -S -emit-llvm.

int main(void)
{
  int a = 1 + 2 * 3;
  return a;
}

File 4.99: clang-example.c

$ 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-f64:32:64-f80:32-n8:16:32-S128"
target triple = "i386-pc-linux-gnu"

; Function Attrs: noinline nounwind
define 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 "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"NumRegisterParameters", i32 0}
!1 = !{!"clang version 4.0.1-8 (tags/RELEASE_401/final)"}

Example 4.163: clang -m32 -S -emit-llvm -o - clang-example.c

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, from C to LLVM IR, you have to make sure that the Clang version and the LLVM version are exactly the same.

This crash currently occurs with Clang 3.6 and LLVM 3.8.


Next: , Previous: , Up: TC-L   [Contents][Index]