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
On Jan 4, 2011, at 9:04 PM, Criswell, John T wrote:
> 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.
>
> ________________________________________
> From: llvmdev-bounces at cs.uiuc.edu [llvmdev-bounces at cs.uiuc.edu] On
Behalf Of Hari Pyla [harip at vt.edu]
> Sent: Tuesday, January 04, 2011 4:19 PM
> To: llvmdev at cs.uiuc.edu
> Subject: [LLVMdev] 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
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev