Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • ghc/ghc
  • bgamari/ghc
  • syd/ghc
  • ggreif/ghc
  • watashi/ghc
  • RolandSenn/ghc
  • mpickering/ghc
  • DavidEichmann/ghc
  • carter/ghc
  • harpocrates/ghc
  • ethercrow/ghc
  • mijicd/ghc
  • adamse/ghc
  • alexbiehl/ghc
  • gridaphobe/ghc
  • trofi/ghc
  • supersven/ghc
  • ppk/ghc
  • ulysses4ever/ghc
  • AndreasK/ghc
  • ghuntley/ghc
  • shayne-fletcher-da/ghc
  • fgaz/ghc
  • yav/ghc
  • osa1/ghc
  • mbbx6spp/ghc
  • JulianLeviston/ghc
  • reactormonk/ghc
  • rae/ghc
  • takenobu-hs/ghc
  • michalt/ghc
  • andrewthad/ghc
  • hsyl20/ghc
  • scottgw/ghc
  • sjakobi/ghc
  • angerman/ghc
  • RyanGlScott/ghc
  • hvr/ghc
  • howtonotwin/ghc
  • chessai/ghc
  • m-renaud/ghc
  • brprice/ghc
  • stevehartdata/ghc
  • sighingnow/ghc
  • kgardas/ghc
  • ckoparkar/ghc
  • alp/ghc
  • smaeul/ghc
  • kakkun61/ghc
  • sykloid/ghc
  • newhoggy/ghc
  • toonn/ghc
  • nineonine/ghc
  • Phyx/ghc
  • ezyang/ghc
  • tweag/ghc
  • langston/ghc
  • ndmitchell/ghc
  • rockbmb/ghc
  • artempyanykh/ghc
  • mniip/ghc
  • mynguyenbmc/ghc
  • alexfmpe/ghc
  • crockeea/ghc
  • nh2/ghc
  • vaibhavsagar/ghc
  • phadej/ghc
  • Haskell-mouse/ghc
  • lolotp/ghc
  • spacekitteh/ghc
  • michaelpj/ghc
  • mgsloan/ghc
  • HPCohen/ghc
  • tmobile/ghc
  • radrow/ghc
  • simonmar/ghc
  • _deepfire/ghc
  • Ericson2314/ghc
  • leitao/ghc
  • fumieval/ghc
  • trac-isovector/ghc
  • cblp/ghc
  • xich/ghc
  • ciil/ghc
  • erthalion/ghc
  • xldenis/ghc
  • autotaker/ghc
  • haskell-wasm/ghc
  • kcsongor/ghc
  • agander/ghc
  • Baranowski/ghc
  • trac-dredozubov/ghc
  • 23Skidoo/ghc
  • iustin/ghc
  • ningning/ghc
  • josefs/ghc
  • kabuhr/ghc
  • gallais/ghc
  • dten/ghc
  • expipiplus1/ghc
  • Pluralia/ghc
  • rohanjr/ghc
  • intricate/ghc
  • kirelagin/ghc
  • Javran/ghc
  • DanielG/ghc
  • trac-mizunashi_mana/ghc
  • pparkkin/ghc
  • bollu/ghc
  • ntc2/ghc
  • jaspervdj/ghc
  • JoshMeredith/ghc
  • wz1000/ghc
  • zkourouma/ghc
  • code5hot/ghc
  • jdprice/ghc
  • tdammers/ghc
  • J-mie6/ghc
  • trac-lantti/ghc
  • ch1bo/ghc
  • cgohla/ghc
  • lucamolteni/ghc
  • acairncross/ghc
  • amerocu/ghc
  • chreekat/ghc
  • txsmith/ghc
  • trupill/ghc
  • typetetris/ghc
  • sergv/ghc
  • fryguybob/ghc
  • erikd/ghc
  • trac-roland/ghc
  • setupminimal/ghc
  • Friede80/ghc
  • SkyWriter/ghc
  • xplorld/ghc
  • abrar/ghc
  • obsidiansystems/ghc
  • Icelandjack/ghc
  • adinapoli/ghc
  • trac-matthewbauer/ghc
  • heatsink/ghc
  • dwijnand/ghc
  • Cmdv/ghc
  • alinab/ghc
  • pepeiborra/ghc
  • fommil/ghc
  • luochen1990/ghc
  • rlupton20/ghc
  • applePrincess/ghc
  • lehins/ghc
  • ronmrdechai/ghc
  • leeadam/ghc
  • harendra/ghc
  • mightymosquito1991/ghc
  • trac-gershomb/ghc
  • lucajulian/ghc
  • Rizary/ghc
  • VictorCMiraldo/ghc
  • jamesbrock/ghc
  • andrewdmeier/ghc
  • luke/ghc
  • pranaysashank/ghc
  • cocreature/ghc
  • hithroc/ghc
  • obreitwi/ghc
  • slrtbtfs/ghc
  • kaol/ghc
  • yairchu/ghc
  • Mathemagician98/ghc
  • trac-taylorfausak/ghc
  • leungbk/ghc
  • MichaWiedenmann/ghc
  • chris-martin/ghc
  • TDecki/ghc
  • adithyaov/ghc
  • trac-gelisam/ghc
  • Lysxia/ghc
  • complyue/ghc
  • bwignall/ghc
  • sternmull/ghc
  • sonika/ghc
  • leif/ghc
  • broadwaylamb/ghc
  • myszon/ghc
  • danbroooks/ghc
  • Mechachleopteryx/ghc
  • zardyh/ghc
  • trac-vdukhovni/ghc
  • OmarKhaledAbdo/ghc
  • arrowd/ghc
  • Bodigrim/ghc
  • matheus23/ghc
  • cardenaso11/ghc
  • trac-Athas/ghc
  • mb720/ghc
  • DylanZA/ghc
  • liff/ghc
  • typedrat/ghc
  • trac-claude/ghc
  • jbm/ghc
  • Gertjan423/ghc
  • PHO/ghc
  • JKTKops/ghc
  • kockahonza/ghc
  • msakai/ghc
  • Sir4ur0n/ghc
  • barambani/ghc
  • vishnu.c/ghc
  • dcoutts/ghc
  • trac-runeks/ghc
  • trac-MaxGabriel/ghc
  • lexi.lambda/ghc
  • strake/ghc
  • spavikevik/ghc
  • JakobBruenker/ghc
  • rmanne/ghc
  • gdziadkiewicz/ghc
  • ani/ghc
  • iliastsi/ghc
  • smunix/ghc
  • judah/ghc
  • blackgnezdo/ghc
  • emilypi/ghc
  • trac-bpfoley/ghc
  • muesli4/ghc
  • trac-gkaracha/ghc
  • Kleidukos/ghc
  • nek0/ghc
  • TristanCacqueray/ghc
  • dwulive/ghc
  • mbakke/ghc
  • arybczak/ghc
  • Yang123321/ghc
  • maksbotan/ghc
  • QuietMisdreavus/ghc
  • trac-olshanskydr/ghc
  • emekoi/ghc
  • samuela/ghc
  • josephcsible/ghc
  • dramforever/ghc
  • lpsmith/ghc
  • DenisFrezzato/ghc
  • michivi/ghc
  • jneira/ghc
  • jeffhappily/ghc
  • Ivan-Yudin/ghc
  • nakaji-dayo/ghc
  • gdevanla/ghc
  • galen/ghc
  • fendor/ghc
  • yaitskov/ghc
  • rcythr/ghc
  • awpr/ghc
  • jeremyschlatter/ghc
  • Aver1y/ghc
  • mitchellvitez/ghc
  • merijn/ghc
  • tomjaguarpaw1/ghc
  • trac-NoidedSuper/ghc
  • erewok/ghc
  • trac-junji.hashimoto/ghc
  • adamwespiser/ghc
  • bjaress/ghc
  • jhrcek/ghc
  • leonschoorl/ghc
  • lukasz-golebiewski/ghc
  • sheaf/ghc
  • last-g/ghc
  • carassius1014/ghc
  • eschwartz/ghc
  • dwincort/ghc
  • felixwiemuth/ghc
  • TimWSpence/ghc
  • marcusmonteirodesouza/ghc
  • WJWH/ghc
  • vtols/ghc
  • theobat/ghc
  • BinderDavid/ghc
  • ckoparkar0/ghc
  • alexander-kjeldaas/ghc
  • dme2/ghc
  • philderbeast/ghc
  • aaronallen8455/ghc
  • rayshih/ghc
  • benkard/ghc
  • mpardalos/ghc
  • saidelman/ghc
  • leiftw/ghc
  • ca333/ghc
  • bwroga/ghc
  • nmichael44/ghc
  • trac-crobbins/ghc
  • felixonmars/ghc
  • adityagupta1089/ghc
  • hgsipiere/ghc
  • treeowl/ghc
  • alexpeits/ghc
  • CraigFe/ghc
  • dnlkrgr/ghc
  • kerckhove_ts/ghc
  • cptwunderlich/ghc
  • eiais/ghc
  • hahohihu/ghc
  • sanchayan/ghc
  • lemmih/ghc
  • sehqlr/ghc
  • trac-dbeacham/ghc
  • luite/ghc
  • trac-f-a/ghc
  • vados/ghc
  • luntain/ghc
  • fatho/ghc
  • alexbiehl-gc/ghc
  • dcbdan/ghc
  • tvh/ghc
  • liam-ly/ghc
  • timbobbarnes/ghc
  • GovanifY/ghc
  • shanth2600/ghc
  • gliboc/ghc
  • duog/ghc
  • moxonsghost/ghc
  • zander/ghc
  • masaeedu/ghc
  • georgefst/ghc
  • guibou/ghc
  • nicuveo/ghc
  • mdebruijne/ghc
  • stjordanis/ghc
  • emiflake/ghc
  • wygulmage/ghc
  • frasertweedale/ghc
  • coot/ghc
  • aratamizuki/ghc
  • tsandstr/ghc
  • mrBliss/ghc
  • Anton-Latukha/ghc
  • tadfisher/ghc
  • vapourismo/ghc
  • Sorokin-Anton/ghc
  • basile-henry/ghc
  • trac-mightybyte/ghc
  • AbsoluteNikola/ghc
  • cobrien99/ghc
  • songzh/ghc
  • blamario/ghc
  • aj4ayushjain/ghc
  • trac-utdemir/ghc
  • tangcl/ghc
  • hdgarrood/ghc
  • maerwald/ghc
  • arjun/ghc
  • ratherforky/ghc
  • haskieLambda/ghc
  • EmilGedda/ghc
  • Bogicevic/ghc
  • eddiejessup/ghc
  • kozross/ghc
  • AlistairB/ghc
  • 3Rafal/ghc
  • christiaanb/ghc
  • trac-bit/ghc
  • matsumonkie/ghc
  • trac-parsonsmatt/ghc
  • chisui/ghc
  • jaro/ghc
  • trac-kmiyazato/ghc
  • davidsd/ghc
  • Tritlo/ghc
  • I-B-3/ghc
  • lykahb/ghc
  • AriFordsham/ghc
  • turion1/ghc
  • berberman/ghc
  • christiantakle/ghc
  • zyklotomic/ghc
  • trac-ocramz/ghc
  • CSEdd/ghc
  • doyougnu/ghc
  • mmhat/ghc
  • why-not-try-calmer/ghc
  • plutotulp/ghc
  • kjekac/ghc
  • Manvi07/ghc
  • teo/ghc
  • cactus/ghc
  • CarrieMY/ghc
  • abel/ghc
  • yihming/ghc
  • tsakki/ghc
  • jessicah/ghc
  • oliverbunting/ghc
  • meld/ghc
  • friedbrice/ghc
  • Joald/ghc
  • abarbu/ghc
  • DigitalBrains1/ghc
  • sterni/ghc
  • alexDarcy/ghc
  • hexchain/ghc
  • minimario/ghc
  • zliu41/ghc
  • tommd/ghc
  • jazcarate/ghc
  • peterbecich/ghc
  • alirezaghey/ghc
  • solomon/ghc
  • mikael.urankar/ghc
  • davjam/ghc
  • int-index/ghc
  • MorrowM/ghc
  • nrnrnr/ghc
  • Sonfamm/ghc-test-only
  • afzt1/ghc
  • nguyenhaibinh-tpc/ghc
  • trac-lierdakil/ghc
  • MichaWiedenmann1/ghc
  • jmorag/ghc
  • Ziharrk/ghc
  • trac-MitchellSalad/ghc
  • juampe/ghc
  • jwaldmann/ghc
  • snowleopard/ghc
  • juhp/ghc
  • normalcoder/ghc
  • ksqsf/ghc
  • trac-jberryman/ghc
  • roberth/ghc
  • 1ntEgr8/ghc
  • epworth/ghc
  • MrAdityaAlok/ghc
  • JunmingZhao42/ghc
  • jappeace/ghc
  • trac-Gabriel439/ghc
  • alt-romes/ghc
  • HugoPeters1024/ghc
  • 10ne1/ghc-fork
  • agentultra/ghc
  • Garfield1002/ghc
  • ChickenProp/ghc
  • clyring/ghc
  • MaxHearnden/ghc
  • jumper149/ghc
  • vem/ghc
  • ketzacoatl/ghc
  • Rosuavio/ghc
  • jackohughes/ghc
  • p4l1ly/ghc
  • konsumlamm/ghc
  • shlevy/ghc
  • torsten.schmits/ghc
  • andremarianiello/ghc
  • amesgen/ghc
  • googleson78/ghc
  • InfiniteVerma/ghc
  • uhbif19/ghc
  • yiyunliu/ghc
  • raehik/ghc
  • mrkun/ghc
  • telser/ghc
  • 1Jajen1/ghc
  • slotThe/ghc
  • WinstonHartnett/ghc
  • mpilgrem/ghc
  • dreamsmasher/ghc
  • schuelermine/ghc
  • trac-Viwor/ghc
  • undergroundquizscene/ghc
  • evertedsphere/ghc
  • coltenwebb/ghc
  • oberblastmeister/ghc
  • agrue/ghc
  • lf-/ghc
  • zacwood9/ghc
  • steshaw/ghc
  • high-cloud/ghc
  • SkamDart/ghc
  • PiDelport/ghc
  • maoif/ghc
  • RossPaterson/ghc
  • CharlesTaylor7/ghc
  • ribosomerocker/ghc
  • trac-ramirez7/ghc
  • daig/ghc
  • NicolasT/ghc
  • FinleyMcIlwaine/ghc
  • lawtonnichols/ghc
  • jmtd/ghc
  • ozkutuk/ghc
  • wildsebastian/ghc
  • lrzlin/ghc
  • tobias/ghc
  • fw/ghc
  • hawkinsw/ghc
  • type-dance/ghc
  • rui314/ghc
  • ocharles/ghc
  • wavewave/ghc
  • TheKK/ghc
  • nomeata/ghc
  • trac-csabahruska/ghc
  • jonathanjameswatson/ghc
  • L-as/ghc
  • Axman6/ghc
  • barracuda156/ghc
  • trac-jship/ghc
  • jake-87/ghc
  • meooow/ghc
  • rebeccat/ghc
  • hamana55/ghc
  • Enigmage/ghc
  • kokobd/ghc
  • agevelt/ghc
  • gshen42/ghc
  • chrismwendt/ghc
  • MangoIV/ghc
  • teto/ghc
  • Sookr1/ghc
  • trac-thomasjm/ghc
  • barci2/ghc-dev
  • trac-m4dc4p/ghc
  • dixonary/ghc
  • breakerzirconia/ghc
  • alexsio27444/ghc
  • glocq/ghc
  • sourabhxyz/ghc
  • ryantrinkle/ghc
  • Jade/ghc
  • scedfaliako/ghc
  • martijnbastiaan/ghc
  • trac-george.colpitts/ghc
  • ammarbinfaisal/ghc
  • mimi.vx/ghc
  • lortabac/ghc
  • trac-zyla/ghc
  • benbellick/ghc
  • aadaa-fgtaa/ghc
  • jvanbruegge/ghc
  • archbung/ghc
  • gilmi/ghc
  • mfonism/ghc
  • alex-mckenna/ghc
  • Ei30metry/ghc
  • DiegoDiverio/ghc
  • jorgecunhamendes/ghc
  • liesnikov/ghc
  • akrmn/ghc
  • trac-simplifierticks/ghc
  • jacco/ghc
  • rhendric/ghc
  • damhiya/ghc
  • ryndubei/ghc
  • DaveBarton/ghc
  • trac-Profpatsch/ghc
  • GZGavinZhao/ghc
  • ncfavier/ghc
  • jameshaydon/ghc
  • ajccosta/ghc
  • dschrempf/ghc
  • cydparser/ghc
  • LinuxUserGD/ghc
  • elodielander/ghc
  • facundominguez/ghc
  • psilospore/ghc
  • lachrimae/ghc
  • dylan-thinnes/ghc-type-errors-plugin
  • hamishmack/ghc
  • Leary/ghc
  • lzszt/ghc
  • lyokha/ghc
  • trac-glaubitz/ghc
  • Rewbert/ghc
  • andreabedini/ghc
  • Jasagredo/ghc
  • sol/ghc
  • OlegAlexander/ghc
  • trac-sthibaul/ghc
  • avdv/ghc
  • Wendaolee/ghc
  • ur4t/ghc
  • daylily/ghc
  • boltzmannrain/ghc
  • mmzk1526/ghc
  • trac-fizzixnerd/ghc
  • soulomoon/ghc
  • rwmjones/ghc
  • j14i/ghc
  • tracsis/ghc
  • gesh/ghc
  • flip101/ghc
  • eldritch-cookie/ghc
  • LemonjamesD/ghc
  • pgujjula/ghc
  • skeuchel/ghc
  • noteed/ghc
  • Torrekie/ghc
  • jlwoodwa/ghc
  • ayanamists/ghc
  • husong998/ghc
  • trac-edmundnoble/ghc
  • josephf/ghc
  • contrun/ghc
  • baulig/ghc
  • edsko/ghc
  • mzschr/ghc-issue-24732
  • ulidtko/ghc
  • Arsen/ghc
  • trac-sjoerd_visscher/ghc
  • crumbtoo/ghc
  • L0neGamer/ghc
  • DrewFenwick/ghc
  • benz0li/ghc
  • MaciejWas/ghc
  • jordanrule/ghc
  • trac-qqwy/ghc
  • LiamGoodacre/ghc
  • isomorpheme/ghc
  • trac-danidiaz/ghc
  • Kariim/ghc
  • taimoorzaeem/ghc
  • hololeap/ghc
  • ticat-fp/ghc
  • meritamen/ghc
  • criskell/ghc
  • trac-kraai/ghc
  • aergus/ghc
  • jdral/ghc
  • SamB/ghc
  • Tristian/ghc
  • ywgrit/ghc
  • KatsuPatrick/ghc
  • OsePedro/ghc
  • mpscholten/ghc
  • zaquest/ghc
  • fangyi-zhou/ghc
  • augyg/ghc
  • rkirkman/ghc
  • gulin.serge/ghc-windows-aarch64-bootstrap
  • iris/ghc
  • kwxm/ghc
  • maralorn/ghc
  • rafl/ghc
  • nikshalark/ghc
  • mrcjkb/ghc
  • blackheaven/ghc
  • laurenyim/ghc
  • bolt12/ghc
  • Xitian9/ghc
  • wenkokke/ghc
  • kephas/ghc
651 results
Show changes
Commits on Source (102)
Showing
with 570 additions and 225 deletions
...@@ -2,7 +2,7 @@ variables: ...@@ -2,7 +2,7 @@ variables:
GIT_SSL_NO_VERIFY: "1" GIT_SSL_NO_VERIFY: "1"
# Commit of ghc/ci-images repository from which to pull Docker images # Commit of ghc/ci-images repository from which to pull Docker images
DOCKER_REV: 486541129a8e7bf77c2cf7cd76ca998f690d5685 DOCKER_REV: efc1ab81236eb37e20cb287ec77aebb6c6341098
# Sequential version number of all cached things. # Sequential version number of all cached things.
# Bump to invalidate GitLab CI cache. # Bump to invalidate GitLab CI cache.
...@@ -1144,6 +1144,8 @@ ghcup-metadata-nightly: ...@@ -1144,6 +1144,8 @@ ghcup-metadata-nightly:
artifacts: false artifacts: false
- job: nightly-x86_64-linux-centos7-validate - job: nightly-x86_64-linux-centos7-validate
artifacts: false artifacts: false
- job: nightly-x86_64-linux-ubuntu22_04-validate
artifacts: false
- job: nightly-x86_64-linux-ubuntu20_04-validate - job: nightly-x86_64-linux-ubuntu20_04-validate
artifacts: false artifacts: false
- job: nightly-x86_64-linux-ubuntu18_04-validate - job: nightly-x86_64-linux-ubuntu18_04-validate
......
...@@ -112,6 +112,7 @@ data LinuxDistro ...@@ -112,6 +112,7 @@ data LinuxDistro
| Debian9 | Debian9
| Fedora33 | Fedora33
| Fedora38 | Fedora38
| Ubuntu2204
| Ubuntu2004 | Ubuntu2004
| Ubuntu1804 | Ubuntu1804
| Centos7 | Centos7
...@@ -150,6 +151,7 @@ data BuildConfig ...@@ -150,6 +151,7 @@ data BuildConfig
, crossEmulator :: CrossEmulator , crossEmulator :: CrossEmulator
, configureWrapper :: Maybe String , configureWrapper :: Maybe String
, fullyStatic :: Bool , fullyStatic :: Bool
, hostFullyStatic :: Bool
, tablesNextToCode :: Bool , tablesNextToCode :: Bool
, threadSanitiser :: Bool , threadSanitiser :: Bool
, noSplitSections :: Bool , noSplitSections :: Bool
...@@ -175,6 +177,7 @@ mkJobFlavour BuildConfig{..} = Flavour buildFlavour opts ...@@ -175,6 +177,7 @@ mkJobFlavour BuildConfig{..} = Flavour buildFlavour opts
opts = [Llvm | llvmBootstrap] ++ opts = [Llvm | llvmBootstrap] ++
[Dwarf | withDwarf] ++ [Dwarf | withDwarf] ++
[FullyStatic | fullyStatic] ++ [FullyStatic | fullyStatic] ++
[HostFullyStatic | hostFullyStatic] ++
[ThreadSanitiser | threadSanitiser] ++ [ThreadSanitiser | threadSanitiser] ++
[NoSplitSections | noSplitSections, buildFlavour == Release ] ++ [NoSplitSections | noSplitSections, buildFlavour == Release ] ++
[BootNonmovingGc | validateNonmovingGc ] ++ [BootNonmovingGc | validateNonmovingGc ] ++
...@@ -186,6 +189,7 @@ data FlavourTrans = ...@@ -186,6 +189,7 @@ data FlavourTrans =
Llvm Llvm
| Dwarf | Dwarf
| FullyStatic | FullyStatic
| HostFullyStatic
| ThreadSanitiser | ThreadSanitiser
| NoSplitSections | NoSplitSections
| BootNonmovingGc | BootNonmovingGc
...@@ -212,6 +216,7 @@ vanilla = BuildConfig ...@@ -212,6 +216,7 @@ vanilla = BuildConfig
, crossEmulator = NoEmulator , crossEmulator = NoEmulator
, configureWrapper = Nothing , configureWrapper = Nothing
, fullyStatic = False , fullyStatic = False
, hostFullyStatic = False
, tablesNextToCode = True , tablesNextToCode = True
, threadSanitiser = False , threadSanitiser = False
, noSplitSections = False , noSplitSections = False
...@@ -308,11 +313,12 @@ distroName Fedora33 = "fedora33" ...@@ -308,11 +313,12 @@ distroName Fedora33 = "fedora33"
distroName Fedora38 = "fedora38" distroName Fedora38 = "fedora38"
distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu1804 = "ubuntu18_04"
distroName Ubuntu2004 = "ubuntu20_04" distroName Ubuntu2004 = "ubuntu20_04"
distroName Ubuntu2204 = "ubuntu22_04"
distroName Centos7 = "centos7" distroName Centos7 = "centos7"
distroName Alpine312 = "alpine3_12" distroName Alpine312 = "alpine3_12"
distroName Alpine318 = "alpine3_18" distroName Alpine318 = "alpine3_18"
distroName Alpine320 = "alpine3_20" distroName Alpine320 = "alpine3_20"
distroName AlpineWasm = "alpine3_18-wasm" distroName AlpineWasm = "alpine3_20-wasm"
distroName Rocky8 = "rocky8" distroName Rocky8 = "rocky8"
opsysName :: Opsys -> String opsysName :: Opsys -> String
...@@ -355,6 +361,7 @@ flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . f ...@@ -355,6 +361,7 @@ flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . f
flavour_string Llvm = "llvm" flavour_string Llvm = "llvm"
flavour_string Dwarf = "debug_info" flavour_string Dwarf = "debug_info"
flavour_string FullyStatic = "fully_static" flavour_string FullyStatic = "fully_static"
flavour_string HostFullyStatic = "host_fully_static"
flavour_string ThreadSanitiser = "thread_sanitizer_cmm" flavour_string ThreadSanitiser = "thread_sanitizer_cmm"
flavour_string NoSplitSections = "no_split_sections" flavour_string NoSplitSections = "no_split_sections"
flavour_string BootNonmovingGc = "boot_nonmoving_gc" flavour_string BootNonmovingGc = "boot_nonmoving_gc"
...@@ -1060,6 +1067,7 @@ ubuntu_x86 :: [JobGroup Job] ...@@ -1060,6 +1067,7 @@ ubuntu_x86 :: [JobGroup Job]
ubuntu_x86 = ubuntu_x86 =
[ disableValidate (standardBuilds Amd64 (Linux Ubuntu1804)) [ disableValidate (standardBuilds Amd64 (Linux Ubuntu1804))
, disableValidate (standardBuilds Amd64 (Linux Ubuntu2004)) , disableValidate (standardBuilds Amd64 (Linux Ubuntu2004))
, disableValidate (standardBuilds Amd64 (Linux Ubuntu2204))
] ]
rhel_x86 :: [JobGroup Job] rhel_x86 :: [JobGroup Job]
...@@ -1145,7 +1153,7 @@ cross_jobs = [ ...@@ -1145,7 +1153,7 @@ cross_jobs = [
wasm_build_config = wasm_build_config =
(crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing) (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing)
{ {
fullyStatic = True hostFullyStatic = True
, buildFlavour = Release -- TODO: This needs to be validate but wasm backend doesn't pass yet , buildFlavour = Release -- TODO: This needs to be validate but wasm backend doesn't pass yet
, textWithSIMDUTF = True , textWithSIMDUTF = True
} }
...@@ -1188,10 +1196,10 @@ platform_mapping = Map.map go combined_result ...@@ -1188,10 +1196,10 @@ platform_mapping = Map.map go combined_result
, "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate" , "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate"
, "x86_64-windows-validate" , "x86_64-windows-validate"
, "aarch64-linux-deb12-validate" , "aarch64-linux-deb12-validate"
, "nightly-x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf" , "nightly-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf"
, "nightly-x86_64-linux-deb11-validate" , "nightly-x86_64-linux-deb11-validate"
, "nightly-x86_64-linux-deb12-validate" , "nightly-x86_64-linux-deb12-validate"
, "x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf" , "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf"
, "x86_64-linux-deb12-validate+thread_sanitizer_cmm" , "x86_64-linux-deb12-validate+thread_sanitizer_cmm"
, "nightly-aarch64-linux-deb10-validate" , "nightly-aarch64-linux-deb10-validate"
, "nightly-aarch64-linux-deb12-validate" , "nightly-aarch64-linux-deb12-validate"
......
...@@ -960,7 +960,7 @@ ...@@ -960,7 +960,7 @@
"XZ_OPT": "-9" "XZ_OPT": "-9"
} }
}, },
"nightly-x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf": { "nightly-x86_64-linux-alpine3_20-validate": {
"after_script": [ "after_script": [
".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output", ".gitlab/ci.sh save_test_output",
...@@ -971,7 +971,7 @@ ...@@ -971,7 +971,7 @@
"artifacts": { "artifacts": {
"expire_in": "8 weeks", "expire_in": "8 weeks",
"paths": [ "paths": [
"ghc-x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf.tar.xz", "ghc-x86_64-linux-alpine3_20-validate.tar.xz",
"junit.xml", "junit.xml",
"unexpected-test-output.tar.gz" "unexpected-test-output.tar.gz"
], ],
...@@ -981,14 +981,14 @@ ...@@ -981,14 +981,14 @@
"when": "always" "when": "always"
}, },
"cache": { "cache": {
"key": "x86_64-linux-alpine3_18-wasm-$CACHE_REV", "key": "x86_64-linux-alpine3_20-$CACHE_REV",
"paths": [ "paths": [
"cabal-cache", "cabal-cache",
"toolchain" "toolchain"
] ]
}, },
"dependencies": [], "dependencies": [],
"image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_18-wasm:$DOCKER_REV", "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_20:$DOCKER_REV",
"needs": [ "needs": [
{ {
"artifacts": false, "artifacts": false,
...@@ -1014,17 +1014,17 @@ ...@@ -1014,17 +1014,17 @@
], ],
"variables": { "variables": {
"BIGNUM_BACKEND": "gmp", "BIGNUM_BACKEND": "gmp",
"BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf", "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-validate",
"BUILD_FLAVOUR": "release+fully_static+text_simdutf", "BROKEN_TESTS": "encoding004 T10458",
"CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check", "BUILD_FLAVOUR": "validate",
"CROSS_TARGET": "wasm32-wasi", "CONFIGURE_ARGS": "--disable-ld-override --enable-strict-ghc-toolchain-check",
"HADRIAN_ARGS": "--docs=none", "INSTALL_CONFIGURE_ARGS": "--disable-ld-override --enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "", "RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf", "TEST_ENV": "x86_64-linux-alpine3_20-validate",
"XZ_OPT": "-9" "XZ_OPT": "-9"
} }
}, },
"nightly-x86_64-linux-alpine3_18-wasm-int_native-cross_wasm32-wasi-release+fully_static+text_simdutf": { "nightly-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
"after_script": [ "after_script": [
".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output", ".gitlab/ci.sh save_test_output",
...@@ -1035,7 +1035,7 @@ ...@@ -1035,7 +1035,7 @@
"artifacts": { "artifacts": {
"expire_in": "8 weeks", "expire_in": "8 weeks",
"paths": [ "paths": [
"ghc-x86_64-linux-alpine3_18-wasm-int_native-cross_wasm32-wasi-release+fully_static+text_simdutf.tar.xz", "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
"junit.xml", "junit.xml",
"unexpected-test-output.tar.gz" "unexpected-test-output.tar.gz"
], ],
...@@ -1045,14 +1045,14 @@ ...@@ -1045,14 +1045,14 @@
"when": "always" "when": "always"
}, },
"cache": { "cache": {
"key": "x86_64-linux-alpine3_18-wasm-$CACHE_REV", "key": "x86_64-linux-alpine3_20-wasm-$CACHE_REV",
"paths": [ "paths": [
"cabal-cache", "cabal-cache",
"toolchain" "toolchain"
] ]
}, },
"dependencies": [], "dependencies": [],
"image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_18-wasm:$DOCKER_REV", "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_20-wasm:$DOCKER_REV",
"needs": [ "needs": [
{ {
"artifacts": false, "artifacts": false,
...@@ -1077,18 +1077,18 @@ ...@@ -1077,18 +1077,18 @@
"x86_64-linux" "x86_64-linux"
], ],
"variables": { "variables": {
"BIGNUM_BACKEND": "native", "BIGNUM_BACKEND": "gmp",
"BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_18-wasm-int_native-cross_wasm32-wasi-release+fully_static+text_simdutf", "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
"BUILD_FLAVOUR": "release+fully_static+text_simdutf", "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
"CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check", "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
"CROSS_TARGET": "wasm32-wasi", "CROSS_TARGET": "wasm32-wasi",
"HADRIAN_ARGS": "--docs=none", "HADRIAN_ARGS": "--docs=none",
"RUNTEST_ARGS": "", "RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-alpine3_18-wasm-int_native-cross_wasm32-wasi-release+fully_static+text_simdutf", "TEST_ENV": "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
"XZ_OPT": "-9" "XZ_OPT": "-9"
} }
}, },
"nightly-x86_64-linux-alpine3_18-wasm-unreg-cross_wasm32-wasi-release+fully_static+text_simdutf": { "nightly-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
"after_script": [ "after_script": [
".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output", ".gitlab/ci.sh save_test_output",
...@@ -1099,7 +1099,7 @@ ...@@ -1099,7 +1099,7 @@
"artifacts": { "artifacts": {
"expire_in": "8 weeks", "expire_in": "8 weeks",
"paths": [ "paths": [
"ghc-x86_64-linux-alpine3_18-wasm-unreg-cross_wasm32-wasi-release+fully_static+text_simdutf.tar.xz", "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
"junit.xml", "junit.xml",
"unexpected-test-output.tar.gz" "unexpected-test-output.tar.gz"
], ],
...@@ -1109,14 +1109,14 @@ ...@@ -1109,14 +1109,14 @@
"when": "always" "when": "always"
}, },
"cache": { "cache": {
"key": "x86_64-linux-alpine3_18-wasm-$CACHE_REV", "key": "x86_64-linux-alpine3_20-wasm-$CACHE_REV",
"paths": [ "paths": [
"cabal-cache", "cabal-cache",
"toolchain" "toolchain"
] ]
}, },
"dependencies": [], "dependencies": [],
"image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_18-wasm:$DOCKER_REV", "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_20-wasm:$DOCKER_REV",
"needs": [ "needs": [
{ {
"artifacts": false, "artifacts": false,
...@@ -1141,18 +1141,18 @@ ...@@ -1141,18 +1141,18 @@
"x86_64-linux" "x86_64-linux"
], ],
"variables": { "variables": {
"BIGNUM_BACKEND": "gmp", "BIGNUM_BACKEND": "native",
"BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_18-wasm-unreg-cross_wasm32-wasi-release+fully_static+text_simdutf", "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
"BUILD_FLAVOUR": "release+fully_static+text_simdutf", "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
"CONFIGURE_ARGS": "--enable-unregisterised --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check", "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
"CROSS_TARGET": "wasm32-wasi", "CROSS_TARGET": "wasm32-wasi",
"HADRIAN_ARGS": "--docs=none", "HADRIAN_ARGS": "--docs=none",
"RUNTEST_ARGS": "", "RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-alpine3_18-wasm-unreg-cross_wasm32-wasi-release+fully_static+text_simdutf", "TEST_ENV": "x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
"XZ_OPT": "-9" "XZ_OPT": "-9"
} }
}, },
"nightly-x86_64-linux-alpine3_20-validate": { "nightly-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
"after_script": [ "after_script": [
".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output", ".gitlab/ci.sh save_test_output",
...@@ -1163,7 +1163,7 @@ ...@@ -1163,7 +1163,7 @@
"artifacts": { "artifacts": {
"expire_in": "8 weeks", "expire_in": "8 weeks",
"paths": [ "paths": [
"ghc-x86_64-linux-alpine3_20-validate.tar.xz", "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
"junit.xml", "junit.xml",
"unexpected-test-output.tar.gz" "unexpected-test-output.tar.gz"
], ],
...@@ -1173,14 +1173,14 @@ ...@@ -1173,14 +1173,14 @@
"when": "always" "when": "always"
}, },
"cache": { "cache": {
"key": "x86_64-linux-alpine3_20-$CACHE_REV", "key": "x86_64-linux-alpine3_20-wasm-$CACHE_REV",
"paths": [ "paths": [
"cabal-cache", "cabal-cache",
"toolchain" "toolchain"
] ]
}, },
"dependencies": [], "dependencies": [],
"image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_20:$DOCKER_REV", "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_20-wasm:$DOCKER_REV",
"needs": [ "needs": [
{ {
"artifacts": false, "artifacts": false,
...@@ -1206,13 +1206,13 @@ ...@@ -1206,13 +1206,13 @@
], ],
"variables": { "variables": {
"BIGNUM_BACKEND": "gmp", "BIGNUM_BACKEND": "gmp",
"BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-validate", "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
"BROKEN_TESTS": "encoding004 T10458", "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
"BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--enable-unregisterised --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
"CONFIGURE_ARGS": "--disable-ld-override --enable-strict-ghc-toolchain-check", "CROSS_TARGET": "wasm32-wasi",
"INSTALL_CONFIGURE_ARGS": "--disable-ld-override --enable-strict-ghc-toolchain-check", "HADRIAN_ARGS": "--docs=none",
"RUNTEST_ARGS": "", "RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-alpine3_20-validate", "TEST_ENV": "x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
"XZ_OPT": "-9" "XZ_OPT": "-9"
} }
}, },
...@@ -2745,6 +2745,69 @@ ...@@ -2745,6 +2745,69 @@
"XZ_OPT": "-9" "XZ_OPT": "-9"
} }
}, },
"nightly-x86_64-linux-ubuntu22_04-validate": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
".gitlab/ci.sh clean",
"cat ci_timings"
],
"allow_failure": false,
"artifacts": {
"expire_in": "8 weeks",
"paths": [
"ghc-x86_64-linux-ubuntu22_04-validate.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
"reports": {
"junit": "junit.xml"
},
"when": "always"
},
"cache": {
"key": "x86_64-linux-ubuntu22_04-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
"image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-ubuntu22_04:$DOCKER_REV",
"needs": [
{
"artifacts": false,
"job": "hadrian-ghc-in-ghci"
}
],
"rules": [
{
"if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)",
"when": "on_success"
}
],
"script": [
"sudo chown ghc:ghc -R .",
".gitlab/ci.sh setup",
".gitlab/ci.sh configure",
".gitlab/ci.sh build_hadrian",
".gitlab/ci.sh test_hadrian"
],
"stage": "full-build",
"tags": [
"x86_64-linux"
],
"variables": {
"BIGNUM_BACKEND": "gmp",
"BIN_DIST_NAME": "ghc-x86_64-linux-ubuntu22_04-validate",
"BUILD_FLAVOUR": "validate",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-ubuntu22_04-validate",
"XZ_OPT": "-9"
}
},
"nightly-x86_64-windows-int_native-validate": { "nightly-x86_64-windows-int_native-validate": {
"after_script": [ "after_script": [
"bash .gitlab/ci.sh save_cache", "bash .gitlab/ci.sh save_cache",
...@@ -4452,6 +4515,71 @@ ...@@ -4452,6 +4515,71 @@
"XZ_OPT": "-9" "XZ_OPT": "-9"
} }
}, },
"release-x86_64-linux-ubuntu22_04-release": {
"after_script": [
".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output",
".gitlab/ci.sh clean",
"cat ci_timings"
],
"allow_failure": false,
"artifacts": {
"expire_in": "1 year",
"paths": [
"ghc-x86_64-linux-ubuntu22_04-release.tar.xz",
"junit.xml",
"unexpected-test-output.tar.gz"
],
"reports": {
"junit": "junit.xml"
},
"when": "always"
},
"cache": {
"key": "x86_64-linux-ubuntu22_04-$CACHE_REV",
"paths": [
"cabal-cache",
"toolchain"
]
},
"dependencies": [],
"image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-ubuntu22_04:$DOCKER_REV",
"needs": [
{
"artifacts": false,
"job": "hadrian-ghc-in-ghci"
}
],
"rules": [
{
"if": "(\"true\" == \"true\") && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null)",
"when": "on_success"
}
],
"script": [
"sudo chown ghc:ghc -R .",
".gitlab/ci.sh setup",
".gitlab/ci.sh configure",
".gitlab/ci.sh build_hadrian",
".gitlab/ci.sh test_hadrian"
],
"stage": "full-build",
"tags": [
"x86_64-linux"
],
"variables": {
"BIGNUM_BACKEND": "gmp",
"BIN_DIST_NAME": "ghc-x86_64-linux-ubuntu22_04-release",
"BUILD_FLAVOUR": "release",
"CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"HADRIAN_ARGS": "--hash-unit-ids",
"IGNORE_PERF_FAILURES": "all",
"INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
"RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-ubuntu22_04-release",
"XZ_OPT": "-9"
}
},
"release-x86_64-windows-int_native-release": { "release-x86_64-windows-int_native-release": {
"after_script": [ "after_script": [
"bash .gitlab/ci.sh save_cache", "bash .gitlab/ci.sh save_cache",
...@@ -4712,7 +4840,7 @@ ...@@ -4712,7 +4840,7 @@
"TEST_ENV": "x86_64-linux-alpine3_12-validate+fully_static" "TEST_ENV": "x86_64-linux-alpine3_12-validate+fully_static"
} }
}, },
"x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf": { "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
"after_script": [ "after_script": [
".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output", ".gitlab/ci.sh save_test_output",
...@@ -4723,7 +4851,7 @@ ...@@ -4723,7 +4851,7 @@
"artifacts": { "artifacts": {
"expire_in": "2 weeks", "expire_in": "2 weeks",
"paths": [ "paths": [
"ghc-x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf.tar.xz", "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
"junit.xml", "junit.xml",
"unexpected-test-output.tar.gz" "unexpected-test-output.tar.gz"
], ],
...@@ -4733,14 +4861,14 @@ ...@@ -4733,14 +4861,14 @@
"when": "always" "when": "always"
}, },
"cache": { "cache": {
"key": "x86_64-linux-alpine3_18-wasm-$CACHE_REV", "key": "x86_64-linux-alpine3_20-wasm-$CACHE_REV",
"paths": [ "paths": [
"cabal-cache", "cabal-cache",
"toolchain" "toolchain"
] ]
}, },
"dependencies": [], "dependencies": [],
"image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_18-wasm:$DOCKER_REV", "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_20-wasm:$DOCKER_REV",
"needs": [ "needs": [
{ {
"artifacts": false, "artifacts": false,
...@@ -4766,16 +4894,16 @@ ...@@ -4766,16 +4894,16 @@
], ],
"variables": { "variables": {
"BIGNUM_BACKEND": "gmp", "BIGNUM_BACKEND": "gmp",
"BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf", "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
"BUILD_FLAVOUR": "release+fully_static+text_simdutf", "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
"CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check", "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
"CROSS_TARGET": "wasm32-wasi", "CROSS_TARGET": "wasm32-wasi",
"HADRIAN_ARGS": "--docs=none", "HADRIAN_ARGS": "--docs=none",
"RUNTEST_ARGS": "", "RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-alpine3_18-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf" "TEST_ENV": "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf"
} }
}, },
"x86_64-linux-alpine3_18-wasm-int_native-cross_wasm32-wasi-release+fully_static+text_simdutf": { "x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
"after_script": [ "after_script": [
".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output", ".gitlab/ci.sh save_test_output",
...@@ -4786,7 +4914,7 @@ ...@@ -4786,7 +4914,7 @@
"artifacts": { "artifacts": {
"expire_in": "2 weeks", "expire_in": "2 weeks",
"paths": [ "paths": [
"ghc-x86_64-linux-alpine3_18-wasm-int_native-cross_wasm32-wasi-release+fully_static+text_simdutf.tar.xz", "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
"junit.xml", "junit.xml",
"unexpected-test-output.tar.gz" "unexpected-test-output.tar.gz"
], ],
...@@ -4796,14 +4924,14 @@ ...@@ -4796,14 +4924,14 @@
"when": "always" "when": "always"
}, },
"cache": { "cache": {
"key": "x86_64-linux-alpine3_18-wasm-$CACHE_REV", "key": "x86_64-linux-alpine3_20-wasm-$CACHE_REV",
"paths": [ "paths": [
"cabal-cache", "cabal-cache",
"toolchain" "toolchain"
] ]
}, },
"dependencies": [], "dependencies": [],
"image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_18-wasm:$DOCKER_REV", "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_20-wasm:$DOCKER_REV",
"needs": [ "needs": [
{ {
"artifacts": false, "artifacts": false,
...@@ -4830,16 +4958,16 @@ ...@@ -4830,16 +4958,16 @@
], ],
"variables": { "variables": {
"BIGNUM_BACKEND": "native", "BIGNUM_BACKEND": "native",
"BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_18-wasm-int_native-cross_wasm32-wasi-release+fully_static+text_simdutf", "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
"BUILD_FLAVOUR": "release+fully_static+text_simdutf", "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
"CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check", "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
"CROSS_TARGET": "wasm32-wasi", "CROSS_TARGET": "wasm32-wasi",
"HADRIAN_ARGS": "--docs=none", "HADRIAN_ARGS": "--docs=none",
"RUNTEST_ARGS": "", "RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-alpine3_18-wasm-int_native-cross_wasm32-wasi-release+fully_static+text_simdutf" "TEST_ENV": "x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf"
} }
}, },
"x86_64-linux-alpine3_18-wasm-unreg-cross_wasm32-wasi-release+fully_static+text_simdutf": { "x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
"after_script": [ "after_script": [
".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_cache",
".gitlab/ci.sh save_test_output", ".gitlab/ci.sh save_test_output",
...@@ -4850,7 +4978,7 @@ ...@@ -4850,7 +4978,7 @@
"artifacts": { "artifacts": {
"expire_in": "2 weeks", "expire_in": "2 weeks",
"paths": [ "paths": [
"ghc-x86_64-linux-alpine3_18-wasm-unreg-cross_wasm32-wasi-release+fully_static+text_simdutf.tar.xz", "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
"junit.xml", "junit.xml",
"unexpected-test-output.tar.gz" "unexpected-test-output.tar.gz"
], ],
...@@ -4860,14 +4988,14 @@ ...@@ -4860,14 +4988,14 @@
"when": "always" "when": "always"
}, },
"cache": { "cache": {
"key": "x86_64-linux-alpine3_18-wasm-$CACHE_REV", "key": "x86_64-linux-alpine3_20-wasm-$CACHE_REV",
"paths": [ "paths": [
"cabal-cache", "cabal-cache",
"toolchain" "toolchain"
] ]
}, },
"dependencies": [], "dependencies": [],
"image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_18-wasm:$DOCKER_REV", "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_20-wasm:$DOCKER_REV",
"needs": [ "needs": [
{ {
"artifacts": false, "artifacts": false,
...@@ -4894,13 +5022,13 @@ ...@@ -4894,13 +5022,13 @@
], ],
"variables": { "variables": {
"BIGNUM_BACKEND": "gmp", "BIGNUM_BACKEND": "gmp",
"BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_18-wasm-unreg-cross_wasm32-wasi-release+fully_static+text_simdutf", "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
"BUILD_FLAVOUR": "release+fully_static+text_simdutf", "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
"CONFIGURE_ARGS": "--enable-unregisterised --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check", "CONFIGURE_ARGS": "--enable-unregisterised --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
"CROSS_TARGET": "wasm32-wasi", "CROSS_TARGET": "wasm32-wasi",
"HADRIAN_ARGS": "--docs=none", "HADRIAN_ARGS": "--docs=none",
"RUNTEST_ARGS": "", "RUNTEST_ARGS": "",
"TEST_ENV": "x86_64-linux-alpine3_18-wasm-unreg-cross_wasm32-wasi-release+fully_static+text_simdutf" "TEST_ENV": "x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf"
} }
}, },
"x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": { "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": {
......
...@@ -19,6 +19,7 @@ def job_triple(job_name): ...@@ -19,6 +19,7 @@ def job_triple(job_name):
'release-x86_64-windows-release': 'x86_64-unknown-mingw32', 'release-x86_64-windows-release': 'x86_64-unknown-mingw32',
'release-x86_64-windows-int_native-release': 'x86_64-unknown-mingw32-int_native', 'release-x86_64-windows-int_native-release': 'x86_64-unknown-mingw32-int_native',
'release-x86_64-linux-rocky8-release': 'x86_64-rocky8-linux', 'release-x86_64-linux-rocky8-release': 'x86_64-rocky8-linux',
'release-x86_64-linux-ubuntu22_04-release': 'x86_64-ubuntu22_04-linux',
'release-x86_64-linux-ubuntu20_04-release': 'x86_64-ubuntu20_04-linux', 'release-x86_64-linux-ubuntu20_04-release': 'x86_64-ubuntu20_04-linux',
'release-x86_64-linux-ubuntu18_04-release': 'x86_64-ubuntu18_04-linux', 'release-x86_64-linux-ubuntu18_04-release': 'x86_64-ubuntu18_04-linux',
'release-x86_64-linux-fedora38-release': 'x86_64-fedora38-linux', 'release-x86_64-linux-fedora38-release': 'x86_64-fedora38-linux',
......
...@@ -191,6 +191,7 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): ...@@ -191,6 +191,7 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map):
# Here are all the bindists we can distribute # Here are all the bindists we can distribute
ubuntu1804 = mk(ubuntu("18_04")) ubuntu1804 = mk(ubuntu("18_04"))
ubuntu2004 = mk(ubuntu("20_04")) ubuntu2004 = mk(ubuntu("20_04"))
ubuntu2204 = mk(ubuntu("22_04"))
rocky8 = mk(rocky("8")) rocky8 = mk(rocky("8"))
centos7 = mk(centos(7)) centos7 = mk(centos(7))
fedora33 = mk(fedora(33)) fedora33 = mk(fedora(33))
...@@ -222,7 +223,10 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): ...@@ -222,7 +223,10 @@ def mk_new_yaml(release_mode, version, date, pipeline_type, job_map):
, "unknown_versioning": deb11 } , "unknown_versioning": deb11 }
, "Linux_Ubuntu" : { "unknown_versioning": ubuntu2004 , "Linux_Ubuntu" : { "unknown_versioning": ubuntu2004
, "( >= 16 && < 18 )": deb9 , "( >= 16 && < 18 )": deb9
, "( >= 18 && < 19 )": ubuntu1804 } , "( >= 18 && < 19 )": ubuntu1804
, "( >= 19 && < 21 )": ubuntu2004
, "( >= 21 )": ubuntu2204
}
, "Linux_Mint" : { "< 20": ubuntu1804 , "Linux_Mint" : { "< 20": ubuntu1804
, ">= 20": ubuntu2004 , ">= 20": ubuntu2004
, "unknown_versioning": ubuntu2004 } , "unknown_versioning": ubuntu2004 }
......
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
/compiler/GHC/Wasm/ @nrnrnr /compiler/GHC/Wasm/ @nrnrnr
/compiler/GHC/JS/ @luite @doyougnu @hsyl20 @JoshMeredith /compiler/GHC/JS/ @luite @doyougnu @hsyl20 @JoshMeredith
/compiler/GHC/StgToJS/ @luite @doyougnu @hsyl20 @JoshMeredith /compiler/GHC/StgToJS/ @luite @doyougnu @hsyl20 @JoshMeredith
/compiler/GHC/Runtime/Interpreter/Wasm.hs @TerrorJack
[Core libraries] [Core libraries]
/libraries/base/ @hvr /libraries/base/ @hvr
......
...@@ -432,6 +432,7 @@ import GHC.Unit.Module.ModDetails ...@@ -432,6 +432,7 @@ import GHC.Unit.Module.ModDetails
import GHC.Unit.Module.ModSummary import GHC.Unit.Module.ModSummary
import GHC.Unit.Module.Graph import GHC.Unit.Module.Graph
import GHC.Unit.Home.ModInfo import GHC.Unit.Home.ModInfo
import GHC.Settings
import Control.Applicative ((<|>)) import Control.Applicative ((<|>))
import Control.Concurrent import Control.Concurrent
...@@ -704,6 +705,53 @@ setTopSessionDynFlags dflags = do ...@@ -704,6 +705,53 @@ setTopSessionDynFlags dflags = do
-- Interpreter -- Interpreter
interp <- if interp <- if
-- Wasm dynamic linker
| ArchWasm32 <- platformArch $ targetPlatform dflags
-> do
s <- liftIO $ newMVar InterpPending
loader <- liftIO Loader.uninitializedLoader
dyld <- liftIO $ makeAbsolute $ topDir dflags </> "dyld.mjs"
#if defined(wasm32_HOST_ARCH)
let libdir = sorry "cannot spawn child process on wasm"
#else
libdir <- liftIO $ do
libdirs <- Loader.getGccSearchDirectory logger dflags "libraries"
case libdirs of
[_, libdir] -> pure libdir
_ -> panic "corrupted wasi-sdk installation"
#endif
let profiled = ways dflags `hasWay` WayProf
way_tag = if profiled then "_p" else ""
let cfg =
WasmInterpConfig
{ wasmInterpDyLD = dyld,
wasmInterpLibDir = libdir,
wasmInterpOpts = getOpts dflags opt_i,
wasmInterpTargetPlatform = targetPlatform dflags,
wasmInterpProfiled = profiled,
wasmInterpHsSoSuffix = way_tag ++ dynLibSuffix (ghcNameVersion dflags),
wasmInterpUnitState = ue_units $ hsc_unit_env hsc_env
}
pure $ Just $ Interp (ExternalInterp $ ExtWasm $ ExtInterpState cfg s) loader lookup_cache
-- JavaScript interpreter
| ArchJavaScript <- platformArch (targetPlatform dflags)
-> do
s <- liftIO $ newMVar InterpPending
loader <- liftIO Loader.uninitializedLoader
let cfg = JSInterpConfig
{ jsInterpNodeConfig = defaultNodeJsSettings
, jsInterpScript = topDir dflags </> "ghc-interp.js"
, jsInterpTmpFs = hsc_tmpfs hsc_env
, jsInterpTmpDir = tmpDir dflags
, jsInterpLogger = hsc_logger hsc_env
, jsInterpCodegenCfg = initStgToJSConfig dflags
, jsInterpUnitEnv = hsc_unit_env hsc_env
, jsInterpFinderOpts = initFinderOpts dflags
, jsInterpFinderCache = hsc_FC hsc_env
}
return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache))
-- external interpreter -- external interpreter
| gopt Opt_ExternalInterpreter dflags | gopt Opt_ExternalInterpreter dflags
-> do -> do
...@@ -733,24 +781,6 @@ setTopSessionDynFlags dflags = do ...@@ -733,24 +781,6 @@ setTopSessionDynFlags dflags = do
loader <- liftIO Loader.uninitializedLoader loader <- liftIO Loader.uninitializedLoader
return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache)) return (Just (Interp (ExternalInterp (ExtIServ (ExtInterpState conf s))) loader lookup_cache))
-- JavaScript interpreter
| ArchJavaScript <- platformArch (targetPlatform dflags)
-> do
s <- liftIO $ newMVar InterpPending
loader <- liftIO Loader.uninitializedLoader
let cfg = JSInterpConfig
{ jsInterpNodeConfig = defaultNodeJsSettings
, jsInterpScript = topDir dflags </> "ghc-interp.js"
, jsInterpTmpFs = hsc_tmpfs hsc_env
, jsInterpTmpDir = tmpDir dflags
, jsInterpLogger = hsc_logger hsc_env
, jsInterpCodegenCfg = initStgToJSConfig dflags
, jsInterpUnitEnv = hsc_unit_env hsc_env
, jsInterpFinderOpts = initFinderOpts dflags
, jsInterpFinderCache = hsc_FC hsc_env
}
return (Just (Interp (ExternalInterp (ExtJS (ExtInterpState cfg s))) loader lookup_cache))
-- Internal interpreter -- Internal interpreter
| otherwise | otherwise
-> ->
......
...@@ -142,6 +142,11 @@ cmmMakeDynamicReference config referenceKind lbl ...@@ -142,6 +142,11 @@ cmmMakeDynamicReference config referenceKind lbl
addImport symbolPtr addImport symbolPtr
return $ cmmLoadBWord platform (cmmMakePicReference config symbolPtr) return $ cmmLoadBWord platform (cmmMakePicReference config symbolPtr)
-- On wasm, always preserve the original CLabel, the backends
-- will handle dynamic references properly
AccessDirectly | ArchWasm32 <- platformArch platform ->
pure $ CmmLit $ CmmLabel lbl
AccessDirectly -> case referenceKind of AccessDirectly -> case referenceKind of
-- for data, we might have to make some calculations: -- for data, we might have to make some calculations:
DataReference -> return $ cmmMakePicReference config lbl DataReference -> return $ cmmMakePicReference config lbl
...@@ -413,6 +418,11 @@ howToAccessLabel config _arch os _kind lbl ...@@ -413,6 +418,11 @@ howToAccessLabel config _arch os _kind lbl
then AccessViaSymbolPtr then AccessViaSymbolPtr
else AccessDirectly else AccessDirectly
-- On wasm, always keep the original CLabel and let the backend decide
-- how to handle dynamic references
howToAccessLabel _ ArchWasm32 _ _ _
= AccessDirectly
-- all other platforms -- all other platforms
howToAccessLabel config _arch _os _kind _lbl howToAccessLabel config _arch _os _kind _lbl
| not (ncgPIC config) | not (ncgPIC config)
......
...@@ -1109,6 +1109,8 @@ getRegister' config plat expr = ...@@ -1109,6 +1109,8 @@ getRegister' config plat expr =
MO_F_Mul w -> floatOp w (\d x y -> unitOL $ annExpr expr (MUL d x y)) MO_F_Mul w -> floatOp w (\d x y -> unitOL $ annExpr expr (MUL d x y))
MO_F_Quot w -> floatOp w (\d x y -> unitOL $ annExpr expr (DIV d x y)) MO_F_Quot w -> floatOp w (\d x y -> unitOL $ annExpr expr (DIV d x y))
-- Floating point comparison -- Floating point comparison
MO_F_Min w -> floatOp w (\d x y -> unitOL $ annExpr expr (FMIN d x y))
MO_F_Max w -> floatOp w (\d x y -> unitOL $ annExpr expr (FMAX d x y))
MO_F_Eq w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y EQ)) MO_F_Eq w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y EQ))
MO_F_Ne w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y NE)) MO_F_Ne w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y NE))
MO_F_Ge w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y FGE)) MO_F_Ge w -> floatCond w (\d x y -> unitOL $ annExpr expr (CSET d x y FGE))
...@@ -2208,6 +2210,8 @@ makeFarBranches {- only used when debugging -} _platform statics basic_blocks = ...@@ -2208,6 +2210,8 @@ makeFarBranches {- only used when debugging -} _platform statics basic_blocks =
FENCE {} -> 1 FENCE {} -> 1
FCVT {} -> 1 FCVT {} -> 1
FABS {} -> 1 FABS {} -> 1
FMIN {} -> 1
FMAX {} -> 1
FMA {} -> 1 FMA {} -> 1
-- estimate the subsituted size for jumps to lables -- estimate the subsituted size for jumps to lables
-- jumps to registers have size 1 -- jumps to registers have size 1
......
...@@ -107,6 +107,8 @@ regUsageOfInstr platform instr = case instr of ...@@ -107,6 +107,8 @@ regUsageOfInstr platform instr = case instr of
FENCE _ _ -> usage ([], []) FENCE _ _ -> usage ([], [])
FCVT _variant dst src -> usage (regOp src, regOp dst) FCVT _variant dst src -> usage (regOp src, regOp dst)
FABS dst src -> usage (regOp src, regOp dst) FABS dst src -> usage (regOp src, regOp dst)
FMIN dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
FMAX dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
FMA _ dst src1 src2 src3 -> FMA _ dst src1 src2 src3 ->
usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst) usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst)
_ -> panic $ "regUsageOfInstr: " ++ instrCon instr _ -> panic $ "regUsageOfInstr: " ++ instrCon instr
...@@ -203,6 +205,8 @@ patchRegsOfInstr instr env = case instr of ...@@ -203,6 +205,8 @@ patchRegsOfInstr instr env = case instr of
FENCE o1 o2 -> FENCE o1 o2 FENCE o1 o2 -> FENCE o1 o2
FCVT variant o1 o2 -> FCVT variant (patchOp o1) (patchOp o2) FCVT variant o1 o2 -> FCVT variant (patchOp o1) (patchOp o2)
FABS o1 o2 -> FABS (patchOp o1) (patchOp o2) FABS o1 o2 -> FABS (patchOp o1) (patchOp o2)
FMIN o1 o2 o3 -> FMIN (patchOp o1) (patchOp o2) (patchOp o3)
FMAX o1 o2 o3 -> FMAX (patchOp o1) (patchOp o2) (patchOp o3)
FMA s o1 o2 o3 o4 -> FMA s o1 o2 o3 o4 ->
FMA s (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) FMA s (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4)
_ -> panic $ "patchRegsOfInstr: " ++ instrCon instr _ -> panic $ "patchRegsOfInstr: " ++ instrCon instr
...@@ -603,6 +607,13 @@ data Instr ...@@ -603,6 +607,13 @@ data Instr
FCVT FcvtVariant Operand Operand FCVT FcvtVariant Operand Operand
| -- | Floating point ABSolute value | -- | Floating point ABSolute value
FABS Operand Operand FABS Operand Operand
| -- | Min
-- dest = min(r1)
FMIN Operand Operand Operand
| -- | Max
FMAX Operand Operand Operand
| -- | Floating-point fused multiply-add instructions | -- | Floating-point fused multiply-add instructions
-- --
-- - fmadd : d = r1 * r2 + r3 -- - fmadd : d = r1 * r2 + r3
...@@ -658,6 +669,8 @@ instrCon i = ...@@ -658,6 +669,8 @@ instrCon i =
FENCE {} -> "FENCE" FENCE {} -> "FENCE"
FCVT {} -> "FCVT" FCVT {} -> "FCVT"
FABS {} -> "FABS" FABS {} -> "FABS"
FMIN {} -> "FMIN"
FMAX {} -> "FMAX"
FMA variant _ _ _ _ -> FMA variant _ _ _ _ ->
case variant of case variant of
FMAdd -> "FMADD" FMAdd -> "FMADD"
......
...@@ -666,6 +666,10 @@ pprInstr platform instr = case instr of ...@@ -666,6 +666,10 @@ pprInstr platform instr = case instr of
$ line (pprOp platform o1 <> text "->" <> pprOp platform o2) $ line (pprOp platform o1 <> text "->" <> pprOp platform o2)
FABS o1 o2 | isSingleOp o2 -> op2 (text "\tfabs.s") o1 o2 FABS o1 o2 | isSingleOp o2 -> op2 (text "\tfabs.s") o1 o2
FABS o1 o2 | isDoubleOp o2 -> op2 (text "\tfabs.d") o1 o2 FABS o1 o2 | isDoubleOp o2 -> op2 (text "\tfabs.d") o1 o2
FMIN o1 o2 o3 | isSingleOp o1 -> op3 (text "\tfmin.s") o1 o2 o3
| isDoubleOp o2 -> op3 (text "\tfmin.d") o1 o2 o3
FMAX o1 o2 o3 | isSingleOp o1 -> op3 (text "\tfmax.s") o1 o2 o3
| isDoubleOp o2 -> op3 (text "\tfmax.d") o1 o2 o3
FMA variant d r1 r2 r3 -> FMA variant d r1 r2 r3 ->
let fma = case variant of let fma = case variant of
FMAdd -> text "\tfmadd" <> dot <> floatPrecission d FMAdd -> text "\tfmadd" <> dot <> floatPrecission d
......
...@@ -40,12 +40,11 @@ ncgWasm :: ...@@ -40,12 +40,11 @@ ncgWasm ::
ncgWasm ncg_config logger platform ts loc h cmms = do ncgWasm ncg_config logger platform ts loc h cmms = do
(r, s) <- streamCmmGroups ncg_config platform cmms (r, s) <- streamCmmGroups ncg_config platform cmms
outputWasm $ "# " <> string7 (fromJust $ ml_hs_file loc) <> "\n\n" outputWasm $ "# " <> string7 (fromJust $ ml_hs_file loc) <> "\n\n"
outputWasm $ execWasmAsmM do_tail_call $ asmTellEverything TagI32 s -- See Note [WasmTailCall]
let cfg = (defaultWasmAsmConfig s) { pic = ncgPIC ncg_config, tailcall = doTailCall ts }
outputWasm $ execWasmAsmM cfg $ asmTellEverything TagI32 s
pure r pure r
where where
-- See Note [WasmTailCall]
do_tail_call = doTailCall ts
outputWasm builder = liftIO $ do outputWasm builder = liftIO $ do
putDumpFileMaybe putDumpFileMaybe
logger logger
......
...@@ -35,13 +35,13 @@ import GHC.Utils.Outputable hiding ((<>)) ...@@ -35,13 +35,13 @@ import GHC.Utils.Outputable hiding ((<>))
import GHC.Utils.Panic (panic) import GHC.Utils.Panic (panic)
-- | Reads current indentation, appends result to state -- | Reads current indentation, appends result to state
newtype WasmAsmM a = WasmAsmM (Bool -> Builder -> State Builder a) newtype WasmAsmM a = WasmAsmM (WasmAsmConfig -> Builder -> State Builder a)
deriving deriving
( Functor, ( Functor,
Applicative, Applicative,
Monad Monad
) )
via (ReaderT Bool (ReaderT Builder (State Builder))) via (ReaderT WasmAsmConfig (ReaderT Builder (State Builder)))
instance Semigroup a => Semigroup (WasmAsmM a) where instance Semigroup a => Semigroup (WasmAsmM a) where
(<>) = liftA2 (<>) (<>) = liftA2 (<>)
...@@ -49,19 +49,18 @@ instance Semigroup a => Semigroup (WasmAsmM a) where ...@@ -49,19 +49,18 @@ instance Semigroup a => Semigroup (WasmAsmM a) where
instance Monoid a => Monoid (WasmAsmM a) where instance Monoid a => Monoid (WasmAsmM a) where
mempty = pure mempty mempty = pure mempty
-- | To tail call or not, that is the question getConf :: WasmAsmM WasmAsmConfig
doTailCall :: WasmAsmM Bool getConf = WasmAsmM $ \conf _ -> pure conf
doTailCall = WasmAsmM $ \do_tail_call _ -> pure do_tail_call
-- | Default indent level is none -- | Default indent level is none
execWasmAsmM :: Bool -> WasmAsmM a -> Builder execWasmAsmM :: WasmAsmConfig -> WasmAsmM a -> Builder
execWasmAsmM do_tail_call (WasmAsmM m) = execWasmAsmM conf (WasmAsmM m) =
execState (m do_tail_call mempty) mempty execState (m conf mempty) mempty
-- | Increase indent level by a tab -- | Increase indent level by a tab
asmWithTab :: WasmAsmM a -> WasmAsmM a asmWithTab :: WasmAsmM a -> WasmAsmM a
asmWithTab (WasmAsmM m) = asmWithTab (WasmAsmM m) =
WasmAsmM $ \do_tail_call t -> m do_tail_call $! char7 '\t' <> t WasmAsmM $ \conf t -> m conf $! char7 '\t' <> t
-- | Writes a single line starting with the current indent -- | Writes a single line starting with the current indent
asmTellLine :: Builder -> WasmAsmM () asmTellLine :: Builder -> WasmAsmM ()
...@@ -113,7 +112,8 @@ asmFromSymName = shortByteString . coerce fastStringToShortByteString ...@@ -113,7 +112,8 @@ asmFromSymName = shortByteString . coerce fastStringToShortByteString
asmTellDefSym :: SymName -> WasmAsmM () asmTellDefSym :: SymName -> WasmAsmM ()
asmTellDefSym sym = do asmTellDefSym sym = do
asmTellTabLine $ ".hidden " <> asm_sym WasmAsmConfig {..} <- getConf
unless pic $ asmTellTabLine $ ".hidden " <> asm_sym
asmTellTabLine $ ".globl " <> asm_sym asmTellTabLine $ ".globl " <> asm_sym
where where
asm_sym = asmFromSymName sym asm_sym = asmFromSymName sym
...@@ -136,7 +136,7 @@ asmTellDataSectionContent ty_word c = asmTellTabLine $ case c of ...@@ -136,7 +136,7 @@ asmTellDataSectionContent ty_word c = asmTellTabLine $ case c of
<> ( case compare o 0 of <> ( case compare o 0 of
EQ -> mempty EQ -> mempty
GT -> "+" <> intDec o GT -> "+" <> intDec o
LT -> intDec o LT -> panic "asmTellDataSectionContent: negative offset"
) )
DataSkip i -> ".skip " <> intDec i DataSkip i -> ".skip " <> intDec i
DataASCII s DataASCII s
...@@ -245,14 +245,27 @@ asmTellWasmInstr ty_word instr = case instr of ...@@ -245,14 +245,27 @@ asmTellWasmInstr ty_word instr = case instr of
WasmConst TagI32 i -> asmTellLine $ "i32.const " <> integerDec i WasmConst TagI32 i -> asmTellLine $ "i32.const " <> integerDec i
WasmConst TagI64 i -> asmTellLine $ "i64.const " <> integerDec i WasmConst TagI64 i -> asmTellLine $ "i64.const " <> integerDec i
WasmConst {} -> panic "asmTellWasmInstr: unreachable" WasmConst {} -> panic "asmTellWasmInstr: unreachable"
WasmSymConst sym -> WasmSymConst sym -> do
asmTellLine $ WasmAsmConfig {..} <- getConf
( case ty_word of let
TagI32 -> "i32.const " asm_sym = asmFromSymName sym
TagI64 -> "i64.const " (ty_const, ty_add) = case ty_word of
_ -> panic "asmTellWasmInstr: unreachable" TagI32 -> ("i32.const ", "i32.add")
) TagI64 -> ("i64.const ", "i64.add")
<> asmFromSymName sym _ -> panic "asmTellWasmInstr: invalid word type"
traverse_ asmTellLine $ if
| pic, getUnique sym `memberUniqueSet` mbrelSyms -> [
"global.get __memory_base",
ty_const <> asm_sym <> "@MBREL",
ty_add
]
| pic, getUnique sym `memberUniqueSet` tbrelSyms -> [
"global.get __table_base",
ty_const <> asm_sym <> "@TBREL",
ty_add
]
| pic -> [ "global.get " <> asm_sym <> "@GOT" ]
| otherwise -> [ ty_const <> asm_sym ]
WasmLoad ty (Just w) s o align -> WasmLoad ty (Just w) s o align ->
asmTellLine $ asmTellLine $
asmFromWasmType ty asmFromWasmType ty
...@@ -400,12 +413,12 @@ asmTellWasmControl ty_word c = case c of ...@@ -400,12 +413,12 @@ asmTellWasmControl ty_word c = case c of
asmTellLine $ "br_table {" <> builderCommas intDec (ts <> [t]) <> "}" asmTellLine $ "br_table {" <> builderCommas intDec (ts <> [t]) <> "}"
-- See Note [WasmTailCall] -- See Note [WasmTailCall]
WasmTailCall (WasmExpr e) -> do WasmTailCall (WasmExpr e) -> do
do_tail_call <- doTailCall WasmAsmConfig {..} <- getConf
if if
| do_tail_call, | tailcall,
WasmSymConst sym <- e -> WasmSymConst sym <- e ->
asmTellLine $ "return_call " <> asmFromSymName sym asmTellLine $ "return_call " <> asmFromSymName sym
| do_tail_call -> | tailcall ->
do do
asmTellWasmInstr ty_word e asmTellWasmInstr ty_word e
asmTellLine $ asmTellLine $
...@@ -442,13 +455,25 @@ asmTellFunc ty_word def_syms sym (func_ty, FuncBody {..}) = do ...@@ -442,13 +455,25 @@ asmTellFunc ty_word def_syms sym (func_ty, FuncBody {..}) = do
asmTellGlobals :: WasmTypeTag w -> WasmAsmM () asmTellGlobals :: WasmTypeTag w -> WasmAsmM ()
asmTellGlobals ty_word = do asmTellGlobals ty_word = do
WasmAsmConfig {..} <- getConf
when pic $ traverse_ asmTellTabLine [
".globaltype __memory_base, i32, immutable",
".globaltype __table_base, i32, immutable"
]
for_ supportedCmmGlobalRegs $ \reg -> for_ supportedCmmGlobalRegs $ \reg ->
let (sym, ty) = fromJust $ globalInfoFromCmmGlobalReg ty_word reg let
in asmTellTabLine $ (sym, ty) = fromJust $ globalInfoFromCmmGlobalReg ty_word reg
asm_sym = asmFromSymName sym
in do
asmTellTabLine $
".globaltype " ".globaltype "
<> asmFromSymName sym <> asm_sym
<> ", " <> ", "
<> asmFromSomeWasmType ty <> asmFromSomeWasmType ty
when pic $ traverse_ asmTellTabLine [
".import_module " <> asm_sym <> ", regs",
".import_name " <> asm_sym <> ", " <> asm_sym
]
asmTellLF asmTellLF
asmTellCtors :: WasmTypeTag w -> [SymName] -> WasmAsmM () asmTellCtors :: WasmTypeTag w -> [SymName] -> WasmAsmM ()
...@@ -496,14 +521,14 @@ asmTellProducers = do ...@@ -496,14 +521,14 @@ asmTellProducers = do
asmTellTargetFeatures :: WasmAsmM () asmTellTargetFeatures :: WasmAsmM ()
asmTellTargetFeatures = do asmTellTargetFeatures = do
do_tail_call <- doTailCall WasmAsmConfig {..} <- getConf
asmTellSectionHeader ".custom_section.target_features" asmTellSectionHeader ".custom_section.target_features"
asmTellVec asmTellVec
[ do [ do
asmTellTabLine ".int8 0x2b" asmTellTabLine ".int8 0x2b"
asmTellBS feature asmTellBS feature
| feature <- | feature <-
["tail-call" | do_tail_call] ["tail-call" | tailcall]
<> [ "bulk-memory", <> [ "bulk-memory",
"mutable-globals", "mutable-globals",
"nontrapping-fptoint", "nontrapping-fptoint",
......
...@@ -45,7 +45,9 @@ module GHC.CmmToAsm.Wasm.Types ...@@ -45,7 +45,9 @@ module GHC.CmmToAsm.Wasm.Types
wasmStateM, wasmStateM,
wasmModifyM, wasmModifyM,
wasmExecM, wasmExecM,
wasmRunM wasmRunM,
WasmAsmConfig (..),
defaultWasmAsmConfig
) )
where where
...@@ -137,7 +139,9 @@ data SymVisibility ...@@ -137,7 +139,9 @@ data SymVisibility
SymStatic SymStatic
| -- | Defined, visible to other compilation units. | -- | Defined, visible to other compilation units.
-- --
-- Adds @.hidden@ & @.globl@ directives in the output assembly. -- Adds @.globl@ directives in the output assembly. Also adds
-- @.hidden@ when not generating PIC code, similar to
-- -fvisibility=hidden in clang.
-- --
-- @[ binding=global vis=hidden ]@ -- @[ binding=global vis=hidden ]@
SymDefault SymDefault
...@@ -483,3 +487,35 @@ instance MonadGetUnique (WasmCodeGenM w) where ...@@ -483,3 +487,35 @@ instance MonadGetUnique (WasmCodeGenM w) where
getUniqueM = wasmStateM $ getUniqueM = wasmStateM $
\s@WasmCodeGenState {..} -> case takeUniqueFromDSupply wasmDUniqSupply of \s@WasmCodeGenState {..} -> case takeUniqueFromDSupply wasmDUniqSupply of
(u, us) -> (# u, s {wasmDUniqSupply = us} #) (u, us) -> (# u, s {wasmDUniqSupply = us} #)
data WasmAsmConfig = WasmAsmConfig
{
pic, tailcall :: Bool,
-- | Data/function symbols with 'SymStatic' visibility (defined
-- but not visible to other compilation units). When doing PIC
-- codegen, private symbols must be emitted as @MBREL@/@TBREL@
-- relocations in the code section. The public symbols, defined or
-- elsewhere, are all emitted as @GOT@ relocations instead.
mbrelSyms, tbrelSyms :: ~SymSet
}
-- | The default 'WasmAsmConfig' must be extracted from the final
-- 'WasmCodeGenState'.
defaultWasmAsmConfig :: WasmCodeGenState w -> WasmAsmConfig
defaultWasmAsmConfig WasmCodeGenState {..} =
WasmAsmConfig
{ pic = False,
tailcall = False,
mbrelSyms = mk_rel_syms dataSections,
tbrelSyms = mk_rel_syms funcBodies
}
where
mk_rel_syms :: SymMap a -> SymSet
mk_rel_syms =
nonDetFoldUniqMap
( \(sym, _) acc ->
if getUnique sym `memberUniqueSet` defaultSyms
then acc
else insertUniqueSet (getUnique sym) acc
)
emptyUniqueSet
...@@ -85,25 +85,23 @@ llvmCodeGen logger cfg h dus cmm_stream ...@@ -85,25 +85,23 @@ llvmCodeGen logger cfg h dus cmm_stream
llvm_ver = fromMaybe supportedLlvmVersionLowerBound mb_ver llvm_ver = fromMaybe supportedLlvmVersionLowerBound mb_ver
-- run code generation -- run code generation
a <- runLlvm logger cfg llvm_ver bufh $ (a, _) <- runLlvm logger cfg llvm_ver bufh dus $
llvmCodeGen' cfg dus cmm_stream llvmCodeGen' cfg cmm_stream
bFlush bufh bFlush bufh
return a return a
llvmCodeGen' :: LlvmCgConfig llvmCodeGen' :: LlvmCgConfig
-> DUniqSupply -- ^ The deterministic uniq supply to run the CgStream.
-- See Note [Deterministic Uniques in the CG]
-> CgStream RawCmmGroup a -> LlvmM a -> CgStream RawCmmGroup a -> LlvmM a
llvmCodeGen' cfg dus cmm_stream llvmCodeGen' cfg cmm_stream
= do -- Preamble = do -- Preamble
renderLlvm (llvmHeader cfg) (llvmHeader cfg) renderLlvm (llvmHeader cfg) (llvmHeader cfg)
ghcInternalFunctions ghcInternalFunctions
cmmMetaLlvmPrelude cmmMetaLlvmPrelude
-- Procedures -- Procedures
(a, _) <- runUDSMT dus $ Stream.consume cmm_stream (hoistUDSMT liftIO) (liftUDSMT . llvmGroupLlvmGens) a <- Stream.consume cmm_stream (GHC.CmmToLlvm.Base.liftUDSMT) (llvmGroupLlvmGens)
-- Declare aliases for forward references -- Declare aliases for forward references
decls <- generateExternDecls decls <- generateExternDecls
......
...@@ -23,7 +23,7 @@ module GHC.CmmToLlvm.Base ( ...@@ -23,7 +23,7 @@ module GHC.CmmToLlvm.Base (
ghcInternalFunctions, getPlatform, getConfig, ghcInternalFunctions, getPlatform, getConfig,
getMetaUniqueId, getMetaUniqueId,
setUniqMeta, getUniqMeta, liftIO, setUniqMeta, getUniqMeta, liftIO, liftUDSMT,
cmmToLlvmType, widthToLlvmFloat, widthToLlvmInt, llvmFunTy, cmmToLlvmType, widthToLlvmFloat, widthToLlvmInt, llvmFunTy,
llvmFunSig, llvmFunArgs, llvmStdFunAttrs, llvmFunAlign, llvmInfAlign, llvmFunSig, llvmFunArgs, llvmStdFunAttrs, llvmFunAlign, llvmInfAlign,
...@@ -57,7 +57,6 @@ import GHC.Types.Unique.FM ...@@ -57,7 +57,6 @@ import GHC.Types.Unique.FM
import GHC.Types.Unique import GHC.Types.Unique
import GHC.Utils.BufHandle ( BufHandle ) import GHC.Utils.BufHandle ( BufHandle )
import GHC.Types.Unique.Set import GHC.Types.Unique.Set
import GHC.Types.Unique.Supply
import qualified GHC.Types.Unique.DSM as DSM import qualified GHC.Types.Unique.DSM as DSM
import GHC.Utils.Logger import GHC.Utils.Logger
...@@ -68,6 +67,7 @@ import Data.Maybe (fromJust, mapMaybe) ...@@ -68,6 +67,7 @@ import Data.Maybe (fromJust, mapMaybe)
import Data.List (find, isPrefixOf) import Data.List (find, isPrefixOf)
import qualified Data.List.NonEmpty as NE import qualified Data.List.NonEmpty as NE
import Data.Ord (comparing) import Data.Ord (comparing)
import qualified Control.Monad.IO.Class as IO
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
-- * Some Data Types -- * Some Data Types
...@@ -296,14 +296,13 @@ data LlvmEnv = LlvmEnv ...@@ -296,14 +296,13 @@ data LlvmEnv = LlvmEnv
type LlvmEnvMap = UniqFM Unique LlvmType type LlvmEnvMap = UniqFM Unique LlvmType
-- | The Llvm monad. Wraps @LlvmEnv@ state as well as the @IO@ monad -- | The Llvm monad. Wraps @LlvmEnv@ state as well as the @IO@ monad
newtype LlvmM a = LlvmM { runLlvmM :: LlvmEnv -> IO (a, LlvmEnv) } newtype LlvmM a = LlvmM { runLlvmM :: LlvmEnv -> DSM.UniqDSMT IO (a, LlvmEnv) }
deriving stock (Functor) deriving stock (Functor)
deriving (Applicative, Monad) via StateT LlvmEnv IO deriving (Applicative, Monad) via StateT LlvmEnv (DSM.UniqDSMT IO)
instance HasLogger LlvmM where instance HasLogger LlvmM where
getLogger = LlvmM $ \env -> return (envLogger env, env) getLogger = LlvmM $ \env -> return (envLogger env, env)
-- | Get target platform -- | Get target platform
getPlatform :: LlvmM Platform getPlatform :: LlvmM Platform
getPlatform = llvmCgPlatform <$> getConfig getPlatform = llvmCgPlatform <$> getConfig
...@@ -312,23 +311,30 @@ getConfig :: LlvmM LlvmCgConfig ...@@ -312,23 +311,30 @@ getConfig :: LlvmM LlvmCgConfig
getConfig = LlvmM $ \env -> return (envConfig env, env) getConfig = LlvmM $ \env -> return (envConfig env, env)
-- TODO(#25274): If you want Llvm code to be deterministic, this instance should use a -- This instance uses a deterministic unique supply from UniqDSMT, so new
-- deterministic unique supply to produce uniques, rather than using 'uniqFromTag'. -- uniques within LlvmM will be sampled deterministically.
instance DSM.MonadGetUnique LlvmM where instance DSM.MonadGetUnique LlvmM where
getUniqueM = do getUniqueM = do
tag <- getEnv envTag tag <- getEnv envTag
liftIO $! uniqFromTag tag liftUDSMT $! do
uq <- DSM.getUniqueM
return (newTagUnique uq tag)
-- | Lifting of IO actions. Not exported, as we want to encapsulate IO. -- | Lifting of IO actions. Not exported, as we want to encapsulate IO.
liftIO :: IO a -> LlvmM a liftIO :: IO a -> LlvmM a
liftIO m = LlvmM $ \env -> do x <- m liftIO m = LlvmM $ \env -> do x <- IO.liftIO m
return (x, env) return (x, env)
-- | Lifting of UniqDSMT actions. Gives access to the deterministic unique supply being threaded through by LlvmM.
liftUDSMT :: DSM.UniqDSMT IO a -> LlvmM a
liftUDSMT m = LlvmM $ \env -> do x <- m
return (x, env)
-- | Get initial Llvm environment. -- | Get initial Llvm environment.
runLlvm :: Logger -> LlvmCgConfig -> LlvmVersion -> BufHandle -> LlvmM a -> IO a runLlvm :: Logger -> LlvmCgConfig -> LlvmVersion -> BufHandle -> DSM.DUniqSupply -> LlvmM a -> IO (a, DSM.DUniqSupply)
runLlvm logger cfg ver out m = do runLlvm logger cfg ver out us m = do
(a, _) <- runLlvmM m env ((a, _), us') <- DSM.runUDSMT us $ runLlvmM m env
return a return (a, us')
where env = LlvmEnv { envFunMap = emptyUFM where env = LlvmEnv { envFunMap = emptyUFM
, envVarMap = emptyUFM , envVarMap = emptyUFM
, envStackRegs = [] , envStackRegs = []
......
...@@ -20,7 +20,8 @@ ToDo [Oct 2013] ...@@ -20,7 +20,8 @@ ToDo [Oct 2013]
module GHC.Core.Opt.SpecConstr( module GHC.Core.Opt.SpecConstr(
specConstrProgram, specConstrProgram,
SpecConstrAnnotation(..) SpecConstrAnnotation(..),
SpecFailWarning(..)
) where ) where
import GHC.Prelude import GHC.Prelude
...@@ -51,6 +52,7 @@ import GHC.Core.Make ( mkImpossibleExpr ) ...@@ -51,6 +52,7 @@ import GHC.Core.Make ( mkImpossibleExpr )
import GHC.Unit.Module import GHC.Unit.Module
import GHC.Unit.Module.ModGuts import GHC.Unit.Module.ModGuts
import GHC.Types.Error (MessageClass(..), Severity(..), DiagnosticReason(WarningWithoutFlag), ResolvedDiagnosticReason (..))
import GHC.Types.Literal ( litIsLifted ) import GHC.Types.Literal ( litIsLifted )
import GHC.Types.Id import GHC.Types.Id
import GHC.Types.Id.Info ( IdDetails(..) ) import GHC.Types.Id.Info ( IdDetails(..) )
...@@ -526,9 +528,11 @@ sc_force to True when calling specLoop. This flag does four things: ...@@ -526,9 +528,11 @@ sc_force to True when calling specLoop. This flag does four things:
(see argToPat; #4448) (see argToPat; #4448)
(FS4) Only specialise on recursive types a finite number of times (FS4) Only specialise on recursive types a finite number of times
(see sc_recursive; #5550; Note [Limit recursive specialisation]) (see sc_recursive; #5550; Note [Limit recursive specialisation])
(FS5) Lift the restriction on the maximum number of arguments which (FS5) Use a different restriction on the maximum number of arguments which
the optimisation will specialise. the optimisation will specialise. We tried removing the limit on worker
(see `too_many_worker_args` in `callsToNewPats`; #14003) args for forced specs (#14003) but this caused issues when specializing
code for large data structures (#25197).
This is handled by `too_many_worker_args` in `callsToNewPats`
The flag holds only for specialising a single binding group, and NOT The flag holds only for specialising a single binding group, and NOT
for nested bindings. (So really it should be passed around explicitly for nested bindings. (So really it should be passed around explicitly
...@@ -782,16 +786,25 @@ specConstrProgram :: ModGuts -> CoreM ModGuts ...@@ -782,16 +786,25 @@ specConstrProgram :: ModGuts -> CoreM ModGuts
specConstrProgram guts specConstrProgram guts
= do { env0 <- initScEnv guts = do { env0 <- initScEnv guts
; us <- getUniqueSupplyM ; us <- getUniqueSupplyM
; let (_usg, binds') = initUs_ us $ ; let (_usg, binds', warnings) = initUs_ us $
scTopBinds env0 (mg_binds guts) scTopBinds env0 (mg_binds guts)
; when (not (null warnings)) $ msg specConstr_warn_class (warn_msg warnings)
; return (guts { mg_binds = binds' }) } ; return (guts { mg_binds = binds' }) }
scTopBinds :: ScEnv -> [InBind] -> UniqSM (ScUsage, [OutBind]) where
scTopBinds _env [] = return (nullUsage, []) specConstr_warn_class = MCDiagnostic SevWarning (ResolvedDiagnosticReason WarningWithoutFlag) Nothing
scTopBinds env (b:bs) = do { (usg, b', bs') <- scBind TopLevel env b $ warn_msg :: SpecFailWarnings -> SDoc
warn_msg warnings = text "SpecConstr encountered one or more function(s) with a SPEC argument that resulted in too many arguments," $$
text "which resulted in no specialization being generated for these functions:" $$
nest 2 (vcat (map ppr warnings)) $$
(text "If this is expected you might want to increase -fmax-forced-spec-args to force specialization anyway.")
scTopBinds :: ScEnv -> [InBind] -> UniqSM (ScUsage, [OutBind], [SpecFailWarning])
scTopBinds _env [] = return (nullUsage, [], [])
scTopBinds env (b:bs) = do { (usg, b', bs', warnings) <- scBind TopLevel env b $
(\env -> scTopBinds env bs) (\env -> scTopBinds env bs)
; return (usg, b' ++ bs') } ; return (usg, b' ++ bs', warnings) }
{- {-
************************************************************************ ************************************************************************
...@@ -905,6 +918,12 @@ data SpecConstrOpts = SpecConstrOpts ...@@ -905,6 +918,12 @@ data SpecConstrOpts = SpecConstrOpts
-- ^ The threshold at which a worker-wrapper transformation used as part of -- ^ The threshold at which a worker-wrapper transformation used as part of
-- this pass will no longer happen, measured in the number of arguments. -- this pass will no longer happen, measured in the number of arguments.
, sc_max_forced_args :: !Int
-- ^ The threshold at which a worker-wrapper transformation used as part of
-- this pass will no longer happen even if a SPEC arg was used to force
-- specialization. Measured in the number of arguments.
-- See Note [Forcing specialisation]
, sc_debug :: !Bool , sc_debug :: !Bool
-- ^ Whether to print debug information -- ^ Whether to print debug information
...@@ -975,6 +994,7 @@ instance Outputable Value where ...@@ -975,6 +994,7 @@ instance Outputable Value where
initScOpts :: DynFlags -> Module -> SpecConstrOpts initScOpts :: DynFlags -> Module -> SpecConstrOpts
initScOpts dflags this_mod = SpecConstrOpts initScOpts dflags this_mod = SpecConstrOpts
{ sc_max_args = maxWorkerArgs dflags, { sc_max_args = maxWorkerArgs dflags,
sc_max_forced_args = maxForcedSpecArgs dflags,
sc_debug = hasPprDebug dflags, sc_debug = hasPprDebug dflags,
sc_uf_opts = unfoldingOpts dflags, sc_uf_opts = unfoldingOpts dflags,
sc_module = this_mod, sc_module = this_mod,
...@@ -1388,29 +1408,29 @@ creates specialised versions of functions. ...@@ -1388,29 +1408,29 @@ creates specialised versions of functions.
-} -}
scBind :: TopLevelFlag -> ScEnv -> InBind scBind :: TopLevelFlag -> ScEnv -> InBind
-> (ScEnv -> UniqSM (ScUsage, a)) -- Specialise the scope of the binding -> (ScEnv -> UniqSM (ScUsage, a, [SpecFailWarning])) -- Specialise the scope of the binding
-> UniqSM (ScUsage, [OutBind], a) -> UniqSM (ScUsage, [OutBind], a, [SpecFailWarning])
scBind top_lvl env (NonRec bndr rhs) do_body scBind top_lvl env (NonRec bndr rhs) do_body
| isTyVar bndr -- Type-lets may be created by doBeta | isTyVar bndr -- Type-lets may be created by doBeta
= do { (final_usage, body') <- do_body (extendScSubst env bndr rhs) = do { (final_usage, body', warnings) <- do_body (extendScSubst env bndr rhs)
; return (final_usage, [], body') } ; return (final_usage, [], body', warnings) }
| not (isTopLevel top_lvl) -- Nested non-recursive value binding | not (isTopLevel top_lvl) -- Nested non-recursive value binding
-- See Note [Specialising local let bindings] -- See Note [Specialising local let bindings]
= do { let (body_env, bndr') = extendBndr env bndr = do { let (body_env, bndr') = extendBndr env bndr
-- Not necessary at top level; but here we are nested -- Not necessary at top level; but here we are nested
; rhs_info <- scRecRhs env (bndr',rhs) ; (rhs_info, rhs_ws) <- scRecRhs env (bndr',rhs)
; let body_env2 = extendHowBound body_env [bndr'] RecFun ; let body_env2 = extendHowBound body_env [bndr'] RecFun
rhs' = ri_new_rhs rhs_info rhs' = ri_new_rhs rhs_info
body_env3 = extendValEnv body_env2 bndr' (isValue (sc_vals env) rhs') body_env3 = extendValEnv body_env2 bndr' (isValue (sc_vals env) rhs')
; (body_usg, body') <- do_body body_env3 ; (body_usg, body', warnings_body) <- do_body body_env3
-- Now make specialised copies of the binding, -- Now make specialised copies of the binding,
-- based on calls in body_usg -- based on calls in body_usg
; (spec_usg, specs) <- specNonRec env (scu_calls body_usg) rhs_info ; (spec_usg, specs, warnings_bnd) <- specNonRec env (scu_calls body_usg) rhs_info
-- NB: For non-recursive bindings we inherit sc_force flag from -- NB: For non-recursive bindings we inherit sc_force flag from
-- the parent function (see Note [Forcing specialisation]) -- the parent function (see Note [Forcing specialisation])
...@@ -1419,7 +1439,7 @@ scBind top_lvl env (NonRec bndr rhs) do_body ...@@ -1419,7 +1439,7 @@ scBind top_lvl env (NonRec bndr rhs) do_body
bind_usage = (body_usg `delCallsFor` [bndr']) bind_usage = (body_usg `delCallsFor` [bndr'])
`combineUsage` spec_usg -- Note [spec_usg includes rhs_usg] `combineUsage` spec_usg -- Note [spec_usg includes rhs_usg]
; return (bind_usage, spec_bnds, body') ; return (bind_usage, spec_bnds, body', mconcat [warnings_bnd, warnings_body, rhs_ws])
} }
| otherwise -- Top-level, non-recursive value binding | otherwise -- Top-level, non-recursive value binding
...@@ -1431,15 +1451,15 @@ scBind top_lvl env (NonRec bndr rhs) do_body ...@@ -1431,15 +1451,15 @@ scBind top_lvl env (NonRec bndr rhs) do_body
-- --
-- I tried always specialising non-recursive top-level bindings too, -- I tried always specialising non-recursive top-level bindings too,
-- but found some regressions (see !8135). So I backed off. -- but found some regressions (see !8135). So I backed off.
= do { (rhs_usage, rhs') <- scExpr env rhs = do { (rhs_usage, rhs', ws_rhs) <- scExpr env rhs
-- At top level, we've already put all binders into scope; see initScEnv -- At top level, we've already put all binders into scope; see initScEnv
-- Hence no need to call `extendBndr`. But we still want to -- Hence no need to call `extendBndr`. But we still want to
-- extend the `ValueEnv` to record the value of this binder. -- extend the `ValueEnv` to record the value of this binder.
; let body_env = extendValEnv env bndr (isValue (sc_vals env) rhs') ; let body_env = extendValEnv env bndr (isValue (sc_vals env) rhs')
; (body_usage, body') <- do_body body_env ; (body_usage, body', body_warnings) <- do_body body_env
; return (rhs_usage `combineUsage` body_usage, [NonRec bndr rhs'], body') } ; return (rhs_usage `combineUsage` body_usage, [NonRec bndr rhs'], body', body_warnings ++ ws_rhs) }
scBind top_lvl env (Rec prs) do_body scBind top_lvl env (Rec prs) do_body
| isTopLevel top_lvl | isTopLevel top_lvl
...@@ -1450,19 +1470,20 @@ scBind top_lvl env (Rec prs) do_body ...@@ -1450,19 +1470,20 @@ scBind top_lvl env (Rec prs) do_body
-- ToDo: I'm honestly not sure of the rationale of this size-testing, nor -- ToDo: I'm honestly not sure of the rationale of this size-testing, nor
-- why it only applies at top level. But that's the way it has been -- why it only applies at top level. But that's the way it has been
-- for a while. See #21456. -- for a while. See #21456.
do { (body_usg, body') <- do_body rhs_env2 do { (body_usg, body', warnings_body) <- do_body rhs_env2
; (rhs_usgs, rhss') <- mapAndUnzipM (scExpr env) rhss ; (rhs_usgs, rhss', rhs_ws) <- mapAndUnzip3M (scExpr env) rhss
; let all_usg = (combineUsages rhs_usgs `combineUsage` body_usg) ; let all_usg = (combineUsages rhs_usgs `combineUsage` body_usg)
`delCallsFor` bndrs' `delCallsFor` bndrs'
bind' = Rec (bndrs' `zip` rhss') bind' = Rec (bndrs' `zip` rhss')
; return (all_usg, [bind'], body') } ; return (all_usg, [bind'], body', warnings_body ++ concat rhs_ws) }
| otherwise | otherwise
= do { rhs_infos <- mapM (scRecRhs rhs_env2) (bndrs' `zip` rhss) = do { (rhs_infos, rhs_wss) <- mapAndUnzipM (scRecRhs rhs_env2) (bndrs' `zip` rhss)
; (body_usg, body') <- do_body rhs_env2 ; let rhs_ws = mconcat rhs_wss
; (body_usg, body', warnings_body) <- do_body rhs_env2
; (spec_usg, specs) <- specRec (scForce rhs_env2 force_spec) ; (spec_usg, specs, spec_ws) <- specRec (scForce rhs_env2 force_spec)
(scu_calls body_usg) rhs_infos (scu_calls body_usg) rhs_infos
-- Do not unconditionally generate specialisations from rhs_usgs -- Do not unconditionally generate specialisations from rhs_usgs
-- Instead use them only if we find an unspecialised call -- Instead use them only if we find an unspecialised call
-- See Note [Seeding recursive groups] -- See Note [Seeding recursive groups]
...@@ -1473,7 +1494,7 @@ scBind top_lvl env (Rec prs) do_body ...@@ -1473,7 +1494,7 @@ scBind top_lvl env (Rec prs) do_body
-- zipWithEqual: length of returned [SpecInfo] -- zipWithEqual: length of returned [SpecInfo]
-- should be the same as incoming [RhsInfo] -- should be the same as incoming [RhsInfo]
; return (all_usg, [bind'], body') } ; return (all_usg, [bind'], body', mconcat [warnings_body,rhs_ws,spec_ws]) }
where where
(bndrs,rhss) = unzip prs (bndrs,rhss) = unzip prs
force_spec = any (forceSpecBndr env) bndrs -- Note [Forcing specialisation] force_spec = any (forceSpecBndr env) bndrs -- Note [Forcing specialisation]
...@@ -1501,59 +1522,63 @@ recursive function, but that's not essential and might even be ...@@ -1501,59 +1522,63 @@ recursive function, but that's not essential and might even be
harmful. I'm not sure. harmful. I'm not sure.
-} -}
withWarnings :: SpecFailWarnings -> (ScUsage, CoreExpr, SpecFailWarnings) -> (ScUsage, CoreExpr, SpecFailWarnings)
withWarnings ws (use,expr,ws2) = (use,expr,ws ++ ws2)
------------------------ ------------------------
scExpr, scExpr' :: ScEnv -> CoreExpr -> UniqSM (ScUsage, CoreExpr) scExpr, scExpr' :: ScEnv -> CoreExpr -> UniqSM (ScUsage, CoreExpr, SpecFailWarnings)
-- The unique supply is needed when we invent -- The unique supply is needed when we invent
-- a new name for the specialised function and its args -- a new name for the specialised function and its args
scExpr env e = scExpr' env e scExpr env e = scExpr' env e
scExpr' env (Var v) = case scSubstId env v of scExpr' env (Var v) = case scSubstId env v of
Var v' -> return (mkVarUsage env v' [], Var v') Var v' -> return (mkVarUsage env v' [], Var v', [])
e' -> scExpr (zapScSubst env) e' e' -> scExpr (zapScSubst env) e'
scExpr' env (Type t) = scExpr' env (Type t) =
let !(MkSolo ty') = scSubstTy env t let !(MkSolo ty') = scSubstTy env t
in return (nullUsage, Type ty') in return (nullUsage, Type ty', [])
scExpr' env (Coercion c) = return (nullUsage, Coercion (scSubstCo env c)) scExpr' env (Coercion c) = return (nullUsage, Coercion (scSubstCo env c), [])
scExpr' _ e@(Lit {}) = return (nullUsage, e) scExpr' _ e@(Lit {}) = return (nullUsage, e, [])
scExpr' env (Tick t e) = do (usg, e') <- scExpr env e scExpr' env (Tick t e) = do (usg, e', ws) <- scExpr env e
return (usg, Tick (scTickish env t) e') return (usg, Tick (scTickish env t) e', ws)
scExpr' env (Cast e co) = do (usg, e') <- scExpr env e scExpr' env (Cast e co) = do (usg, e', ws) <- scExpr env e
return (usg, mkCast e' (scSubstCo env co)) return (usg, mkCast e' (scSubstCo env co), ws)
-- Important to use mkCast here -- Important to use mkCast here
-- See Note [SpecConstr call patterns] -- See Note [SpecConstr call patterns]
scExpr' env e@(App _ _) = scApp env (collectArgs e) scExpr' env e@(App _ _) = scApp env (collectArgs e)
scExpr' env (Lam b e) = do let (env', b') = extendBndr env b scExpr' env (Lam b e) = do let (env', b') = extendBndr env b
(usg, e') <- scExpr env' e (usg, e', ws) <- scExpr env' e
return (usg, Lam b' e') return (usg, Lam b' e', ws)
scExpr' env (Let bind body) scExpr' env (Let bind body)
= do { (final_usage, binds', body') <- scBind NotTopLevel env bind $ = do { (final_usage, binds', body', ws) <- scBind NotTopLevel env bind $
(\env -> scExpr env body) (\env -> scExpr env body)
; return (final_usage, mkLets binds' body') } ; return (final_usage, mkLets binds' body', ws) }
scExpr' env (Case scrut b ty alts) scExpr' env (Case scrut b ty alts)
= do { (scrut_usg, scrut') <- scExpr env scrut = do { (scrut_usg, scrut', ws) <- scExpr env scrut
; case isValue (sc_vals env) scrut' of ; case isValue (sc_vals env) scrut' of
Just (ConVal args_are_work_free con args) Just (ConVal args_are_work_free con args)
| args_are_work_free -> sc_con_app con args scrut' | args_are_work_free -> sc_con_app con args scrut' ws
-- Don't duplicate work!! #7865 -- Don't duplicate work!! #7865
-- See Note [ConVal work-free-ness] (1) -- See Note [ConVal work-free-ness] (1)
_other -> sc_vanilla scrut_usg scrut' _other -> sc_vanilla scrut_usg scrut' ws
} }
where where
sc_con_app con args scrut' -- Known constructor; simplify sc_con_app con args scrut' ws -- Known constructor; simplify
= do { let Alt _ bs rhs = findAlt con alts = do { let Alt _ bs rhs = findAlt con alts
`orElse` Alt DEFAULT [] (mkImpossibleExpr ty "SpecConstr") `orElse` Alt DEFAULT [] (mkImpossibleExpr ty "SpecConstr")
alt_env' = extendScSubstList env ((b,scrut') : bs `zip` trimConArgs con args) alt_env' = extendScSubstList env ((b,scrut') : bs `zip` trimConArgs con args)
; scExpr alt_env' rhs } ; (use',expr',ws_new) <- scExpr alt_env' rhs
; return (use',expr',ws ++ ws_new) }
sc_vanilla scrut_usg scrut' -- Normal case sc_vanilla scrut_usg scrut' ws -- Normal case
= do { let (alt_env,b') = extendBndrWith RecArg env b = do { let (alt_env,b') = extendBndrWith RecArg env b
-- Record RecArg for the components -- Record RecArg for the components
; (alt_usgs, alt_occs, alts') <- mapAndUnzip3M (sc_alt alt_env scrut' b') alts ; (alt_usgs, alt_occs, alts', ws_alts) <- mapAndUnzip4M (sc_alt alt_env scrut' b') alts
; let scrut_occ = foldr combineOcc NoOcc alt_occs ; let scrut_occ = foldr combineOcc NoOcc alt_occs
scrut_usg' = setScrutOcc env scrut_usg scrut' scrut_occ scrut_usg' = setScrutOcc env scrut_usg scrut' scrut_occ
...@@ -1563,21 +1588,21 @@ scExpr' env (Case scrut b ty alts) ...@@ -1563,21 +1588,21 @@ scExpr' env (Case scrut b ty alts)
; let !(MkSolo ty') = scSubstTy env ty ; let !(MkSolo ty') = scSubstTy env ty
; return (foldr combineUsage scrut_usg' alt_usgs, ; return (foldr combineUsage scrut_usg' alt_usgs,
Case scrut' b' ty' alts') } Case scrut' b' ty' alts', ws ++ concat ws_alts) }
single_alt = isSingleton alts single_alt = isSingleton alts
sc_alt env scrut' b' (Alt con bs rhs) sc_alt env scrut' b' (Alt con bs rhs)
= do { let (env1, bs1) = extendBndrsWith RecArg env bs = do { let (env1, bs1) = extendBndrsWith RecArg env bs
(env2, bs2) = extendCaseBndrs env1 scrut' b' con bs1 (env2, bs2) = extendCaseBndrs env1 scrut' b' con bs1
; (usg, rhs') <- scExpr env2 rhs ; (usg, rhs', ws) <- scExpr env2 rhs
; let (usg', b_occ:arg_occs) = lookupOccs usg (b':bs2) ; let (usg', b_occ:arg_occs) = lookupOccs usg (b':bs2)
scrut_occ = case con of scrut_occ = case con of
DataAlt dc -- See Note [Do not specialise evals] DataAlt dc -- See Note [Do not specialise evals]
| not (single_alt && all deadArgOcc arg_occs) | not (single_alt && all deadArgOcc arg_occs)
-> ScrutOcc (unitUFM dc arg_occs) -> ScrutOcc (unitUFM dc arg_occs)
_ -> UnkOcc _ -> UnkOcc
; return (usg', b_occ `combineOcc` scrut_occ, Alt con bs2 rhs') } ; return (usg', b_occ `combineOcc` scrut_occ, Alt con bs2 rhs', ws) }
-- | Substitute the free variables captured by a breakpoint. -- | Substitute the free variables captured by a breakpoint.
...@@ -1626,19 +1651,20 @@ follows. ...@@ -1626,19 +1651,20 @@ follows.
still worth specialising on x. Hence the /single-alternative/ guard. still worth specialising on x. Hence the /single-alternative/ guard.
-} -}
scApp :: ScEnv -> (InExpr, [InExpr]) -> UniqSM (ScUsage, CoreExpr) scApp :: ScEnv -> (InExpr, [InExpr]) -> UniqSM (ScUsage, CoreExpr, SpecFailWarnings)
scApp env (Var fn, args) -- Function is a variable scApp env (Var fn, args) -- Function is a variable
= assert (not (null args)) $ = assert (not (null args)) $
do { args_w_usgs <- mapM (scExpr env) args do { args_w_usgs <- mapM (scExpr env) args
; let (arg_usgs, args') = unzip args_w_usgs ; let (arg_usgs, args', arg_ws) = unzip3 args_w_usgs
arg_usg = combineUsages arg_usgs arg_usg = combineUsages arg_usgs
arg_w = concat arg_ws
; case scSubstId env fn of ; case scSubstId env fn of
fn'@(Lam {}) -> scExpr (zapScSubst env) (doBeta fn' args') fn'@(Lam {}) -> withWarnings arg_w <$> scExpr (zapScSubst env) (doBeta fn' args')
-- Do beta-reduction and try again -- Do beta-reduction and try again
Var fn' -> return (arg_usg' `combineUsage` mkVarUsage env fn' args', Var fn' -> return (arg_usg' `combineUsage` mkVarUsage env fn' args',
mkApps (Var fn') args') mkApps (Var fn') args', arg_w )
where where
-- arg_usg': see Note [Specialising on dictionaries] -- arg_usg': see Note [Specialising on dictionaries]
arg_usg' | Just cls <- isClassOpId_maybe fn' arg_usg' | Just cls <- isClassOpId_maybe fn'
...@@ -1647,7 +1673,7 @@ scApp env (Var fn, args) -- Function is a variable ...@@ -1647,7 +1673,7 @@ scApp env (Var fn, args) -- Function is a variable
| otherwise | otherwise
= arg_usg = arg_usg
other_fn' -> return (arg_usg, mkApps other_fn' args') } other_fn' -> return (arg_usg, mkApps other_fn' args', arg_w) }
-- NB: doing this ignores any usage info from the substituted -- NB: doing this ignores any usage info from the substituted
-- function, but I don't think that matters. If it does -- function, but I don't think that matters. If it does
-- we can fix it. -- we can fix it.
...@@ -1661,9 +1687,9 @@ scApp env (Var fn, args) -- Function is a variable ...@@ -1661,9 +1687,9 @@ scApp env (Var fn, args) -- Function is a variable
-- which it may, we can get -- which it may, we can get
-- (let f = ...f... in f) arg1 arg2 -- (let f = ...f... in f) arg1 arg2
scApp env (other_fn, args) scApp env (other_fn, args)
= do { (fn_usg, fn') <- scExpr env other_fn = do { (fn_usg, fn', fn_ws) <- scExpr env other_fn
; (arg_usgs, args') <- mapAndUnzipM (scExpr env) args ; (arg_usgs, args', arg_ws) <- mapAndUnzip3M (scExpr env) args
; return (combineUsages arg_usgs `combineUsage` fn_usg, mkApps fn' args') } ; return (combineUsages arg_usgs `combineUsage` fn_usg, mkApps fn' args', combineSpecWarning fn_ws (concat arg_ws)) }
---------------------- ----------------------
mkVarUsage :: ScEnv -> Id -> [CoreExpr] -> ScUsage mkVarUsage :: ScEnv -> Id -> [CoreExpr] -> ScUsage
...@@ -1679,16 +1705,16 @@ mkVarUsage env fn args ...@@ -1679,16 +1705,16 @@ mkVarUsage env fn args
| otherwise = evalScrutOcc | otherwise = evalScrutOcc
---------------------- ----------------------
scRecRhs :: ScEnv -> (OutId, InExpr) -> UniqSM RhsInfo scRecRhs :: ScEnv -> (OutId, InExpr) -> UniqSM (RhsInfo, SpecFailWarnings)
scRecRhs env (bndr,rhs) scRecRhs env (bndr,rhs)
= do { let (arg_bndrs,body) = collectBinders rhs = do { let (arg_bndrs,body) = collectBinders rhs
(body_env, arg_bndrs') = extendBndrsWith RecArg env arg_bndrs (body_env, arg_bndrs') = extendBndrsWith RecArg env arg_bndrs
; (body_usg, body') <- scExpr body_env body ; (body_usg, body', body_ws) <- scExpr body_env body
; let (rhs_usg, arg_occs) = lookupOccs body_usg arg_bndrs' ; let (rhs_usg, arg_occs) = lookupOccs body_usg arg_bndrs'
; return (RI { ri_rhs_usg = rhs_usg ; return (RI { ri_rhs_usg = rhs_usg
, ri_fn = bndr, ri_new_rhs = mkLams arg_bndrs' body' , ri_fn = bndr, ri_new_rhs = mkLams arg_bndrs' body'
, ri_lam_bndrs = arg_bndrs, ri_lam_body = body , ri_lam_bndrs = arg_bndrs, ri_lam_body = body
, ri_arg_occs = arg_occs }) } , ri_arg_occs = arg_occs }, body_ws) }
-- The arg_occs says how the visible, -- The arg_occs says how the visible,
-- lambda-bound binders of the RHS are used -- lambda-bound binders of the RHS are used
-- (including the TyVar binders) -- (including the TyVar binders)
...@@ -1757,7 +1783,7 @@ initSpecInfo (RI { ri_rhs_usg = rhs_usg }) ...@@ -1757,7 +1783,7 @@ initSpecInfo (RI { ri_rhs_usg = rhs_usg })
specNonRec :: ScEnv specNonRec :: ScEnv
-> CallEnv -- Calls in body -> CallEnv -- Calls in body
-> RhsInfo -- Structure info usage info for un-specialised RHS -> RhsInfo -- Structure info usage info for un-specialised RHS
-> UniqSM (ScUsage, SpecInfo) -- Usage from RHSs (specialised and not) -> UniqSM (ScUsage, SpecInfo, [SpecFailWarning]) -- Usage from RHSs (specialised and not)
-- plus details of specialisations -- plus details of specialisations
specNonRec env body_calls rhs_info specNonRec env body_calls rhs_info
...@@ -1767,11 +1793,12 @@ specNonRec env body_calls rhs_info ...@@ -1767,11 +1793,12 @@ specNonRec env body_calls rhs_info
specRec :: ScEnv specRec :: ScEnv
-> CallEnv -- Calls in body -> CallEnv -- Calls in body
-> [RhsInfo] -- Structure info and usage info for un-specialised RHSs -> [RhsInfo] -- Structure info and usage info for un-specialised RHSs
-> UniqSM (ScUsage, [SpecInfo]) -- Usage from all RHSs (specialised and not) -> UniqSM (ScUsage, [SpecInfo], SpecFailWarnings)
-- Usage from all RHSs (specialised and not)
-- plus details of specialisations -- plus details of specialisations
specRec env body_calls rhs_infos specRec env body_calls rhs_infos
= go 1 body_calls nullUsage (map initSpecInfo rhs_infos) = go 1 body_calls nullUsage (map initSpecInfo rhs_infos) []
-- body_calls: see Note [Seeding recursive groups] -- body_calls: see Note [Seeding recursive groups]
-- NB: 'go' always calls 'specialise' once, which in turn unleashes -- NB: 'go' always calls 'specialise' once, which in turn unleashes
-- si_mb_unspec if there are any boring calls in body_calls, -- si_mb_unspec if there are any boring calls in body_calls,
...@@ -1786,23 +1813,25 @@ specRec env body_calls rhs_infos ...@@ -1786,23 +1813,25 @@ specRec env body_calls rhs_infos
-- Two accumulating parameters: -- Two accumulating parameters:
-> ScUsage -- Usage from earlier specialisations -> ScUsage -- Usage from earlier specialisations
-> [SpecInfo] -- Details of specialisations so far -> [SpecInfo] -- Details of specialisations so far
-> UniqSM (ScUsage, [SpecInfo]) -> SpecFailWarnings -- Warnings so far
go n_iter seed_calls usg_so_far spec_infos -> UniqSM (ScUsage, [SpecInfo], SpecFailWarnings)
go n_iter seed_calls usg_so_far spec_infos ws_so_far
= -- pprTrace "specRec3" (vcat [ text "bndrs" <+> ppr (map ri_fn rhs_infos) = -- pprTrace "specRec3" (vcat [ text "bndrs" <+> ppr (map ri_fn rhs_infos)
-- , text "iteration" <+> int n_iter -- , text "iteration" <+> int n_iter
-- , text "spec_infos" <+> ppr (map (map os_pat . si_specs) spec_infos) -- , text "spec_infos" <+> ppr (map (map os_pat . si_specs) spec_infos)
-- ]) $ -- ]) $
do { specs_w_usg <- zipWithM (specialise env seed_calls) rhs_infos spec_infos do { specs_w_usg <- zipWithM (specialise env seed_calls) rhs_infos spec_infos
; let (extra_usg_s, all_spec_infos) = unzip specs_w_usg
; let (extra_usg_s, all_spec_infos, extra_ws ) = unzip3 specs_w_usg
extra_usg = combineUsages extra_usg_s extra_usg = combineUsages extra_usg_s
all_usg = usg_so_far `combineUsage` extra_usg all_usg = usg_so_far `combineUsage` extra_usg
new_calls = scu_calls extra_usg new_calls = scu_calls extra_usg
; go_again n_iter new_calls all_usg all_spec_infos } ; go_again n_iter new_calls all_usg all_spec_infos (ws_so_far ++ concat extra_ws) }
-- go_again deals with termination -- go_again deals with termination
go_again n_iter seed_calls usg_so_far spec_infos go_again n_iter seed_calls usg_so_far spec_infos ws_so_far
| isEmptyVarEnv seed_calls | isEmptyVarEnv seed_calls
= return (usg_so_far, spec_infos) = return (usg_so_far, spec_infos, ws_so_far)
-- Limit recursive specialisation -- Limit recursive specialisation
-- See Note [Limit recursive specialisation] -- See Note [Limit recursive specialisation]
...@@ -1816,10 +1845,10 @@ specRec env body_calls rhs_infos ...@@ -1816,10 +1845,10 @@ specRec env body_calls rhs_infos
-- for the unspecialised function, since it may now be called -- for the unspecialised function, since it may now be called
-- pprTrace "specRec2" (ppr (map (map os_pat . si_specs) spec_infos)) $ -- pprTrace "specRec2" (ppr (map (map os_pat . si_specs) spec_infos)) $
let rhs_usgs = combineUsages (mapMaybe si_mb_unspec spec_infos) let rhs_usgs = combineUsages (mapMaybe si_mb_unspec spec_infos)
in return (usg_so_far `combineUsage` rhs_usgs, spec_infos) in return (usg_so_far `combineUsage` rhs_usgs, spec_infos, ws_so_far)
| otherwise | otherwise
= go (n_iter + 1) seed_calls usg_so_far spec_infos = go (n_iter + 1) seed_calls usg_so_far spec_infos ws_so_far
-- See Note [Limit recursive specialisation] -- See Note [Limit recursive specialisation]
the_limit = case sc_count opts of the_limit = case sc_count opts of
...@@ -1832,7 +1861,7 @@ specialise ...@@ -1832,7 +1861,7 @@ specialise
-> CallEnv -- Info on newly-discovered calls to this function -> CallEnv -- Info on newly-discovered calls to this function
-> RhsInfo -> RhsInfo
-> SpecInfo -- Original RHS plus patterns dealt with -> SpecInfo -- Original RHS plus patterns dealt with
-> UniqSM (ScUsage, SpecInfo) -- New specialised versions and their usage -> UniqSM (ScUsage, SpecInfo, [SpecFailWarning]) -- New specialised versions and their usage
-- See Note [spec_usg includes rhs_usg] -- See Note [spec_usg includes rhs_usg]
...@@ -1850,7 +1879,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs ...@@ -1850,7 +1879,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs
| isDeadEndId fn -- Note [Do not specialise diverging functions] | isDeadEndId fn -- Note [Do not specialise diverging functions]
-- /and/ do not generate specialisation seeds from its RHS -- /and/ do not generate specialisation seeds from its RHS
= -- pprTrace "specialise bot" (ppr fn) $ = -- pprTrace "specialise bot" (ppr fn) $
return (nullUsage, spec_info) return (nullUsage, spec_info, [])
| not (isNeverActive (idInlineActivation fn)) | not (isNeverActive (idInlineActivation fn))
-- See Note [Transfer activation] -- See Note [Transfer activation]
...@@ -1861,7 +1890,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs ...@@ -1861,7 +1890,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs
, not (null arg_bndrs) -- Only specialise functions , not (null arg_bndrs) -- Only specialise functions
, Just all_calls <- lookupVarEnv bind_calls fn -- Some calls to it , Just all_calls <- lookupVarEnv bind_calls fn -- Some calls to it
= -- pprTrace "specialise entry {" (ppr fn <+> ppr all_calls) $ = -- pprTrace "specialise entry {" (ppr fn <+> ppr all_calls) $
do { (boring_call, pats_discarded, new_pats) do { (boring_call, pats_discarded, new_pats, warnings)
<- callsToNewPats env fn spec_info arg_occs all_calls <- callsToNewPats env fn spec_info arg_occs all_calls
; let n_pats = length new_pats ; let n_pats = length new_pats
...@@ -1876,7 +1905,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs ...@@ -1876,7 +1905,7 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs
-- , text "new_pats" <+> ppr new_pats]) -- , text "new_pats" <+> ppr new_pats])
; let spec_env = decreaseSpecCount env n_pats ; let spec_env = decreaseSpecCount env n_pats
; (spec_usgs, new_specs) <- mapAndUnzipM (spec_one spec_env fn arg_bndrs body) ; (spec_usgs, new_specs, new_wss) <- mapAndUnzip3M (spec_one spec_env fn arg_bndrs body)
(new_pats `zip` [spec_count..]) (new_pats `zip` [spec_count..])
-- See Note [Specialise original body] -- See Note [Specialise original body]
...@@ -1900,15 +1929,16 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs ...@@ -1900,15 +1929,16 @@ specialise env bind_calls (RI { ri_fn = fn, ri_lam_bndrs = arg_bndrs
; return (new_usg, SI { si_specs = new_specs ++ specs ; return (new_usg, SI { si_specs = new_specs ++ specs
, si_n_specs = spec_count + n_pats , si_n_specs = spec_count + n_pats
, si_mb_unspec = mb_unspec' }) } , si_mb_unspec = mb_unspec' }
,warnings ++ concat new_wss) }
| otherwise -- No calls, inactive, or not a function | otherwise -- No calls, inactive, or not a function
-- Behave as if there was a single, boring call -- Behave as if there was a single, boring call
= -- pprTrace "specialise inactive" (ppr fn $$ ppr mb_unspec) $ = -- pprTrace "specialise inactive" (ppr fn $$ ppr mb_unspec) $
case mb_unspec of -- Behave as if there was a single, boring call case mb_unspec of -- Behave as if there was a single, boring call
Just rhs_usg -> return (rhs_usg, spec_info { si_mb_unspec = Nothing }) Just rhs_usg -> return (rhs_usg, spec_info { si_mb_unspec = Nothing }, [])
-- See Note [spec_usg includes rhs_usg] -- See Note [spec_usg includes rhs_usg]
Nothing -> return (nullUsage, spec_info) Nothing -> return (nullUsage, spec_info, [])
--------------------- ---------------------
...@@ -1917,7 +1947,7 @@ spec_one :: ScEnv ...@@ -1917,7 +1947,7 @@ spec_one :: ScEnv
-> [InVar] -- Lambda-binders of RHS; should match patterns -> [InVar] -- Lambda-binders of RHS; should match patterns
-> InExpr -- Body of the original function -> InExpr -- Body of the original function
-> (CallPat, Int) -> (CallPat, Int)
-> UniqSM (ScUsage, OneSpec) -- Rule and binding -> UniqSM (ScUsage, OneSpec, SpecFailWarnings) -- Rule and binding, warnings if any
-- spec_one creates a specialised copy of the function, together -- spec_one creates a specialised copy of the function, together
-- with a rule for using it. I'm very proud of how short this -- with a rule for using it. I'm very proud of how short this
...@@ -1969,7 +1999,7 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) ...@@ -1969,7 +1999,7 @@ spec_one env fn arg_bndrs body (call_pat, rule_number)
-- Specialise the body -- Specialise the body
-- ; pprTraceM "body_subst_for" $ ppr (spec_occ) $$ ppr (sc_subst body_env) -- ; pprTraceM "body_subst_for" $ ppr (spec_occ) $$ ppr (sc_subst body_env)
; (spec_usg, spec_body) <- scExpr body_env body ; (spec_usg, spec_body, body_warnings) <- scExpr body_env body
-- And build the results -- And build the results
; (qvars', pats') <- generaliseDictPats qvars pats ; (qvars', pats') <- generaliseDictPats qvars pats
...@@ -2018,7 +2048,7 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) ...@@ -2018,7 +2048,7 @@ spec_one env fn arg_bndrs body (call_pat, rule_number)
-- ] -- ]
; return (spec_usg, OS { os_pat = call_pat, os_rule = rule ; return (spec_usg, OS { os_pat = call_pat, os_rule = rule
, os_id = spec_id , os_id = spec_id
, os_rhs = spec_rhs }) } , os_rhs = spec_rhs }, body_warnings) }
generaliseDictPats :: [Var] -> [CoreExpr] -- Quantified vars and pats generaliseDictPats :: [Var] -> [CoreExpr] -- Quantified vars and pats
-> UniqSM ([Var], [CoreExpr]) -- New quantified vars and pats -> UniqSM ([Var], [CoreExpr]) -- New quantified vars and pats
...@@ -2402,12 +2432,26 @@ instance Outputable CallPat where ...@@ -2402,12 +2432,26 @@ instance Outputable CallPat where
, text "cp_args =" <+> ppr args , text "cp_args =" <+> ppr args
, text "cp_strict_args = " <> ppr strict ]) , text "cp_strict_args = " <> ppr strict ])
newtype SpecFailWarning = SpecFailForcedArgCount { spec_failed_fun_name :: Name }
type SpecFailWarnings = [SpecFailWarning]
instance Outputable SpecFailWarning where
ppr (SpecFailForcedArgCount name) = ppr name <+> pprDefinedAt name
combineSpecWarning :: SpecFailWarnings -> SpecFailWarnings -> SpecFailWarnings
combineSpecWarning = (++)
data ArgCountResult = WorkerSmallEnough | WorkerTooLarge | WorkerTooLargeForced Name
callsToNewPats :: ScEnv -> Id callsToNewPats :: ScEnv -> Id
-> SpecInfo -> SpecInfo
-> [ArgOcc] -> [Call] -> [ArgOcc] -> [Call]
-> UniqSM ( Bool -- At least one boring call -> UniqSM ( Bool -- At least one boring call
, Bool -- Patterns were discarded , Bool -- Patterns were discarded
, [CallPat] ) -- Patterns to specialise , [CallPat] -- Patterns to specialise
, [SpecFailWarning] -- Things that didn't specialise we want to warn the user about)
)
-- Result has no duplicate patterns, -- Result has no duplicate patterns,
-- nor ones mentioned in si_specs (hence "new" patterns) -- nor ones mentioned in si_specs (hence "new" patterns)
-- Bool indicates that there was at least one boring pattern -- Bool indicates that there was at least one boring pattern
...@@ -2433,12 +2477,18 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls ...@@ -2433,12 +2477,18 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls
non_dups = subsumePats in_scope new_pats non_dups = subsumePats in_scope new_pats
-- Remove ones that have too many worker variables -- Remove ones that have too many worker variables
small_pats = filterOut too_many_worker_args non_dups (small_pats, arg_count_warnings) = partitionByWorkerSize too_many_worker_args non_dups
too_many_worker_args _ -- too_many_worker_args :: CallPat -> Either SpecFailWarning Bool
| sc_force env = False -- See (FS5) of Note [Forcing specialisation]
too_many_worker_args (CP { cp_qvars = vars, cp_args = args }) too_many_worker_args (CP { cp_qvars = vars, cp_args = args })
= not (isWorkerSmallEnough (sc_max_args $ sc_opts env) (valArgCount args) vars) | sc_force env
-- See (FS5) of Note [Forcing specialisation]
= if (isWorkerSmallEnough (sc_max_forced_args $ sc_opts env) (valArgCount args) vars)
then WorkerSmallEnough
else WorkerTooLargeForced (idName fn)
| (isWorkerSmallEnough (sc_max_args $ sc_opts env) (valArgCount args) vars)
= WorkerSmallEnough
| otherwise = WorkerTooLarge
-- We are about to construct w/w pair in 'spec_one'. -- We are about to construct w/w pair in 'spec_one'.
-- Omit specialisation leading to high arity workers. -- Omit specialisation leading to high arity workers.
-- See Note [Limit w/w arity] in GHC.Core.Opt.WorkWrap.Utils -- See Note [Limit w/w arity] in GHC.Core.Opt.WorkWrap.Utils
...@@ -2454,10 +2504,21 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls ...@@ -2454,10 +2504,21 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls
-- , text "done_specs:" <+> ppr (map os_pat done_specs) -- , text "done_specs:" <+> ppr (map os_pat done_specs)
-- , text "trimmed_pats:" <+> ppr trimmed_pats ]) -- , text "trimmed_pats:" <+> ppr trimmed_pats ])
; return (have_boring_call, pats_were_discarded, trimmed_pats) } ; return (have_boring_call, pats_were_discarded, trimmed_pats, arg_count_warnings) }
-- If any of the calls does not give rise to a specialisation, either -- If any of the calls does not give rise to a specialisation, either
-- because it is boring, or because there are too many specialisations, -- because it is boring, or because there are too many specialisations,
-- return a flag to say so, so that we know to keep the original function. -- return a flag to say so, so that we know to keep the original function.
where
partitionByWorkerSize worker_size pats = go pats [] []
where
go [] small warnings = (small, warnings)
go (p:ps) small warnings
| WorkerSmallEnough <- worker_size p
= go ps (p:small) warnings
| WorkerTooLarge <- worker_size p
= go ps small warnings
| WorkerTooLargeForced name <- worker_size p
= go ps small (SpecFailForcedArgCount name : warnings)
trim_pats :: ScEnv -> Id -> SpecInfo -> [CallPat] -> (Bool, [CallPat]) trim_pats :: ScEnv -> Id -> SpecInfo -> [CallPat] -> (Bool, [CallPat])
......
...@@ -21,8 +21,7 @@ initNCGConfig dflags this_mod = NCGConfig ...@@ -21,8 +21,7 @@ initNCGConfig dflags this_mod = NCGConfig
, ncgAsmContext = initSDocContext dflags PprCode , ncgAsmContext = initSDocContext dflags PprCode
, ncgProcAlignment = cmmProcAlignment dflags , ncgProcAlignment = cmmProcAlignment dflags
, ncgExternalDynamicRefs = gopt Opt_ExternalDynamicRefs dflags , ncgExternalDynamicRefs = gopt Opt_ExternalDynamicRefs dflags
-- no PIC on wasm32 for now , ncgPIC = positionIndependent dflags
, ncgPIC = positionIndependent dflags && not (platformArch (targetPlatform dflags) == ArchWasm32)
, ncgInlineThresholdMemcpy = fromIntegral $ maxInlineMemcpyInsns dflags , ncgInlineThresholdMemcpy = fromIntegral $ maxInlineMemcpyInsns dflags
, ncgInlineThresholdMemset = fromIntegral $ maxInlineMemsetInsns dflags , ncgInlineThresholdMemset = fromIntegral $ maxInlineMemsetInsns dflags
, ncgSplitSections = gopt Opt_SplitSections dflags , ncgSplitSections = gopt Opt_SplitSections dflags
......
...@@ -395,6 +395,7 @@ data DynFlags = DynFlags { ...@@ -395,6 +395,7 @@ data DynFlags = DynFlags {
unfoldingOpts :: !UnfoldingOpts, unfoldingOpts :: !UnfoldingOpts,
maxWorkerArgs :: Int, maxWorkerArgs :: Int,
maxForcedSpecArgs :: Int,
ghciHistSize :: Int, ghciHistSize :: Int,
...@@ -677,6 +678,8 @@ defaultDynFlags mySettings = ...@@ -677,6 +678,8 @@ defaultDynFlags mySettings =
unfoldingOpts = defaultUnfoldingOpts, unfoldingOpts = defaultUnfoldingOpts,
maxWorkerArgs = 10, maxWorkerArgs = 10,
maxForcedSpecArgs = 333,
-- 333 is fairly arbitrary, see Note [Forcing specialisation]:FS5
ghciHistSize = 50, -- keep a log of length 50 by default ghciHistSize = 50, -- keep a log of length 50 by default
......
...@@ -35,6 +35,7 @@ import GHC.HsToCore.Errors.Types (DsMessage) ...@@ -35,6 +35,7 @@ import GHC.HsToCore.Errors.Types (DsMessage)
import GHC.Iface.Errors.Types import GHC.Iface.Errors.Types
import GHC.Tc.Errors.Ppr () -- instance Diagnostic TcRnMessage import GHC.Tc.Errors.Ppr () -- instance Diagnostic TcRnMessage
import GHC.Iface.Errors.Ppr () -- instance Diagnostic IfaceMessage import GHC.Iface.Errors.Ppr () -- instance Diagnostic IfaceMessage
import GHC.CmmToLlvm.Version (llvmVersionStr, supportedLlvmVersionLowerBound, supportedLlvmVersionUpperBound)
-- --
-- Suggestions -- Suggestions
...@@ -268,6 +269,14 @@ instance Diagnostic DriverMessage where ...@@ -268,6 +269,14 @@ instance Diagnostic DriverMessage where
mkSimpleDecorated $ mkSimpleDecorated $
vcat [ text "Unexpected backpack instantiation in dependency graph while constructing Makefile:" vcat [ text "Unexpected backpack instantiation in dependency graph while constructing Makefile:"
, nest 2 $ ppr node ] , nest 2 $ ppr node ]
DriverNoConfiguredLLVMToolchain ->
mkSimpleDecorated $
text "GHC was not configured with a supported LLVM toolchain" $$
text ("Make sure you have installed LLVM between ["
++ llvmVersionStr supportedLlvmVersionLowerBound
++ " and "
++ llvmVersionStr supportedLlvmVersionUpperBound
++ ") and reinstall GHC to make -fllvm work")
diagnosticReason = \case diagnosticReason = \case
DriverUnknownMessage m DriverUnknownMessage m
...@@ -337,6 +346,8 @@ instance Diagnostic DriverMessage where ...@@ -337,6 +346,8 @@ instance Diagnostic DriverMessage where
-> ErrorWithoutFlag -> ErrorWithoutFlag
DriverInstantiationNodeInDependencyGeneration {} DriverInstantiationNodeInDependencyGeneration {}
-> ErrorWithoutFlag -> ErrorWithoutFlag
DriverNoConfiguredLLVMToolchain
-> ErrorWithoutFlag
diagnosticHints = \case diagnosticHints = \case
DriverUnknownMessage m DriverUnknownMessage m
...@@ -408,5 +419,7 @@ instance Diagnostic DriverMessage where ...@@ -408,5 +419,7 @@ instance Diagnostic DriverMessage where
-> noHints -> noHints
DriverInstantiationNodeInDependencyGeneration {} DriverInstantiationNodeInDependencyGeneration {}
-> noHints -> noHints
DriverNoConfiguredLLVMToolchain
-> noHints
diagnosticCode = constructorCode diagnosticCode = constructorCode