summaryrefslogtreecommitdiff
path: root/compiler/nativeGen/AsmCodeGen.lhs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/nativeGen/AsmCodeGen.lhs')
-rw-r--r--compiler/nativeGen/AsmCodeGen.lhs66
1 files changed, 32 insertions, 34 deletions
diff --git a/compiler/nativeGen/AsmCodeGen.lhs b/compiler/nativeGen/AsmCodeGen.lhs
index 23aca9293c..7710691457 100644
--- a/compiler/nativeGen/AsmCodeGen.lhs
+++ b/compiler/nativeGen/AsmCodeGen.lhs
@@ -7,6 +7,7 @@
-- -----------------------------------------------------------------------------
\begin{code}
+{-# LANGUAGE GADTs #-}
module AsmCodeGen ( nativeCodeGen ) where
#include "HsVersions.h"
@@ -50,9 +51,11 @@ import NCGMonad
import BlockId
import CgUtils ( fixStgRegisters )
-import OldCmm
+import Cmm
+import CmmUtils
+import Hoopl
import CmmOpt ( cmmMachOpFold )
-import OldPprCmm
+import PprCmm
import CLabel
import UniqFM
@@ -290,8 +293,8 @@ nativeCodeGen' dflags ncgImpl h us cmms
| gopt Opt_SplitObjs dflags = split_marker : tops
| otherwise = tops
- split_marker = CmmProc mapEmpty mkSplitMarkerLabel [] (ListGraph [])
-
+ split_marker = CmmProc mapEmpty mkSplitMarkerLabel []
+ (ofBlockList (panic "split_marker_entry") [])
cmmNativeGenStream :: (Outputable statics, Outputable instr, Instruction instr)
=> DynFlags
@@ -878,9 +881,9 @@ Ideas for other things we could do (put these in Hoopl please!):
cmmToCmm :: DynFlags -> RawCmmDecl -> (RawCmmDecl, [CLabel])
cmmToCmm _ top@(CmmData _ _) = (top, [])
-cmmToCmm dflags (CmmProc info lbl live (ListGraph blocks)) = runCmmOpt dflags $ do
- blocks' <- mapM cmmBlockConFold blocks
- return $ CmmProc info lbl live (ListGraph blocks')
+cmmToCmm dflags (CmmProc info lbl live graph) = runCmmOpt dflags $ do
+ blocks' <- mapM cmmBlockConFold (toBlockList graph)
+ return $ CmmProc info lbl live (ofBlockList (g_entry graph) blocks')
newtype CmmOptM a = CmmOptM (([CLabel], DynFlags) -> (# a, [CLabel] #))
@@ -903,10 +906,13 @@ runCmmOpt :: DynFlags -> CmmOptM a -> (a, [CLabel])
runCmmOpt dflags (CmmOptM f) = case f ([], dflags) of
(# result, imports #) -> (result, imports)
-cmmBlockConFold :: CmmBasicBlock -> CmmOptM CmmBasicBlock
-cmmBlockConFold (BasicBlock id stmts) = do
+cmmBlockConFold :: CmmBlock -> CmmOptM CmmBlock
+cmmBlockConFold block = do
+ let (entry, middle, last) = blockSplit block
+ stmts = blockToList middle
stmts' <- mapM cmmStmtConFold stmts
- return $ BasicBlock id stmts'
+ last' <- cmmStmtConFold last
+ return $ blockJoin entry (blockFromList stmts') last'
-- This does three optimizations, but they're very quick to check, so we don't
-- bother turning them off even when the Hoopl code is active. Since
@@ -917,13 +923,13 @@ cmmBlockConFold (BasicBlock id stmts) = do
-- We might be tempted to skip this step entirely of not Opt_PIC, but
-- there is some PowerPC code for the non-PIC case, which would also
-- have to be separated.
-cmmStmtConFold :: CmmStmt -> CmmOptM CmmStmt
+cmmStmtConFold :: CmmNode e x -> CmmOptM (CmmNode e x)
cmmStmtConFold stmt
= case stmt of
CmmAssign reg src
-> do src' <- cmmExprConFold DataReference src
return $ case src' of
- CmmReg reg' | reg == reg' -> CmmNop
+ CmmReg reg' | reg == reg' -> CmmComment (fsLit "nop")
new_src -> CmmAssign reg new_src
CmmStore addr src
@@ -931,35 +937,27 @@ cmmStmtConFold stmt
src' <- cmmExprConFold DataReference src
return $ CmmStore addr' src'
- CmmJump addr live
+ CmmCall { cml_target = addr }
-> do addr' <- cmmExprConFold JumpReference addr
- return $ CmmJump addr' live
+ return $ stmt { cml_target = addr' }
- CmmCall target regs args returns
+ CmmUnsafeForeignCall target regs args
-> do target' <- case target of
- CmmCallee e conv -> do
+ ForeignTarget e conv -> do
e' <- cmmExprConFold CallReference e
- return $ CmmCallee e' conv
- op@(CmmPrim _ Nothing) ->
- return op
- CmmPrim op (Just stmts) ->
- do stmts' <- mapM cmmStmtConFold stmts
- return $ CmmPrim op (Just stmts')
- args' <- mapM (\(CmmHinted arg hint) -> do
- arg' <- cmmExprConFold DataReference arg
- return (CmmHinted arg' hint)) args
- return $ CmmCall target' regs args' returns
-
- CmmCondBranch test dest
+ return $ ForeignTarget e' conv
+ PrimTarget _ ->
+ return target
+ args' <- mapM (cmmExprConFold DataReference) args
+ return $ CmmUnsafeForeignCall target' regs args'
+
+ CmmCondBranch test true false
-> do test' <- cmmExprConFold DataReference test
dflags <- getDynFlags
return $ case test' of
- CmmLit (CmmInt 0 _) ->
- CmmComment (mkFastString ("deleted: " ++
- showSDoc dflags (pprStmt stmt)))
-
- CmmLit (CmmInt _ _) -> CmmBranch dest
- _other -> CmmCondBranch test' dest
+ CmmLit (CmmInt 0 _) -> CmmBranch false
+ CmmLit (CmmInt _ _) -> CmmBranch true
+ _other -> CmmCondBranch test' true false
CmmSwitch expr ids
-> do expr' <- cmmExprConFold DataReference expr