force inlineing a function using opt

Hi,
  I am instrumenting the stores in a program by inserting a function call (store_prologue) before every store instruction in the IR file. I set the prologue function's attribute to "AlwaysInline" using addFnAttr(). In the program the prologue function is defined as static inline. I am using opt to generate an optimized (inline the calls to the store prologue) using the following options "-always-inline". I also tried "-inline". However, the calls to the prologue function are not inlined. I was wondering if I am doing something wrong?. Is there any way to force inline a function. I really appreciate your help.

  Best,
  --Hari

If I understand correctly, you're saying that the C source definition of the prologue function is declared as static. If you compile that function to LLVM IR, it will get interal linkage and will not be visible to functions in other compilation units; instead, it will get renamed if there is a function defined with the same name. As such, it will never get inlined as the instrumented code will be calling a "different" function.

Try making the C source definition externally visible (i.e., remove the static keyword) and see if it fixes the problem.

-- John T.

Hi John,
Thank you for the email. I tried both static inline and also inline but neither of them worked. I am listing a code snippet to
illustrate precisely the approach I tried. My overall objective is to instrument stores in a program. I am instrumenting stores in the program by inserting the store_inst_prologue function in the IR.

My source program:

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>

inline void store_inst_prologue(unsigned long ptr, int len);
void foo(unsigned long ptr, int len);

__thread uint8_t instrument=0;

void foo(unsigned long ptr, int len)
{
  printf("store address: %p, len: %d\n", ptr, len);
}

inline void store_inst_prologue(unsigned long ptr, int len)
{
  if (instrument!=0)
        foo(ptr, len);
}

int a=10;
int main()
{
int b=20;

//explicit call to prologue fn to avoid dead code elimination
store_inst_prologue (100, 42);

a =42;
b =a*2;

return 0;
}

I am generating an IR using the following command
$llvm-gcc -emit-llvm -S test.c -o test.ll

Then I am running my parser built using the LLVM API to instrument stores in the test.ll to form test_instrumented.ll
My parser takes the test.ll file and iterates over all the instructions and inserts a call instruction before every store instruction in IR.

In my parser code, while creating the signature for the store prologue fn, I set its attribute to "AlwaysInline" using the addFnattr() method.
I can send you the parser code if you think it helps.

//input to parser (test.ll)
….
….
define i32 @main() nounwind {
entry:
  %retval = alloca i32 ; <i32*> [#uses=2]
  %0 = alloca i32 ; <i32*> [#uses=2]
  %b = alloca i32 ; <i32*> [#uses=2]
  %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
  store i32 20, i32* %b, align 4
  call void @store_inst_prologue(i64 100, i32 42) nounwind inlinehint
  store i32 42, i32* @a, align 4
  %1 = load i32* @a, align 4 ; <i32> [#uses=1]
  %2 = mul nsw i32 %1, 2 ; <i32> [#uses=1]
  store i32 %2, i32* %b, align 4
  store i32 0, i32* %0, align 4
  %3 = load i32* %0, align 4 ; <i32> [#uses=1]
  store i32 %3, i32* %retval, align 4
  br label %return

return: ; preds = %entry
  %retval1 = load i32* %retval ; <i32> [#uses=1]
  ret i32 %retval1
}

//output from parser (test_instrumented.ll)
….
….
define i32 @main() nounwind {
entry:
  %retval = alloca i32 ; <i32*> [#uses=3]
  %0 = alloca i32 ; <i32*> [#uses=3]
  %b = alloca i32 ; <i32*> [#uses=4]
  %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
  %1 = ptrtoint i32* %b to i64 ; <i64> [#uses=1]
=> call void @store_inst_prologue(i64 %1, i32 4) nounwind
  store i32 20, i32* %b, align 4
  call void @store_inst_prologue(i64 100, i32 42) nounwind inlinehint
=> call void @store_inst_prologue(i64 ptrtoint (i32* @a to i64), i32 4) nounwind
  store i32 42, i32* @a, align 4
  %2 = load i32* @a, align 4 ; <i32> [#uses=1]
  %3 = mul nsw i32 %2, 2 ; <i32> [#uses=1]
  %4 = ptrtoint i32* %b to i64 ; <i64> [#uses=1]
=> call void @store_inst_prologue(i64 %4, i32 4) nounwind
  store i32 %3, i32* %b, align 4
  %5 = ptrtoint i32* %0 to i64 ; <i64> [#uses=1]
=> call void @store_inst_prologue(i64 %5, i32 4) nounwind
  store i32 0, i32* %0, align 4
  %6 = load i32* %0, align 4 ; <i32> [#uses=1]
  %7 = ptrtoint i32* %retval to i64 ; <i64> [#uses=1]
=> call void @store_inst_prologue(i64 %7, i32 4) nounwind
  store i32 %6, i32* %retval, align 4
  br label %return

return: ; preds = %entry
  %retval1 = load i32* %retval ; <i32> [#uses=1]
  ret i32 %retval1
}

I am correctly able to instrument the stores. I am now using opt to make the store_inst_prologue function calls inlined.
I used the following command
$opt -always-inline -inline test_instrumented.ll -S -o test_instrumented.s

However, in the test_instrumented.s file the calls still remain as opposed to being inlined. I was wondering if I am doing something wrong or what would would be the best way to make the store_inst_prologue inline. I really appreciate your help.

Thanks,
--Hari

Kindly ignore my previous message. Using inline instead of static inline worked.

Thanks,
--Hari