[commit: ghc] wip/rwbarton-D3217: When floating, don't box an expression that's okay for speculation (#13338) (ecd2bf8)
git at git.haskell.org
git at git.haskell.org
Mon Feb 27 13:20:34 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/rwbarton-D3217
Link : http://ghc.haskell.org/trac/ghc/changeset/ecd2bf89816bd6f5f4c3e7648037d80fd79abb72/ghc
>---------------------------------------------------------------
commit ecd2bf89816bd6f5f4c3e7648037d80fd79abb72
Author: Reid Barton <rwbarton at gmail.com>
Date: Sun Feb 26 12:09:47 2017 -0500
When floating, don't box an expression that's okay for speculation (#13338)
Summary:
Commit 432f952e (Float unboxed expressions by boxing) lets the float-out pass
turn, for example,
... (-# (remInt# x# 100000#) i#) ...
into
let lvl :: Int
lvl = case remInt# x# 100000# of v { __DEFAULT__ -> I# v }
in ... (-# (case lvl of { I# v -> v }) i#) ...
But when, as in the example above, the expression that was floated out was
the argument of an application, the resulting application may no longer
satisfy the let/app invariant, because exprOkForSpeculation doesn't look
far enough inside the definition of lvl.
Solution: When the expression we floated out was okay for speculation, don't
bother boxing it. It will be evaluated earlier, and that's okay by assumption.
Fixes the let/app invariant and is cheaper too.
Test Plan: make slowtest TEST=T13338
Reviewers: simonpj, austin, bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D3217
>---------------------------------------------------------------
ecd2bf89816bd6f5f4c3e7648037d80fd79abb72
compiler/simplCore/SetLevels.hs | 9 ++++++++-
testsuite/tests/simplCore/should_compile/T13338.hs | 12 ++++++++++++
testsuite/tests/simplCore/should_compile/all.T | 1 +
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/compiler/simplCore/SetLevels.hs b/compiler/simplCore/SetLevels.hs
index 22d4048..0e067cc 100644
--- a/compiler/simplCore/SetLevels.hs
+++ b/compiler/simplCore/SetLevels.hs
@@ -561,9 +561,15 @@ lvlMFE env strict_ctxt ann_expr
= -- Don't float it out
lvlExpr env ann_expr
- | float_is_new_lam || need_join || exprIsTopLevelBindable expr expr_ty
+ | float_is_new_lam || need_join || exprIsTopLevelBindable expr expr_ty
+ || exprOkForSpeculation expr && not (isTopLvl dest_lvl)
-- No wrapping needed if the type is lifted, or is a literal string
-- or if we are wrapping it in one or more value lambdas
+ -- or is okay for speculation (we'll now evaluate it earlier).
+ -- In the last case we _must not_ wrap, because it could violate
+ -- the let/app invariant (Trac #13338).
+ -- But we can't float an unboxed thing to top level; so don't float
+ -- it all, as in lvlBind. (See "Don't break let/app" below.)
= do { expr1 <- lvlFloatRhs abs_vars dest_lvl rhs_env NonRecursive join_arity_maybe ann_expr
-- Treat the expr just like a right-hand side
; var <- newLvlVar expr1 join_arity_maybe
@@ -578,6 +584,7 @@ lvlMFE env strict_ctxt ann_expr
| escapes_value_lam
, not (exprIsCheap expr) -- Boxing/unboxing isn't worth
-- it for cheap expressions
+ , not (exprOkForSpeculation expr && isTopLvl dest_lvl) -- Don't break let/app
, Just (tc, _) <- splitTyConApp_maybe expr_ty
, Just dc <- boxingDataCon_maybe tc
, let dc_res_ty = dataConOrigResTy dc -- No free type variables
diff --git a/testsuite/tests/simplCore/should_compile/T13338.hs b/testsuite/tests/simplCore/should_compile/T13338.hs
new file mode 100644
index 0000000..347a9d7
--- /dev/null
+++ b/testsuite/tests/simplCore/should_compile/T13338.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE MagicHash #-}
+
+module T13338 where
+
+import GHC.Exts
+
+magic# :: Int# -> Bool
+magic# x# = True
+{-# NOINLINE magic# #-}
+
+f :: Int# -> Int -> Int
+f x# n = length [ i | i@(I# i#) <- [0..n], magic# (remInt# x# 100000# -# i#) ]
diff --git a/testsuite/tests/simplCore/should_compile/all.T b/testsuite/tests/simplCore/should_compile/all.T
index 53f5ade..23cd77c 100644
--- a/testsuite/tests/simplCore/should_compile/all.T
+++ b/testsuite/tests/simplCore/should_compile/all.T
@@ -244,3 +244,4 @@ test('T13317',
normal,
run_command,
['$MAKE -s --no-print-directory T13317'])
+test('T13338', only_ways(['optasm']), compile, ['-dcore-lint'])
More information about the ghc-commits
mailing list