K Jelesnianski via llvm-dev
2021-Feb-23 21:19 UTC
[llvm-dev] How to recover function parameter Value* when -O2 active
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 } -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210223/44409841/attachment.html>
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