Commit 5748c79e authored by Andreas Klebinger's avatar Andreas Klebinger Committed by Ben Gamari

Change jump targets in JMP_TBL from blocks to X86.JumpDest.

Jump tables always point to blocks when we first generate them.  However
there are rare situations where we can shortcut one of these blocks to a
static address during the asm shortcutting pass.

While we already updated the data section accordingly this patch also
extends this to the references stored in JMP_TBL.

Test Plan: ci

Reviewers: bgamari

Reviewed By: bgamari

Subscribers: thomie, carter

GHC Trac Issues: #15104

Differential Revision: https://phabricator.haskell.org/D4595
parent b592bd98
...@@ -2857,11 +2857,16 @@ genSwitch dflags expr targets ...@@ -2857,11 +2857,16 @@ genSwitch dflags expr targets
JMP_TBL op ids (Section ReadOnlyData lbl) lbl JMP_TBL op ids (Section ReadOnlyData lbl) lbl
] ]
return code return code
where (offset, ids) = switchTargetsToTable targets where
(offset, blockIds) = switchTargetsToTable targets
ids = map (fmap DestBlockId) blockIds
generateJumpTableForInstr :: DynFlags -> Instr -> Maybe (NatCmmDecl (Alignment, CmmStatics) Instr) generateJumpTableForInstr :: DynFlags -> Instr -> Maybe (NatCmmDecl (Alignment, CmmStatics) Instr)
generateJumpTableForInstr dflags (JMP_TBL _ ids section lbl) generateJumpTableForInstr dflags (JMP_TBL _ ids section lbl)
= Just (createJumpTable dflags ids section lbl) = let getBlockId (DestBlockId id) = id
getBlockId _ = panic "Non-Label target in Jump Table"
blockIds = map (fmap getBlockId) ids
in Just (createJumpTable dflags blockIds section lbl)
generateJumpTableForInstr _ _ = Nothing generateJumpTableForInstr _ _ = Nothing
createJumpTable :: DynFlags -> [Maybe BlockId] -> Section -> CLabel createJumpTable :: DynFlags -> [Maybe BlockId] -> Section -> CLabel
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
-- --
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module X86.Instr (Instr(..), Operand(..), PrefetchVariant(..), JumpDest, module X86.Instr (Instr(..), Operand(..), PrefetchVariant(..), JumpDest(..),
getJumpDestBlockId, canShortcut, shortcutStatics, getJumpDestBlockId, canShortcut, shortcutStatics,
shortcutJump, i386_insert_ffrees, allocMoreStack, shortcutJump, i386_insert_ffrees, allocMoreStack,
maxSpillSlots, archWordFormat) maxSpillSlots, archWordFormat)
...@@ -322,7 +322,7 @@ data Instr ...@@ -322,7 +322,7 @@ data Instr
| JXX_GBL Cond Imm -- non-local version of JXX | JXX_GBL Cond Imm -- non-local version of JXX
-- Table jump -- Table jump
| JMP_TBL Operand -- Address to jump to | JMP_TBL Operand -- Address to jump to
[Maybe BlockId] -- Blocks in the jump table [Maybe JumpDest] -- Targets of the jump table
Section -- Data section jump table should be put in Section -- Data section jump table should be put in
CLabel -- Label of jump table CLabel -- Label of jump table
| CALL (Either Imm Reg) [Reg] | CALL (Either Imm Reg) [Reg]
...@@ -704,7 +704,7 @@ x86_jumpDestsOfInstr ...@@ -704,7 +704,7 @@ x86_jumpDestsOfInstr
x86_jumpDestsOfInstr insn x86_jumpDestsOfInstr insn
= case insn of = case insn of
JXX _ id -> [id] JXX _ id -> [id]
JMP_TBL _ ids _ _ -> [id | Just id <- ids] JMP_TBL _ ids _ _ -> [id | Just (DestBlockId id) <- ids]
_ -> [] _ -> []
...@@ -715,8 +715,12 @@ x86_patchJumpInstr insn patchF ...@@ -715,8 +715,12 @@ x86_patchJumpInstr insn patchF
= case insn of = case insn of
JXX cc id -> JXX cc (patchF id) JXX cc id -> JXX cc (patchF id)
JMP_TBL op ids section lbl JMP_TBL op ids section lbl
-> JMP_TBL op (map (fmap patchF) ids) section lbl -> JMP_TBL op (map (fmap (patchJumpDest patchF)) ids) section lbl
_ -> insn _ -> insn
where
patchJumpDest f (DestBlockId id) = DestBlockId (f id)
patchJumpDest _ dest = dest
...@@ -1036,13 +1040,11 @@ shortcutJump fn insn = shortcutJump' fn (setEmpty :: LabelSet) insn ...@@ -1036,13 +1040,11 @@ shortcutJump fn insn = shortcutJump' fn (setEmpty :: LabelSet) insn
Just (DestImm imm) -> shortcutJump' fn seen' (JXX_GBL cc imm) Just (DestImm imm) -> shortcutJump' fn seen' (JXX_GBL cc imm)
where seen' = setInsert id seen where seen' = setInsert id seen
shortcutJump' fn _ (JMP_TBL addr blocks section tblId) = shortcutJump' fn _ (JMP_TBL addr blocks section tblId) =
let updateBlock Nothing = Nothing let updateBlock (Just (DestBlockId bid)) =
updateBlock (Just bid) =
case fn bid of case fn bid of
Nothing -> Just bid Nothing -> Just (DestBlockId bid )
Just (DestBlockId bid') -> Just bid' Just dest -> Just dest
Just (DestImm _) -> updateBlock dest = dest
panic "Can't shortcut jump table to immediate"
blocks' = map updateBlock blocks blocks' = map updateBlock blocks
in JMP_TBL addr blocks' section tblId in JMP_TBL addr blocks' section tblId
shortcutJump' _ _ other = other shortcutJump' _ _ other = other
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment