[commit: ghc] wip/T14373: Add note about mechanics of double switching (5719218)

git at git.haskell.org git at git.haskell.org
Thu Dec 21 17:33:51 UTC 2017


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/T14373
Link       : http://ghc.haskell.org/trac/ghc/changeset/57192187a2c086945897259847e3605bd9fea6b9/ghc

>---------------------------------------------------------------

commit 57192187a2c086945897259847e3605bd9fea6b9
Author: Gabor Greif <ggreif at gmail.com>
Date:   Thu Dec 21 18:19:33 2017 +0100

    Add note about mechanics of double switching
    
    for big families


>---------------------------------------------------------------

57192187a2c086945897259847e3605bd9fea6b9
 compiler/codeGen/StgCmmExpr.hs | 54 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/compiler/codeGen/StgCmmExpr.hs b/compiler/codeGen/StgCmmExpr.hs
index 446e421..663afdc 100644
--- a/compiler/codeGen/StgCmmExpr.hs
+++ b/compiler/codeGen/StgCmmExpr.hs
@@ -623,6 +623,7 @@ cgAlts gc_plan bndr (AlgAlt tycon) alts
                  (if small then fam_sz else maxpt) (pure ())
 
            else -- No, get exact tag from info table when mAX_PTR_TAG
+                -- See Note [double switching for big families]
               do
                 let untagged_ptr = cmmUntag dflags (CmmReg bndr_reg)
                     itag_expr = getConstrTag dflags untagged_ptr
@@ -653,6 +654,57 @@ cgAlts gc_plan bndr (AlgAlt tycon) alts
 cgAlts _ _ _ _ = panic "cgAlts"
         -- UbxTupAlt and PolyAlt have only one alternative
 
+-- Note [double switching for big families]
+--
+-- Generally, switching on big family alternatives now
+-- is done by two nested switch statements. The outer
+-- looks at the pointer tag and the inner dereferences the
+-- pointer and switches on the info table tag.
+--
+-- We can handle a simple case first, namely when none
+-- of the case alternatives mention a constructor having
+-- a pointer tag of 1..mAX_PTR_TAG-1. In this case we
+-- simply emit a switch on the info table tag.
+-- Note that the other simple case is when all mentioned
+-- alternatives lie in 1..mAX_PTR_TAG-1, in which case we can
+-- switch on the ptr tag only, just like in the small family case.
+--
+-- There are two intricacies with a nested switch:
+-- a) Both should branch to the same default alternative, and as such
+--    avoid duplicate codegen of potentially heavy code. The outer
+--    switch generates the actual code with a prepended fresh label,
+--    while the inner one only generates a jump to that label.
+-- b) Where to codegen the inner switch's code? It would be nice to
+--    leave the codegen to the mAX_PTR_TAG-numbered branch of the
+--    outer switch, but we don't have a c-- statement for this purpose.
+--    So we just emit a branch to a fresh label, and pass the
+--    code-emission action to the outer switch's emitter as
+--    pre-join-label code. What we end up with is:
+--
+--        switch [1..7] (R1 & 7) -- on ptr tag
+--          1 --> lbl0
+--          2 --> lbl1
+--          ...
+--          6 --> lbl5
+--          7 --> fallbackLbl_info
+--        
+--        <pre-join insertion comes here>
+--        fallbackLbl_info:
+--        switch [6..20] (R1->infoTag)
+--          6 --> lbl6
+--          7 --> lbl7
+--          ...
+--          19 --> lbl19
+--        </pre-join insertion>
+--        
+--        joinLbl:  -- lbl0 .. lbl19 all finally branch here
+--          <continuation>
+--
+--    Note that the joinLbl is internal to the 'emitSwitch',
+--    so we now have a tail argument to 'emitSwitch' which generates
+--    some custom code before that label. One can pass 'pure ()' to
+--    avoid this.
+
 
 -- Note [alg-alt heap check]
 --
@@ -690,6 +742,8 @@ cgAlts _ _ _ _ = panic "cgAlts"
 -- tricky part is that the default case needs (logical) duplication.
 -- To do this we emit an extra label for it and branch to that from
 -- the second switch. This avoids duplicated codegen. See Trac #14373.
+-- See Note [double switching for big families] for the mechanics
+-- involved.
 --
 -- Also see Note [Data constructor dynamic tags]
 



More information about the ghc-commits mailing list