Eliminate more dead reg->reg moves in linear allocator
[ghc-hetmet.git] / compiler / nativeGen / RegAllocInfo.hs
index d526641..4cb688a 100644 (file)
@@ -17,6 +17,8 @@ module RegAllocInfo (
        patchJump,
        isRegRegMove,
 
+        JumpDest, canShortcut, shortcutJump, shortcutStatic,
+
        maxSpillSlots,
        mkSpillInstr,
        mkLoadInstr,
@@ -26,7 +28,8 @@ module RegAllocInfo (
 
 #include "HsVersions.h"
 
-import Cmm             ( BlockId )
+import Cmm
+import CLabel
 import MachOp           ( MachRep(..), wordRep )
 import MachInstrs
 import MachRegs
@@ -172,6 +175,7 @@ regUsage instr = case instr of
     CMP    sz src dst  -> mkRUR (use_R src ++ use_R dst)
     SETCC  cond op     -> mkRU [] (def_W op)
     JXX    cond lbl    -> mkRU [] []
+    JXX_GBL cond lbl   -> mkRU [] []
     JMP    op          -> mkRUR (use_R op)
     JMP_TBL op ids      -> mkRUR (use_R op)
     CALL (Left imm)  params -> mkRU params callClobberedRegs
@@ -210,8 +214,8 @@ regUsage instr = case instr of
 #if x86_64_TARGET_ARCH
     CVTSS2SD src dst   -> mkRU [src] [dst]
     CVTSD2SS src dst   -> mkRU [src] [dst]
-    CVTSS2SI src dst   -> mkRU (use_R src) [dst]
-    CVTSD2SI src dst   -> mkRU (use_R src) [dst]
+    CVTTSS2SIQ src dst -> mkRU (use_R src) [dst]
+    CVTTSD2SIQ src dst -> mkRU (use_R src) [dst]
     CVTSI2SS src dst   -> mkRU (use_R src) [dst]
     CVTSI2SD src dst   -> mkRU (use_R src) [dst]
     FDIV sz src dst     -> usageRM src dst
@@ -333,6 +337,7 @@ regUsage instr = case instr of
     CMP   sz reg ri    -> usage (reg : regRI ri,[])
     CMPL  sz reg ri    -> usage (reg : regRI ri,[])
     BCC          cond lbl      -> noUsage
+    BCCFAR cond lbl    -> noUsage
     MTCTR reg          -> usage ([reg],[])
     BCTR  targets      -> noUsage
     BL    imm params   -> usage (params, callClobberedRegs)
@@ -397,6 +402,7 @@ jumpDests insn acc
        JMP_TBL _ ids   -> ids ++ acc
 #elif powerpc_TARGET_ARCH
         BCC _ id        -> id : acc
+        BCCFAR _ id     -> id : acc
         BCTR targets    -> targets ++ acc
 #endif
        _other          -> acc
@@ -410,10 +416,50 @@ patchJump insn old new
        JMP_TBL op ids -> error "Cannot patch JMP_TBL"
 #elif powerpc_TARGET_ARCH
         BCC cc id | id == old -> BCC cc new
+        BCCFAR cc id | id == old -> BCCFAR cc new
         BCTR targets -> error "Cannot patch BCTR"
 #endif
        _other          -> insn
 
+data JumpDest = DestBlockId BlockId | DestImm Imm
+
+canShortcut :: Instr -> Maybe JumpDest
+#if i386_TARGET_ARCH || x86_64_TARGET_ARCH
+canShortcut (JXX ALWAYS id) = Just (DestBlockId id)
+canShortcut (JMP (OpImm imm)) = Just (DestImm imm)
+#endif
+canShortcut _ = Nothing
+
+shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
+#if i386_TARGET_ARCH || x86_64_TARGET_ARCH
+shortcutJump fn insn@(JXX cc id) = 
+  case fn id of
+    Nothing                -> insn
+    Just (DestBlockId id') -> shortcutJump fn (JXX cc id')
+    Just (DestImm imm)     -> shortcutJump fn (JXX_GBL cc imm)
+#endif
+shortcutJump fn other = other
+
+-- Here because it knows about JumpDest
+shortcutStatic :: (BlockId -> Maybe JumpDest) -> CmmStatic -> CmmStatic
+shortcutStatic fn (CmmStaticLit (CmmLabel lab))
+  | Just uq <- maybeAsmTemp lab 
+  = CmmStaticLit (CmmLabel (shortBlockId fn (BlockId uq)))
+shortcutStatic fn (CmmStaticLit (CmmLabelDiffOff lbl1 lbl2 off))
+  | Just uq <- maybeAsmTemp lbl1
+  = CmmStaticLit (CmmLabelDiffOff (shortBlockId fn (BlockId uq)) lbl2 off)
+        -- slightly dodgy, we're ignoring the second label, but this
+        -- works with the way we use CmmLabelDiffOff for jump tables now.
+shortcutStatic fn other_static
+        = other_static
+
+shortBlockId fn blockid@(BlockId uq) =
+   case fn blockid of
+      Nothing -> mkAsmTempLabel uq
+      Just (DestBlockId blockid')  -> shortBlockId fn blockid'
+      Just (DestImm (ImmCLbl lbl)) -> lbl
+      _other -> panic "shortBlockId"
+
 -- -----------------------------------------------------------------------------
 -- 'patchRegs' function
 
@@ -542,8 +588,8 @@ patchRegs instr env = case instr of
 #if x86_64_TARGET_ARCH
     CVTSS2SD src dst   -> CVTSS2SD (env src) (env dst)
     CVTSD2SS src dst   -> CVTSD2SS (env src) (env dst)
-    CVTSS2SI src dst   -> CVTSS2SI (patchOp src) (env dst)
-    CVTSD2SI src dst   -> CVTSD2SI (patchOp src) (env dst)
+    CVTTSS2SIQ src dst -> CVTTSS2SIQ (patchOp src) (env dst)
+    CVTTSD2SIQ src dst -> CVTTSD2SIQ (patchOp src) (env dst)
     CVTSI2SS src dst   -> CVTSI2SS (patchOp src) (env dst)
     CVTSI2SD src dst   -> CVTSI2SD (patchOp src) (env dst)
     FDIV sz src dst    -> FDIV sz (patchOp src) (patchOp dst)
@@ -559,6 +605,7 @@ patchRegs instr env = case instr of
     COMMENT _          -> instr
     DELTA _            -> instr
     JXX _ _            -> instr
+    JXX_GBL _ _                -> instr
     CLTD _             -> instr
 
     _other             -> panic "patchRegs: unrecognised instr"
@@ -640,6 +687,7 @@ patchRegs instr env = case instr of
     CMP          sz reg ri     -> CMP sz (env reg) (fixRI ri)
     CMPL  sz reg ri    -> CMPL sz (env reg) (fixRI ri)
     BCC          cond lbl      -> BCC cond lbl
+    BCCFAR cond lbl    -> BCCFAR cond lbl
     MTCTR reg          -> MTCTR (env reg)
     BCTR  targets      -> BCTR targets
     BL    imm argRegs  -> BL imm argRegs       -- argument regs
@@ -712,8 +760,8 @@ mkSpillInstr
    -> Int              -- spill slot to use
    -> Instr
 mkSpillInstr reg delta slot
-  = ASSERT(isRealReg reg)
-    let        
+ -- = ASSERT(isRealReg reg)                    -- BUGS: used for graph coloring: is this ok?
+  = let        
         off     = spillSlotToOffset slot
     in
 #ifdef alpha_TARGET_ARCH
@@ -757,8 +805,8 @@ mkLoadInstr
    -> Int              -- spill slot to use
    -> Instr
 mkLoadInstr reg delta slot
-  = ASSERT(isRealReg reg)
-    let
+ -- = ASSERT(isRealReg reg)                    -- BUGS: used for graph coloring: is this ok?
+  = let
         off     = spillSlotToOffset slot
     in
 #if alpha_TARGET_ARCH
@@ -843,4 +891,5 @@ spillSlotToOffset slot
    = 64 + spillSlotSize * slot
    | otherwise
    = pprPanic "spillSlotToOffset:" 
-              (text "invalid spill location: " <> int slot)
+              (   text "invalid spill location: " <> int slot
+             $$  text "maxSpillSlots:          " <> int maxSpillSlots)