0

I got a requirement in which i have a c file and i am generating LLVM IR for the same. From the generated LLVM IR for each instruction i am calculating how many cycles it will take to execute, now my problem is how can i trace back the same to the c code and displays the particular c code block(say function) took calculated number of cycles(Which i am actually calculating from the generated LLVM IR code).

I have a c code as below:

int arithmeticOperations(int x, int y) { int aa, ab, ac, ad; if(x>10) { aa = x+y; ab = x-y; for(x = 1; x <= aa; ++x) { y += x; } } else { ac = x*y; ad = x/y; } return aa * ab * ac * ad; } void arithmeticOperationsPart2(int x, int y) { int aa, ab, ac, ad; if(x>10) { aa = x+y; ab = x-y; } else { ac = x*y; ad = x/y; } } int main() { arithmeticOperations(35, 7); arithmeticOperationsPart2(35, 7); } 

I am creating LLVM IR using command:

clang -Os -S -emit-llvm addition.c 

This output addition.ll file as below:

; ModuleID = 'addition.c' source_filename = "addition.c" target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc18.0.0" ; Function Attrs: norecurse nounwind optsize readnone uwtable define i32 @arithmeticOperations(i32, i32) local_unnamed_addr #0 { %3 = icmp sgt i32 %0, 10 br i1 %3, label %4, label %7 ; <label>:4: ; preds = %2 %5 = add nsw i32 %1, %0 %6 = sub nsw i32 %0, %1 br label %10 ; <label>:7: ; preds = %2 %8 = mul nsw i32 %1, %0 %9 = sdiv i32 %0, %1 br label %10 ; <label>:10: ; preds = %4, %7 %11 = phi i32 [ undef, %7 ], [ %5, %4 ] %12 = phi i32 [ undef, %7 ], [ %6, %4 ] %13 = phi i32 [ %8, %7 ], [ undef, %4 ] %14 = phi i32 [ %9, %7 ], [ undef, %4 ] %15 = mul nsw i32 %12, %11 %16 = mul nsw i32 %15, %13 %17 = mul nsw i32 %16, %14 ret i32 %17 } ; Function Attrs: norecurse nounwind optsize readnone uwtable define void @arithmeticOperationsPart2(i32, i32) local_unnamed_addr #0 { ret void } ; Function Attrs: norecurse nounwind optsize readnone uwtable define i32 @main() local_unnamed_addr #0 { ret i32 0 } attributes #0 = { norecurse nounwind optsize readnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "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"="x86-64" "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, !"PIC Level", i32 2} !1 = !{!"clang version 5.0.0 (trunk 302984) (llvm/trunk 302983)"} 

Now i want to filter what LLVM code corresponds to the c source code it generated.(Say specific to a function)

For example(currently i want to filter the c function arithmeticOperations ):

 %3 = icmp sgt i32 %0, 10 br i1 %3, label %4, label %7 ; <label>:4: ; preds = %2 %5 = add nsw i32 %1, %0 %6 = sub nsw i32 %0, %1 br label %10 ; <label>:7: ; preds = %2 %8 = mul nsw i32 %1, %0 %9 = sdiv i32 %0, %1 br label %10 ; <label>:10: ; preds = %4, %7 %11 = phi i32 [ undef, %7 ], [ %5, %4 ] %12 = phi i32 [ undef, %7 ], [ %6, %4 ] %13 = phi i32 [ %8, %7 ], [ undef, %4 ] %14 = phi i32 [ %9, %7 ], [ undef, %4 ] %15 = mul nsw i32 %12, %11 %16 = mul nsw i32 %15, %13 %17 = mul nsw i32 %16, %14 ret i32 %17 

corresponds to the below part of the c code:

int aa, ab, ac, ad; if(x>10) { aa = x+y; ab = x-y; for(x = 1; x <= aa; ++x) { y += x; } } else { ac = x*y; ad = x/y; } return aa * ab * ac * ad; 
3
  • Why not generate the assembly list file from the C or LLVM IR and get the instruction count for your platform architecture auto-magically? Commented Jul 17, 2017 at 14:54
  • @FrankC.: Thanks for your reply, I didn't quite get that, will the instruction count generated form LLVM IR will be generic for all targets? Commented Jul 18, 2017 at 6:01
  • When you generate the assembler listing from the LLVM-IR the instruction set would be platform architecture specific. Commented Jul 18, 2017 at 8:23

1 Answer 1

1

You can tell clang to emit debug info by adding the -g flag:

clang -Os -S -emit-llvm -g addition.c 

Then you will find plenty of information about which instruction corresponds to which original line in your ll file.

For example the start of the arithmeticOperations function is translated as follows, with the lines ending in !dgb !<number> referring to debug information entries:

; Function Attrs: nounwind optsize readnone uwtable define i32 @arithmeticOperations(i32 %x, i32 %y) local_unnamed_addr #0 !dbg !7 { entry: tail call void @llvm.dbg.value(metadata i32 %y, i64 0, metadata !12, metadata !18), !dbg !19 tail call void @llvm.dbg.value(metadata i32 %x, i64 0, metadata !13, metadata !18), !dbg !20 %cmp = icmp sgt i32 %x, 10, !dbg !21 br i1 %cmp, label %if.then, label %if.else, !dbg !23 

Towards the end of the file there will be many "DILocation" entries telling you where the corresponding source code was:

... !19 = !DILocation(line: 1, column: 37, scope: !7) !20 = !DILocation(line: 1, column: 30, scope: !7) !21 = !DILocation(line: 4, column: 9, scope: !22) !22 = distinct !DILexicalBlock(scope: !7, file: !1, line: 4, column: 8) !23 = !DILocation(line: 4, column: 8, scope: !7) 

So if you are interested where this line came from:

%cmp = icmp sgt i32 %x, 10, !dbg !21 

You have to look for the debug entry !21:

!21 = !DILocation(line: 4, column: 9, scope: !22) 

And indeed, line 9 is where the if is:

9: if(x>10) 

Clangs debug info is so precise it even points to the '>' operator.

Sign up to request clarification or add additional context in comments.

3 Comments

One point to note is optimizations are passes are not required to preserve the debug info. So -g should be used only with -O0 or equivalent.
@PaulR: Thanks a lot for your answer, it is a good piece of information for me, but what I am looking for is to automate the process. With this approach, i have to write again a parser to match debug info lines to the source code.
@PaulR: I did some research and found few parser but none are up to date, so thanks for your approach using which I can manipulate the file and extract information.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.