<div dir="ltr">Hi Roland,<div>I think that&#39;s exactly what I need. I was able to build simpletool and to use Truffle so I&#39;ll adapt it to my need using LLVMTruffleInstrument instead TruffleInsturment. Does it sound correct to you?</div><div><br></div><div>In addition I tried lli with the experimental options but I had the following errors:</div><div><br></div><div>bash-4.2# cat hello.c <br>#include&lt;stdio.h&gt;<br><br>int main() {<br>        printf(&quot;Hello World!\n&quot;);<br>        return 0;<br>}<br>bash-4.2# $LLVM_TOOLCHAIN/clang hello.c -o hello<br>bash-4.2# lli hello<br>Hello World!<br>bash-4.2# lli --experimental-options --llvm.llDebug --llvm.traceIR test.bc <br>ERROR: java.lang.IllegalStateException: The registerService method can only be called during the execution of the Env.createContext method.<br>org.graalvm.polyglot.PolyglotException: java.lang.IllegalStateException: The registerService method can only be called during the execution of the Env.createContext method.<br>        at com.oracle.truffle.api.TruffleLanguage$Env.registerService(TruffleLanguage.java:2382)<br>        at com.oracle.truffle.llvm.instruments.trace.LLVMTracerInstrument.initialize(LLVMTracerInstrument.java:58)<br>        at com.oracle.truffle.llvm.runtime.LLVMContext.initialize(LLVMContext.java:276)<br>        at com.oracle.truffle.llvm.runtime.LLVMLanguage.initializeContext(LLVMLanguage.java:187)<br>        at com.oracle.truffle.llvm.runtime.LLVMLanguage.initializeContext(LLVMLanguage.java:65)<br>        at com.oracle.truffle.api.TruffleLanguage$Env.postInit(TruffleLanguage.java:2576)<br>        at com.oracle.truffle.api.LanguageAccessor$LanguageImpl.postInitEnv(LanguageAccessor.java:197)<br>        at com.oracle.truffle.polyglot.PolyglotLanguageContext.ensureInitialized(PolyglotLanguageContext.java:541)<br>        at com.oracle.truffle.polyglot.PolyglotContextImpl.eval(PolyglotContextImpl.java:818)<br>        at org.graalvm.polyglot.Context.eval(Context.java:344)<br>        at com.oracle.truffle.llvm.launcher.LLVMLauncher.execute(LLVMLauncher.java:215)<br>        at com.oracle.truffle.llvm.launcher.LLVMLauncher.launch(LLVMLauncher.java:63)<br>        at org.graalvm.launcher.AbstractLanguageLauncher.launch(AbstractLanguageLauncher.java:121)<br>        at org.graalvm.launcher.AbstractLanguageLauncher.launch(AbstractLanguageLauncher.java:70)<br>        at com.oracle.truffle.llvm.launcher.LLVMLauncher.main(LLVMLauncher.java:53)<br>Original Internal Error: <br>java.lang.IllegalStateException: The registerService method can only be called during the execution of the Env.createContext method.<br>        at com.oracle.truffle.api.TruffleLanguage$Env.registerService(TruffleLanguage.java:2382)<br>        at com.oracle.truffle.llvm.instruments.trace.LLVMTracerInstrument.initialize(LLVMTracerInstrument.java:58)<br>        at com.oracle.truffle.llvm.runtime.LLVMContext.initialize(LLVMContext.java:276)<br>        at com.oracle.truffle.llvm.runtime.LLVMLanguage.initializeContext(LLVMLanguage.java:187)<br>        at com.oracle.truffle.llvm.runtime.LLVMLanguage.initializeContext(LLVMLanguage.java:65)<br>        at com.oracle.truffle.api.TruffleLanguage$Env.postInit(TruffleLanguage.java:2576)<br>        at com.oracle.truffle.api.LanguageAccessor$LanguageImpl.postInitEnv(LanguageAccessor.java:197)<br>        at com.oracle.truffle.polyglot.PolyglotLanguageContext.ensureInitialized(PolyglotLanguageContext.java:541)<br>        at com.oracle.truffle.polyglot.PolyglotContextImpl.eval(PolyglotContextImpl.java:818)<br>        at org.graalvm.polyglot.Context.eval(Context.java:344)<br>        at com.oracle.truffle.llvm.launcher.LLVMLauncher.execute(LLVMLauncher.java:215)<br>        at com.oracle.truffle.llvm.launcher.LLVMLauncher.launch(LLVMLauncher.java:63)<br>        at org.graalvm.launcher.AbstractLanguageLauncher.launch(AbstractLanguageLauncher.java:121)<br>        at org.graalvm.launcher.AbstractLanguageLauncher.launch(AbstractLanguageLauncher.java:70)<br>        at com.oracle.truffle.llvm.launcher.LLVMLauncher.main(LLVMLauncher.java:53)<br>Caused by: Attached Guest Language Frames (0)<br></div><div><br></div><div>I have does this test from a container created as instructed on GitHub.</div><div><br></div><div>Thanks</div><div>Alberto</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Il giorno mer 12 feb 2020 alle ore 11:24 Roland Schatz &lt;<a href="mailto:roland.schatz@oracle.com">roland.schatz@oracle.com</a>&gt; ha scritto:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  
    
  
  <div>
    <div>Hi Alberto,<br>
    </div>
    <div><br>
    </div>
    <div>On 2/11/20 6:40 PM, Alberto Barbaro
      wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="auto">Hi Roland,
        <div dir="auto">Yes you are right, that&#39;s the proper class name.</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">Atm the goal for me is just to print all the
          instructions that are executed In the LLVM IR firm if
          possible.</div>
      </div>
    </blockquote>
    <br>
    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&#39;re trying to do:<br>
<a href="https://urldefense.com/v3/__https://www.graalvm.org/docs/graalvm-as-a-platform/implement-instrument/__;!!GqivPVa7Brio!LHP8aOKNGmE-WuwHkir3ZUrZuzRwXu27SJOebSdyeiF9ZKEvCsnX0oF1ZXfoXCsYXetyFw$" target="_blank">https://www.graalvm.org/docs/graalvm-as-a-platform/implement-instrument/</a><br>
    <br>
    We already have a few instruments that you might find useful, either
    for using directly, or for building on top of them.<br>
    <br>
    You can already get a trace of all executed bitcode instructions:<br>
    <blockquote type="cite">$ llvm-dis hello.bc<br>
      $ lli --experimental-options --llvm.llDebug --llvm.traceIR
      hello.bc<br>
      [lli] &gt;&gt; Entering function @main at hello.ll:9:1 with
      arguments:[StackPointer 0x7f62b3fff010 (Bounds: 0x7f62aefff010 -
      0x7f62b3fff010), 1, 0x55ad10a8ba48, 0x55ad10a8ba58]<br>
      [lli] &gt;&gt; hello.ll:10:1 -&gt;   %1 = alloca i32, align 4<br>
      [lli] &gt;&gt; hello.ll:11:1 -&gt;   store i32 0, i32* %1, align 4<br>
      [lli] &gt;&gt; hello.ll:12:1 -&gt;   %2 = call i32 (i8*, ...)
      @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str,
      i32 0, i32 0)), !dbg !13<br>
      Hello, World!<br>
      [lli] &gt;&gt; hello.ll:13:1 -&gt;   ret i32 0, !dbg !14<br>
      [lli] &gt;&gt; Leaving @main<br>
    </blockquote>
    <br>
    The code for that is mainly in the classes LLVMTracerInstrument and
    LLVMTraceNodeFactory. That might be an easier entry point for what
    you&#39;re trying to do.<br>
    <br>
    <br>
    <br>
    We also have a code coverage tool:<br>
    <a href="https://urldefense.com/v3/__https://www.graalvm.org/docs/reference-manual/tools/*code-coverage__;Iw!!GqivPVa7Brio!LHP8aOKNGmE-WuwHkir3ZUrZuzRwXu27SJOebSdyeiF9ZKEvCsnX0oF1ZXfoXCtk5lLLuQ$" target="_blank">https://www.graalvm.org/docs/reference-manual/tools/#code-coverage</a><br>
<a href="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$" target="_blank">https://github.com/oracle/graal/tree/master/tools/src/com.oracle.truffle.tools.coverage/src/com/oracle/truffle/tools/coverage</a><br>
    <br>
    If you run it with regular &quot;lli --coverage ...&quot;, you&#39;ll get C code
    covarage, but you can combine that with the &quot;--llvm.llDebug&quot; option
    to get bitcode coverage, too (see below for example output).<br>
    <br>
    <br>
    I hope this helps,<br>
    Roland<br>
    <br>
    <br>
    <br>
    <blockquote type="cite">$ lli --coverage --coverage.Output=detailed
      --experimental-options --llvm.llDebug hello.bc<br>
      Hello, World!<br>
------------------------------------------------------------------------------------------<br>
      Code coverage per line of code and what percent of each element
      was covered during execution (per source)<br>
        + indicates the line is covered during execution<br>
        - indicates the line is not covered during execution<br>
        p indicates the line is part of a statement that was
      incidentally covered during execution<br>
          e.g. a not-taken branch of a covered if statement<br>
------------------------------------------------------------------------------------------<br>
       Path                                                 | 
      Statements |    Lines |    Roots<br>
       /home/roland/test/hello/hello.ll                     |    
      100.00% |  100.00% |  100.00%<br>
      <br>
        ; ModuleID = &#39;hello.bc&#39;<br>
        source_filename = &quot;hello.c&quot;<br>
        target datalayout = &quot;e-m:e-i64:64-f80:128-n8:16:32:64-S128&quot;<br>
        target triple = &quot;x86_64-pc-linux-gnu&quot;<br>
      <br>
        @.str = private unnamed_addr constant [15 x i8] c&quot;Hello,
      World!\0A\00&quot;, align 1<br>
      <br>
        ; Function Attrs: noinline nounwind optnone sspstrong uwtable<br>
        define dso_local i32 @main() #0 !dbg !9 {<br>
      +   %1 = alloca i32, align 4<br>
      +   store i32 0, i32* %1, align 4<br>
      +   %2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds
      ([15 x i8], [15 x i8]* @.str, i32 0, i32 0)), !dbg !13<br>
      +   ret i32 0, !dbg !14<br>
        }<br>
      <br>
        declare i32 @printf(i8*, ...) #1<br>
      <br>
        attributes #0 = { noinline nounwind optnone sspstrong uwtable
      &quot;correctly-rounded-divide-sqrt-fp-math&quot;=&quot;false&quot;
      &quot;disable-tail-calls&quot;=&quot;false&quot; &quot;less-precise-fpmad&quot;=&quot;false&quot;
      &quot;min-legal-vector-width&quot;=&quot;0&quot; &quot;no-frame-pointer-elim&quot;=&quot;true&quot;
      &quot;no-frame-pointer-elim-non-leaf&quot; &quot;no-infs-fp-math&quot;=&quot;false&quot;
      &quot;no-jump-tables&quot;=&quot;false&quot; &quot;no-nans-fp-math&quot;=&quot;false&quot;
      &quot;no-signed-zeros-fp-math&quot;=&quot;false&quot; &quot;no-trapping-math&quot;=&quot;false&quot;
      &quot;stack-protector-buffer-size&quot;=&quot;8&quot; &quot;target-cpu&quot;=&quot;x86-64&quot;
      &quot;target-features&quot;=&quot;+fxsr,+mmx,+sse,+sse2,+x87&quot;
      &quot;unsafe-fp-math&quot;=&quot;false&quot; &quot;use-soft-float&quot;=&quot;false&quot; }<br>
        attributes #1 = {
      &quot;correctly-rounded-divide-sqrt-fp-math&quot;=&quot;false&quot;
      &quot;disable-tail-calls&quot;=&quot;false&quot; &quot;less-precise-fpmad&quot;=&quot;false&quot;
      &quot;no-frame-pointer-elim&quot;=&quot;true&quot; &quot;no-frame-pointer-elim-non-leaf&quot;
      &quot;no-infs-fp-math&quot;=&quot;false&quot; &quot;no-nans-fp-math&quot;=&quot;false&quot;
      &quot;no-signed-zeros-fp-math&quot;=&quot;false&quot; &quot;no-trapping-math&quot;=&quot;false&quot;
      &quot;stack-protector-buffer-size&quot;=&quot;8&quot; &quot;target-cpu&quot;=&quot;x86-64&quot;
      &quot;target-features&quot;=&quot;+fxsr,+mmx,+sse,+sse2,+x87&quot;
      &quot;unsafe-fp-math&quot;=&quot;false&quot; &quot;use-soft-float&quot;=&quot;false&quot; }<br>
      <br>
        !<a href="https://urldefense.com/v3/__http://llvm.dbg.cu__;!!GqivPVa7Brio!LHP8aOKNGmE-WuwHkir3ZUrZuzRwXu27SJOebSdyeiF9ZKEvCsnX0oF1ZXfoXCsR1z5IWw$" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
        !llvm.module.flags = !{!3, !4, !5, !6, !7}<br>
        !llvm.ident = !{!8}<br>
      <br>
        !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1,
      producer: &quot;clang version 8.0.1 (tags/RELEASE_801/final)&quot;,
      isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug,
      enums: !2, nameTableKind: None)<br>
        !1 = !DIFile(filename: &quot;hello.c&quot;, directory:
      &quot;/home/roland/test/hello&quot;)<br>
        !2 = !{}<br>
        !3 = !{i32 2, !&quot;Dwarf Version&quot;, i32 4}<br>
        !4 = !{i32 2, !&quot;Debug Info Version&quot;, i32 3}<br>
        !5 = !{i32 1, !&quot;wchar_size&quot;, i32 4}<br>
        !6 = !{i32 7, !&quot;PIC Level&quot;, i32 2}<br>
        !7 = !{i32 7, !&quot;PIE Level&quot;, i32 2}<br>
        !8 = !{!&quot;clang version 8.0.1 (tags/RELEASE_801/final)&quot;}<br>
        !9 = distinct !DISubprogram(name: &quot;main&quot;, scope: !1, file: !1,
      line: 3, type: !10, scopeLine: 3, spFlags: DISPFlagDefinition,
      unit: !0, retainedNodes: !2)<br>
        !10 = !DISubroutineType(types: !11)<br>
        !11 = !{!12}<br>
        !12 = !DIBasicType(name: &quot;int&quot;, size: 32, encoding:
      DW_ATE_signed)<br>
        !13 = !DILocation(line: 4, column: 5, scope: !9)<br>
        !14 = !DILocation(line: 5, column: 5, scope: !9)<br>
------------------------------------------------------------------------------------------<br>
       Path                                                 | 
      Statements |    Lines |    Roots<br>
       com.oracle.truffle.llvm.libraries.bitcode/src/crt0.c |    
      100.00% |          |  100.00%<br>
      <br>
      NO CONTENT AVAILABLE<br>
------------------------------------------------------------------------------------------<br>
       Path                                                 | 
      Statements |    Lines |    Roots<br>
       com.oracle.truffle.llvm.libraries.bitcode/src/exit.c |     
      87.50% |          |  100.00%<br>
      <br>
      NO CONTENT AVAILABLE<br>
------------------------------------------------------------------------------------------<br>
    </blockquote>
    <br>
    <blockquote type="cite">$ lli --coverage --coverage.Output=detailed
      hello.bc<br>
      Hello, World!<br>
------------------------------------------------------------------------------------------<br>
      Code coverage per line of code and what percent of each element
      was covered during execution (per source)<br>
        + indicates the line is covered during execution<br>
        - indicates the line is not covered during execution<br>
        p indicates the line is part of a statement that was
      incidentally covered during execution<br>
          e.g. a not-taken branch of a covered if statement<br>
------------------------------------------------------------------------------------------<br>
       Path                                                 | 
      Statements |    Lines |    Roots<br>
       /home/roland/test/hello/hello.c                      |    
      100.00% |  100.00% |  100.00%<br>
      <br>
        #include &lt;stdio.h&gt;<br>
      <br>
        int main() {<br>
      +     printf(&quot;Hello, World!\n&quot;);<br>
      +     return 0;<br>
        }<br>
------------------------------------------------------------------------------------------<br>
       Path                                                 | 
      Statements |    Lines |    Roots<br>
       com.oracle.truffle.llvm.libraries.bitcode/src/crt0.c |    
      100.00% |          |  100.00%<br>
      <br>
      NO CONTENT AVAILABLE<br>
------------------------------------------------------------------------------------------<br>
       Path                                                 | 
      Statements |    Lines |    Roots<br>
       com.oracle.truffle.llvm.libraries.bitcode/src/exit.c |     
      87.50% |          |  100.00%<br>
      <br>
      NO CONTENT AVAILABLE<br>
------------------------------------------------------------------------------------------<br>
    </blockquote>
    <br>
    <br>
    <blockquote type="cite">
      <div dir="auto">
        <div dir="auto"><br>
        </div>
        <div dir="auto">If all goes well I&#39;d like to work on a code
          coverage tool for the bitcode.</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">Thanks</div>
        <div dir="auto">Alberto</div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Tue, Feb 11, 2020, 16:02
          Roland Schatz &lt;<a href="mailto:roland.schatz@oracle.com" target="_blank">roland.schatz@oracle.com</a>&gt;
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div>
            <div>Hi Alberto!<br>
              <br>
              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.<br>
              <br>
              What are you trying to achieve by subclassing it?<br>
              <br>
              - Roland<br>
              <br>
              On 2/11/20 4:31 PM, Alberto Barbaro wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="auto">Hi all,
                <div dir="auto">I&#39;ve just started to use graalvm and
                  I&#39;ve noticed that the LLVMBitcodeVisitor class is
                  market as final. I&#39;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?</div>
                <div dir="auto"><br>
                </div>
                <div dir="auto">Thanks</div>
                <div dir="auto">Alberto</div>
              </div>
              <br>
              <fieldset></fieldset>
              <pre>_______________________________________________
GraalVM-Users mailing list
<a href="mailto:GraalVM-Users@oss.oracle.com" rel="noreferrer" target="_blank">GraalVM-Users@oss.oracle.com</a>
<a href="https://oss.oracle.com/mailman/listinfo/graalvm-users" rel="noreferrer" target="_blank">https://oss.oracle.com/mailman/listinfo/graalvm-users</a></pre>
            </blockquote>
            <p><br>
            </p>
          </div>
          _______________________________________________<br>
          GraalVM-Users mailing list<br>
          <a href="mailto:GraalVM-Users@oss.oracle.com" rel="noreferrer" target="_blank">GraalVM-Users@oss.oracle.com</a><br>
          <a href="https://oss.oracle.com/mailman/listinfo/graalvm-users" rel="noreferrer noreferrer" target="_blank">https://oss.oracle.com/mailman/listinfo/graalvm-users</a></blockquote>
      </div>
    </blockquote>
    <p><br>
    </p>
  </div>

_______________________________________________<br>
GraalVM-Users mailing list<br>
<a href="mailto:GraalVM-Users@oss.oracle.com" target="_blank">GraalVM-Users@oss.oracle.com</a><br>
<a href="https://oss.oracle.com/mailman/listinfo/graalvm-users" rel="noreferrer" target="_blank">https://oss.oracle.com/mailman/listinfo/graalvm-users</a></blockquote></div>