Johannes Doerfert via llvm-dev
2021-Feb-23 23:19 UTC
[llvm-dev] How to recover function parameter Value* when -O2 active
If you want to access the `llvm::AllocaInst` generated by Clang for the argument you should run your pass early in the pipeline. If you just want to see the value passed to `bar`, take the `llvm::Argument` and pass it to your profiling function. If you need indirection for some reason, create a new `llvm::AllocaInst`, store the `llvm::Argument` you are interested in in it, and pass the `llvm::AllocaInst` to your function. I hope this helps. ~ Johannes On 2/23/21 3:19 PM, K Jelesnianski via llvm-dev wrote:> Dear LLVM mailing list, > > I am currently having difficulty with figuring out how to get a function > parameter Value* when I am compiling with -O2. It seems -O2 performs an > optimization that optimizes out the local variable formed for the function > parameter. > I have a pass where I am inserting new function calls, and need to pass the > function parameters variable address. With -O0 this issue does not come up > as each function parameter when using -O0 gets its own AllocaInst and I can > leverage that Value* to pass to my new function call. I have tried to > leverage llvm.dbg information but it seems LLVM is not inserting > llvm.dbg.addr for me to use. > > Below is the code example I am working with: > /* example.c */ > int fd_in; > char* ut_addr; > > __attribute__((noinline)) void bar (int b){ > my_pass_function( &b ); // NEW (what I want to be done by my pass) > ut_addr = (char*) mmap( 0, b, my_prot, MAP_PRIVATE, fd_in, 0); > } > > __attribute__((noinline)) void foo (int f){ > bar( f ); > } > > int main(int argc, char** argv){ > int m; > struct stat statbuf; > char *input; > > if( (fd_in = open ( input, O_RDONLY)) < 0){ /* open the > input file */ > return 0; > } > if( fstat( fd_in , &statbuf ) < 0 ){ /* find size of input > file */ > return 0; > } > > m = statbuf.st_size; > foo( m ); > return 0; > } > ----------------------------------------------------------------- > The original IR I get for bar() is below, as you can see the function > parameter is the "raw" value "i32 %b" passed into the function and not a > variable that I can leverage, get its Value* . Hence when I run my newly > instrumented code, I get a segmentation fault. > > define void @bar(i32 %b) local_unnamed_addr #0 !dbg !35 { > entry: > call void @llvm.dbg.value(metadata i32 %b, metadata !39, metadata > !DIExpression()), !dbg !44 > call void @llvm.dbg.value(metadata i64 1000, metadata !40, metadata > !DIExpression()), !dbg !44 > call void @llvm.dbg.value(metadata i32 1, metadata !43, metadata > !DIExpression()), !dbg !44 > %conv = sext i32 %b to i64, !dbg !45 > %0 = load i32, i32* @fd_in, align 4, !dbg !46, !tbaa !47 > %call = tail call i8* @mmap(i8* null, i64 %conv, i32 1, i32 2, i32 %0, > i64 0) #7, !dbg !51 > store i8* %call, i8** @ut_addr, align 8, !dbg !52, !tbaa !53 > ret void, !dbg !55 > } > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
K Jelesnianski via llvm-dev
2021-Feb-24 00:08 UTC
[llvm-dev] How to recover function parameter Value* when -O2 active
Thank you so much for your reply! I want my pass to run as late as possible to not be messed up by any of the regular internal optimizations. I need a reference of i32 %b (regularly we see this in IR as i32* %b) so if I understand you I think I need an indirection. In that case is it safe to just create an AllocaInst ? Does adding the AllocaInst effect the way the data flows between functions? The reason I am saying this is: Following my above example code, assuming I am interested in the local variable "m" declared and set in main() (so a memory slot dedicated for "m" is created in the stack, right?), "m" is passed to foo(m), nothing is altered, "m" is further passed to bar(). If I created the AllocaInst in bar and assign %b to it, will I be creating a new stack memory slot for bar's Argument "b" and will then I be passing in the memory address of "b" (context of bar()) and not "m" (context of main()). I want to, if possible, pass the stack address of "m" (from the context of main) to my profiling function call that is currently in the context of bar(). On Tue, Feb 23, 2021 at 6:19 PM Johannes Doerfert < johannesdoerfert at gmail.com> wrote:> If you want to access the `llvm::AllocaInst` generated by Clang for > the argument you should run your pass early in the pipeline. If you > just want to see the value passed to `bar`, take the `llvm::Argument` > and pass it to your profiling function. If you need indirection for > some reason, create a new `llvm::AllocaInst`, store the `llvm::Argument` > you are interested in in it, and pass the `llvm::AllocaInst` to your > function. > > I hope this helps. > > ~ Johannes > > > On 2/23/21 3:19 PM, K Jelesnianski via llvm-dev wrote: > > Dear LLVM mailing list, > > > > I am currently having difficulty with figuring out how to get a function > > parameter Value* when I am compiling with -O2. It seems -O2 performs an > > optimization that optimizes out the local variable formed for the > function > > parameter. > > I have a pass where I am inserting new function calls, and need to pass > the > > function parameters variable address. With -O0 this issue does not come > up > > as each function parameter when using -O0 gets its own AllocaInst and I > can > > leverage that Value* to pass to my new function call. I have tried to > > leverage llvm.dbg information but it seems LLVM is not inserting > > llvm.dbg.addr for me to use. > > > > Below is the code example I am working with: > > /* example.c */ > > int fd_in; > > char* ut_addr; > > > > __attribute__((noinline)) void bar (int b){ > > my_pass_function( &b ); // NEW (what I want to be done by my > pass) > > ut_addr = (char*) mmap( 0, b, my_prot, MAP_PRIVATE, fd_in, 0); > > } > > > > __attribute__((noinline)) void foo (int f){ > > bar( f ); > > } > > > > int main(int argc, char** argv){ > > int m; > > struct stat statbuf; > > char *input; > > > > if( (fd_in = open ( input, O_RDONLY)) < 0){ /* open the > > input file */ > > return 0; > > } > > if( fstat( fd_in , &statbuf ) < 0 ){ /* find size of > input > > file */ > > return 0; > > } > > > > m = statbuf.st_size; > > foo( m ); > > return 0; > > } > > ----------------------------------------------------------------- > > The original IR I get for bar() is below, as you can see the function > > parameter is the "raw" value "i32 %b" passed into the function and not a > > variable that I can leverage, get its Value* . Hence when I run my newly > > instrumented code, I get a segmentation fault. > > > > define void @bar(i32 %b) local_unnamed_addr #0 !dbg !35 { > > entry: > > call void @llvm.dbg.value(metadata i32 %b, metadata !39, metadata > > !DIExpression()), !dbg !44 > > call void @llvm.dbg.value(metadata i64 1000, metadata !40, metadata > > !DIExpression()), !dbg !44 > > call void @llvm.dbg.value(metadata i32 1, metadata !43, metadata > > !DIExpression()), !dbg !44 > > %conv = sext i32 %b to i64, !dbg !45 > > %0 = load i32, i32* @fd_in, align 4, !dbg !46, !tbaa !47 > > %call = tail call i8* @mmap(i8* null, i64 %conv, i32 1, i32 2, i32 %0, > > i64 0) #7, !dbg !51 > > store i8* %call, i8** @ut_addr, align 8, !dbg !52, !tbaa !53 > > ret void, !dbg !55 > > } > > > > > > _______________________________________________ > > LLVM Developers mailing list > > llvm-dev at lists.llvm.org > > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210223/dedee42d/attachment-0001.html>