Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

15 changed files:

Changes:

  • compiler/GHC/CmmToAsm/LA64/CodeGen.hs
    ... ... @@ -57,6 +57,12 @@ import Control.Monad
    57 57
     import GHC.Cmm.Dataflow.Label
    
    58 58
     import GHC.Types.Unique.DSM
    
    59 59
     import GHC.Types.Literal.Floating
    
    60
    +import GHC.Unit.Types ( ghcInternalUnitId )
    
    61
    +
    
    62
    +la664Enabled :: NatM Bool
    
    63
    +la664Enabled = do
    
    64
    +  config <- getConfig
    
    65
    +  return (ncgLa664Enabled config)
    
    60 66
     
    
    61 67
     -- [General layout of an NCG]
    
    62 68
     cmmTopCodeGen ::
    
    ... ... @@ -1651,6 +1657,10 @@ genPrim (MO_Prefetch_Data _n) [] [_] = return nilOL
    1651 1657
     genPrim (MO_AtomicRead w mo)  [dst]  [addr]         = genAtomicRead w mo dst addr
    
    1652 1658
     genPrim (MO_AtomicWrite w mo) []     [addr,val]     = genAtomicWrite w mo addr val
    
    1653 1659
     
    
    1660
    +genPrim (MO_AtomicRMW width amop)    [dst] [addr,n] = genLibCCall (atomicRMWLabel width amop) [dst] [addr,n]
    
    1661
    +genPrim (MO_Cmpxchg width)   [dst]   [addr,expe,new]  = genCmpxchg width dst addr expe new
    
    1662
    +genPrim (MO_Xchg width)      [dst]   [addr,value]     = genXchg width dst addr value
    
    1663
    +
    
    1654 1664
     genPrim mop@(MO_S_Mul2     _w) _         _          = unsupported mop
    
    1655 1665
     genPrim mop@(MO_S_QuotRem  _w) _         _          = unsupported mop
    
    1656 1666
     genPrim mop@(MO_U_QuotRem  _w) _         _          = unsupported mop
    
    ... ... @@ -1674,9 +1684,6 @@ genPrim (MO_PopCnt width) [dst] [src] = genLibCCall (popCntLabel w
    1674 1684
     genPrim (MO_Pdep width)      [dst]   [src,mask]     = genLibCCall (pdepLabel width) [dst] [src,mask]
    
    1675 1685
     genPrim (MO_Pext width)      [dst]   [src,mask]     = genLibCCall (pextLabel width) [dst] [src,mask]
    
    1676 1686
     genPrim (MO_UF_Conv width)   [dst]   [src]          = genLibCCall (word2FloatLabel width) [dst] [src]
    
    1677
    -genPrim (MO_AtomicRMW width amop)    [dst] [addr,n] = genLibCCall (atomicRMWLabel width amop) [dst] [addr,n]
    
    1678
    -genPrim (MO_Cmpxchg width)   [dst]   [addr,old,new] = genLibCCall (cmpxchgLabel width) [dst] [addr,old,new]
    
    1679
    -genPrim (MO_Xchg width)      [dst]   [addr,val]     = genLibCCall (xchgLabel width) [dst] [addr,val]
    
    1680 1687
     genPrim (MO_Memcpy _align)   []   [dst,src,n]       = genLibCCall (fsLit "memcpy")  [] [dst,src,n]
    
    1681 1688
     genPrim (MO_Memmove _align)  []   [dst,src,n]       = genLibCCall (fsLit "memmove") [] [dst,src,n]
    
    1682 1689
     genPrim (MO_Memcmp _align)   [rst]   [dst,src,n]    = genLibCCall (fsLit "memcmp")  [rst] [dst,src,n]
    
    ... ... @@ -1872,6 +1879,20 @@ genBitRev w dst src = do
    1872 1879
                  )
    
    1873 1880
         _ -> return ( code_x `snocOL` BITREV (OpReg w dst_reg) (OpReg w reg_x))
    
    1874 1881
     
    
    1882
    +genPrimCCall
    
    1883
    +  :: FastString
    
    1884
    +  -> [CmmFormal]
    
    1885
    +  -> [CmmActual]
    
    1886
    +  -> NatM InstrBlock
    
    1887
    +
    
    1888
    +genPrimCCall name dsts args = do
    
    1889
    +  config <- getConfig
    
    1890
    +  target <-
    
    1891
    +    cmmMakeDynamicReference config CallReference
    
    1892
    +      $ mkCmmCodeLabel ghcInternalUnitId name
    
    1893
    +  let cconv = ForeignConvention CCallConv [NoHint] [NoHint] CmmMayReturn
    
    1894
    +  genCCall target cconv dsts args
    
    1895
    +
    
    1875 1896
     -- Generate C call to the given function in libc
    
    1876 1897
     genLibCCall :: FastString -> [CmmFormal] -> [CmmActual] -> NatM InstrBlock
    
    1877 1898
     genLibCCall name dsts args = do
    
    ... ... @@ -1945,6 +1966,52 @@ genAtomicWrite w mo addr val = do
    1945 1966
                  )
    
    1946 1967
         _ ->  panic $ "Unexpected MemOrderAcquire on an AtomicWrite" ++ show mo
    
    1947 1968
     
    
    1969
    +genCmpxchg :: Width -> LocalReg -> CmmExpr -> CmmExpr -> CmmExpr -> NatM InstrBlock
    
    1970
    +genCmpxchg w dst addr expe new = do
    
    1971
    +  config <- getConfig
    
    1972
    +  let
    
    1973
    +    platform = ncgPlatform config
    
    1974
    +    format = intFormat w
    
    1975
    +
    
    1976
    +  la664Enabled >>= \case
    
    1977
    +
    
    1978
    +    True -> do
    
    1979
    +      (addr_reg, _, code_addr) <- getSomeReg addr
    
    1980
    +      (expe_reg, _, code_expe) <- getSomeReg expe
    
    1981
    +      (new_reg, _, code_new) <- getSomeReg new
    
    1982
    +      let dst_reg = getRegisterReg platform (CmmLocal dst)
    
    1983
    +      return $ code_addr `appOL` code_expe `appOL` code_new `appOL` toOL
    
    1984
    +        [
    
    1985
    +          -- Behave like the GCC builtin CAS operation
    
    1986
    +          AMCASDB format (OpReg w expe_reg) (OpReg w new_reg) (OpReg w addr_reg),
    
    1987
    +          MOV (OpReg w dst_reg) (OpReg w expe_reg)
    
    1988
    +        ]
    
    1989
    +
    
    1990
    +    False ->
    
    1991
    +      genPrimCCall (cmpxchgLabel w) [dst] [addr,expe,new]
    
    1992
    +
    
    1993
    +genXchg :: Width -> LocalReg -> CmmExpr -> CmmExpr -> NatM InstrBlock
    
    1994
    +genXchg w dst addr val = do
    
    1995
    +  config <- getConfig
    
    1996
    +  tmp <- getNewRegNat II64
    
    1997
    +  let
    
    1998
    +    platform = ncgPlatform config
    
    1999
    +    format = intFormat w
    
    2000
    +
    
    2001
    +  la664Enabled >>= \case
    
    2002
    +
    
    2003
    +    True -> do
    
    2004
    +      (addr_reg, _, code_addr) <- getSomeReg addr
    
    2005
    +      (val_reg, _, code_val) <- getSomeReg val
    
    2006
    +      let dst_reg = getRegisterReg platform (CmmLocal dst)
    
    2007
    +      return $ code_addr `appOL` code_val `appOL` toOL
    
    2008
    +        [
    
    2009
    +          AMSWAPDB format (OpReg w tmp) (OpReg w val_reg) (OpReg w addr_reg),
    
    2010
    +          MOV (OpReg W64 dst_reg) (OpReg W64 tmp)
    
    2011
    +        ]
    
    2012
    +    False ->
    
    2013
    +      genPrimCCall (xchgLabel w) [dst] [addr,val]
    
    2014
    +
    
    1948 2015
     -- -----------------------------------------------------------------------------
    
    1949 2016
     {-
    
    1950 2017
     Generating C calls
    
    ... ... @@ -1977,6 +2044,7 @@ member of a structure or union argument, or a vector/floating-point argument
    1977 2044
     wider than FRLEN may be passed in a GAR.
    
    1978 2045
     -}
    
    1979 2046
     
    
    2047
    +-- Generate C call to the given function in ghc-prim
    
    1980 2048
     genCCall
    
    1981 2049
       :: CmmExpr            -- address of func call
    
    1982 2050
       -> ForeignConvention  -- calling convention
    

  • compiler/GHC/CmmToAsm/LA64/Instr.hs
    ... ... @@ -150,10 +150,11 @@ regUsageOfInstr platform instr = case instr of
    150 150
       -- ranges, corresponding to 2 and 1 instruction implementations respectively.
    
    151 151
       --
    
    152 152
       -- BCOND1 is selected by default.
    
    153
    -  BCOND1 _ j d t           -> usage (regTarget t ++ regOp j ++ regOp d, [])
    
    154
    -  BCOND _ j d t            -> usage (regTarget t ++ regOp j ++ regOp d, [])
    
    155
    -  BEQZ j t                 -> usage (regTarget t ++ regOp j, [])
    
    156
    -  BNEZ j t                 -> usage (regTarget t ++ regOp j, [])
    
    153
    +  BCOND1 _ j d t        -> usage (regTarget t ++ regOp j ++ regOp d, [])
    
    154
    +  BCOND _ j d t         -> usage (regTarget t ++ regOp j ++ regOp d, [])
    
    155
    +  BEQZ1 o1 o2           -> usage (regOp o1 ++ regOp o2, [])
    
    156
    +  BEQZ j t              -> usage (regTarget t ++ regOp j, [])
    
    157
    +  BNEZ j t              -> usage (regTarget t ++ regOp j, [])
    
    157 158
       -- 5. Common Memory Access Instructions --------------------------------------
    
    158 159
       LD _ dst src             -> usage (regOp src, regOp dst)
    
    159 160
       LDU _ dst src            -> usage (regOp src, regOp dst)
    
    ... ... @@ -168,7 +169,17 @@ regUsageOfInstr platform instr = case instr of
    168 169
       -- LDCOND dst src1 src2     -> usage (regOp src1 ++ regOp src2, regOp dst)
    
    169 170
       -- STCOND dst src1 src2     -> usage (regOp src1 ++ regOp src2, regOp dst)
    
    170 171
       -- 7. Atomic Memory Access Instructions --------------------------------------
    
    172
    +  -- In LoongArch, if the AM* atomic memory access instruction has the same register number as rd and rj,
    
    173
    +  -- the execution will trigger an Instruction Non-defined Exception. Here should be avoided.
    
    171 174
       AMSWAPDB _ dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
    
    175
    +  AMADDDB  _ dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
    
    176
    +  AMANDDB  _ dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
    
    177
    +  AMORDB   _ dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
    
    178
    +  AMXORDB  _ dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
    
    179
    +  --AMCASDB  _ dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp src1 ++ regOp src2 ++ regOp dst)
    
    180
    +  AMCASDB  _ dst src1 src2 -> usage (regOp dst ++ regOp src1 ++ regOp src2, regOp dst)
    
    181
    +  LL  _ dst src1 _ -> usage (regOp src1, regOp dst)
    
    182
    +  SC  _ dst src1 _ -> usage (regOp src1, regOp dst)
    
    172 183
       -- 8. Barrier Instructions ---------------------------------------------------
    
    173 184
       DBAR _hint               -> usage ([], [])
    
    174 185
       IBAR _hint               -> usage ([], [])
    
    ... ... @@ -330,6 +341,7 @@ patchRegsOfInstr instr env = case instr of
    330 341
         TAIL36 r t     -> TAIL36 (patchOp r) (patchTarget t)
    
    331 342
         BCOND1 c j d t -> BCOND1 c (patchOp j) (patchOp d) (patchTarget t)
    
    332 343
         BCOND c j d t  -> BCOND c (patchOp j) (patchOp d) (patchTarget t)
    
    344
    +    BEQZ1 o1 o2    -> BEQZ1 (patchOp o1) (patchOp o2)
    
    333 345
         BEQZ j t       -> BEQZ (patchOp j) (patchTarget t)
    
    334 346
         BNEZ j t       -> BNEZ (patchOp j) (patchTarget t)
    
    335 347
         -- 5. Common Memory Access Instructions --------------------------------------
    
    ... ... @@ -348,6 +360,13 @@ patchRegsOfInstr instr env = case instr of
    348 360
         -- STCOND o1 o2 o3       -> STCOND  (patchOp o1)  (patchOp o2)  (patchOp o3)
    
    349 361
         -- 7. Atomic Memory Access Instructions --------------------------------------
    
    350 362
         AMSWAPDB f o1 o2 o3 -> AMSWAPDB f (patchOp o1) (patchOp o2) (patchOp o3)
    
    363
    +    AMADDDB f o1 o2 o3  -> AMADDDB f (patchOp o1) (patchOp o2) (patchOp o3)
    
    364
    +    AMANDDB f o1 o2 o3  -> AMANDDB f (patchOp o1) (patchOp o2) (patchOp o3)
    
    365
    +    AMORDB f o1 o2 o3   -> AMORDB f (patchOp o1) (patchOp o2) (patchOp o3)
    
    366
    +    AMXORDB f o1 o2 o3  -> AMXORDB f (patchOp o1) (patchOp o2) (patchOp o3)
    
    367
    +    AMCASDB f o1 o2 o3  -> AMCASDB f (patchOp o1) (patchOp o2) (patchOp o3)
    
    368
    +    LL f o1 o2 o3  -> LL f (patchOp o1) (patchOp o2) (patchOp o3)
    
    369
    +    SC f o1 o2 o3  -> SC f (patchOp o1) (patchOp o2) (patchOp o3)
    
    351 370
         -- 8. Barrier Instructions ---------------------------------------------------
    
    352 371
         DBAR o1             -> DBAR o1
    
    353 372
         IBAR o1             -> IBAR o1
    
    ... ... @@ -398,6 +417,7 @@ isJumpishInstr instr = case instr of
    398 417
       TAIL36 {} -> True
    
    399 418
       BCOND1 {} -> True
    
    400 419
       BCOND {} -> True
    
    420
    +  BEQZ1 {} -> True
    
    401 421
       BEQZ {} -> True
    
    402 422
       BNEZ {} -> True
    
    403 423
       _ -> False
    
    ... ... @@ -718,6 +738,7 @@ data Instr
    718 738
         | TAIL36 Operand Target
    
    719 739
         | BCOND1 Cond Operand Operand Target
    
    720 740
         | BCOND Cond Operand Operand Target
    
    741
    +    | BEQZ1 Operand Operand
    
    721 742
         | BEQZ Operand Target
    
    722 743
         | BNEZ Operand Target
    
    723 744
         -- 5. Common Memory Access Instructions --------------------------------------
    
    ... ... @@ -733,6 +754,13 @@ data Instr
    733 754
         -- 6. Bound Check Memory Access Instructions ---------------------------------
    
    734 755
         -- 7. Atomic Memory Access Instructions --------------------------------------
    
    735 756
         | AMSWAPDB Format Operand Operand Operand
    
    757
    +    | AMADDDB Format Operand Operand Operand
    
    758
    +    | AMANDDB Format Operand Operand Operand
    
    759
    +    | AMORDB Format Operand Operand Operand
    
    760
    +    | AMXORDB Format Operand Operand Operand
    
    761
    +    | AMCASDB Format Operand Operand Operand
    
    762
    +    | LL Format Operand Operand Operand
    
    763
    +    | SC Format Operand Operand Operand
    
    736 764
         -- 8. Barrier Instructions ---------------------------------------------------
    
    737 765
         | DBAR BarrierType
    
    738 766
         | IBAR BarrierType
    
    ... ... @@ -839,6 +867,7 @@ instrCon i =
    839 867
           TAIL36{} -> "TAIL36"
    
    840 868
           BCOND1{} -> "BCOND1"
    
    841 869
           BCOND{} -> "BCOND"
    
    870
    +      BEQZ1{} -> "BEQZ1"
    
    842 871
           BEQZ{} -> "BEQZ"
    
    843 872
           BNEZ{} -> "BNEZ"
    
    844 873
           LD{} -> "LD"
    
    ... ... @@ -851,6 +880,13 @@ instrCon i =
    851 880
           STPTR{} -> "STPTR"
    
    852 881
           PRELD{} -> "PRELD"
    
    853 882
           AMSWAPDB{} -> "AMSWAPDB"
    
    883
    +      AMADDDB{} -> "AMADDDB"
    
    884
    +      AMANDDB{} -> "AMANDDB"
    
    885
    +      AMORDB{} -> "AMORDB"
    
    886
    +      AMXORDB{} -> "AMXORDB"
    
    887
    +      AMCASDB{} -> "AMCASDB"
    
    888
    +      LL{} -> "LL"
    
    889
    +      SC{} -> "SC"
    
    854 890
           DBAR{} -> "DBAR"
    
    855 891
           IBAR{} -> "IBAR"
    
    856 892
           FCVT{} -> "FCVT"
    

  • compiler/GHC/CmmToAsm/LA64/Ppr.hs
    ... ... @@ -852,6 +852,7 @@ pprInstr platform instr = case instr of
    852 852
           line $ text "\tbgeu" <+> pprOp platform d <> comma <+> pprOp platform j <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))
    
    853 853
         UGT ->
    
    854 854
           line $ text "\tbltu" <+> pprOp platform d <> comma <+> pprOp platform j <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))
    
    855
    +
    
    855 856
         _ -> line $ text "\t" <> pprBcond c <+> pprOp platform j <> comma <+> pprOp platform d <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))
    
    856 857
     
    
    857 858
       BCOND1 _ _ _ (TLabel _) -> panic "LA64.ppr: BCOND1: No conditional branching to TLabel!"
    
    ... ... @@ -916,17 +917,18 @@ pprInstr platform instr = case instr of
    916 917
     
    
    917 918
       BCOND _ _ _ (TReg _) -> panic "LA64.ppr: BCOND: No conditional branching to registers!"
    
    918 919
     
    
    920
    +  BEQZ1 o1 o2 | isImmOp o2 -> op2 (text "\tbeqz") o1 o2
    
    919 921
       BEQZ j (TBlock bid) ->
    
    920 922
         line $ text "\tbeqz" <+> pprOp platform j <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))
    
    921 923
       BEQZ j (TLabel lbl) ->
    
    922 924
         line $ text "\tbeqz" <+> pprOp platform j <> comma <+> pprAsmLabel platform lbl
    
    923
    -  BEQZ _ (TReg _)     -> panic "LA64.ppr: BEQZ: No conditional branching to registers!"
    
    925
    +  BEQZ _ (TReg _) -> panic "LA64.ppr: BEQZ: No conditional branching to registers!"
    
    924 926
     
    
    925 927
       BNEZ j (TBlock bid) ->
    
    926 928
         line $ text "\tbnez" <+> pprOp platform j <> comma <+> pprAsmLabel platform (mkLocalBlockLabel (getUnique bid))
    
    927 929
       BNEZ j (TLabel lbl) ->
    
    928 930
         line $ text "\tbnez" <+> pprOp platform j <> comma <+> pprAsmLabel platform lbl
    
    929
    -  BNEZ _ (TReg _)     -> panic "LA64.ppr: BNEZ: No conditional branching to registers!"
    
    931
    +  BNEZ _ (TReg _) -> panic "LA64.ppr: BNEZ: No conditional branching to registers!"
    
    930 932
     
    
    931 933
       -- 5. Common Memory Access Instructions --------------------------------------
    
    932 934
         -- LD.{B[U]/H[U]/W[U]/D}, ST.{B/H/W/D}: AddrRegImm
    
    ... ... @@ -1020,8 +1022,29 @@ pprInstr platform instr = case instr of
    1020 1022
       AMSWAPDB II32 o1 o2 o3 -> op3 (text "\tamswap_db.w") o1 o2 o3
    
    1021 1023
       AMSWAPDB II64 o1 o2 o3 -> op3 (text "\tamswap_db.d") o1 o2 o3
    
    1022 1024
         -- AM.{SWAP/ADD}[_DB].{B/H}
    
    1025
    +  AMADDDB II8  o1 o2 o3 -> op3 (text "\tamadd_db.b") o1 o2 o3
    
    1026
    +  AMADDDB II16 o1 o2 o3 -> op3 (text "\tamadd_db.h") o1 o2 o3
    
    1027
    +  AMADDDB II32 o1 o2 o3 -> op3 (text "\tamadd_db.w") o1 o2 o3
    
    1028
    +  AMADDDB II64 o1 o2 o3 -> op3 (text "\tamadd_db.d") o1 o2 o3
    
    1029
    +
    
    1030
    +  AMANDDB II32 o1 o2 o3 -> op3 (text "\tamand_db.w") o1 o2 o3
    
    1031
    +  AMANDDB II64 o1 o2 o3 -> op3 (text "\tamand_db.d") o1 o2 o3
    
    1032
    +
    
    1033
    +  AMORDB II32 o1 o2 o3 -> op3 (text "\tamor_db.w") o1 o2 o3
    
    1034
    +  AMORDB II64 o1 o2 o3 -> op3 (text "\tamor_db.d") o1 o2 o3
    
    1035
    +
    
    1036
    +  AMXORDB II32 o1 o2 o3 -> op3 (text "\tamxor_db.w") o1 o2 o3
    
    1037
    +  AMXORDB II64 o1 o2 o3 -> op3 (text "\tamxor_db.d") o1 o2 o3
    
    1023 1038
         -- AMCAS[_DB].{B/H/W/D}
    
    1039
    +  AMCASDB II8  o1 o2 o3 -> op3 (text "\tamcas_db.b") o1 o2 o3
    
    1040
    +  AMCASDB II16 o1 o2 o3 -> op3 (text "\tamcas_db.h") o1 o2 o3
    
    1041
    +  AMCASDB II32 o1 o2 o3 -> op3 (text "\tamcas_db.w") o1 o2 o3
    
    1042
    +  AMCASDB II64 o1 o2 o3 -> op3 (text "\tamcas_db.d") o1 o2 o3
    
    1024 1043
         -- LL.{W/D}, SC.{W/D}
    
    1044
    +  LL II32 o1 o2 o3 -> op3 (text "\tll.w") o1 o2 o3
    
    1045
    +  SC II32 o1 o2 o3 -> op3 (text "\tsc.w") o1 o2 o3
    
    1046
    +  LL II64 o1 o2 o3 -> op3 (text "\tll.d") o1 o2 o3
    
    1047
    +  SC II64 o1 o2 o3 -> op3 (text "\tsc.d") o1 o2 o3
    
    1025 1048
         -- SC.Q
    
    1026 1049
         -- LL.ACQ.{W/D}, SC.REL.{W/D}
    
    1027 1050
       -- 8. Barrier Instructions ---------------------------------------------------
    

  • m4/fp_check_timer_create.m4 deleted
    1
    -# Check for a working timer_create().  We need a pretty detailed check
    
    2
    -# here, because there exist partially-working implementations of
    
    3
    -# timer_create() in certain versions of Linux (see bug #1933).
    
    4
    -#
    
    5
    -AC_DEFUN([FP_CHECK_TIMER_CREATE],[
    
    6
    -AC_CHECK_FUNC([timer_create],[HAVE_timer_create=yes],[HAVE_timer_create=no])
    
    7
    -
    
    8
    -if test "$HAVE_timer_create" = "yes"
    
    9
    -then
    
    10
    -  if test "$cross_compiling" = "yes"
    
    11
    -  then
    
    12
    -    # We can't test timer_create when we're cross-compiling, so we
    
    13
    -    # optimistiaclly assume that it actually works properly.
    
    14
    -    AC_DEFINE([USE_TIMER_CREATE], 1,  [Define to 1 if we can use timer_create(CLOCK_REALTIME,...)])
    
    15
    -  else
    
    16
    -  AC_CACHE_CHECK([for a working timer_create(CLOCK_REALTIME)],
    
    17
    -    [fptools_cv_timer_create_works],
    
    18
    -    [AC_TRY_RUN([
    
    19
    -#include <stdio.h>
    
    20
    -#if defined(HAVE_STDLIB_H)
    
    21
    -#include <stdlib.h>
    
    22
    -#endif
    
    23
    -#include <time.h>
    
    24
    -#if defined(HAVE_SIGNAL_H)
    
    25
    -#include <signal.h>
    
    26
    -#endif
    
    27
    -#if defined(HAVE_UNISTD_H)
    
    28
    -#include <unistd.h>
    
    29
    -#endif
    
    30
    -
    
    31
    -static volatile int tock = 0;
    
    32
    -static void handler(int i)
    
    33
    -{
    
    34
    -   tock = 1;
    
    35
    -}
    
    36
    -
    
    37
    -static void timeout(int i)
    
    38
    -{
    
    39
    -  // timer_settime() has been known to hang, so just in case
    
    40
    -  // we install a 1-second timeout (see #2257)
    
    41
    -  exit(99);
    
    42
    -}
    
    43
    -
    
    44
    -int main(int argc, char *argv[])
    
    45
    -{
    
    46
    -
    
    47
    -    struct sigevent ev;
    
    48
    -    timer_t timer;
    
    49
    -    struct itimerspec it;
    
    50
    -    struct sigaction action;
    
    51
    -    int m,n,count = 0;
    
    52
    -
    
    53
    -    ev.sigev_notify = SIGEV_SIGNAL;
    
    54
    -    ev.sigev_signo  = SIGVTALRM;
    
    55
    -
    
    56
    -    action.sa_handler = handler;
    
    57
    -    action.sa_flags = 0;
    
    58
    -    sigemptyset(&action.sa_mask);
    
    59
    -    if (sigaction(SIGVTALRM, &action, NULL) == -1) {
    
    60
    -        fprintf(stderr,"SIGVTALRM problem\n");
    
    61
    -        exit(3);
    
    62
    -    }
    
    63
    -
    
    64
    -    action.sa_handler = timeout;
    
    65
    -    action.sa_flags = 0;
    
    66
    -    sigemptyset(&action.sa_mask);
    
    67
    -    if (sigaction(SIGALRM, &action, NULL) == -1) {
    
    68
    -      fprintf(stderr,"SIGALRM problem\n");
    
    69
    -      exit(3);
    
    70
    -    }
    
    71
    -    alarm(1);
    
    72
    -
    
    73
    -    if (timer_create(CLOCK_REALTIME, &ev, &timer) != 0) {
    
    74
    -        fprintf(stderr,"No CLOCK_REALTIME timer\n");
    
    75
    -        exit(2);
    
    76
    -    }
    
    77
    -
    
    78
    -    tock = 0;
    
    79
    -
    
    80
    -    it.it_value.tv_sec = 0;
    
    81
    -    it.it_value.tv_nsec = 1000000; // 1ms
    
    82
    -    it.it_interval = it.it_value;
    
    83
    -    if (timer_settime(timer, 0, &it, NULL) != 0) {
    
    84
    -        fprintf(stderr,"settime problem\n");
    
    85
    -        exit(4);
    
    86
    -    }
    
    87
    -
    
    88
    -    // some environments have coarse scheduler/timer granularity of ~10ms and worse
    
    89
    -    usleep(100000); // 100ms
    
    90
    -
    
    91
    -    if (!tock) {
    
    92
    -        fprintf(stderr,"no CLOCK_REALTIME signal\n");
    
    93
    -        exit(5);
    
    94
    -    }
    
    95
    -
    
    96
    -    timer_delete(timer);
    
    97
    -
    
    98
    -    exit(0);
    
    99
    -}
    
    100
    -     ],
    
    101
    -     [fptools_cv_timer_create_works=yes],
    
    102
    -     [fptools_cv_timer_create_works=no])
    
    103
    -  ])
    
    104
    -case $fptools_cv_timer_create_works in
    
    105
    -    yes) AC_DEFINE([USE_TIMER_CREATE], 1,
    
    106
    -                   [Define to 1 if we can use timer_create(CLOCK_REALTIME,...)]);;
    
    107
    -esac
    
    108
    -  fi
    
    109
    -fi
    
    110
    -])

  • rts/Timer.c
    ... ... @@ -7,12 +7,14 @@
    7 7
      * ---------------------------------------------------------------------------*/
    
    8 8
     
    
    9 9
     /*
    
    10
    - * The interval timer is used for profiling and for context switching in the
    
    11
    - * threaded build.
    
    10
    + * The interval timer is used for profiling and for context switching.
    
    12 11
      *
    
    13 12
      * This file defines the platform-independent view of interval timing, relying
    
    14
    - * on platform-specific services to install and run the timers.
    
    13
    + * on platform-specific services to install and run the timers. See
    
    14
    + * posix/Ticker.c and win32/Ticker.c for the platform specific parts.
    
    15 15
      *
    
    16
    + * If you are looking for Itimer.c then you either file or one of the
    
    17
    + * platform-specific Ticker.c files.
    
    16 18
      */
    
    17 19
     
    
    18 20
     #include "rts/PosixSource.h"
    

  • rts/configure.ac
    ... ... @@ -204,7 +204,6 @@ FP_MUSTTAIL
    204 204
     
    
    205 205
     dnl ** check for librt
    
    206 206
     AC_CHECK_FUNCS(clock_gettime timer_settime)
    
    207
    -FP_CHECK_TIMER_CREATE
    
    208 207
     
    
    209 208
     dnl ** check for Apple's "interesting" long double compatibility scheme
    
    210 209
     AC_MSG_CHECKING(for printf\$LDBLStub)
    

  • rts/include/rts/Timer.h
    ... ... @@ -15,4 +15,4 @@
    15 15
     
    
    16 16
     void startTimer (void);
    
    17 17
     void stopTimer  (void);
    
    18
    -int rtsTimerSignal (void);
    18
    +int rtsTimerSignal (void); // Deprecated: see issue #27073

  • rts/include/stg/SMP.h
    ... ... @@ -21,7 +21,7 @@ void arm_atomic_spin_unlock(void);
    21 21
     // Unconditionally atomic operations
    
    22 22
     // These are atomic even in the non-threaded RTS. These are necessary in the
    
    23 23
     // Proftimer implementation, which may be called from the pthreads-based
    
    24
    -// ITimer implementation.
    
    24
    +// Ticker implementation.
    
    25 25
     #define RELAXED_LOAD_ALWAYS(ptr) __atomic_load_n(ptr, __ATOMIC_RELAXED)
    
    26 26
     #define RELAXED_STORE_ALWAYS(ptr,val) __atomic_store_n(ptr, val, __ATOMIC_RELAXED)
    
    27 27
     #define RELAXED_ADD_ALWAYS(ptr,val) __atomic_add_fetch(ptr, val, __ATOMIC_RELAXED)
    

  • rts/posix/Signals.c
    ... ... @@ -640,35 +640,6 @@ set_sigtstp_action (bool handle)
    640 640
         }
    
    641 641
     }
    
    642 642
     
    
    643
    -/* Used by ItimerTimerCreate and ItimerSetitimer implementations */
    
    644
    -void
    
    645
    -install_vtalrm_handler(int sig, TickProc handle_tick)
    
    646
    -{
    
    647
    -    struct sigaction action;
    
    648
    -    memset(&action, 0, sizeof(struct sigaction));
    
    649
    -
    
    650
    -    action.sa_handler = handle_tick;
    
    651
    -
    
    652
    -    sigemptyset(&action.sa_mask);
    
    653
    -
    
    654
    -#if defined(SA_RESTART)
    
    655
    -    // specify SA_RESTART.  One consequence if we don't do this is
    
    656
    -    // that readline gets confused by the -threaded RTS.  It seems
    
    657
    -    // that if a SIGALRM handler is installed without SA_RESTART,
    
    658
    -    // readline installs its own SIGALRM signal handler (see
    
    659
    -    // readline's signals.c), and this somehow causes readline to go
    
    660
    -    // wrong when the input exceeds a single line (try it).
    
    661
    -    action.sa_flags = SA_RESTART;
    
    662
    -#else
    
    663
    -    action.sa_flags = 0;
    
    664
    -#endif
    
    665
    -
    
    666
    -    if (sigaction(sig, &action, NULL) == -1) {
    
    667
    -        sysErrorBelch("sigaction");
    
    668
    -        stg_exit(EXIT_FAILURE);
    
    669
    -    }
    
    670
    -}
    
    671
    -
    
    672 643
     /* -----------------------------------------------------------------------------
    
    673 644
      * Install default signal handlers.
    
    674 645
      *
    

  • rts/posix/Signals.h
    ... ... @@ -25,8 +25,6 @@ extern siginfo_t *next_pending_handler;
    25 25
     void startSignalHandlers(Capability *cap);
    
    26 26
     #endif
    
    27 27
     
    
    28
    -void install_vtalrm_handler(int sig, TickProc handle_tick);
    
    29
    -
    
    30 28
     /* Communicating with the IO manager thread (see GHC.Conc).
    
    31 29
      *
    
    32 30
      * TODO: these I/O manager things are not related to signals and ought to live
    

  • rts/posix/Ticker.c
    ... ... @@ -2,116 +2,38 @@
    2 2
      *
    
    3 3
      * (c) The GHC Team, 1995-2007
    
    4 4
      *
    
    5
    - * Interval timer for profiling and pre-emptive scheduling.
    
    5
    + * Posix implementation(s) of the interval timer for profiling and pre-emptive
    
    6
    + * scheduling.
    
    6 7
      *
    
    7 8
      * ---------------------------------------------------------------------------*/
    
    8 9
     
    
    9
    -/*
    
    10
    - * The interval timer is used for profiling and for context switching in the
    
    11
    - * threaded build.  Though POSIX 1003.1b includes a standard interface for
    
    12
    - * such things, no one really seems to be implementing them yet.  Even
    
    13
    - * Solaris 2.3 only seems to provide support for @CLOCK_REAL@, whereas we're
    
    14
    - * keen on getting access to @CLOCK_VIRTUAL@.
    
    15
    - *
    
    16
    - * Hence, we often use the old-fashioned @setitimer@ that just about everyone
    
    17
    - * seems to support.  So much for standards.
    
    18
    - *
    
    19
    - * If you are looking for Itimer.c then this is the right file. I renamed it
    
    20
    - * Ticker.c for consistency.
    
    10
    +/* The interval timer is used for profiling and for context switching.
    
    11
    + * This file defines the platform-specific services to install and run the
    
    12
    + * timers, and we call this the ticker. See rts/Timer.c for the
    
    13
    + * platform-dependent view of interval timing.
    
    14
    + *
    
    15
    + * Historically we had ticker implementations using signals. This was always a
    
    16
    + * rather shakey thing to do but we had few alternatives.
    
    17
    + * - One problem with using signals is that there are severe limits on what
    
    18
    + *   code can be called from signal handlers. In particular it's not possible
    
    19
    + *   to take locks in a signal handler contex. This was enough for contex
    
    20
    + *   switching, but it's no good for things like flushing the eventlog, or
    
    21
    + *   waking up rts tasks.
    
    22
    + * - We also want to avoid using alarm signals, as these can interrupt system
    
    23
    + *   calls (#10840) or can be overwritten by user code.
    
    21 24
      */
    
    22 25
     
    
    23
    -#include "rts/PosixSource.h"
    
    24
    -
    
    25
    -/* We've defined _POSIX_SOURCE via "rts/PosixSource.h", and yet still use
    
    26
    -   some non-POSIX features.  With _POSIX_SOURCE defined, visibility of
    
    27
    -   non-POSIX extension prototypes requires _DARWIN_C_SOURCE on Mac OS X,
    
    28
    -   __BSD_VISIBLE on FreeBSD and DragonflyBSD, and _NetBSD_SOURCE on
    
    29
    -   NetBSD.  Otherwise, for example, code using pthread_setname_np(3) and
    
    30
    -   variants will not compile.  We must therefore define the additional
    
    31
    -   macros that expose non-POSIX APIs early, before any of the relevant
    
    32
    -   system headers are included via "Rts.h".
    
    33
    -
    
    34
    -   An alternative approach could be to write portable wrappers or stubs for all
    
    35
    -   the non-posix functions in a C-module that does not include "rts/PosixSource.h",
    
    36
    -   and then use only POSIX features and the portable wrapper functions in all
    
    37
    -   other C-modules. */
    
    38
    -#include "ghcconfig.h"
    
    39
    -#if defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS)
    
    40
    -#define __BSD_VISIBLE   1
    
    41
    -#endif
    
    42
    -#if defined(darwin_HOST_OS)
    
    43
    -#define _DARWIN_C_SOURCE 1
    
    44
    -#endif
    
    45
    -#if defined(netbsd_HOST_OS)
    
    46
    -#define _NETBSD_SOURCE 1
    
    47
    -#endif
    
    48
    -
    
    49
    -#include "Rts.h"
    
    50
    -
    
    51
    -/*
    
    52
    - * It used to be that timer_create doesn't exist on iOS and setitimer doesn't fire on iOS
    
    53
    - * during debugging. See #7723. Seems to be an issue with signals.
    
    54
    - *
    
    55
    - * We also want to avoid using alarm signals, as these can interrupt system calls (#10840)
    
    56
    - * or can be overwritten by user code.
    
    26
    +/* Select a ticker implementation to use:
    
    57 27
      *
    
    58
    - * So we are using the pthread based implementation.
    
    59
    - */
    
    60
    -#if defined(ios_HOST_OS) || defined(darwin_HOST_OS)
    
    61
    -#define USE_PTHREAD_FOR_ITIMER
    
    62
    -#endif
    
    63
    -
    
    64
    -/*
    
    65
    - * On Linux we can use timerfd_* (introduced in Linux
    
    66
    - * 2.6.25) and a thread instead of alarm signals. It avoids the risk of
    
    67
    - * interrupting syscalls (see #10840) and the risk of being accidentally
    
    68
    - * modified in user code using signals. NetBSD has also added timerfd
    
    69
    - * support since version 10.
    
    28
    + * On modern Linux, FreeBSD and NetBSD we can use timerfd_create and a thread
    
    29
    + * that waits on it using poll. Linux has had timerfd since version 2.6.25.
    
    30
    + * NetBSD has had timerfd since version 10, and FreeBSD since version 15.
    
    70 31
      *
    
    71
    - * For older version of linux/netbsd without timerfd we fall back to the
    
    72
    - * pthread based implementation.
    
    32
    + * For older version of linux/bsd without timerfd, and for all other posix
    
    33
    + * platforms, we use the implementation using posix pthreads and nanosleep().
    
    73 34
      */
    
    74 35
     #if defined(HAVE_SYS_TIMERFD_H)
    
    75
    -#define USE_TIMERFD_FOR_ITIMER
    
    76
    -#endif
    
    77
    -
    
    78
    -#if defined(linux_HOST_OS)
    
    79
    -#define USE_PTHREAD_FOR_ITIMER
    
    80
    -#endif
    
    81
    -
    
    82
    -#if defined(netbsd_HOST_OS)
    
    83
    -#define USE_PTHREAD_FOR_ITIMER
    
    84
    -#endif
    
    85
    -
    
    86
    -#if defined(freebsd_HOST_OS)
    
    87
    -#define USE_PTHREAD_FOR_ITIMER
    
    88
    -#endif
    
    89
    -
    
    90
    -#if defined(solaris2_HOST_OS)
    
    91
    -/* USE_TIMER_CREATE is usually disabled for Solaris. In fact it is
    
    92
    -   supported well on this OS, but requires additional privilege. When
    
    93
    -   user does not have it, then the testing configure program fails
    
    94
    -   which results in USE_TIMER_CREATE not defined.
    
    95
    -   On the other hand when we cross-compile, then we optimistically
    
    96
    -   assume usage of timer_create function. The problem is that if we
    
    97
    -   cross compile for example from i386-solaris2 to x86_64-solaris2,
    
    98
    -   then the build fails with error like this:
    
    99
    -
    
    100
    -ghc-stage2: timer_create: Not owner
    
    101
    -
    
    102
    -   which happens on first ghc-stage2 invocation. So to support
    
    103
    -   cross-compilation to Solaris we manually undefine USE_TIMER_CREATE
    
    104
    -   here */
    
    105
    -#undef USE_TIMER_CREATE
    
    106
    -#endif /* solaris2_HOST_OS */
    
    107
    -
    
    108
    -// Select the variant to use
    
    109
    -#if defined(USE_TIMERFD_FOR_ITIMER)
    
    110 36
     #include "ticker/TimerFd.c"
    
    111
    -#elif defined(USE_PTHREAD_FOR_ITIMER)
    
    112
    -#include "ticker/Pthread.c"
    
    113
    -#elif defined(USE_TIMER_CREATE)
    
    114
    -#include "ticker/TimerCreate.c"
    
    115 37
     #else
    
    116
    -#include "ticker/Setitimer.c"
    
    38
    +#include "ticker/Pthread.c"
    
    117 39
     #endif

  • rts/posix/ticker/Setitimer.c deleted
    1
    -/* -----------------------------------------------------------------------------
    
    2
    - *
    
    3
    - * (c) The GHC Team, 1995-2007
    
    4
    - *
    
    5
    - * Interval timer for profiling and pre-emptive scheduling.
    
    6
    - *
    
    7
    - * ---------------------------------------------------------------------------*/
    
    8
    -
    
    9
    -#include "rts/PosixSource.h"
    
    10
    -#include "Rts.h"
    
    11
    -
    
    12
    -#include "Ticker.h"
    
    13
    -#include "Proftimer.h"
    
    14
    -#include "Schedule.h"
    
    15
    -#include "posix/Clock.h"
    
    16
    -#include "posix/Signals.h"
    
    17
    -
    
    18
    -#include <time.h>
    
    19
    -#if HAVE_SYS_TIME_H
    
    20
    -# include <sys/time.h>
    
    21
    -#endif
    
    22
    -
    
    23
    -#if defined(HAVE_SIGNAL_H)
    
    24
    -# include <signal.h>
    
    25
    -#endif
    
    26
    -
    
    27
    -#include <string.h>
    
    28
    -
    
    29
    -static Time itimer_interval = DEFAULT_TICK_INTERVAL;
    
    30
    -
    
    31
    -void
    
    32
    -initTicker (Time interval, TickProc handle_tick)
    
    33
    -{
    
    34
    -    itimer_interval = interval;
    
    35
    -    install_vtalrm_handler(SIGALRM, handle_tick);
    
    36
    -}
    
    37
    -
    
    38
    -void
    
    39
    -startTicker(void)
    
    40
    -{
    
    41
    -    struct itimerval it;
    
    42
    -
    
    43
    -    it.it_value.tv_sec = TimeToSeconds(itimer_interval);
    
    44
    -    it.it_value.tv_usec = TimeToUS(itimer_interval) % 1000000;
    
    45
    -    it.it_interval = it.it_value;
    
    46
    -
    
    47
    -    if (setitimer(ITIMER_REAL, &it, NULL) != 0) {
    
    48
    -        sysErrorBelch("setitimer");
    
    49
    -        stg_exit(EXIT_FAILURE);
    
    50
    -    }
    
    51
    -}
    
    52
    -
    
    53
    -void
    
    54
    -stopTicker(void)
    
    55
    -{
    
    56
    -    struct itimerval it;
    
    57
    -
    
    58
    -    it.it_value.tv_sec = 0;
    
    59
    -    it.it_value.tv_usec = 0;
    
    60
    -    it.it_interval = it.it_value;
    
    61
    -
    
    62
    -    if (setitimer(ITIMER_REAL, &it, NULL) != 0) {
    
    63
    -        sysErrorBelch("setitimer");
    
    64
    -        stg_exit(EXIT_FAILURE);
    
    65
    -    }
    
    66
    -}
    
    67
    -
    
    68
    -void
    
    69
    -exitTicker (bool wait STG_UNUSED)
    
    70
    -{
    
    71
    -    return;
    
    72
    -}
    
    73
    -
    
    74
    -int
    
    75
    -rtsTimerSignal(void)
    
    76
    -{
    
    77
    -    return SIGALRM;
    
    78
    -    // Using SIGALRM can leads to problems, see #850.  But we have no
    
    79
    -    // option if timer_create() is not available.
    
    80
    -}

  • rts/posix/ticker/TimerCreate.c deleted
    1
    -/* -----------------------------------------------------------------------------
    
    2
    - *
    
    3
    - * (c) The GHC Team, 1995-2007
    
    4
    - *
    
    5
    - * Interval timer for profiling and pre-emptive scheduling.
    
    6
    - *
    
    7
    - * ---------------------------------------------------------------------------*/
    
    8
    -
    
    9
    -#include "rts/PosixSource.h"
    
    10
    -#include "Rts.h"
    
    11
    -
    
    12
    -#include "Ticker.h"
    
    13
    -#include "Proftimer.h"
    
    14
    -#include "Schedule.h"
    
    15
    -#include "posix/Clock.h"
    
    16
    -#include "posix/Signals.h"
    
    17
    -
    
    18
    -#if defined(HAVE_SIGNAL_H)
    
    19
    -# include <signal.h>
    
    20
    -#endif
    
    21
    -
    
    22
    -#include <string.h>
    
    23
    -
    
    24
    -static Time itimer_interval = DEFAULT_TICK_INTERVAL;
    
    25
    -static timer_t timer;
    
    26
    -
    
    27
    -void
    
    28
    -initTicker (Time interval, TickProc handle_tick)
    
    29
    -{
    
    30
    -    itimer_interval = interval;
    
    31
    -
    
    32
    -    struct sigevent ev;
    
    33
    -
    
    34
    -    // Keep programs like valgrind happy
    
    35
    -    memset(&ev, 0, sizeof(ev));
    
    36
    -
    
    37
    -    ev.sigev_notify = SIGEV_SIGNAL;
    
    38
    -    ev.sigev_signo  = SIGVTALRM;
    
    39
    -
    
    40
    -    if (timer_create(CLOCK_ID, &ev, &timer) != 0) {
    
    41
    -        sysErrorBelch("timer_create");
    
    42
    -        stg_exit(EXIT_FAILURE);
    
    43
    -    }
    
    44
    -
    
    45
    -    install_vtalrm_handler(SIGVTALRM, handle_tick);
    
    46
    -}
    
    47
    -
    
    48
    -void
    
    49
    -startTicker(void)
    
    50
    -{
    
    51
    -    struct itimerspec it;
    
    52
    -
    
    53
    -    it.it_value.tv_sec  = TimeToSeconds(itimer_interval);
    
    54
    -    it.it_value.tv_nsec = TimeToNS(itimer_interval) % 1000000000;
    
    55
    -    it.it_interval = it.it_value;
    
    56
    -
    
    57
    -    if (timer_settime(timer, 0, &it, NULL) != 0) {
    
    58
    -        sysErrorBelch("timer_settime");
    
    59
    -        stg_exit(EXIT_FAILURE);
    
    60
    -    }
    
    61
    -}
    
    62
    -
    
    63
    -void
    
    64
    -stopTicker(void)
    
    65
    -{
    
    66
    -    struct itimerspec it;
    
    67
    -
    
    68
    -    it.it_value.tv_sec = 0;
    
    69
    -    it.it_value.tv_nsec = 0;
    
    70
    -    it.it_interval = it.it_value;
    
    71
    -
    
    72
    -    if (timer_settime(timer, 0, &it, NULL) != 0) {
    
    73
    -        sysErrorBelch("timer_settime");
    
    74
    -        stg_exit(EXIT_FAILURE);
    
    75
    -    }
    
    76
    -}
    
    77
    -
    
    78
    -void
    
    79
    -exitTicker (bool wait STG_UNUSED)
    
    80
    -{
    
    81
    -    // Before deleting the timer set the signal to ignore to avoid the
    
    82
    -    // possibility of the signal being delivered after the timer is deleted.
    
    83
    -    signal(SIGVTALRM, SIG_IGN);
    
    84
    -    timer_delete(timer);
    
    85
    -    // ignore errors - we don't really care if it fails.
    
    86
    -}
    
    87
    -
    
    88
    -int
    
    89
    -rtsTimerSignal(void)
    
    90
    -{
    
    91
    -    return SIGVTALRM;
    
    92
    -}

  • testsuite/tests/perf/compiler/T13960.hs
    1
    +{-# LANGUAGE OverloadedStrings #-}
    
    2
    +
    
    3
    +-- GHC used to run out of simplifier ticks due to inlining the internals of
    
    4
    +-- `toStrict . toLazyByteString`.
    
    5
    +module T13960 (breaks) where
    
    6
    +
    
    7
    +import Data.ByteString (ByteString)
    
    8
    +import Data.ByteString.Builder (Builder, stringUtf8, toLazyByteString)
    
    9
    +import Data.ByteString.Lazy (toStrict)
    
    10
    +import Data.String (IsString(..))
    
    11
    +
    
    12
    +newtype Query = Query ByteString
    
    13
    +
    
    14
    +toByteString :: Builder -> ByteString
    
    15
    +toByteString x = toStrict (toLazyByteString x)
    
    16
    +
    
    17
    +instance IsString Query where
    
    18
    +  fromString = Query . toByteString . stringUtf8
    
    19
    +
    
    20
    +breaks :: [(Query, Query)]
    
    21
    +breaks =
    
    22
    +  [ ("query001a", "query001b")
    
    23
    +  , ("query002a", "query002b")
    
    24
    +  , ("query003a", "query003b")
    
    25
    +  , ("query004a", "query004b")
    
    26
    +  , ("query005a", "query005b")
    
    27
    +  , ("query006a", "query006b")
    
    28
    +  , ("query007a", "query007b")
    
    29
    +  , ("query008a", "query008b")
    
    30
    +  , ("query009a", "query009b")
    
    31
    +  , ("query010a", "query010b")
    
    32
    +  , ("query011a", "query011b")
    
    33
    +  , ("query012a", "query012b")
    
    34
    +  , ("query013a", "query013b")
    
    35
    +  , ("query014a", "query014b")
    
    36
    +  , ("query015a", "query015b")
    
    37
    +  , ("query016a", "query016b")
    
    38
    +  , ("query017a", "query017b")
    
    39
    +  , ("query018a", "query018b")
    
    40
    +  , ("query019a", "query019b")
    
    41
    +  , ("query020a", "query020b")
    
    42
    +  , ("query021a", "query021b")
    
    43
    +  , ("query022a", "query022b")
    
    44
    +  , ("query023a", "query023b")
    
    45
    +  , ("query024a", "query024b")
    
    46
    +  , ("query025a", "query025b")
    
    47
    +  , ("query026a", "query026b")
    
    48
    +  , ("query027a", "query027b")
    
    49
    +  , ("query028a", "query028b")
    
    50
    +  , ("query029a", "query029b")
    
    51
    +  , ("query030a", "query030b")
    
    52
    +  , ("query031a", "query031b")
    
    53
    +  , ("query032a", "query032b")
    
    54
    +  , ("query033a", "query033b")
    
    55
    +  , ("query034a", "query034b")
    
    56
    +  , ("query035a", "query035b")
    
    57
    +  , ("query036a", "query036b")
    
    58
    +  , ("query037a", "query037b")
    
    59
    +  , ("query038a", "query038b")
    
    60
    +  , ("query039a", "query039b")
    
    61
    +  , ("query040a", "query040b")
    
    62
    +  , ("query041a", "query041b")
    
    63
    +  , ("query042a", "query042b")
    
    64
    +  , ("query043a", "query043b")
    
    65
    +  , ("query044a", "query044b")
    
    66
    +  , ("query045a", "query045b")
    
    67
    +  , ("query046a", "query046b")
    
    68
    +  , ("query047a", "query047b")
    
    69
    +  , ("query048a", "query048b")
    
    70
    +  , ("query049a", "query049b")
    
    71
    +  , ("query050a", "query050b")
    
    72
    +  ]

  • testsuite/tests/perf/compiler/all.T
    ... ... @@ -686,6 +686,12 @@ test ('T13820',
    686 686
           ],
    
    687 687
           compile,
    
    688 688
           ['-v0'])
    
    689
    +test ('T13960',
    
    690
    +      [ collect_compiler_stats('peak_megabytes_allocated', 20),
    
    691
    +        collect_compiler_stats('bytes allocated', 2),
    
    692
    +      ],
    
    693
    +      compile,
    
    694
    +      ['-O'])
    
    689 695
     test ('T14766',
    
    690 696
           [ collect_compiler_stats('bytes allocated',2),
    
    691 697
             pre_cmd('python3 genT14766.py > T14766.hs'),