<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">Dear TB,<br>
      <br>
      Comments inline below.<br>
      <br>
      On 6/16/16 11:01 AM, TB Schardl via llvm-dev wrote:<br>
    </div>
    <blockquote
cite="mid:CAGAvDYjO2P76+irbz9frPC=K6VT0Yjz-Ch2sMqiPdkOqRA2Rpw@mail.gmail.com"
      type="cite">
      <meta http-equiv="Context-Type" content="text/html; charset=UTF-8">
      <div dir="ltr"><span
          id="docs-internal-guid-34866559-59e2-3d1a-9c9a-13d0f118737f">
          <p><span>Hey LLVM-dev,</span></p>
          <p dir="ltr"><span><br>
            </span></p>
          <p dir="ltr"><span>We propose to build the CSI framework to
              provide a comprehensive suite of compiler-inserted
              instrumentation hooks that dynamic-analysis tools can use
              to observe and investigate program runtime behavior. 
              Traditionally, tools based on compiler instrumentation
              would each separately modify the compiler to insert their
              own instrumentation.  In contrast, CSI inserts a standard
              collection of instrumentation hooks into the
              program-under-test.  Each CSI-tool is implemented as a
              library that defines relevant hooks, and the remaining
              hooks are "nulled" out and elided during link-time
              optimization (LTO), resulting in instrumented runtimes on
              par with custom instrumentation.  CSI allows many
              compiler-based tools to be written as simple libraries
              without modifying the compiler, greatly lowering the bar
              for</span></p>
          <p dir="ltr"><span>developing dynamic-analysis tools.</span></p>
        </span></div>
    </blockquote>
    <br>
    Can you clarify the scope of tools that you want to develop?  Are
    these profiling tools, security enforcement tools, debugging tools,
    etc?  The type of tools you want to build will dictate whether such
    a framework makes sense.<br>
    <br>
    <blockquote
cite="mid:CAGAvDYjO2P76+irbz9frPC=K6VT0Yjz-Ch2sMqiPdkOqRA2Rpw@mail.gmail.com"
      type="cite">
      <div dir="ltr"><span
          id="docs-internal-guid-34866559-59e2-3d1a-9c9a-13d0f118737f"><br>
          <p dir="ltr"><span>================</span></p>
          <p dir="ltr"><span>Motivation</span></p>
          <p dir="ltr"><span>================</span></p>
          <br>
          <p dir="ltr"><span>Key to understanding and improving the
              behavior of any system is visibility -- the ability to
              know what is going on inside the system.  Various
              dynamic-analysis tools, such as race detectors, memory
              checkers, cache simulators, call-graph generators,
              code-coverage analyzers, and performance profilers, rely
              on compiler instrumentation to gain visibility into the
              program behaviors during execution.  With this approach,
              the tool writer modifies the compiler to insert
              instrumentation code into the program-under-test so that
              it can execute behind the scene while the
              program-under-test runs.  This approach, however, means
              that the development of new tools requires compiler work,
              which many potential tool writers are ill equipped to do,
              and thus raises the bar for building new and innovative
              tools.</span></p>
        </span></div>
    </blockquote>
    <span id="docs-internal-guid-34866559-59e2-3d1a-9c9a-13d0f118737f"></span><br>
    <br>
    <br>
    <span id="docs-internal-guid-34866559-59e2-3d1a-9c9a-13d0f118737f"></span>
    <blockquote
cite="mid:CAGAvDYjO2P76+irbz9frPC=K6VT0Yjz-Ch2sMqiPdkOqRA2Rpw@mail.gmail.com"
      type="cite">
      <div dir="ltr"><span
          id="docs-internal-guid-34866559-59e2-3d1a-9c9a-13d0f118737f">
          <p dir="ltr"><span>The goal of the CSI framework is to provide
              comprehensive static instrumentation through the compiler,
              in order to simplify the task of building efficient and
              effective platform-independent tools.  The CSI framework
              allows the tool writer to easily develop analysis tools
              that require</span></p>
          <p dir="ltr"><span>compiler instrumentation without needing to
              understand the compiler internals or modifying the
              compiler, which greatly lowers the bar for developing
              dynamic-analysis tools.</span></p>
          <br>
          <p dir="ltr"><span>================</span></p>
          <p dir="ltr"><span>Approach</span></p>
          <p dir="ltr"><span>================</span></p>
          <br>
          <p dir="ltr"><span>The CSI framework inserts instrumentation
              hooks at salient locations throughout the compiled code of
              a program-under-test, such as function entry and exit
              points, basic-block entry and exit points, before and
              after each memory operation, etc.  Tool writers can
              instrument a program-under-test simply by first writing a
              library that defines the semantics of relevant hooks</span></p>
          <p dir="ltr"><span>and then statically linking their compiled
              library with the program-under-test.</span></p>
          <br>
          <p dir="ltr"><span>At first glance, this brute-force method of
              inserting hooks at every salient location in the
              program-under-test seems to be replete with overheads. 
              CSI overcomes these overheads through the use of
              link-time-optimization (LTO), which is now readily
              available in most major compilers, including GCC and
              LLVM.  Using LTO, instrumentation hooks that are not used
              by a particular tool can be elided, allowing the overheads
              of these hooks to be avoided when the</span></p>
          <p dir="ltr"><span>instrumented program-under-test is run.  </span></p>
        </span></div>
    </blockquote>
    <br>
    The algorithms for optimizing away run-time hooks is not necessarily
    uniform.  For example, if a tool instruments loads and stores to
    collect the set of memory locations accessed by a program, then
    optimizing away a redundant check on a store is okay.  If the
    instrumentation is meant to enforce memory safety, then redundant
    checks can only be optimized away if there is no intervening call to
    free() between the two checks (which may require inter-procedural
    analysis to determine).  In such a case, you either need to be very
    pessimistic about the optimizations that you use, or you will get
    incorrect optimizations for certain classes of dynamic analyses.<br>
    <br>
    <br>
    <blockquote
cite="mid:CAGAvDYjO2P76+irbz9frPC=K6VT0Yjz-Ch2sMqiPdkOqRA2Rpw@mail.gmail.com"
      type="cite">
      <div dir="ltr"><span
          id="docs-internal-guid-34866559-59e2-3d1a-9c9a-13d0f118737f">
          <p dir="ltr"><span>Furthermore, LTO can optimize a tool's
              instrumentation within a program using traditional
              compiler optimizations.  Our initial study indicates that
              the use of LTO does not unduly slow down the build time,
              and the LTO can indeed optimize away unused hooks.  One of
              our experiments with Apache HTTP server shows that,
              compiling with CSI and linking with the "null" CSI-tool
              (which consists solely of empty hooks) slows down the
              build time of the Apache HTTP server by less than 40%, and
              the resulting tool-instrumented executable is as fast as
              the original uninstrumented code.</span></p>
        </span></div>
    </blockquote>
    <br>
    Is your intention to have a compiler flag that enables insertions of
    hooks, or are you planning on having a pass always add the hooks and
    having libLTO always remove them?  I assume the former, but you
    should probably clarify.<br>
    <br>
    <br>
    <blockquote
cite="mid:CAGAvDYjO2P76+irbz9frPC=K6VT0Yjz-Ch2sMqiPdkOqRA2Rpw@mail.gmail.com"
      type="cite">
      <div dir="ltr"><span
          id="docs-internal-guid-34866559-59e2-3d1a-9c9a-13d0f118737f">
          <br>
          <p dir="ltr"><span>================</span></p>
          <p dir="ltr"><span>CSI version 1</span></p>
          <p dir="ltr"><span>================</span></p>
          <br>
          <p dir="ltr"><span>The initial version of CSI supports a basic
              set of hooks that covers the following categories of
              program objects: functions, function exits (specifically,
              returns), basic blocks, call sites, loads, and stores. <br>
            </span></p>
        </span></div>
    </blockquote>
    <br>
    Don't forget that atomic instructions (e.g., compare-and-swap) and
    some of the intrinsics (e.g., llvm.memcpy()) also access memory.<br>
    <br>
    <blockquote
cite="mid:CAGAvDYjO2P76+irbz9frPC=K6VT0Yjz-Ch2sMqiPdkOqRA2Rpw@mail.gmail.com"
      type="cite">
      <div dir="ltr"><span
          id="docs-internal-guid-34866559-59e2-3d1a-9c9a-13d0f118737f">
          <p dir="ltr"><span> We prioritized instrumenting these IR
              objects based on the need of seven example CSI tools,
              including a race detector, a cache-reuse analyzer, and a
              code-coverage analyzer.  We plan to evolve the CSI API
              over time to be more comprehensive, and we have designed
              the CSI API to be extensible, allowing new instrumentation
              to be added as needs grow.  We chose to initially
              implement a minimal "core" set of hooks, because we felt
              it was best to add new instrumentation on an as-needed
              basis in order to keep the interface simple.</span></p>
          <br>
          <p dir="ltr"><span>There are three salient features about the
              design of CSI.  First, CSI assigns each instrumented
              program object a unique integer identifier within one of
              the (currently) six program-object categories.  Within
              each category, the ID's are consecutively numbered from 0
              up to the number of such objects minus 1.  The contiguous
              assignment of the ID's allows the tool writer to easily
              keep track of IR objects in the program and iterate
              through all objects in a category (whether the object is
              encountered during execution or not).  Second, CSI
              provides a platform-independent means to relate a given
              program object to locations in the source code. 
              Specifically, CSI provides "front-end-data (FED)" tables,
              which provide file name and source lines for each program
              object given the object's ID.  Third, each CSI hook takes
              in as a parameter a "property": a 64-bit unsigned integer
              that CSI uses to export the results of compiler analyses
              and other information known at compile time.  The use of
              properties allow the tool to rely on compiler analyses to
              optimize instrumentation and decrease overhead.  In
              particular, since the value of a property is known at
              compile time, LTO can constant-fold the conditional test
              around a property to elide unnecessary instrumentation.</span></p>
          <br>
          <p dir="ltr"><span>================</span></p>
          <p dir="ltr"><span>Future plan</span></p>
          <p dir="ltr"><span>================</span></p>
          <br>
          <p dir="ltr"><span>We plan to expand CSI in future versions by
              instrumenting additional program objects, such as atomic
              instructions, floating-point instructions, and
              exceptions.  We are also planning to provide additional
              static information to tool writers, both through
              information encoded in the properties passed to hooks and
              by other means.  In particular, we are also looking at
              mechanisms to present tool writers with more complex
              static information, such as how different program objects
              relate to each other, e.g., which basic blocks belong to a
              given function.</span></p>
        </span></div>
    </blockquote>
    <br>
    As an aside, I'm not sure that I buy the idea that tool developers
    should be oblivious to the compiler internals.  If a tool developer
    doesn't understand what the compiler is doing, then she/he may not
    understand the results of the output.  For example, LLVM load/stores
    do not include stack spill slots, memory accesses incurred by
    calling conventions, etc.  Depending on where the instrumentation
    passes are placed in the pass pipeline, instrumentation calls can be
    moved or removed (perhaps in undesirable ways for some dynamic
    analysis applications).<br>
    <br>
    I would also argue that a key design feature of LLVM is to make
    writing such passes simple, and I think LLVM accomplishes this.  If
    one understands how to build an efficient dynamic analysis, one can
    probably handle writing the compiler passes.<br>
    <br>
    Overall, I think having common instrumentation infrastructure is a
    good thing.  However, I'm not sure how common it can be across
    different applications of instrumentation.  As an example, most
    memory safety solutions have the same instrumentation and
    optimization needs (and constraints on optimization) regardless of
    how they implement the checks on loads and stores.  However, it's
    less clear to me that a race detector and a memory safety compiler
    can safely use the same optimizations.  You may find yourself
    implementing a common infrastructure with each tool implementing
    specialized optimizations to make each type of dynamic analysis
    really fast.<br>
    <br>
    Food for thought,<br>
    <br>
    John Criswell<br>
    <br>
    <blockquote
cite="mid:CAGAvDYjO2P76+irbz9frPC=K6VT0Yjz-Ch2sMqiPdkOqRA2Rpw@mail.gmail.com"
      type="cite">
      <div dir="ltr"><span
          id="docs-internal-guid-34866559-59e2-3d1a-9c9a-13d0f118737f">
          <div><span><br>
            </span></div>
        </span></div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
LLVM Developers mailing list
<a class="moz-txt-link-abbreviated" href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
    </blockquote>
    <br>
    <p><br>
    </p>
    <pre class="moz-signature" cols="72">-- 
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
<a class="moz-txt-link-freetext" href="http://www.cs.rochester.edu/u/criswell">http://www.cs.rochester.edu/u/criswell</a></pre>
  </body>
</html>