2
votes

I'm writing a LLVM parser to analyse whether a program is adhering to a certain programming paradigm. To that I need to analyse each block of the IR and check certain instructions. When I created the .ll file, I don't see the label names but an address:

; <label>:4                                       ; preds = %0
  %5 = load i32* %c, align 4
  %6 = add nsw i32 %5, 10
  store i32 %6, i32* %c, align 4
  br label %10

; <label>:7                                       ; preds = %0
  %8 = load i32* %c, align 4
  %9 = add nsw i32 %8, 15
  store i32 %9, i32* %c, align 4
  br label %10

; <label>:10                                      ; preds = %7, %4
  %11 = load i32* %1
  ret i32 %11 

What I need is to get these "labels" into a list. I have also seen that some .ll files has following format:

if.then:                                          ; preds = %entry
      %5 = load i32* %c, align 4
      %6 = add nsw i32 %5, 10
      store i32 %6, i32* %c, align 4
      br label %10

if.else:                                          ; preds = %entry
      %8 = load i32* %c, align 4
      %9 = add nsw i32 %8, 15
      store i32 %9, i32* %c, align 4
      br label %10

if.end:                                           ; preds = %if.else,       
      %11 = load i32* %1
      ret i32 %11 

With the 2nd format, I can use the getName() to get the name of the block: i.e: 'if.then', 'if.else' etc.

But with the 1st format, it's impossible as it doesn't have a name. But I tested with printAsOperand(errs(), true) from which I can print the addresses like: '%4, %7 %10'. What my question is, how to add these addresses (or operands) into a stings list? or obtain these values and assign to a certain variable.

2

2 Answers

1
votes

Instruction / basic block names is a debugging feature that simplifies the development of IR-level passes, but no guarantees are made towards them. E.g. they could be simply stripped off, they could be misleading, etc. You should not rely on them for anything meaningful (and in general they may not have any connection to the original source code). Normally the names are no generated in Release builds of LLVM. You need to build everything in Debug (or Release+Assertions) mode.

1
votes

Here's the way to do it;

raw_ostream should be used in printAsOperand() method to get the required address into a variable:

following is the method I used for the purpose:

#include "llvm/Support/raw_ostream.h"

std::string get_block_reference(BasicBlock *BB){
    std::string block_address;
    raw_string_ostream string_stream(block_address);
    BB->printAsOperand(string_stream, false);

    return string_stream.str();
}