[llvm-dev] IR -> source pretty printing?

Lin, Jin via llvm-dev llvm-dev at lists.llvm.org
Wed Jul 13 14:47:02 PDT 2016


Hi Stephen,

A tool within LLVM has been developed to address your issue. Here is a brief description for this tool. Please let me know if you have any questions.

Thanks,

Jin

The existing LLVM compiler only provides incomplete hierarchical information such as loopInfo and regionInfo. It does not provide any information to model the if branches. It does not provide accurate information to understand whether the loop is do-while loop, while loop or do-loop either. This information is essential for compiler analysis, transformations and program understanding.  In order to overcome these issues, the SNodeInfo is designed to provide the complete hierarchical information.

An SNode represents a single structured control flow element, e.g. if-then, if-then-else, do-while-loop, while-loop, do-loop, switch. In the extreme case, it represents one basic block. At the top level, SNodes are linked to each other
via the Pred/Succ lists to form a complete CFG for the routine. Each SNode consists of one or more structural sub-elements, or Children. For example, an if-then-else has Children representing the conditional SNode, the then SNode, and the else SNode. Each child is itself at the top of an arbitrarily complex tree of
SNodes.

Given an example in C code and the corresponding LLVM IR, it is hard to figure out the control flow inside the loop from the LLVM IR. After the SNodeInfo is built on top of the LLVM IR, it is easy to understand there is a if-then statement inside a loop.

void foo(int n, int *b)
{
    for (int j=0;j<n;j++) {
      b[j] = j;
    }
}


LLVM IR for the example compiled with -g

; Function Attrs: nounwind uwtable
define void @foo(i32 %n, i32* nocapture %b) #0 !dbg !7 {
entry:
  tail call void @llvm.dbg.value(metadata i32 %n, i64 0, metadata !13, metadata !17), !dbg !18
  tail call void @llvm.dbg.value(metadata i32* %b, i64 0, metadata !14, metadata !17), !dbg !18
  tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !15, metadata !17), !dbg !19
  %cmp5 = icmp sgt i32 %n, 0, !dbg !20
  br i1 %cmp5, label %for.body, label %for.cond.cleanup, !dbg !20

for.cond.cleanup:                                 ; preds = %for.body, %entry
  ret void, !dbg !23

for.body:                                         ; preds = %entry, %for.body
  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
  %arrayidx = getelementptr inbounds i32, i32* %b, i64 %indvars.iv, !dbg !24
  %0 = trunc i64 %indvars.iv to i32, !dbg !24
  store i32 %0, i32* %arrayidx, align 4, !dbg !24, !tbaa !26
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1, !dbg !20
  %lftr.wideiv = trunc i64 %indvars.iv.next to i32, !dbg !20
  %exitcond = icmp eq i32 %lftr.wideiv, %n, !dbg !20
  br i1 %exitcond, label %for.cond.cleanup, label %for.body, !dbg !20
}

Pretty print of SNode Graph

   /* B[%entry]  */
   /* Line 1 */
   tail call void @llvm.dbg.value(metadata i32 %n, i64 0, metadata !13, metadata !17), !dbg !18
   tail call void @llvm.dbg.value(metadata i32* %b, i64 0, metadata !14, metadata !17), !dbg !18
   /* Line 3 */
   tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !15, metadata !17), !dbg !19
   %cmp5 = icmp sgt i32 %n, 0, !dbg !20
   br i1 %cmp5, label %for.body, label %for.cond.cleanup, !dbg !20
   if (%cmp5) {
      do {

         /* B[%for.body]  */
         %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
         /* Line 4 */
         %arrayidx = getelementptr inbounds i32, i32* %b, i64 %indvars.iv, !dbg !24
         %0 = trunc i64 %indvars.iv to i32, !dbg !24
         store i32 %0, i32* %arrayidx, align 4, !dbg !24, !tbaa !26
         /* Line 3 */
         %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1, !dbg !20
         %lftr.wideiv = trunc i64 %indvars.iv.next to i32, !dbg !20
         %exitcond = icmp eq i32 %lftr.wideiv, %n, !dbg !20
         br i1 %exitcond, label %for.cond.cleanup, label %for.body, !dbg !20


      } while (%exitcond == false)
   }

   /* B[%for.cond.cleanup]  */
   /* Line 6 */
   ret void, !dbg !23





From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of Eli Friedman via llvm-dev
Sent: Wednesday, July 13, 2016 10:55 AM
To: Stephen Thomas <stephen.warner.thomas at gmail.com>
Cc: llvm-dev <llvm-dev at lists.llvm.org>
Subject: Re: [llvm-dev] IR -> source pretty printing?

On Wed, Jul 13, 2016 at 7:00 AM, Stephen Thomas via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote:
Hi,

I often find myself staring at IR and wanting to look at the C source code it corresponds to. To do so, I look up the debug identifier for the given IR line, scroll to the bottom of the IR file to find the debug identifier, look at the debug location (source and column), and then look at the source file. Too many steps. What would be great is a tool that took two files, i.e., a .c file and a .bc file, and printed out the IR with the corresponding C source right beneath each IR line.

It wouldn't be too hard for me to write such a tool, but I thought I'd check to see if something already exists before I reinvent the wheel. Is there anything out there?


llvm-dis has a -show-annotations option; not precisely what you're looking for, but it does print the line numbers inline.
-Eli
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160713/832f2525/attachment.html>


More information about the llvm-dev mailing list