How to write the same things as `opt` command in C++ API

Hi, I’m Ryo Ota. I’m using LLVM 3.8.1. I have a quesion about inlining function in C++ API.

I’d like to inline some functions in a module in the same way as opt -inline command. But my C++ code didn’t work what I want to do.

For example, by using opt -inline command,main.ll is converted into the inlined.ll(opt command worked what I want to do)

[main.ll (Not inlined)]

; ModuleID = 'my module'

define private i32 @a() {
entry:
  %c = call i32 @c()
  ret i32 %c
}

define private i32 @b() {
entry:
  %a = call i32 @a()
  %b = call i32 @b() ; key-point (infinite-recursive)
  %res = add i32 %a, %b
  ret i32 %res
}

define private i32 @c() {
entry:
  ret i32 2
}

define i32 @main() {
entrypoint:
  %b = call i32 @b()
  ret i32 %b

} 



I believe calling pm_builder.populateModulePassManager(pm); will cause a bunch of passes to be ran as if you had ran ‘opt -O2’. What do you get if you run ‘opt-3.8 -S -O2 main.ll’?

Thank you very much your fast response!
When typed ‘opt-3.8 -S -O2 main.ll’, I got:

; ModuleID = ‘main.ll’

; Function Attrs: norecurse nounwind readnone

define i32 @main() #0 {

entrypoint:

ret i32 undef

}

attributes #0 = { norecurse nounwind readnone }

This result is the same as my C++ code.

I’m not sure my use of llvm::legacyPassManeger and llvm::PassManagerBuilder. To write inlining in C++, I explored in llvm’s Github and other repositories which use LLVM, then I wrote the C++ code. I’d like to be taught the correct use.

Sincerely,

Ryo

2017年3月31日(金) 15:50 Craig Topper <craig.topper@gmail.com>:

You are right!

I believe calling pm_builder.populateModulePassManager(pm); will cause a bunch of passes to be ran as if you had ran ‘opt -O2’

I modified like this:

//    llvm::PassManagerBuilder pm_builder;     // (deleted)

    llvm::legacy::PassManager pm;

//    pm_builder.populateModulePassManager(pm); // (deleted)

    pm.add(llvm::createFunctionInliningPass()); // (added)

Then, my code worked the same result of opt -inline.

[output]

; ModuleID = ‘my module’

define private i32 @b() {
entry:
%c = call i32 @b()
%res = add i32 2, %c
ret i32 %res
}

define i32 @main() {
entrypoint:
%b = call i32 @b()
ret i32 %b
}

Thank you,
Ryo

2017年3月31日(金) 15:57 <nwtgck@gmail.com>: