문제

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.

도움이 되었습니까?

해결책

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top