[graalvm-users] How to extend or create a new LLVM Bitcode Visitor

Roland Schatz roland.schatz at oracle.com
Wed Feb 12 03:20:53 PST 2020


Hi Alberto,

On 2/11/20 6:40 PM, Alberto Barbaro wrote:
> Hi Roland,
> Yes you are right, that's the proper class name.
>
> Atm the goal for me is just to print all the instructions that are 
> executed In the LLVM IR firm if possible.

The LLVMBitcodeInstructionVisitor is used just for parsing the bitcode. 
For runtime instrumentation, there is the Truffle instrumentation 
framework that might be better suited for what you're trying to do:
https://www.graalvm.org/docs/graalvm-as-a-platform/implement-instrument/

We already have a few instruments that you might find useful, either for 
using directly, or for building on top of them.

You can already get a trace of all executed bitcode instructions:
> $ llvm-dis hello.bc
> $ lli --experimental-options --llvm.llDebug --llvm.traceIR hello.bc
> [lli] >> Entering function @main at hello.ll:9:1 with 
> arguments:[StackPointer 0x7f62b3fff010 (Bounds: 0x7f62aefff010 - 
> 0x7f62b3fff010), 1, 0x55ad10a8ba48, 0x55ad10a8ba58]
> [lli] >> hello.ll:10:1 ->   %1 = alloca i32, align 4
> [lli] >> hello.ll:11:1 ->   store i32 0, i32* %1, align 4
> [lli] >> hello.ll:12:1 ->   %2 = call i32 (i8*, ...) @printf(i8* 
> getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i32 0, i32 0)), 
> !dbg !13
> Hello, World!
> [lli] >> hello.ll:13:1 ->   ret i32 0, !dbg !14
> [lli] >> Leaving @main

The code for that is mainly in the classes LLVMTracerInstrument and 
LLVMTraceNodeFactory. That might be an easier entry point for what 
you're trying to do.



We also have a code coverage tool:
https://www.graalvm.org/docs/reference-manual/tools/#code-coverage
https://github.com/oracle/graal/tree/master/tools/src/com.oracle.truffle.tools.coverage/src/com/oracle/truffle/tools/coverage

If you run it with regular "lli --coverage ...", you'll get C code 
covarage, but you can combine that with the "--llvm.llDebug" option to 
get bitcode coverage, too (see below for example output).


I hope this helps,
Roland



> $ lli --coverage --coverage.Output=detailed --experimental-options 
> --llvm.llDebug hello.bc
> Hello, World!
> ------------------------------------------------------------------------------------------
> Code coverage per line of code and what percent of each element was 
> covered during execution (per source)
>   + indicates the line is covered during execution
>   - indicates the line is not covered during execution
>   p indicates the line is part of a statement that was incidentally 
> covered during execution
>     e.g. a not-taken branch of a covered if statement
> ------------------------------------------------------------------------------------------
>  Path                                                 | Statements 
> |    Lines |    Roots
>  /home/roland/test/hello/hello.ll                     | 100.00% |  
> 100.00% |  100.00%
>
>   ; ModuleID = 'hello.bc'
>   source_filename = "hello.c"
>   target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>   target triple = "x86_64-pc-linux-gnu"
>
>   @.str = private unnamed_addr constant [15 x i8] c"Hello, 
> World!\0A\00", align 1
>
>   ; Function Attrs: noinline nounwind optnone sspstrong uwtable
>   define dso_local i32 @main() #0 !dbg !9 {
> +   %1 = alloca i32, align 4
> +   store i32 0, i32* %1, align 4
> +   %2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x 
> i8], [15 x i8]* @.str, i32 0, i32 0)), !dbg !13
> +   ret i32 0, !dbg !14
>   }
>
>   declare i32 @printf(i8*, ...) #1
>
>   attributes #0 = { noinline nounwind optnone sspstrong uwtable 
> "correctly-rounded-divide-sqrt-fp-math"="false" 
> "disable-tail-calls"="false" "less-precise-fpmad"="false" 
> "min-legal-vector-width"="0" "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"="x86-64" 
> "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" 
> "unsafe-fp-math"="false" "use-soft-float"="false" }
>   attributes #1 = { "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-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.dbg.cu = !{!0}
>   !llvm.module.flags = !{!3, !4, !5, !6, !7}
>   !llvm.ident = !{!8}
>
>   !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, 
> producer: "clang version 8.0.1 (tags/RELEASE_801/final)", isOptimized: 
> false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, 
> nameTableKind: None)
>   !1 = !DIFile(filename: "hello.c", directory: "/home/roland/test/hello")
>   !2 = !{}
>   !3 = !{i32 2, !"Dwarf Version", i32 4}
>   !4 = !{i32 2, !"Debug Info Version", i32 3}
>   !5 = !{i32 1, !"wchar_size", i32 4}
>   !6 = !{i32 7, !"PIC Level", i32 2}
>   !7 = !{i32 7, !"PIE Level", i32 2}
>   !8 = !{!"clang version 8.0.1 (tags/RELEASE_801/final)"}
>   !9 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 
> 3, type: !10, scopeLine: 3, spFlags: DISPFlagDefinition, unit: !0, 
> retainedNodes: !2)
>   !10 = !DISubroutineType(types: !11)
>   !11 = !{!12}
>   !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
>   !13 = !DILocation(line: 4, column: 5, scope: !9)
>   !14 = !DILocation(line: 5, column: 5, scope: !9)
> ------------------------------------------------------------------------------------------
>  Path                                                 | Statements 
> |    Lines |    Roots
>  com.oracle.truffle.llvm.libraries.bitcode/src/crt0.c | 100.00% 
> |          |  100.00%
>
> NO CONTENT AVAILABLE
> ------------------------------------------------------------------------------------------
>  Path                                                 | Statements 
> |    Lines |    Roots
>  com.oracle.truffle.llvm.libraries.bitcode/src/exit.c | 87.50% 
> |          |  100.00%
>
> NO CONTENT AVAILABLE
> ------------------------------------------------------------------------------------------

> $ lli --coverage --coverage.Output=detailed hello.bc
> Hello, World!
> ------------------------------------------------------------------------------------------
> Code coverage per line of code and what percent of each element was 
> covered during execution (per source)
>   + indicates the line is covered during execution
>   - indicates the line is not covered during execution
>   p indicates the line is part of a statement that was incidentally 
> covered during execution
>     e.g. a not-taken branch of a covered if statement
> ------------------------------------------------------------------------------------------
>  Path                                                 | Statements 
> |    Lines |    Roots
>  /home/roland/test/hello/hello.c                      | 100.00% |  
> 100.00% |  100.00%
>
>   #include <stdio.h>
>
>   int main() {
> +     printf("Hello, World!\n");
> +     return 0;
>   }
> ------------------------------------------------------------------------------------------
>  Path                                                 | Statements 
> |    Lines |    Roots
>  com.oracle.truffle.llvm.libraries.bitcode/src/crt0.c | 100.00% 
> |          |  100.00%
>
> NO CONTENT AVAILABLE
> ------------------------------------------------------------------------------------------
>  Path                                                 | Statements 
> |    Lines |    Roots
>  com.oracle.truffle.llvm.libraries.bitcode/src/exit.c | 87.50% 
> |          |  100.00%
>
> NO CONTENT AVAILABLE
> ------------------------------------------------------------------------------------------


>
> If all goes well I'd like to work on a code coverage tool for the bitcode.
>
> Thanks
> Alberto
>
> On Tue, Feb 11, 2020, 16:02 Roland Schatz <roland.schatz at oracle.com 
> <mailto:roland.schatz at oracle.com>> wrote:
>
>     Hi Alberto!
>
>     I assume you mean the LLVMBitcodeInstructionVisitor class, right?
>     This class is part of the internal implementation of the LLVM
>     runtime in GraalVM, and not meant to be extended or used outside
>     of the LLVM runtime. This is not meant as API, we might change
>     that class without notice, even in minor releases.
>
>     What are you trying to achieve by subclassing it?
>
>     - Roland
>
>     On 2/11/20 4:31 PM, Alberto Barbaro wrote:
>>     Hi all,
>>     I've just started to use graalvm and I've noticed that the
>>     LLVMBitcodeVisitor class is market as final. I'd like to create
>>     my own visitor extending it... So I was wondering if there is a
>>     better approach rather then modifying a bit the source code. How
>>     would you recommend to do it?
>>
>>     Thanks
>>     Alberto
>>
>>     _______________________________________________
>>     GraalVM-Users mailing list
>>     GraalVM-Users at oss.oracle.com  <mailto:GraalVM-Users at oss.oracle.com>
>>     https://oss.oracle.com/mailman/listinfo/graalvm-users
>
>
>     _______________________________________________
>     GraalVM-Users mailing list
>     GraalVM-Users at oss.oracle.com <mailto:GraalVM-Users at oss.oracle.com>
>     https://oss.oracle.com/mailman/listinfo/graalvm-users
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://oss.oracle.com/pipermail/graalvm-users/attachments/20200212/512b4a16/attachment-0001.html 


More information about the GraalVM-Users mailing list