Question

I am profiling a few files in Spec2K6 benchmark with a profiler written in LLVM, and cannot understand what is the correct way to link multiple .bc files.

For example, the benchmark has concat.c, which uses the xmalloc method defined in xmalloc.c, which uses xexit method from xexit.c

I am using the following commands to link multiple .bc files before I profile them -

CFLAGS='-D_GNU_SOURCE -D_XOPEN_SOURCE=600 -c -Wall -pedantic -Wno-long-long -g -O0 -    I/net/x/silkyar/llvm/include -I/net/403.gcc/src'
clang $CFLAGS -emit-llvm -c 403.gcc/src/concat.c -o concat.bc
clang $CFLAGS -emit-llvm -c 403.gcc/src/xexit.c -o xexit.bc
clang $CFLAGS -emit-llvm -c 403.gcc/src/xmalloc.c -o xmalloc.bc 
llvm-link concat.bc xexit.bc xmalloc.bc -o a.bc
llc a.bc -o a.s
g++ -o final a.s
./final

but this fails with, llvm-link: link error in 'xexit.bc': Linking globals named 'xexit': symbol multiply defined! /tmp/ccUldT0Y.o:(.debug_info+0x1e): undefined reference to .Lline_table_start0' /tmp/ccUldT0Y.o:(.debug_info+0x42f): undefined reference to.Lline_table_start1' /tmp/ccUldT0Y.o:(.debug_info+0x4a0): undefined reference to `.Lline_table_start2' collect2: ld returned 1 exit status

Could anyone please guide me on how llvm-link works.

Thanks.

Was it helpful?

Solution

In general, llvm-link works fine. Here's a simple demonstration (with LLVM built from trunk a few days ago):

$ cat lib.c 
int libfoo(int x) {
    return x * 2;
}

$ cat user.c
int libfoo(int);


int bar(int a, int b) {
    return a + libfoo(b);
}
$ clang -emit-llvm -c user.c -o user.bc
$ clang -emit-llvm -c lib.c -o lib.bc
$ llvm-link lib.bc user.bc -o linked.bc
$ llvm-dis linked.bc
$ cat linked.ll
; ModuleID = 'linked.bc'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i32 @libfoo(i32 %x) nounwind uwtable {
entry:
  %x.addr = alloca i32, align 4
  store i32 %x, i32* %x.addr, align 4
  %0 = load i32* %x.addr, align 4
  %mul = mul nsw i32 %0, 2
  ret i32 %mul
}

define i32 @bar(i32 %a, i32 %b) nounwind uwtable {
entry:
  %a.addr = alloca i32, align 4
  %b.addr = alloca i32, align 4
  store i32 %a, i32* %a.addr, align 4
  store i32 %b, i32* %b.addr, align 4
  %0 = load i32* %a.addr, align 4
  %1 = load i32* %b.addr, align 4
  %call = call i32 @libfoo(i32 %1)
  %add = add nsw i32 %0, %call
  ret i32 %add
}

So you have to carefully examine your specific code for symbol duplication, missing, etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top