X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FdeSugar%2FDsExpr.lhs;h=6cbd5380b83e73315bcc44f245d1bf9059bf3007;hb=f5baf549bcd4b835fdc8e0ce00b854f522464e68;hp=0633717d09538b9f0f1077a42729eb7efa4e3731;hpb=6febb616f1ff46942434e9df39c6e4977b07cc6f;p=ghc-hetmet.git diff --git a/compiler/deSugar/DsExpr.lhs b/compiler/deSugar/DsExpr.lhs index 0633717..6cbd538 100644 --- a/compiler/deSugar/DsExpr.lhs +++ b/compiler/deSugar/DsExpr.lhs @@ -42,6 +42,7 @@ import TcType import Type import CoreSyn import CoreUtils +import MkCore import DynFlags import CostCentre @@ -211,7 +212,7 @@ dsExpr (HsLam a_Match) = uncurry mkLams <$> matchWrapper LambdaExpr a_Match dsExpr (HsApp fun arg) - = mkDsApp <$> dsLExpr fun <*> dsLExpr arg + = mkCoreApp <$> dsLExpr fun <*> dsLExpr arg \end{code} Operator sections. At first it looks as if we can convert @@ -238,10 +239,10 @@ will sort it out. \begin{code} dsExpr (OpApp e1 op _ e2) = -- for the type of y, we need the type of op's 2nd argument - mkDsApps <$> dsLExpr op <*> mapM dsLExpr [e1, e2] + mkCoreApps <$> dsLExpr op <*> mapM dsLExpr [e1, e2] dsExpr (SectionL expr op) -- Desugar (e !) to ((!) e) - = mkDsApp <$> dsLExpr op <*> dsLExpr expr + = mkCoreApp <$> dsLExpr op <*> dsLExpr expr -- dsLExpr (SectionR op expr) -- \ x -> op x expr dsExpr (SectionR op expr) = do @@ -253,7 +254,7 @@ dsExpr (SectionR op expr) = do x_id <- newSysLocalDs x_ty y_id <- newSysLocalDs y_ty return (bindNonRec y_id y_core $ - Lam x_id (mkDsApps core_op [Var x_id, Var y_id])) + Lam x_id (mkCoreApps core_op [Var x_id, Var y_id])) dsExpr (HsSCC cc expr) = do mod_name <- getModuleDs @@ -265,10 +266,15 @@ dsExpr (HsSCC cc expr) = do dsExpr (HsCoreAnn fs expr) = Note (CoreNote $ unpackFS fs) <$> dsLExpr expr -dsExpr (HsCase discrim matches) = do - core_discrim <- dsLExpr discrim - ([discrim_var], matching_code) <- matchWrapper CaseAlt matches - return (scrungleMatch discrim_var core_discrim matching_code) +dsExpr (HsCase discrim matches@(MatchGroup _ rhs_ty)) + | isEmptyMatchGroup matches -- A Core 'case' is always non-empty + = -- So desugar empty HsCase to error call + mkErrorAppDs pAT_ERROR_ID (funResultTy rhs_ty) "case" + + | otherwise + = do { core_discrim <- dsLExpr discrim + ; ([discrim_var], matching_code) <- matchWrapper CaseAlt matches + ; return (scrungleMatch discrim_var core_discrim matching_code) } -- Pepe: The binds are in scope in the body but NOT in the binding group -- This is to avoid silliness in breakpoints @@ -309,20 +315,20 @@ dsExpr (HsIf guard_expr then_expr else_expr) dsExpr (ExplicitList elt_ty xs) = dsExplicitList elt_ty xs --- we create a list from the array elements and convert them into a list using --- `PrelPArr.toP' --- --- * the main disadvantage to this scheme is that `toP' traverses the list --- twice: once to determine the length and a second time to put to elements --- into the array; this inefficiency could be avoided by exposing some of --- the innards of `PrelPArr' to the compiler (ie, have a `PrelPArrBase') so --- that we can exploit the fact that we already know the length of the array --- here at compile time +-- We desugar [:x1, ..., xn:] as +-- singletonP x1 +:+ ... +:+ singletonP xn -- +dsExpr (ExplicitPArr ty []) = do + emptyP <- dsLookupGlobalId emptyPName + return (Var emptyP `App` Type ty) dsExpr (ExplicitPArr ty xs) = do - toP <- dsLookupGlobalId toPName - coreList <- dsExpr (ExplicitList ty xs) - return (mkApps (Var toP) [Type ty, coreList]) + singletonP <- dsLookupGlobalId singletonPName + appP <- dsLookupGlobalId appPName + xs' <- mapM dsLExpr xs + return . foldr1 (binary appP) $ map (unary singletonP) xs' + where + unary fn x = mkApps (Var fn) [Type ty, x] + binary fn x y = mkApps (Var fn) [Type ty, x, y] dsExpr (ExplicitTuple expr_list boxity) = do core_exprs <- mapM dsLExpr expr_list @@ -505,10 +511,8 @@ dsExpr (HsBinTick ixT ixF e) = do \begin{code} -#ifdef DEBUG -- HsSyn constructs that just shouldn't be here: dsExpr (ExprWithTySig _ _) = panic "dsExpr:ExprWithTySig" -#endif findField :: [HsRecField Id arg] -> Name -> [arg] @@ -541,13 +545,18 @@ fruitless allocations. Essentially, whenever we see a list literal If fusion fails to occur then build will get inlined and (since we defined a RULE for foldr (:) []) we will get back exactly the - normal desugaring for an explicit list! However, if it does occur - then we can potentially save quite a bit of allocation (up to 25\% - of the total in some nofib programs!) + normal desugaring for an explicit list. + +This optimisation can be worth a lot: up to 25% of the total +allocation in some nofib programs. Specifically + + Program Size Allocs Runtime CompTime + rewrite +0.0% -26.3% 0.02 -1.8% + ansi -0.3% -13.8% 0.00 +0.0% + lift +0.0% -8.7% 0.00 -2.3% Of course, if rules aren't turned on then there is pretty much no point doing this fancy stuff, and it may even be harmful. - \begin{code} dsExplicitList :: PostTcType -> [LHsExpr Id] -> DsM CoreExpr @@ -555,7 +564,7 @@ dsExplicitList :: PostTcType -> [LHsExpr Id] -> DsM CoreExpr dsExplicitList elt_ty xs = do dflags <- getDOptsDs xs' <- mapM dsLExpr xs - if not (dopt Opt_RewriteRules dflags) + if not (dopt Opt_EnableRewriteRules dflags) then return $ mkListExpr elt_ty xs' else mkBuildExpr elt_ty (mkSplitExplicitList (thisPackage dflags) xs') where