Hello everyone!

First of all, my apologies for letting you wait that long. Especially, I
want to let you know that I really feel sorry for not following up your
offer back in January, Simon.

I somewhat underestimated the amount of time I had to invest in
university during the last semester. Unfortunately, I couldn't find the
time to work out the demonstration I mentioned in my last mail back in
December.

At the moment, I'm making up for this showcase. In doing so, I stumbled
across another question concerning the cmm-pipeline:

Given a CmmGraph, is there a possibility to annotate information to a
single node within this graph? I.e. I want to annotate to certain
CmmCalls that they where introduced by 'proc point splitting'. I would
like to slightly modifiy the generation of LLVM IR for such Calls later on.

Thanks for your help in advance!

Regards,

David



On 12/14/2015 06:16 PM, David Spitzenberg wrote:
> Simon
> 
>> |  Could you explain the need of further info-tables for 'inner'
>> |  proc-points (those, which are not the entry-block of a function) to
>> |  me, please?
>>
>> The main purpose of inner info tables is this.  Given (case e of blah) we 
>> push a return address (for 'blah') on the stack and evaluate 'e'.  During 
>> evaluation of 'e', garbage collection may take place.  So the garbage 
>> collector needs to walk the stack to follow live pointers.  Who knows what 
>> pointers are live?  Answer: the code for 'blah' clearly knows what pointers 
>> are alive in the current stack frame, because it is going to access them.  
>> So the return address gets an info table that makes that implicit knowledge 
>> explicit, as a bitmap describing the liveness/pointer-hood of the stack 
>> frame.
>>
>> Addresses that are only jumped to don’t need info tables.
>>
>> It would be great if, as you learn about this stuff, you could add to the 
>> Commentary
>> https://ghc.haskell.org/trac/ghc/wiki/Commentary
>> to capture what you have learned.
> 
> Thank you very much! In cases I find the current description imprecise
> or incomplete I can add what I've learned to the Commentary of course.
> 
>> |  The documentation states, that proc-point splitting is only required
>> |  by the LLVM backend (see [2]). Does the cmm-pipeline perform proc-
>> |  point splitting even when using the native code generator?
>>
>> I'm not certain, but I don't think so.
>>
>> |  As stated above, the major problem of LLVM seems to be inferring
>> |  control flow when it comes to call proc-points. As it's hard to avoid
>> |  proc-point splitting, we leave the cmm-pipeline 'as-is'. We modify the
>>
>> I regard the whole proc-point thing as a major wart.  I think we should work 
>> hard to eliminate it.  So: another line of thought might be: how could we 
>> influence LLVM so that we didn't need proc-point splitting?
> 
> I totally agree with you here. However, determining how LLVM needs to be
> influenced to eliminate proc-point splitting is a thing I won't be
> capable of doing mid term because of my current knowledge and lack of time.
> 
>> |  To make control flow more apparent to LLVM, they came up with the
>> |  following idea. Remark before showing the idea: I know that it greatly
>>
>> I'm sorry to say that I didn't really understand the idea.  Maybe someone 
>> else did?  David Terei?
> 
> My apologies for being imprecise. I hope to find the time to
> work out a little demonstration during the upcoming holidays. I'm
> currently fully occupied by university because of upcoming exams this week.
> 
>> If you are seriously about investing effort in the back end, I'd be happy to 
>> help; in that case a Skype call is probably the best way.
> 
> That is a great idea. Due to the above mentioned time constraints I
> propose that we follow up in January.
> 
> Regards,
> 
> David
> 
> 
> 
> 
> 
>> Simon
>>
>> |  interferes with CPS. It leaves parts of the continuation-handling to
>> |  the implicit LLVM call-stack. Further, this does not solve the problem
>> |  of proc-point splitting at all. It is more a workaround than a
>> |  solution.
>> |  But it would greatly increase LLVM's possibilities to optimize code
>> |  later on. That's why I found this idea worth mentioning. Especially
>> |  because after reading your answer, Ben, I'm somewhat convinced that
>> |  solving the problem of proc-point splitting is nearly impossible with
>> |  the capabilities of LLVM IR available at the moment. Now back to the
>> |  idea.
>> |  
>> |  As stated above, the major problem of LLVM seems to be inferring
>> |  control flow when it comes to call proc-points. As it's hard to avoid
>> |  proc-point splitting, we leave the cmm-pipeline 'as-is'. We modify the
>> |  code, llvmGen produces when it comes to call proc-points instead. All
>> |  other types of proc-points remain unchanged.
>> |  
>> |  Initial situation in pseudo cmm:
>> |  
>> |  foo() {
>> |  ...
>> |  call bar() returns to cont // bar defined externally
>> |  
>> |  cont:
>> |  ...
>> |  }
>> |  
>> |  After proc-point splitting, this is converted into LLVM IR similar to
>> |  the following:
>> |  
>> |  @foo() {
>> |  ...
>> |  store @cont(), %Sp ; push continuation on the stack tail call @bar() ;
>> |  @bar defined externally }
>> |  
>> |  @cont() {
>> |  ...
>> |  }
>> |  
>> |  To fix the above issue, we introduce a method, which restores the
>> |  pointers Sp, Hp and the register R1 (among everything else, what has
>> |  to be restored) and 'fakes' the continuation. Note, that '@restore'
>> |  returns without calling into the continuation. This way, the call into
>> |  the continuation can be made direct. The above code would be
>> |  transformed into something similar to the following:
>> |  
>> |  @foo() {
>> |  ...
>> |  store @restore(), %Sp ; 'fake' continuation call @bar() ; br label
>> |  restore
>> |  
>> |  restore:
>> |  %Sp = load (getelementptr @environment 0, 0) ; restore what has to be
>> |  ... ; restored tail call @cont() }
>> |  
>> |  @cont() {
>> |  ...
>> |  }
>> |  
>> |  @restore(%Sp, %Hp, %R1, ...) {
>> |  store %Sp, (getelementptr @environment 0, 0) ; store everything into
>> |  ... ; global variable ret void }
>> |  
>> |  @environment ; structure of type similar to {i64*, i64*, i64*, i64,
>> |  i64, ..}
>> |  
>> |  As an alternative, the above transformation could be done by a LLVM
>> |  pass. llvmGen could then annotate the continuation of calls call cite.
>> |  This would greatly simplify the detection of the correct continuation.
>> |  
>> |  What do you think about this idea? Especially when thinking about the
>> |  interference with CPS?
>> |  
>> |  Regards,
>> |  
>> |  David
>> |  
>> |  
>> |  
>> |  
>> |  [1]
>> |  https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/GeneratedCod
>> |  e#Importantconceptsinthemachine
>> |  
>> |  [2]
>> |  https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/CodeGen#Seco
>> |  ndstage:theCmmpipeline
>> |  
>> |  
>> |  
>> |  
>> |  On 11/21/2015 12:00 AM, Ben Gamari wrote:
>> |  > Simon Peyton Jones <simo...@microsoft.com> writes:
>> |  >
>> |  >> David
>> |  >>
>> |  >> All this stuff is terribly paged-out for me. But I'd love someone
>> |  to
>> |  >> pay attention to some of this back-end stuff, so if you'd like to
>> |  >> work there, I'd like to help you.
>> |  >>
>> |  >> David Terei was also thinking of getting rid of proc point
>> |  splitting
>> |  >> for LLVM (see attached email and the notes attached to it)
>> |  >>
>> |  >> Simon Marlow also was thinking about this; see his attached email.
>> |  >>
>> |  >> The main *reason* for establishing a proc-point is so that, when
>> |  >> generating C code (which we don't do any more) you can take its
>> |  >> address. E.g.
>> |  >>
>> |  >> foo() { ... Push &bar onto the stack (effectively a return address)
>> |  >>   Jump to thingumpy }
>> |  >>
>> |  >> bar() { ... }
>> |  >>
>> |  >> Really bar is part of foo, but we have make it a separate top level
>> |  >> thing so that we can take the address of bar and push it on the
>> |  stack.
>> |  >>
>> |  >> The trouble is that if there is a label inside bar that foo wants
>> |  to
>> |  >> jump to (i.e. without pushing &bar etc) then we have to make that
>> |  >> label too into a proc-point, so that both foo and bar can see it.
>> |  >> Urgh.
>> |  >>
>> |  >> In LLVM this probably is not true; presumably you can take the
>> |  >> address of any label?
>> |  >>
>> |  > This is true. While labels themselves have function-local scope in
>> |  > LLVM, there is an expression, `blockaddress`, which allows you to
>> |  take
>> |  > an address to a label in another function [1]. That being said, in
>> |  > reading through the documentation it's not at all clear to me that
>> |  it
>> |  > would be safe to jump to such an address. In fact, given that the
>> |  > instruction that this expression is supposed to be used with,
>> |  > `indirectbr`, can only be used for local blocks, I suspect it is
>> |  not.
>> |  > More information about this feature can be found here [2].
>> |  >
>> |  > The jump issue aside, I don't know how you would deal with
>> |  > tables-next-to-code. The prefix data support that currently
>> |  available
>> |  > in LLVM is attached to functions and I unfortunately don't see that
>> |  > changing any time soon.
>> |  >
>> |  > Ultimately it seems that trying to refer to labels defined in other
>> |  > functions is using LLVM against the way it was intended. One
>> |  > alternative would be to teach llvmGen to merge mutually recusive
>> |  > top-level functions into a single LLVM function during code
>> |  > generation. Otherwise I'm afraid you are stuck with either the
>> |  status
>> |  > quo or attempting to improve on LLVM's own cross-procedure
>> |  optimization ability.
>> |  >
>> |  > That being said, it sounds as though eliminating proc-point
>> |  splitting
>> |  > would make for quite a nice project in the native code generator.
>> |  >
>> |  > Cheers,
>> |  >
>> |  > - Ben
>> |  >
>> |  >
>> |  > [1]
>> |  >
>> |  https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fllvm.o
>> |  > rg%2fdocs%2fLangRef.html%23addresses-of-basic-
>> |  blocks&data=01%7c01%7csi
>> |  >
>> |  monpj%40064d.mgd.microsoft.com%7c7fdbfda0b4514a098c4d08d2f74448f1%7c72
>> |  >
>> |  f988bf86f141af91ab2d7cd011db47%7c1&sdata=nKVLgmZezUdEYL%2fma1exMMPLbcT
>> |  > RkaE1JrvVaR1EesY%3d [2]
>> |  >
>> |  https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fblog.l
>> |  > lvm.org%2f2010%2f01%2faddress-of-label-and-indirect-
>> |  branches.html&data
>> |  >
>> |  =01%7c01%7csimonpj%40064d.mgd.microsoft.com%7c7fdbfda0b4514a098c4d08d2
>> |  >
>> |  f74448f1%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=BTMdZESwYS4tZa5W
>> |  > sOAqyFutoI5xNNFDe0b%2bdKC3ODs%3d [3]
>> |  >
>> |  https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fllvm.o
>> |  > rg%2fdocs%2fLangRef.html%23prefix-
>> |  data&data=01%7c01%7csimonpj%40064d.m
>> |  >
>> |  gd.microsoft.com%7c7fdbfda0b4514a098c4d08d2f74448f1%7c72f988bf86f141af
>> |  >
>> |  91ab2d7cd011db47%7c1&sdata=rdo4ZLjjE%2bWxNykVL%2bSuToWioY6nzQpflSk296E
>> |  > 8W70%3d
>> |  >
>>
> 
> 
> _______________________________________________
> ghc-devs mailing list
> ghc-devs@haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
> 
_______________________________________________
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Reply via email to