diff options
author | Andreas Klebinger <klebinger.andreas@gmx.at> | 2018-04-13 11:32:23 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-04-13 11:33:09 -0400 |
commit | 120a261773d3da7ef81d1ba9e41733afbadefe1d (patch) | |
tree | 7af80db23503ecfd5e2f8db6b4ecaa5ace09b12e /compiler/nativeGen/X86/Instr.hs | |
parent | a303584e58b3f4791bc5881cb722e7f498e14554 (diff) | |
download | haskell-120a261773d3da7ef81d1ba9e41733afbadefe1d.tar.gz |
Update JMP_TBL targets during shortcutting in X86 NCG.
Without updating the JMP_TBL information the block list in
JMP_TBL contained blocks which were eliminated in some circumstances.
The actual assembly generation doesn't look at these fields so this
didn't cause any bugs yet. However as long as we carry this information
around we should make an effort to keep it correct.
Especially since it's useful for debugging purposes and can be used
for passes near the end of the codegen pipeline.
In particular it's used by jumpDestsOfInstr which without these changes
returns the wrong destinations.
Test Plan: ci
Reviewers: bgamari
Subscribers: thomie, carter
Differential Revision: https://phabricator.haskell.org/D4566
Diffstat (limited to 'compiler/nativeGen/X86/Instr.hs')
-rw-r--r-- | compiler/nativeGen/X86/Instr.hs | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/compiler/nativeGen/X86/Instr.hs b/compiler/nativeGen/X86/Instr.hs index f4f625b4a5..49beafa1ff 100644 --- a/compiler/nativeGen/X86/Instr.hs +++ b/compiler/nativeGen/X86/Instr.hs @@ -1026,14 +1026,26 @@ canShortcut _ = Nothing -- The blockset helps avoid following cycles. shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr shortcutJump fn insn = shortcutJump' fn (setEmpty :: LabelSet) insn - where shortcutJump' fn seen insn@(JXX cc id) = - if setMember id seen then insn - else case fn id of - Nothing -> insn - Just (DestBlockId id') -> shortcutJump' fn seen' (JXX cc id') - Just (DestImm imm) -> shortcutJump' fn seen' (JXX_GBL cc imm) - where seen' = setInsert id seen - shortcutJump' _ _ other = other + where + shortcutJump' :: (BlockId -> Maybe JumpDest) -> LabelSet -> Instr -> Instr + shortcutJump' fn seen insn@(JXX cc id) = + if setMember id seen then insn + else case fn id of + Nothing -> insn + Just (DestBlockId id') -> shortcutJump' fn seen' (JXX cc id') + Just (DestImm imm) -> shortcutJump' fn seen' (JXX_GBL cc imm) + where seen' = setInsert id seen + shortcutJump' fn _ (JMP_TBL addr blocks section tblId) = + let updateBlock Nothing = Nothing + updateBlock (Just bid) = + case fn bid of + Nothing -> Just bid + Just (DestBlockId bid') -> Just bid' + Just (DestImm _) -> + panic "Can't shortcut jump table to immediate" + blocks' = map updateBlock blocks + in JMP_TBL addr blocks' section tblId + shortcutJump' _ _ other = other -- Here because it knows about JumpDest shortcutStatics :: (BlockId -> Maybe JumpDest) -> (Alignment, CmmStatics) -> (Alignment, CmmStatics) |