Peter Trommler pushed to branch wip/T26519 at Glasgow Haskell Compiler / GHC
Commits:
-
023c301c
by sheaf at 2026-01-13T04:57:30-05:00
-
d0966e64
by fendor at 2026-01-13T04:58:11-05:00
-
b324fd55
by Peter Trommler at 2026-01-13T13:28:52+01:00
4 changed files:
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
- compiler/GHC/CmmToAsm/Reg/Linear.hs
- compiler/GHC/CmmToAsm/Reg/Linear/StackMap.hs
- utils/ghc-pkg/Main.hs
Changes:
| ... | ... | @@ -467,48 +467,26 @@ getRegister' _ platform (CmmLoad mem pk _) |
| 467 | 467 | return (Any II64 code)
|
| 468 | 468 | |
| 469 | 469 | -- catch simple cases of zero- or sign-extended load
|
| 470 | -getRegister' _ _ (CmmMachOp (MO_UU_Conv W8 W32) [CmmLoad mem _ _]) = do
|
|
| 471 | - Amode addr addr_code <- getAmode D mem
|
|
| 472 | - return (Any II32 (\dst -> addr_code `snocOL` LD II8 dst addr))
|
|
| 473 | - |
|
| 474 | -getRegister' _ _ (CmmMachOp (MO_XX_Conv W8 W32) [CmmLoad mem _ _]) = do
|
|
| 475 | - Amode addr addr_code <- getAmode D mem
|
|
| 476 | - return (Any II32 (\dst -> addr_code `snocOL` LD II8 dst addr))
|
|
| 477 | - |
|
| 478 | -getRegister' _ _ (CmmMachOp (MO_UU_Conv W8 W64) [CmmLoad mem _ _]) = do
|
|
| 479 | - Amode addr addr_code <- getAmode D mem
|
|
| 480 | - return (Any II64 (\dst -> addr_code `snocOL` LD II8 dst addr))
|
|
| 481 | - |
|
| 482 | -getRegister' _ _ (CmmMachOp (MO_XX_Conv W8 W64) [CmmLoad mem _ _]) = do
|
|
| 483 | - Amode addr addr_code <- getAmode D mem
|
|
| 484 | - return (Any II64 (\dst -> addr_code `snocOL` LD II8 dst addr))
|
|
| 485 | - |
|
| 486 | --- Note: there is no Load Byte Arithmetic instruction, so no signed case here
|
|
| 487 | - |
|
| 488 | -getRegister' _ _ (CmmMachOp (MO_UU_Conv W16 W32) [CmmLoad mem _ _]) = do
|
|
| 489 | - Amode addr addr_code <- getAmode D mem
|
|
| 490 | - return (Any II32 (\dst -> addr_code `snocOL` LD II16 dst addr))
|
|
| 491 | - |
|
| 492 | -getRegister' _ _ (CmmMachOp (MO_SS_Conv W16 W32) [CmmLoad mem _ _]) = do
|
|
| 493 | - Amode addr addr_code <- getAmode D mem
|
|
| 494 | - return (Any II32 (\dst -> addr_code `snocOL` LA II16 dst addr))
|
|
| 495 | - |
|
| 496 | -getRegister' _ _ (CmmMachOp (MO_UU_Conv W16 W64) [CmmLoad mem _ _]) = do
|
|
| 497 | - Amode addr addr_code <- getAmode D mem
|
|
| 498 | - return (Any II64 (\dst -> addr_code `snocOL` LD II16 dst addr))
|
|
| 499 | - |
|
| 500 | -getRegister' _ _ (CmmMachOp (MO_SS_Conv W16 W64) [CmmLoad mem _ _]) = do
|
|
| 501 | - Amode addr addr_code <- getAmode D mem
|
|
| 502 | - return (Any II64 (\dst -> addr_code `snocOL` LA II16 dst addr))
|
|
| 503 | - |
|
| 504 | -getRegister' _ _ (CmmMachOp (MO_UU_Conv W32 W64) [CmmLoad mem _ _]) = do
|
|
| 505 | - Amode addr addr_code <- getAmode D mem
|
|
| 506 | - return (Any II64 (\dst -> addr_code `snocOL` LD II32 dst addr))
|
|
| 507 | - |
|
| 508 | -getRegister' _ _ (CmmMachOp (MO_SS_Conv W32 W64) [CmmLoad mem _ _]) = do
|
|
| 509 | - -- lwa is DS-form. See Note [Power instruction format]
|
|
| 510 | - Amode addr addr_code <- getAmode DS mem
|
|
| 511 | - return (Any II64 (\dst -> addr_code `snocOL` LA II32 dst addr))
|
|
| 470 | +getRegister' _ _ (CmmMachOp (MO_UU_Conv src tgt) [CmmLoad mem pk _])
|
|
| 471 | + | src < tgt
|
|
| 472 | + , cmmTypeFormat pk == intFormat src = loadZeroExpand mem pk tgt
|
|
| 473 | + |
|
| 474 | +getRegister' _ _ (CmmMachOp (MO_XX_Conv src tgt) [CmmLoad mem pk _])
|
|
| 475 | + | src < tgt
|
|
| 476 | + , cmmTypeFormat pk == intFormat src = loadZeroExpand mem pk tgt
|
|
| 477 | + |
|
| 478 | + -- XXX: This is ugly, refactor
|
|
| 479 | +getRegister' _ _ (CmmMachOp (MO_SS_Conv src tgt) [CmmLoad mem pk _])
|
|
| 480 | + -- Note: there is no Load Byte Arithmetic instruction
|
|
| 481 | + | cmmTypeFormat pk /= II8
|
|
| 482 | + , src < tgt = do
|
|
| 483 | + let format = cmmTypeFormat pk
|
|
| 484 | + -- lwa is DS-form. See Note [Power instruction format]
|
|
| 485 | + let form = if format >= II32 then DS else D
|
|
| 486 | + Amode addr addr_code <- getAmode form mem
|
|
| 487 | + let code dst = assert (format == intFormat src)
|
|
| 488 | + $ addr_code `snocOL` LA format dst addr
|
|
| 489 | + return (Any (intFormat tgt) code)
|
|
| 512 | 490 | |
| 513 | 491 | getRegister' config platform (CmmMachOp (MO_RelaxedRead w) [e]) =
|
| 514 | 492 | getRegister' config platform (CmmLoad e (cmmBits w) NaturallyAligned)
|
| ... | ... | @@ -789,6 +767,12 @@ extendSExpr from to x = CmmMachOp (MO_SS_Conv from to) [x] |
| 789 | 767 | extendUExpr :: Width -> Width -> CmmExpr -> CmmExpr
|
| 790 | 768 | extendUExpr from to x = CmmMachOp (MO_UU_Conv from to) [x]
|
| 791 | 769 | |
| 770 | +loadZeroExpand :: CmmExpr -> CmmType -> Width -> NatM Register
|
|
| 771 | +loadZeroExpand mem pk tgt = do
|
|
| 772 | + Amode addr addr_code <- getAmode D mem
|
|
| 773 | + let code dst = addr_code `snocOL` LD (cmmTypeFormat pk) dst addr
|
|
| 774 | + return (Any (intFormat tgt) code)
|
|
| 775 | + |
|
| 792 | 776 | -- -----------------------------------------------------------------------------
|
| 793 | 777 | -- The 'Amode' type: Memory addressing modes passed up the tree.
|
| 794 | 778 | |
| ... | ... | @@ -2448,8 +2432,8 @@ srCode width sgn instr x y = do |
| 2448 | 2432 | let op_len = max W32 width
|
| 2449 | 2433 | extend = if sgn then extendSExpr else extendUExpr
|
| 2450 | 2434 | (src1, code1) <- getSomeReg (extend width op_len x)
|
| 2451 | - (src2, code2) <- getSomeReg (extendUExpr width op_len y)
|
|
| 2452 | - -- Note: Shift amount `y` is unsigned
|
|
| 2435 | + (src2, code2) <- getSomeReg y
|
|
| 2436 | + |
|
| 2453 | 2437 | let code dst = code1 `appOL` code2 `snocOL`
|
| 2454 | 2438 | instr (intFormat op_len) dst src1 (RIReg src2)
|
| 2455 | 2439 | return (Any (intFormat width) code)
|
| ... | ... | @@ -406,7 +406,7 @@ linearRA block_live block_id = go [] [] |
| 406 | 406 | -- | Do allocation for a single instruction.
|
| 407 | 407 | raInsn
|
| 408 | 408 | :: OutputableRegConstraint freeRegs instr
|
| 409 | - => BlockMap Regs -- ^ map of what vregs are love on entry to each block.
|
|
| 409 | + => BlockMap Regs -- ^ map of what vregs are live on entry to each block.
|
|
| 410 | 410 | -> [instr] -- ^ accumulator for instructions already processed.
|
| 411 | 411 | -> BlockId -- ^ the id of the current block, for debugging
|
| 412 | 412 | -> LiveInstr instr -- ^ the instr to have its regs allocated, with liveness info.
|
| ... | ... | @@ -37,7 +37,11 @@ data StackMap |
| 37 | 37 | |
| 38 | 38 | -- See Note [UniqFM and the register allocator]
|
| 39 | 39 | -- | Assignment of vregs to stack slots.
|
| 40 | - , stackMapAssignment :: UniqFM Unique StackSlot }
|
|
| 40 | + --
|
|
| 41 | + -- We record not just the slot, but also how many stack slots the vreg
|
|
| 42 | + -- takes up, in order to avoid re-using a stack slot for a register
|
|
| 43 | + -- that has grown but already had a stack slot (#26668).
|
|
| 44 | + , stackMapAssignment :: UniqFM Unique (StackSlot, Int) }
|
|
| 41 | 45 | |
| 42 | 46 | |
| 43 | 47 | -- | An empty stack map, with all slots available.
|
| ... | ... | @@ -50,14 +54,19 @@ emptyStackMap = StackMap 0 emptyUFM |
| 50 | 54 | --
|
| 51 | 55 | getStackSlotFor :: StackMap -> Format -> Unique -> (StackMap, Int)
|
| 52 | 56 | |
| 53 | -getStackSlotFor fs@(StackMap _ reserved) _fmt regUnique
|
|
| 54 | - | Just slot <- lookupUFM reserved regUnique = (fs, slot)
|
|
| 55 | - |
|
| 56 | -getStackSlotFor (StackMap freeSlot reserved) fmt regUnique =
|
|
| 57 | - let
|
|
| 58 | - nbSlots = (formatInBytes fmt + 7) `div` 8
|
|
| 59 | - in
|
|
| 60 | - (StackMap (freeSlot+nbSlots) (addToUFM reserved regUnique freeSlot), freeSlot)
|
|
| 57 | +getStackSlotFor fs@(StackMap freeSlot reserved) fmt regUnique
|
|
| 58 | + -- The register already has a stack slot; try to re-use it.
|
|
| 59 | + | Just (slot, nbSlots) <- lookupUFM reserved regUnique
|
|
| 60 | + -- Make sure the slot is big enough for this format, in case the register
|
|
| 61 | + -- has grown (#26668).
|
|
| 62 | + , nbNeededSlots <= nbSlots
|
|
| 63 | + = (fs, slot)
|
|
| 64 | + | otherwise
|
|
| 65 | + = (StackMap (freeSlot+nbNeededSlots) (addToUFM reserved regUnique (freeSlot, nbNeededSlots)), freeSlot)
|
|
| 66 | + -- NB: this can create fragmentation if a register keeps growing.
|
|
| 67 | + -- That's probably OK, as this is only happens very rarely.
|
|
| 68 | + where
|
|
| 69 | + !nbNeededSlots = (formatInBytes fmt + 7) `div` 8
|
|
| 61 | 70 | |
| 62 | 71 | -- | Return the number of stack slots that were allocated
|
| 63 | 72 | getStackUse :: StackMap -> Int
|
| ... | ... | @@ -23,7 +23,6 @@ |
| 23 | 23 | |
| 24 | 24 | module Main (main) where
|
| 25 | 25 | |
| 26 | -import Debug.Trace
|
|
| 27 | 26 | import qualified GHC.Unit.Database as GhcPkg
|
| 28 | 27 | import GHC.Unit.Database hiding (mkMungePathUrl)
|
| 29 | 28 | import GHC.HandleEncoding
|
| ... | ... | @@ -1634,7 +1633,7 @@ listPackages verbosity my_flags mPackageName mModuleName = do |
| 1634 | 1633 | simplePackageList :: [Flag] -> [InstalledPackageInfo] -> IO ()
|
| 1635 | 1634 | simplePackageList my_flags pkgs = do
|
| 1636 | 1635 | let showPkg :: InstalledPackageInfo -> String
|
| 1637 | - showPkg | FlagShowUnitIds `elem` my_flags = traceId . display . installedUnitId
|
|
| 1636 | + showPkg | FlagShowUnitIds `elem` my_flags = display . installedUnitId
|
|
| 1638 | 1637 | | FlagNamesOnly `elem` my_flags = display . mungedName . mungedId
|
| 1639 | 1638 | | otherwise = display . mungedId
|
| 1640 | 1639 | strs = map showPkg pkgs
|