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

Roland Schatz roland.schatz at oracle.com
Wed Feb 12 07:25:27 PST 2020


Hi Alberto,


On 2/12/20 2:52 PM, Alberto Barbaro wrote:
> Hi Roland,
> I think that's exactly what I need. I was able to build simpletool and 
> to use Truffle so I'll adapt it to my need using LLVMTruffleInstrument 
> instead TruffleInsturment. Does it sound correct to you?


I think either way is fine. It's probably a good idea to do your own 
instrument, but you can start from the LLVMTracerInstrument, because it 
already does something very similar to what you want to do.


>
> In addition I tried lli with the experimental options but I had the 
> following errors:
>
> [...]
> ERROR: java.lang.IllegalStateException: The registerService method can 
> only be called during the execution of the Env.createContext method.
> org.graalvm.polyglot.PolyglotException: 
> java.lang.IllegalStateException: The registerService method can only 
> be called during the execution of the Env.createContext method.
> at 
> com.oracle.truffle.api.TruffleLanguage$Env.registerService(TruffleLanguage.java:2382)
> at 
> com.oracle.truffle.llvm.instruments.trace.LLVMTracerInstrument.initialize(LLVMTracerInstrument.java:58)
> at 
> com.oracle.truffle.llvm.runtime.LLVMContext.initialize(LLVMContext.java:276)
> [...]


 From the stack trace, looks like you're on version 19.3, right? Then 
that is a known bug, it's already fixed on current master and on the 
20.0 release branch. You can use one of our dev builds 
(https://github.com/graalvm/graalvm-ce-dev-builds/releases) in the 
meantime. It will also be fixed in the upcoming 20.0 release.


- Roland


>
> Il giorno mer 12 feb 2020 alle ore 11:24 Roland Schatz 
> <roland.schatz at oracle.com <mailto:roland.schatz at oracle.com>> ha scritto:
>
>     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/
>     <https://urldefense.com/v3/__https://www.graalvm.org/docs/graalvm-as-a-platform/implement-instrument/__;!!GqivPVa7Brio!M_VQB1VYM2oG0tUtVXzAs5zr9rDHleDIiNnN14WgTynkSubDpWG5C3J0oIZzg4DLWps$>
>
>     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://urldefense.com/v3/__https://www.graalvm.org/docs/reference-manual/tools/*code-coverage__;Iw!!GqivPVa7Brio!M_VQB1VYM2oG0tUtVXzAs5zr9rDHleDIiNnN14WgTynkSubDpWG5C3J0oIZzo_rD3k0$>
>     https://github.com/oracle/graal/tree/master/tools/src/com.oracle.truffle.tools.coverage/src/com/oracle/truffle/tools/coverage
>     <https://urldefense.com/v3/__https://github.com/oracle/graal/tree/master/tools/src/com.oracle.truffle.tools.coverage/src/com/oracle/truffle/tools/coverage__;!!GqivPVa7Brio!M_VQB1VYM2oG0tUtVXzAs5zr9rDHleDIiNnN14WgTynkSubDpWG5C3J0oIZzHgM1A5U$>
>
>     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
>>     <https://urldefense.com/v3/__http://llvm.dbg.cu__;!!GqivPVa7Brio!M_VQB1VYM2oG0tUtVXzAs5zr9rDHleDIiNnN14WgTynkSubDpWG5C3J0oIZzO4ag0HM$>
>>     = !{!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
>>
>
>     _______________________________________________
>     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/cd660c31/attachment-0001.html 


More information about the GraalVM-Users mailing list