Vedant Kumar via llvm-dev
2015-Oct-16 20:54 UTC
[llvm-dev] [RFC] Clean up the way we store optional Function data
Here is a WIP patch as promised: http://reviews.llvm.org/D13829 It uses a hungoff uselist to store optional data as needed. Some early objections from Duncan: - An extra one-time malloc() is required to set personality functions. - We get and set personality functions frequently. This patch introduces a level of indirection which slows the common case down. Is this overhead acceptable? If not, maybe we could leave personality function handling untouched and add a "Constant **OptionalData" array to Function. vedant> On Oct 14, 2015, at 3:12 PM, Vedant Kumar <vsk at apple.com> wrote: > > I like the idea of using hung off uses. > > We can keep using SubclassData to indicate whether or not some optional data is present. > > Benefits: zero space overhead until some optional data is set, we can get rid of the DenseMaps in LLVMContextImpl, and RAUW just works (so no clang changes are needed). > > I'll have a patch up before the end of the week. > > thanks > vedant > > >> On Oct 12, 2015, at 12:15 PM, Sanjoy Das via llvm-dev <llvm-dev at lists.llvm.org> wrote: >> >> >> >> David Majnemer wrote: >>> >>> >>> On Mon, Oct 12, 2015 at 11:00 AM, Duncan P. N. Exon Smith via llvm-dev >>> <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: >>> >>> >>>> On 2015-Oct-12, at 10:41, Sanjoy Das >>> <sanjoy at playingwithpointers.com >>> <mailto:sanjoy at playingwithpointers.com>> wrote: >>>> >>>> >>>> >>>> Vedant Kumar wrote: >>>>>>> That's a neat idea. To summarize: make Function have 3 optional >>> operands. (For context -- Function currently has 1 optional operand, >>> and my proposal is to move to 0.) >>>>>>> >>>>>>> Could someone else chime in on what they'd like to see? >>>>>> Sanjoy's idea makes sense to me, but only if we never need to add >>>>>> prefix/prologue data after functions are created. Are there any >>> places >>>>>> where we need/want to add them after the fact? >>>>> >>>>> I think so. I see: >>>>> >>>>> LinkModules.cpp: >>> Dst.setPrefixData(MapValue(Src.getPrefixData(), ValueMap, >>>>> BitcodeReader.cpp: >>> FunctionPrologueWorklist.back().first->setPrologueData(C); >>>>> InlineFunction.cpp: Caller->setPersonalityFn(CalledPersonality); >>>>> >>>>> Some of these sites could be refactored so that the Functions are >>> created with the prefix/prologue data they need. I don't think >>> that's possible for personality functions (see my third example). >>>>> >>>>> Would we inhibit any future patches which add prefix/prologue >>> data to Functions on the fly by taking this approach? >>>> >>>> You should always be able to create a new `llvm::Function` >>> instance (and RAUW it in) if you want to add prefix/prologue data to >>> functions after they've been created; just like you have to do today >>> for any other `llvm::User`s that do not have hung off uses. >>> >>> It's possible, but a lot more involved with `Function`s. Besides >>> RAUW, you need to transfer over all the basic blocks. >>> >>> This seems kind of wrong to me, if we expect it to happen. >>> >>>> Which brings me to -- can you use hung off uses for this? These >>> use lists can be resized on the fly, so you should be able to add >>> and remove prologue data on the fly. If you're using hung off uses, >>> you'll probably still need a descriptor to remember whether / which >>> operands are prologue data etc. >>> >>> Sure, this is another option. It might be simplest. I'd be >>> tempted to start with a 0/3 choice (if we allocate any hung-off >>> uses, allocate enough for all three operands) to simplify the >>> logic. Although I can't remember right now whether that's >>> legal (having nullptr operands followed by real ones)... >>> >>>>>>>>> Personalities are stored as ``optional`` Function operands. >>> We actually always >>>>>>>>> allocate the space for this ``optional`` operand: there's a >>> FIXME in the >>>>>>>>> destructor for Function about this. >>> >>> Makes me wonder, why didn't we use hung off uses to begin with? >>> Do functions "usually" have personality functions, for some >>> definition of? >>> >>> >>> Depends. In C++? It's pretty common to have objects which have >>> non-trivial destructors on the stack which means calling a function will >>> be an invoke which will require the function to have a personality. In >>> C? It's pretty rare. You'd need something like __attribute__((cleanup)) >>> to do it, the most common source of this will be something >>> like pthread_cleanup_push. If I recall correctly, Julia sets the >>> personality on functions regardless of whether or not there are any >>> invokes, they need the AsmPrinter to scribble something down. I can't >>> say for other languages (Rust, etc.). From what I understand, Swift >>> doesn't use landingpad for EH so they wouldn't need the personality set. >> >> Most functions we emit from our Java frontend have personalities. >> >> -- Sanjoy >> >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>> >>> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >
Duncan P. N. Exon Smith via llvm-dev
2015-Oct-17 00:56 UTC
[llvm-dev] [RFC] Clean up the way we store optional Function data
> On 2015-Oct-16, at 13:54, Vedant Kumar <vsk at apple.com> wrote: > > Here is a WIP patch as promised: > > http://reviews.llvm.org/D13829 > > It uses a hungoff uselist to store optional data as needed. > > Some early objections from Duncan: > > - An extra one-time malloc() is required to set personality functions. > - We get and set personality functions frequently. This patch introduces a level of indirection which slows the common case down. > > Is this overhead acceptable?If the overhead isn't bad, then this SGTM. (I haven't looked at the patch.) I guess I was thinking about large applications that use C++ exceptions and build with LTO, but even there it's a per-function overhead. I doubt it really matters.> If not, maybe we could leave personality function handling untouched and add a "Constant **OptionalData" array to Function.The `IndirectUser` approach you outlined initially might be better than this?> vedant > > >> On Oct 14, 2015, at 3:12 PM, Vedant Kumar <vsk at apple.com> wrote: >> >> I like the idea of using hung off uses. >> >> We can keep using SubclassData to indicate whether or not some optional data is present. >> >> Benefits: zero space overhead until some optional data is set, we can get rid of the DenseMaps in LLVMContextImpl, and RAUW just works (so no clang changes are needed). >> >> I'll have a patch up before the end of the week. >> >> thanks >> vedant >> >> >>> On Oct 12, 2015, at 12:15 PM, Sanjoy Das via llvm-dev <llvm-dev at lists.llvm.org> wrote: >>> >>> >>> >>> David Majnemer wrote: >>>> >>>> >>>> On Mon, Oct 12, 2015 at 11:00 AM, Duncan P. N. Exon Smith via llvm-dev >>>> <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: >>>> >>>> >>>>> On 2015-Oct-12, at 10:41, Sanjoy Das >>>> <sanjoy at playingwithpointers.com >>>> <mailto:sanjoy at playingwithpointers.com>> wrote: >>>>> >>>>> >>>>> >>>>> Vedant Kumar wrote: >>>>>>>> That's a neat idea. To summarize: make Function have 3 optional >>>> operands. (For context -- Function currently has 1 optional operand, >>>> and my proposal is to move to 0.) >>>>>>>> >>>>>>>> Could someone else chime in on what they'd like to see? >>>>>>> Sanjoy's idea makes sense to me, but only if we never need to add >>>>>>> prefix/prologue data after functions are created. Are there any >>>> places >>>>>>> where we need/want to add them after the fact? >>>>>> >>>>>> I think so. I see: >>>>>> >>>>>> LinkModules.cpp: >>>> Dst.setPrefixData(MapValue(Src.getPrefixData(), ValueMap, >>>>>> BitcodeReader.cpp: >>>> FunctionPrologueWorklist.back().first->setPrologueData(C); >>>>>> InlineFunction.cpp: Caller->setPersonalityFn(CalledPersonality); >>>>>> >>>>>> Some of these sites could be refactored so that the Functions are >>>> created with the prefix/prologue data they need. I don't think >>>> that's possible for personality functions (see my third example). >>>>>> >>>>>> Would we inhibit any future patches which add prefix/prologue >>>> data to Functions on the fly by taking this approach? >>>>> >>>>> You should always be able to create a new `llvm::Function` >>>> instance (and RAUW it in) if you want to add prefix/prologue data to >>>> functions after they've been created; just like you have to do today >>>> for any other `llvm::User`s that do not have hung off uses. >>>> >>>> It's possible, but a lot more involved with `Function`s. Besides >>>> RAUW, you need to transfer over all the basic blocks. >>>> >>>> This seems kind of wrong to me, if we expect it to happen. >>>> >>>>> Which brings me to -- can you use hung off uses for this? These >>>> use lists can be resized on the fly, so you should be able to add >>>> and remove prologue data on the fly. If you're using hung off uses, >>>> you'll probably still need a descriptor to remember whether / which >>>> operands are prologue data etc. >>>> >>>> Sure, this is another option. It might be simplest. I'd be >>>> tempted to start with a 0/3 choice (if we allocate any hung-off >>>> uses, allocate enough for all three operands) to simplify the >>>> logic. Although I can't remember right now whether that's >>>> legal (having nullptr operands followed by real ones)... >>>> >>>>>>>>>> Personalities are stored as ``optional`` Function operands. >>>> We actually always >>>>>>>>>> allocate the space for this ``optional`` operand: there's a >>>> FIXME in the >>>>>>>>>> destructor for Function about this. >>>> >>>> Makes me wonder, why didn't we use hung off uses to begin with? >>>> Do functions "usually" have personality functions, for some >>>> definition of? >>>> >>>> >>>> Depends. In C++? It's pretty common to have objects which have >>>> non-trivial destructors on the stack which means calling a function will >>>> be an invoke which will require the function to have a personality. In >>>> C? It's pretty rare. You'd need something like __attribute__((cleanup)) >>>> to do it, the most common source of this will be something >>>> like pthread_cleanup_push. If I recall correctly, Julia sets the >>>> personality on functions regardless of whether or not there are any >>>> invokes, they need the AsmPrinter to scribble something down. I can't >>>> say for other languages (Rust, etc.). From what I understand, Swift >>>> doesn't use landingpad for EH so they wouldn't need the personality set. >>> >>> Most functions we emit from our Java frontend have personalities. >>> >>> -- Sanjoy >>> >>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> >>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>> >>>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >
Vedant Kumar via llvm-dev
2015-Oct-21 21:25 UTC
[llvm-dev] [RFC] Clean up the way we store optional Function data
I've done some measurements on this. The test program I have just calls Function::Create(), F->setPersonalityFn(), and then F->eraseFromParent() in a loop 2^20 times. Results: pre-patch --- min: 1.10s max: 1.13s avg: 1.11s post-patch --- min: 1.26s max: 1.35s avg: 1.29s So we expect to lose 0.2 seconds per 1 million functions (with personality functions) in a project. I've only tested on my machine, and I haven't accounted for performance variations in other parts of the codebase where code was removed. I'm happy enough with the patch and think that this is a reasonable tradeoff. Should we go with this? http://reviews.llvm.org/D13829 vedant> On Oct 16, 2015, at 5:56 PM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote: > > >> On 2015-Oct-16, at 13:54, Vedant Kumar <vsk at apple.com> wrote: >> >> Here is a WIP patch as promised: >> >> http://reviews.llvm.org/D13829 >> >> It uses a hungoff uselist to store optional data as needed. >> >> Some early objections from Duncan: >> >> - An extra one-time malloc() is required to set personality functions. >> - We get and set personality functions frequently. This patch introduces a level of indirection which slows the common case down. >> >> Is this overhead acceptable? > > If the overhead isn't bad, then this SGTM. (I haven't looked at the > patch.) > > I guess I was thinking about large applications that use C++ exceptions > and build with LTO, but even there it's a per-function overhead. I > doubt it really matters. > >> If not, maybe we could leave personality function handling untouched and add a "Constant **OptionalData" array to Function. > > The `IndirectUser` approach you outlined initially might be better > than this? > >> vedant >> >> >>> On Oct 14, 2015, at 3:12 PM, Vedant Kumar <vsk at apple.com> wrote: >>> >>> I like the idea of using hung off uses. >>> >>> We can keep using SubclassData to indicate whether or not some optional data is present. >>> >>> Benefits: zero space overhead until some optional data is set, we can get rid of the DenseMaps in LLVMContextImpl, and RAUW just works (so no clang changes are needed). >>> >>> I'll have a patch up before the end of the week. >>> >>> thanks >>> vedant >>> >>> >>>> On Oct 12, 2015, at 12:15 PM, Sanjoy Das via llvm-dev <llvm-dev at lists.llvm.org> wrote: >>>> >>>> >>>> >>>> David Majnemer wrote: >>>>> >>>>> >>>>> On Mon, Oct 12, 2015 at 11:00 AM, Duncan P. N. Exon Smith via llvm-dev >>>>> <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote: >>>>> >>>>> >>>>>> On 2015-Oct-12, at 10:41, Sanjoy Das >>>>> <sanjoy at playingwithpointers.com >>>>> <mailto:sanjoy at playingwithpointers.com>> wrote: >>>>>> >>>>>> >>>>>> >>>>>> Vedant Kumar wrote: >>>>>>>>> That's a neat idea. To summarize: make Function have 3 optional >>>>> operands. (For context -- Function currently has 1 optional operand, >>>>> and my proposal is to move to 0.) >>>>>>>>> >>>>>>>>> Could someone else chime in on what they'd like to see? >>>>>>>> Sanjoy's idea makes sense to me, but only if we never need to add >>>>>>>> prefix/prologue data after functions are created. Are there any >>>>> places >>>>>>>> where we need/want to add them after the fact? >>>>>>> >>>>>>> I think so. I see: >>>>>>> >>>>>>> LinkModules.cpp: >>>>> Dst.setPrefixData(MapValue(Src.getPrefixData(), ValueMap, >>>>>>> BitcodeReader.cpp: >>>>> FunctionPrologueWorklist.back().first->setPrologueData(C); >>>>>>> InlineFunction.cpp: Caller->setPersonalityFn(CalledPersonality); >>>>>>> >>>>>>> Some of these sites could be refactored so that the Functions are >>>>> created with the prefix/prologue data they need. I don't think >>>>> that's possible for personality functions (see my third example). >>>>>>> >>>>>>> Would we inhibit any future patches which add prefix/prologue >>>>> data to Functions on the fly by taking this approach? >>>>>> >>>>>> You should always be able to create a new `llvm::Function` >>>>> instance (and RAUW it in) if you want to add prefix/prologue data to >>>>> functions after they've been created; just like you have to do today >>>>> for any other `llvm::User`s that do not have hung off uses. >>>>> >>>>> It's possible, but a lot more involved with `Function`s. Besides >>>>> RAUW, you need to transfer over all the basic blocks. >>>>> >>>>> This seems kind of wrong to me, if we expect it to happen. >>>>> >>>>>> Which brings me to -- can you use hung off uses for this? These >>>>> use lists can be resized on the fly, so you should be able to add >>>>> and remove prologue data on the fly. If you're using hung off uses, >>>>> you'll probably still need a descriptor to remember whether / which >>>>> operands are prologue data etc. >>>>> >>>>> Sure, this is another option. It might be simplest. I'd be >>>>> tempted to start with a 0/3 choice (if we allocate any hung-off >>>>> uses, allocate enough for all three operands) to simplify the >>>>> logic. Although I can't remember right now whether that's >>>>> legal (having nullptr operands followed by real ones)... >>>>> >>>>>>>>>>> Personalities are stored as ``optional`` Function operands. >>>>> We actually always >>>>>>>>>>> allocate the space for this ``optional`` operand: there's a >>>>> FIXME in the >>>>>>>>>>> destructor for Function about this. >>>>> >>>>> Makes me wonder, why didn't we use hung off uses to begin with? >>>>> Do functions "usually" have personality functions, for some >>>>> definition of? >>>>> >>>>> >>>>> Depends. In C++? It's pretty common to have objects which have >>>>> non-trivial destructors on the stack which means calling a function will >>>>> be an invoke which will require the function to have a personality. In >>>>> C? It's pretty rare. You'd need something like __attribute__((cleanup)) >>>>> to do it, the most common source of this will be something >>>>> like pthread_cleanup_push. If I recall correctly, Julia sets the >>>>> personality on functions regardless of whether or not there are any >>>>> invokes, they need the AsmPrinter to scribble something down. I can't >>>>> say for other languages (Rust, etc.). From what I understand, Swift >>>>> doesn't use landingpad for EH so they wouldn't need the personality set. >>>> >>>> Most functions we emit from our Java frontend have personalities. >>>> >>>> -- Sanjoy >>>> >>>>> >>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> >>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>>> >>>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> llvm-dev at lists.llvm.org >>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>> >> >
Reasonably Related Threads
- [RFC] Clean up the way we store optional Function data
- [RFC] Clean up the way we store optional Function data
- [RFC] Clean up the way we store optional Function data
- [RFC] Clean up the way we store optional Function data
- [RFC] Clean up the way we store optional Function data