> Is the "cml_cont" field of the CmmCall variant is really used in practice?
Seconding what Michal has already said, yes, the `cml_cont` field is used quite a bit in Cmm. Any non-tail call in the program will have this field populated with information about where control-flow continues after the call returns. This field is used for some important steps, such as Proc Point analysis ( CmmProcPoint.callProcPoints ), the result of which is used to layout the stack. Stack layout uses the information about what values are live in the continuation block of a non-tail call to determine what values need to be saved to the stack. Thus, the control-flow graph structure of a CmmProc is defined in part by the `cml_cont` field (see the Cmm specific instance of Hoopl's NonLocal class in CmmNode, where it is used to indicate successors of a block). > I traversed the output of raw Cmm produced by ghc compiling the whole base > package, but the value of cml_cont is always Nothing. Hrm, were you looking for "returns to" in that output? ~kavon > On Mar 18, 2018, at 8:52 AM, Michal Terepeta <michal.terep...@gmail.com> > wrote: > > On Sun, Mar 18, 2018 at 6:38 AM Shao, Cheng <cheng.s...@tweag.io > <mailto:cheng.s...@tweag.io>> wrote: > Hi all, > > Is the "cml_cont" field of the CmmCall variant is really used in practice? I > traversed the output of raw Cmm produced by ghc compiling the whole base > package, but the value of cml_cont is always Nothing. > > Regards, > Shao Cheng > > > Hi, > > I'm not a GHC expert, so please don't trust everything I say ;) > > That being said, I think `cml_cont` is used a lot. If you look at the > `compiler/codeGen` directory (that's what turns STG to cmm), you'll > see that `MkGraph.mkCallReturnsTo` is called a few times. That's the > function that will construct a `CmmCall` with the continuation block. > > When dumping cmm, you'll often see all those `returns to` notes. For > instance, compiling: > > ``` > foo :: Int -> Int > foo x = > case x of > 42 -> 111111 > _ -> 000000 > ``` > > results in: > > ``` > [...] > c2cN: // global > I64[Sp - 8] = c2cI; > R1 = R2; > Sp = Sp - 8; > if (R1 & 7 != 0) goto c2cI; else goto c2cJ; > > // Evaluate the parameter. > c2cJ: // global > call (I64[R1])(R1) returns to c2cI, args: 8, res: 8, upd: 8; > // ^^^^^^^^^^^^^^^ > // this specifies the continuation block > // see also PprCmm.pprNode > > // Now check if it's 42. > c2cI: // global > if (I64[R1 + 7] == 42) goto c2cU; else goto c2cT; > c2cU: // global > [...] > ``` > > As far as I understand it, this allows the code above to jump to the > `x` closure (to evalutae it), and have the closure jump back to the > continuation block (note that it's address is stored before we jump to > closure). AFAICS this particular code is created by > `StgCmmExpr.emitEnter`. > > Hope this helps! > > - Michal > > _______________________________________________ > ghc-devs mailing list > ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
signature.asc
Description: Message signed with OpenPGP
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs