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

Alberto Barbaro barbaro.alberto at gmail.com
Wed Feb 12 05:52:56 PST 2020


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?

In addition I tried lli with the experimental options but I had the
following errors:

bash-4.2# cat hello.c
#include<stdio.h>

int main() {
printf("Hello World!\n");
return 0;
}
bash-4.2# $LLVM_TOOLCHAIN/clang hello.c -o hello
bash-4.2# lli hello
Hello World!
bash-4.2# lli --experimental-options --llvm.llDebug --llvm.traceIR test.bc
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)
at
com.oracle.truffle.llvm.runtime.LLVMLanguage.initializeContext(LLVMLanguage.java:187)
at
com.oracle.truffle.llvm.runtime.LLVMLanguage.initializeContext(LLVMLanguage.java:65)
at
com.oracle.truffle.api.TruffleLanguage$Env.postInit(TruffleLanguage.java:2576)
at
com.oracle.truffle.api.LanguageAccessor$LanguageImpl.postInitEnv(LanguageAccessor.java:197)
at
com.oracle.truffle.polyglot.PolyglotLanguageContext.ensureInitialized(PolyglotLanguageContext.java:541)
at
com.oracle.truffle.polyglot.PolyglotContextImpl.eval(PolyglotContextImpl.java:818)
at org.graalvm.polyglot.Context.eval(Context.java:344)
at
com.oracle.truffle.llvm.launcher.LLVMLauncher.execute(LLVMLauncher.java:215)
at
com.oracle.truffle.llvm.launcher.LLVMLauncher.launch(LLVMLauncher.java:63)
at
org.graalvm.launcher.AbstractLanguageLauncher.launch(AbstractLanguageLauncher.java:121)
at
org.graalvm.launcher.AbstractLanguageLauncher.launch(AbstractLanguageLauncher.java:70)
at com.oracle.truffle.llvm.launcher.LLVMLauncher.main(LLVMLauncher.java:53)
Original Internal Error:
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)
at
com.oracle.truffle.llvm.runtime.LLVMLanguage.initializeContext(LLVMLanguage.java:187)
at
com.oracle.truffle.llvm.runtime.LLVMLanguage.initializeContext(LLVMLanguage.java:65)
at
com.oracle.truffle.api.TruffleLanguage$Env.postInit(TruffleLanguage.java:2576)
at
com.oracle.truffle.api.LanguageAccessor$LanguageImpl.postInitEnv(LanguageAccessor.java:197)
at
com.oracle.truffle.polyglot.PolyglotLanguageContext.ensureInitialized(PolyglotLanguageContext.java:541)
at
com.oracle.truffle.polyglot.PolyglotContextImpl.eval(PolyglotContextImpl.java:818)
at org.graalvm.polyglot.Context.eval(Context.java:344)
at
com.oracle.truffle.llvm.launcher.LLVMLauncher.execute(LLVMLauncher.java:215)
at
com.oracle.truffle.llvm.launcher.LLVMLauncher.launch(LLVMLauncher.java:63)
at
org.graalvm.launcher.AbstractLanguageLauncher.launch(AbstractLanguageLauncher.java:121)
at
org.graalvm.launcher.AbstractLanguageLauncher.launch(AbstractLanguageLauncher.java:70)
at com.oracle.truffle.llvm.launcher.LLVMLauncher.main(LLVMLauncher.java:53)
Caused by: Attached Guest Language Frames (0)

I have does this test from a container created as instructed on GitHub.

Thanks
Alberto

Il giorno mer 12 feb 2020 alle ore 11:24 Roland Schatz <
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://urldefense.com/v3/__https://www.graalvm.org/docs/graalvm-as-a-platform/implement-instrument/__;!!GqivPVa7Brio!LHP8aOKNGmE-WuwHkir3ZUrZuzRwXu27SJOebSdyeiF9ZKEvCsnX0oF1ZXfoXCsYXetyFw$ 
>
> 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://urldefense.com/v3/__https://www.graalvm.org/docs/reference-manual/tools/*code-coverage__;Iw!!GqivPVa7Brio!LHP8aOKNGmE-WuwHkir3ZUrZuzRwXu27SJOebSdyeiF9ZKEvCsnX0oF1ZXfoXCtk5lLLuQ$ 
>
> 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!LHP8aOKNGmE-WuwHkir3ZUrZuzRwXu27SJOebSdyeiF9ZKEvCsnX0oF1ZXfoXCukdr3fOw$ 
>
> 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>
> 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 listGraalVM-Users at oss.oracle.comhttps://oss.oracle.com/mailman/listinfo/graalvm-users
>>
>>
>> _______________________________________________
>> GraalVM-Users mailing list
>> GraalVM-Users at oss.oracle.com
>> https://oss.oracle.com/mailman/listinfo/graalvm-users
>
>
> _______________________________________________
> GraalVM-Users mailing list
> 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/961903d9/attachment-0001.html 


More information about the GraalVM-Users mailing list