[llvm-dev] How to recover function parameter Value* when -O2 active

K Jelesnianski via llvm-dev llvm-dev at lists.llvm.org
Tue Feb 23 16:33:26 PST 2021


Ah makes sense completely, I forgot about it being pass by value. Thanks
again for clearing this up.

Also unrelated but: I just discovered LLVM has its own discord and I posted
my question there first, is it popular? Or is mailing list still more
responsive?

On Tue, Feb 23, 2021 at 7:18 PM Johannes Doerfert <
johannesdoerfert at gmail.com> wrote:

>
> On 2/23/21 6:08 PM, K Jelesnianski wrote:
> > 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().
>
> Your code *does not* pass the address of `m` in `main` to `foo`.
> It passes `m` by value to `foo`, thus the argument `b`is a copy
> of `m` if you want. You cannot recover the address of `m` in `foo`
> by any legal means. In fact, the optimizer will realize there is
> no need for stack allocations and put both `m` and `b` into (virtual)
> registers instead. If you want to trace a stack allocation, trace
> it early. If you "wait" and it is remove because it was not observed/
> needed, it's gone for good.
>
> For your code, change it to:
>
> void foo(int *bptr) { int b = *bptr; ... }
> void main(...) {
>    ...
>    *m = ...
>    ...
>    foo(&m);
> }
>
> and then you can profile the `i32* %bptr` argument of foo which is
> the "stack" address of `m` in `main`.
>
> ~ Johannes
>
>
>
> > 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/71239394/attachment.html>


More information about the llvm-dev mailing list