Semi-tagging optimisation
[ghc-hetmet.git] / compiler / codeGen / CgUtils.hs
index ab39080..f2b3c72 100644 (file)
@@ -17,6 +17,8 @@ module CgUtils (
        tagToClosure,
 
        cmmAndWord, cmmOrWord, cmmNegate, cmmEqWord, cmmNeWord,
+        cmmULtWord, cmmUGtWord,
+        cmmULeWord, cmmUGeWord,
        cmmOffsetExprW, cmmOffsetExprB,
        cmmRegOffW, cmmRegOffB,
        cmmLabelOffW, cmmLabelOffB,
@@ -151,6 +153,7 @@ cmmOrWord  e1 e2 = CmmMachOp mo_wordOr  [e1, e2]
 cmmAndWord e1 e2 = CmmMachOp mo_wordAnd [e1, e2]
 cmmNeWord  e1 e2 = CmmMachOp mo_wordNe  [e1, e2]
 cmmEqWord  e1 e2 = CmmMachOp mo_wordEq  [e1, e2]
+cmmULeWord e1 e2 = CmmMachOp mo_wordULe [e1, e2]
 cmmULtWord e1 e2 = CmmMachOp mo_wordULt [e1, e2]
 cmmUGeWord e1 e2 = CmmMachOp mo_wordUGe [e1, e2]
 cmmUGtWord e1 e2 = CmmMachOp mo_wordUGt [e1, e2]
@@ -474,15 +477,18 @@ mk_switch tag_expr branches mb_deflt lo_tag hi_tag via_C
   where
     use_switch          = {- pprTrace "mk_switch" (
                        ppr tag_expr <+> text "n_tags:" <+> int n_tags <+>
+                        text "branches:" <+> ppr (map fst branches) <+>
                        text "n_branches:" <+> int n_branches <+>
-                       text "lo_tag: " <+> int lo_tag <+>
-                       text "hi_tag: " <+> int hi_tag <+>
-                       text "real_lo_tag: " <+> int real_lo_tag <+>
-                       text "real_hi_tag: " <+> int real_hi_tag) $ -}
+                       text "lo_tag:" <+> int lo_tag <+>
+                       text "hi_tag:" <+> int hi_tag <+>
+                       text "real_lo_tag:" <+> int real_lo_tag <+>
+                       text "real_hi_tag:" <+> int real_hi_tag) $ -}
                   ASSERT( n_branches > 1 && n_tags > 1 ) 
-                  n_tags > 2 && (small || dense || via_C)
-                -- a 2-branch switch always turns into an if.
-    small               = n_tags <= 4
+                  n_tags > 2 && (via_C || (dense && big_enough))
+                -- up to 4 branches we use a decision tree, otherwise
+                 -- a switch (== jump table in the NCG).  This seems to be
+                 -- optimal, and corresponds with what gcc does.
+    big_enough          = n_branches > 4
     dense               = n_branches > (n_tags `div` 2)
     n_branches   = length branches