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
  • MTaimoorZaeem/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 (17)
Showing
with 361 additions and 187 deletions
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
{- BlockId module should probably go away completely, being superseded by Label -} {- BlockId module should probably go away completely, being superseded by Label -}
module BlockId module BlockId
( BlockId, mkBlockId -- ToDo: BlockId should be abstract, but it isn't yet ( BlockId, mkBlockId -- ToDo: BlockId should be abstract, but it isn't yet
, newBlockId
, BlockSet, BlockEnv , BlockSet, BlockEnv
, IsSet(..), setInsertList, setDeleteList, setUnions , IsSet(..), setInsertList, setDeleteList, setUnions
, IsMap(..), mapInsertList, mapDeleteList, mapUnions , IsMap(..), mapInsertList, mapDeleteList, mapUnions
...@@ -16,6 +17,7 @@ import IdInfo ...@@ -16,6 +17,7 @@ import IdInfo
import Name import Name
import Outputable import Outputable
import Unique import Unique
import UniqSupply
import Compiler.Hoopl as Hoopl hiding (Unique) import Compiler.Hoopl as Hoopl hiding (Unique)
import Compiler.Hoopl.Internals (uniqueToLbl, lblToUnique) import Compiler.Hoopl.Internals (uniqueToLbl, lblToUnique)
...@@ -43,6 +45,9 @@ instance Outputable BlockId where ...@@ -43,6 +45,9 @@ instance Outputable BlockId where
mkBlockId :: Unique -> BlockId mkBlockId :: Unique -> BlockId
mkBlockId unique = uniqueToLbl $ intToUnique $ getKey unique mkBlockId unique = uniqueToLbl $ intToUnique $ getKey unique
newBlockId :: MonadUnique m => m BlockId
newBlockId = mkBlockId <$> getUniqueM
retPtLbl :: BlockId -> CLabel retPtLbl :: BlockId -> CLabel
retPtLbl label = mkReturnPtLabel $ getUnique label retPtLbl label = mkReturnPtLabel $ getUnique label
......
...@@ -132,7 +132,7 @@ hash_block block = ...@@ -132,7 +132,7 @@ hash_block block =
hash_node :: CmmNode O x -> Word32 hash_node :: CmmNode O x -> Word32
hash_node n | dont_care n = 0 -- don't care hash_node n | dont_care n = 0 -- don't care
hash_node (CmmUnwind _ e) = hash_e e hash_node (CmmUnwind _ regs) = hash_list hash_e $ map snd regs
hash_node (CmmAssign r e) = hash_reg r + hash_e e hash_node (CmmAssign r e) = hash_reg r + hash_e e
hash_node (CmmStore e e') = hash_e e + hash_e e' hash_node (CmmStore e e') = hash_e e + hash_e e'
hash_node (CmmUnsafeForeignCall t _ as) = hash_tgt t + hash_list hash_e as hash_node (CmmUnsafeForeignCall t _ as) = hash_tgt t + hash_list hash_e as
......
...@@ -4,7 +4,7 @@ module CmmLayoutStack ( ...@@ -4,7 +4,7 @@ module CmmLayoutStack (
) where ) where
import StgCmmUtils ( callerSaveVolatileRegs ) -- XXX layering violation import StgCmmUtils ( callerSaveVolatileRegs ) -- XXX layering violation
import StgCmmForeign ( saveThreadState, loadThreadState ) -- XXX layering violation import StgCmmForeign ( saveThreadState, loadThreadState, InitialSp ) -- XXX layering violation
import BasicTypes import BasicTypes
import Cmm import Cmm
...@@ -19,6 +19,7 @@ import CmmProcPoint ...@@ -19,6 +19,7 @@ import CmmProcPoint
import SMRep import SMRep
import Hoopl import Hoopl
import UniqSupply import UniqSupply
import StgCmmUtils ( newTemp )
import Maybes import Maybes
import UniqFM import UniqFM
import Util import Util
...@@ -27,11 +28,11 @@ import DynFlags ...@@ -27,11 +28,11 @@ import DynFlags
import FastString import FastString
import Outputable hiding ( isEmpty ) import Outputable hiding ( isEmpty )
import qualified Data.Set as Set import qualified Data.Set as Set
import Control.Monad ((<=<))
import Control.Monad.Fix import Control.Monad.Fix
import Data.Array as Array import Data.Array as Array
import Data.Bits import Data.Bits
import Data.List (nub) import Data.List (nub)
import Control.Monad (liftM)
import Prelude hiding ((<*>)) import Prelude hiding ((<*>))
...@@ -275,10 +276,10 @@ layout dflags procpoints liveness entry entry_args final_stackmaps final_sp_high ...@@ -275,10 +276,10 @@ layout dflags procpoints liveness entry entry_args final_stackmaps final_sp_high
-- --
let middle_pre = blockToList $ foldl blockSnoc middle1 middle2 let middle_pre = blockToList $ foldl blockSnoc middle1 middle2
final_blocks = manifestSp dflags final_stackmaps stack0 sp0 final_sp_high entry0 final_blocks <- manifestSp dflags final_stackmaps stack0 sp0 final_sp_high entry0
middle_pre sp_off last1 fixup_blocks middle_pre sp_off last1 fixup_blocks
acc_stackmaps' = mapUnion acc_stackmaps out let acc_stackmaps' = mapUnion acc_stackmaps out
-- If this block jumps to the GC, then we do not take its -- If this block jumps to the GC, then we do not take its
-- stack usage into account for the high-water mark. -- stack usage into account for the high-water mark.
...@@ -525,10 +526,11 @@ makeFixupBlock :: DynFlags -> ByteOff -> Label -> StackMap ...@@ -525,10 +526,11 @@ makeFixupBlock :: DynFlags -> ByteOff -> Label -> StackMap
makeFixupBlock dflags sp0 l stack tscope assigs makeFixupBlock dflags sp0 l stack tscope assigs
| null assigs && sp0 == sm_sp stack = return (l, []) | null assigs && sp0 == sm_sp stack = return (l, [])
| otherwise = do | otherwise = do
tmp_lbl <- liftM mkBlockId $ getUniqueM tmp_lbl <- newBlockId
let sp_off = sp0 - sm_sp stack let sp_off = sp0 - sm_sp stack
block = blockJoin (CmmEntry tmp_lbl tscope) fixed_up <- maybeAddSpAdj dflags sp0 sp_off (blockFromList assigs)
(maybeAddSpAdj dflags sp_off (blockFromList assigs)) let block = blockJoin (CmmEntry tmp_lbl tscope)
fixed_up
(CmmBranch l) (CmmBranch l)
return (tmp_lbl, [block]) return (tmp_lbl, [block])
...@@ -780,36 +782,38 @@ manifestSp ...@@ -780,36 +782,38 @@ manifestSp
-> ByteOff -- sp_off -> ByteOff -- sp_off
-> CmmNode O C -- last node -> CmmNode O C -- last node
-> [CmmBlock] -- new blocks -> [CmmBlock] -- new blocks
-> [CmmBlock] -- final blocks with Sp manifest -> UniqSM [CmmBlock] -- final blocks with Sp manifest
manifestSp dflags stackmaps stack0 sp0 sp_high manifestSp dflags stackmaps stack0 sp0 sp_high
first middle_pre sp_off last fixup_blocks first middle_pre sp_off last fixup_blocks
= final_block : fixup_blocks' = do
where let -- Add unwind pseudo-instructions to document Sp level for debugging
area_off = getAreaOff stackmaps add_unwind_info block
| debugLevel dflags > 0 = do lbl <- newBlockId
pure $ CmmUnwind (NewLabel lbl) [(Sp, sp_unwind)] : block
| otherwise = pure block
sp_unwind = CmmRegOff (CmmGlobal Sp) (sp0 - wORD_SIZE dflags)
adj_pre_sp, adj_post_sp :: CmmNode e x -> CmmNode e x final_middle <- maybeAddSpAdj dflags sp0 sp_off <=<
adj_pre_sp = mapExpDeep (areaToSp dflags sp0 sp_high area_off) pure . blockFromList <=<
adj_post_sp = mapExpDeep (areaToSp dflags (sp0 - sp_off) sp_high area_off) add_unwind_info $
map adj_pre_sp $
elimStackStores stack0 stackmaps area_off $
middle_pre
-- Add unwind pseudo-instructions to document Sp level for debugging let final_last = optStackCheck (adj_post_sp last)
add_unwind_info block
| debugLevel dflags > 0 = CmmUnwind Sp sp_unwind : block
| otherwise = block
sp_unwind = CmmRegOff (CmmGlobal Sp) (sp0 - wORD_SIZE dflags)
final_middle = maybeAddSpAdj dflags sp_off $ final_block = blockJoin first final_middle final_last
blockFromList $
add_unwind_info $
map adj_pre_sp $
elimStackStores stack0 stackmaps area_off $
middle_pre
final_last = optStackCheck (adj_post_sp last) fixup_blocks' = map (mapBlock3' (id, adj_post_sp, id)) fixup_blocks
final_block = blockJoin first final_middle final_last pure $ final_block : fixup_blocks'
where
area_off = getAreaOff stackmaps
fixup_blocks' = map (mapBlock3' (id, adj_post_sp, id)) fixup_blocks adj_pre_sp, adj_post_sp :: CmmNode e x -> CmmNode e x
adj_pre_sp = mapExpDeep (areaToSp dflags sp0 sp_high area_off)
adj_post_sp = mapExpDeep (areaToSp dflags (sp0 - sp_off) sp_high area_off)
getAreaOff :: BlockEnv StackMap -> (Area -> StackLoc) getAreaOff :: BlockEnv StackMap -> (Area -> StackLoc)
...@@ -820,10 +824,19 @@ getAreaOff stackmaps (Young l) = ...@@ -820,10 +824,19 @@ getAreaOff stackmaps (Young l) =
Nothing -> pprPanic "getAreaOff" (ppr l) Nothing -> pprPanic "getAreaOff" (ppr l)
maybeAddSpAdj :: DynFlags -> ByteOff -> Block CmmNode O O -> Block CmmNode O O maybeAddSpAdj :: DynFlags
maybeAddSpAdj _ 0 block = block -> ByteOff -- ^ Sp on entry to the block
maybeAddSpAdj dflags sp_off block -> ByteOff -- ^ sp_off
= block `blockSnoc` CmmAssign spReg (cmmOffset dflags (CmmReg spReg) sp_off) -> Block CmmNode O O -- ^ the block to append the adjustment to
-> UniqSM (Block CmmNode O O)
maybeAddSpAdj _ _ 0 block = pure block
maybeAddSpAdj dflags sp0 sp_off block
= do
lbl <- newBlockId
pure $ block `blockSnoc` CmmAssign spReg (cmmOffset dflags (CmmReg spReg) sp_off)
`blockSnoc` CmmUnwind (NewLabel lbl)
[(Sp, cmmRegOff (CmmGlobal Sp)
(sp0 - wORD_SIZE dflags - sp_off))]
{- {-
...@@ -989,6 +1002,31 @@ expecting them (see Note {safe foreign call convention]). Note also ...@@ -989,6 +1002,31 @@ expecting them (see Note {safe foreign call convention]). Note also
that safe foreign call is replace by an unsafe one in the Cmm graph. that safe foreign call is replace by an unsafe one in the Cmm graph.
-} -}
findLastUnwinding :: GlobalReg -> CmmBlock -> Maybe CmmExpr
findLastUnwinding reg block =
case mapMaybe isUnwind $ blockToList mid of
[] -> Nothing
xs -> Just $ last xs
where
(_,mid,_) = blockSplit block
isUnwind (CmmUnwind _ regs) = lookup reg regs
isUnwind _ = Nothing
-- | @substReg reg expr subst@ replaces all occurrences of @CmmReg reg@ in
-- @expr@ with @subst@.
substReg :: DynFlags -> CmmReg -> CmmExpr -> CmmExpr -> CmmExpr
substReg dflags reg = go
where
go (CmmReg reg') subst
| reg == reg' = subst
go (CmmRegOff reg' off) subst
| reg == reg' =
CmmMachOp (MO_Add rep) [subst, CmmLit (CmmInt (fromIntegral off) rep)]
where rep = typeWidth (cmmRegType dflags reg')
go (CmmLoad e ty) subst = CmmLoad (go e subst) ty
go (CmmMachOp op es) subst = CmmMachOp op (map (flip go subst) es)
go other _ = other
lowerSafeForeignCall :: DynFlags -> CmmBlock -> UniqSM CmmBlock lowerSafeForeignCall :: DynFlags -> CmmBlock -> UniqSM CmmBlock
lowerSafeForeignCall dflags block lowerSafeForeignCall dflags block
| (entry@(CmmEntry _ tscp), middle, CmmForeignCall { .. }) <- blockSplit block | (entry@(CmmEntry _ tscp), middle, CmmForeignCall { .. }) <- blockSplit block
...@@ -998,12 +1036,12 @@ lowerSafeForeignCall dflags block ...@@ -998,12 +1036,12 @@ lowerSafeForeignCall dflags block
id <- newTemp (bWord dflags) id <- newTemp (bWord dflags)
new_base <- newTemp (cmmRegType dflags (CmmGlobal BaseReg)) new_base <- newTemp (cmmRegType dflags (CmmGlobal BaseReg))
let (caller_save, caller_load) = callerSaveVolatileRegs dflags let (caller_save, caller_load) = callerSaveVolatileRegs dflags
load_stack <- newTemp (gcWord dflags) let initialSp = findLastUnwinding Sp block
tso <- newTemp (gcWord dflags) substSp :: Maybe InitialSp
cn <- newTemp (bWord dflags) substSp = substReg dflags (CmmGlobal Sp) <$> initialSp
bdfree <- newTemp (bWord dflags) save_state_code <- saveThreadState dflags substSp
bdstart <- newTemp (bWord dflags) load_state_code <- loadThreadState dflags substSp
let suspend = saveThreadState dflags tso cn <*> let suspend = save_state_code <*>
caller_save <*> caller_save <*>
mkMiddle (callSuspendThread dflags id intrbl) mkMiddle (callSuspendThread dflags id intrbl)
midCall = mkUnsafeCall tgt res args midCall = mkUnsafeCall tgt res args
...@@ -1012,7 +1050,7 @@ lowerSafeForeignCall dflags block ...@@ -1012,7 +1050,7 @@ lowerSafeForeignCall dflags block
-- might now have a different Capability! -- might now have a different Capability!
mkAssign (CmmGlobal BaseReg) (CmmReg (CmmLocal new_base)) <*> mkAssign (CmmGlobal BaseReg) (CmmReg (CmmLocal new_base)) <*>
caller_load <*> caller_load <*>
loadThreadState dflags tso load_stack cn bdfree bdstart load_state_code
(_, regs, copyout) = (_, regs, copyout) =
copyOutOflow dflags NativeReturn Jump (Young succ) copyOutOflow dflags NativeReturn Jump (Young succ)
...@@ -1050,9 +1088,6 @@ lowerSafeForeignCall dflags block ...@@ -1050,9 +1088,6 @@ lowerSafeForeignCall dflags block
foreignLbl :: FastString -> CmmExpr foreignLbl :: FastString -> CmmExpr
foreignLbl name = CmmLit (CmmLabel (mkForeignLabel name Nothing ForeignLabelInExternalPackage IsFunction)) foreignLbl name = CmmLit (CmmLabel (mkForeignLabel name Nothing ForeignLabelInExternalPackage IsFunction))
newTemp :: CmmType -> UniqSM LocalReg
newTemp rep = getUniqueM >>= \u -> return (LocalReg u rep)
callSuspendThread :: DynFlags -> LocalReg -> Bool -> CmmNode O O callSuspendThread :: DynFlags -> LocalReg -> Bool -> CmmNode O O
callSuspendThread dflags id intrbl = callSuspendThread dflags id intrbl =
CmmUnsafeForeignCall CmmUnsafeForeignCall
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
module CmmNode ( module CmmNode (
CmmNode(..), CmmFormal, CmmActual, CmmTickish, CmmNode(..), CmmFormal, CmmActual, CmmTickish,
UpdFrameOffset, Convention(..), UpdFrameOffset, NewOrExistingLabel(..), Convention(..),
ForeignConvention(..), ForeignTarget(..), foreignTargetHints, ForeignConvention(..), ForeignTarget(..), foreignTargetHints,
CmmReturnInfo(..), CmmReturnInfo(..),
mapExp, mapExpDeep, wrapRecExp, foldExp, foldExpDeep, wrapRecExpf, mapExp, mapExpDeep, wrapRecExp, foldExp, foldExpDeep, wrapRecExpf,
...@@ -57,8 +57,9 @@ data CmmNode e x where ...@@ -57,8 +57,9 @@ data CmmNode e x where
-- instructions for a debugger. This describes how to reconstruct -- instructions for a debugger. This describes how to reconstruct
-- the "old" value of a register if we want to navigate the stack -- the "old" value of a register if we want to navigate the stack
-- up one frame. Having unwind information for @Sp@ will allow the -- up one frame. Having unwind information for @Sp@ will allow the
-- debugger to "walk" the stack. -- debugger to "walk" the stack. The label represents a pointer
CmmUnwind :: !GlobalReg -> !CmmExpr -> CmmNode O O -- to the current location in the generated code.
CmmUnwind :: !NewOrExistingLabel -> [(GlobalReg, CmmExpr)] -> CmmNode O O
CmmAssign :: !CmmReg -> !CmmExpr -> CmmNode O O CmmAssign :: !CmmReg -> !CmmExpr -> CmmNode O O
-- Assign to register -- Assign to register
...@@ -243,6 +244,14 @@ type CmmFormal = LocalReg ...@@ -243,6 +244,14 @@ type CmmFormal = LocalReg
type UpdFrameOffset = ByteOff type UpdFrameOffset = ByteOff
-- | Contains either a new label or reference to an existing label
data NewOrExistingLabel = NewLabel !Label | ExistingLabel !Label
deriving (Eq)
instance Outputable NewOrExistingLabel where
ppr (NewLabel lbl) = text "NewLabel" <+> ppr lbl
ppr (ExistingLabel lbl) = text "ExistingLabel" <+> ppr lbl
-- | A convention maps a list of values (function arguments or return -- | A convention maps a list of values (function arguments or return
-- values) to registers or stack locations. -- values) to registers or stack locations.
data Convention data Convention
...@@ -460,7 +469,7 @@ mapExp :: (CmmExpr -> CmmExpr) -> CmmNode e x -> CmmNode e x ...@@ -460,7 +469,7 @@ mapExp :: (CmmExpr -> CmmExpr) -> CmmNode e x -> CmmNode e x
mapExp _ f@(CmmEntry{}) = f mapExp _ f@(CmmEntry{}) = f
mapExp _ m@(CmmComment _) = m mapExp _ m@(CmmComment _) = m
mapExp _ m@(CmmTick _) = m mapExp _ m@(CmmTick _) = m
mapExp f (CmmUnwind r e) = CmmUnwind r (f e) mapExp f (CmmUnwind lbl regs) = CmmUnwind lbl (map (fmap f) regs)
mapExp f (CmmAssign r e) = CmmAssign r (f e) mapExp f (CmmAssign r e) = CmmAssign r (f e)
mapExp f (CmmStore addr e) = CmmStore (f addr) (f e) mapExp f (CmmStore addr e) = CmmStore (f addr) (f e)
mapExp f (CmmUnsafeForeignCall tgt fs as) = CmmUnsafeForeignCall (mapForeignTarget f tgt) fs (map f as) mapExp f (CmmUnsafeForeignCall tgt fs as) = CmmUnsafeForeignCall (mapForeignTarget f tgt) fs (map f as)
...@@ -491,7 +500,7 @@ mapExpM :: (CmmExpr -> Maybe CmmExpr) -> CmmNode e x -> Maybe (CmmNode e x) ...@@ -491,7 +500,7 @@ mapExpM :: (CmmExpr -> Maybe CmmExpr) -> CmmNode e x -> Maybe (CmmNode e x)
mapExpM _ (CmmEntry{}) = Nothing mapExpM _ (CmmEntry{}) = Nothing
mapExpM _ (CmmComment _) = Nothing mapExpM _ (CmmComment _) = Nothing
mapExpM _ (CmmTick _) = Nothing mapExpM _ (CmmTick _) = Nothing
mapExpM f (CmmUnwind r e) = CmmUnwind r `fmap` f e mapExpM f (CmmUnwind lbl regs) = CmmUnwind lbl `fmap` mapM (\(r,e) -> f e >>= \e' -> pure (r,e')) regs
mapExpM f (CmmAssign r e) = CmmAssign r `fmap` f e mapExpM f (CmmAssign r e) = CmmAssign r `fmap` f e
mapExpM f (CmmStore addr e) = (\[addr', e'] -> CmmStore addr' e') `fmap` mapListM f [addr, e] mapExpM f (CmmStore addr e) = (\[addr', e'] -> CmmStore addr' e') `fmap` mapListM f [addr, e]
mapExpM _ (CmmBranch _) = Nothing mapExpM _ (CmmBranch _) = Nothing
...@@ -544,7 +553,7 @@ foldExp :: (CmmExpr -> z -> z) -> CmmNode e x -> z -> z ...@@ -544,7 +553,7 @@ foldExp :: (CmmExpr -> z -> z) -> CmmNode e x -> z -> z
foldExp _ (CmmEntry {}) z = z foldExp _ (CmmEntry {}) z = z
foldExp _ (CmmComment {}) z = z foldExp _ (CmmComment {}) z = z
foldExp _ (CmmTick {}) z = z foldExp _ (CmmTick {}) z = z
foldExp f (CmmUnwind _ e) z = f e z foldExp f (CmmUnwind _ regs) z = foldr f z $ map snd regs
foldExp f (CmmAssign _ e) z = f e z foldExp f (CmmAssign _ e) z = f e z
foldExp f (CmmStore addr e) z = f addr $ f e z foldExp f (CmmStore addr e) z = f addr $ f e z
foldExp f (CmmUnsafeForeignCall t _ as) z = foldr f (foldExpForeignTarget f t z) as foldExp f (CmmUnsafeForeignCall t _ as) z = foldr f (foldExpForeignTarget f t z) as
......
...@@ -635,8 +635,15 @@ stmt :: { CmmParse () } ...@@ -635,8 +635,15 @@ stmt :: { CmmParse () }
{ pushStackFrame $3 $5 } { pushStackFrame $3 $5 }
| 'reserve' expr '=' lreg maybe_body | 'reserve' expr '=' lreg maybe_body
{ reserveStackFrame $2 $4 $5 } { reserveStackFrame $2 $4 $5 }
| 'unwind' GLOBALREG '=' expr | 'unwind' unwind_regs ';'
{ $4 >>= code . emitUnwind $2 } { $2 >>= code . emitUnwind }
unwind_regs
:: { CmmParse [(GlobalReg, CmmExpr)] }
: GLOBALREG '=' expr ',' unwind_regs
{ do e <- $3; rest <- $5; return (($1, e) : rest) }
| GLOBALREG '=' expr
{ do e <- $3; return [($1, e)] }
foreignLabel :: { CmmParse CmmExpr } foreignLabel :: { CmmParse CmmExpr }
: NAME { return (CmmLit (CmmLabel (mkForeignLabel $1 Nothing ForeignLabelInThisPackage IsFunction))) } : NAME { return (CmmLit (CmmLabel (mkForeignLabel $1 Nothing ForeignLabelInThisPackage IsFunction))) }
......
...@@ -12,15 +12,18 @@ ...@@ -12,15 +12,18 @@
module Debug ( module Debug (
DebugBlock(..), dblIsEntry, DebugBlock(..), dblIsEntry,
UnwindTable, UnwindExpr(..),
cmmDebugGen, cmmDebugGen,
cmmDebugLabels, cmmDebugLabels,
cmmDebugLink, cmmDebugLink,
debugToMap debugToMap,
-- * Unwinding information
UnwindTable, UnwindPoints(..), UnwindExpr(..),
addDefaultUnwindings
) where ) where
import BlockId ( blockLbl ) import BlockId
import CLabel import CLabel
import Cmm import Cmm
import CmmUtils import CmmUtils
...@@ -32,6 +35,7 @@ import PprCore () ...@@ -32,6 +35,7 @@ import PprCore ()
import PprCmmExpr ( pprExpr ) import PprCmmExpr ( pprExpr )
import SrcLoc import SrcLoc
import Util import Util
import Unique
import Compiler.Hoopl import Compiler.Hoopl
...@@ -56,7 +60,7 @@ data DebugBlock = ...@@ -56,7 +60,7 @@ data DebugBlock =
, dblPosition :: !(Maybe Int) -- ^ Output position relative to , dblPosition :: !(Maybe Int) -- ^ Output position relative to
-- other blocks. @Nothing@ means -- other blocks. @Nothing@ means
-- the block was optimized out -- the block was optimized out
, dblUnwind :: !UnwindTable -- ^ Unwind information , dblUnwind :: UnwindPoints -- ^ Unwind information
, dblBlocks :: ![DebugBlock] -- ^ Nested blocks , dblBlocks :: ![DebugBlock] -- ^ Nested blocks
} }
...@@ -74,14 +78,17 @@ instance Outputable DebugBlock where ...@@ -74,14 +78,17 @@ instance Outputable DebugBlock where
(maybe empty ppr (dblSourceTick blk)) <+> (maybe empty ppr (dblSourceTick blk)) <+>
(maybe (text "removed") ((text "pos " <>) . ppr) (maybe (text "removed") ((text "pos " <>) . ppr)
(dblPosition blk)) <+> (dblPosition blk)) <+>
pprUwMap (dblUnwind blk) $$ pprUwPts (dblUnwind blk) $$
(if null (dblBlocks blk) then empty else ppr (dblBlocks blk)) (if null (dblBlocks blk) then empty else ppr (dblBlocks blk))
where pprUw (g, expr) = ppr g <> char '=' <> ppr expr where pprUwPts (UnwindPoints pts) = hsep $ punctuate comma $ map pprUwPt pts
pprUwMap = braces . hsep . punctuate comma . map pprUw . Map.toList pprUwPt (lbl, uws) =
braces $ ppr lbl<>colon
<+> hsep (punctuate comma $ map pprUw $ Map.toList uws)
pprUw (g, expr) = ppr g <> char '=' <> ppr expr
-- | Intermediate data structure holding debug-relevant context information -- | Intermediate data structure holding debug-relevant context information
-- about a block. -- about a block.
type BlockContext = (CmmBlock, RawCmmDecl, UnwindTable) type BlockContext = (CmmBlock, RawCmmDecl, UnwindPoints)
-- | Extract debug data from a group of procedures. We will prefer -- | Extract debug data from a group of procedures. We will prefer
-- source notes that come from the given module (presumably the module -- source notes that come from the given module (presumably the module
...@@ -151,6 +158,8 @@ cmmDebugGen modLoc decls = map (blocksForScope Nothing) topScopes ...@@ -151,6 +158,8 @@ cmmDebugGen modLoc decls = map (blocksForScope Nothing) topScopes
nested = fromMaybe [] $ Map.lookup scope scopeMap nested = fromMaybe [] $ Map.lookup scope scopeMap
childs = map (mkBlock False) (tail bctxs) ++ childs = map (mkBlock False) (tail bctxs) ++
map (blocksForScope stick) nested map (blocksForScope stick) nested
mkBlock :: Bool -> BlockContext -> DebugBlock
mkBlock top (block, prc, unwind) mkBlock top (block, prc, unwind)
= DebugBlock { dblProcedure = g_entry graph = DebugBlock { dblProcedure = g_entry graph
, dblLabel = label , dblLabel = label
...@@ -194,24 +203,35 @@ cmmDebugGen modLoc decls = map (blocksForScope Nothing) topScopes ...@@ -194,24 +203,35 @@ cmmDebugGen modLoc decls = map (blocksForScope Nothing) topScopes
-- lacking. -- lacking.
blockContexts :: RawCmmGroup -> Map.Map CmmTickScope [BlockContext] blockContexts :: RawCmmGroup -> Map.Map CmmTickScope [BlockContext]
blockContexts decls = Map.map reverse $ foldr walkProc Map.empty decls blockContexts decls = Map.map reverse $ foldr walkProc Map.empty decls
where walkProc CmmData{} m = m where walkProc :: RawCmmDecl
-> Map.Map CmmTickScope [BlockContext]
-> Map.Map CmmTickScope [BlockContext]
walkProc CmmData{} m = m
walkProc prc@(CmmProc _ _ _ graph) m walkProc prc@(CmmProc _ _ _ graph) m
| mapNull blocks = m | mapNull blocks = m
| otherwise = snd $ walkBlock prc entry Map.empty (emptyLbls, m) | otherwise = snd $ walkBlock prc entry Map.empty (emptyLbls, m)
where blocks = toBlockMap graph where blocks = toBlockMap graph
entry = [mapFind (g_entry graph) blocks] entry = [mapFind (g_entry graph) blocks]
emptyLbls = setEmpty :: LabelSet emptyLbls = setEmpty :: LabelSet
walkBlock _ [] _ c = c
walkBlock prc (block:blocks) unwind (visited, m) walkBlock :: RawCmmDecl -> [Block CmmNode C C]
-> UnwindTable -- ^ unwinding table of predecessor block
-> (LabelSet, Map.Map CmmTickScope [BlockContext])
-> (LabelSet, Map.Map CmmTickScope [BlockContext])
walkBlock _ [] _ c = c
walkBlock prc (block:blocks) predUnwind (visited, m)
| lbl `setMember` visited | lbl `setMember` visited
= walkBlock prc blocks unwind (visited, m) = walkBlock prc blocks predUnwind (visited, m)
| otherwise | otherwise
= walkBlock prc blocks unwind $ = walkBlock prc blocks predUnwind $
walkBlock prc succs unwind' walkBlock prc succs succUnwind
(lbl `setInsert` visited, (lbl `setInsert` visited,
insertMulti scope (block, prc, unwind') m) insertMulti scope (block, prc, unwind') m)
where CmmEntry lbl scope = firstNode block where CmmEntry lbl scope = firstNode block
unwind' = extractUnwind block `Map.union` unwind -- fold in unwinding information from predecessor block
unwind' = addDefaultUnwindings predUnwind
$ extractUnwindTables block
succUnwind = lastUnwindingPoint unwind'
(CmmProc _ _ _ graph) = prc (CmmProc _ _ _ graph) = prc
succs = map (flip mapFind (toBlockMap graph)) succs = map (flip mapFind (toBlockMap graph))
(successors (lastNode block)) (successors (lastNode block))
...@@ -251,13 +271,23 @@ debugToMap = mapUnions . map go ...@@ -251,13 +271,23 @@ debugToMap = mapUnions . map go
-- | Maps registers to expressions that yield their "old" values -- | Maps registers to expressions that yield their "old" values
-- further up the stack. Most interesting for the stack pointer Sp, -- further up the stack. Most interesting for the stack pointer Sp,
-- but might be useful to document saved registers, too. -- but might be useful to document saved registers, too. The 'Label'
-- gives the label in the generated block that this table is associated
-- with.
type UnwindTable = Map.Map GlobalReg UnwindExpr type UnwindTable = Map.Map GlobalReg UnwindExpr
-- | A sequence of locations within a block annotated with unwinding tables.
-- This list is sorted in the order that the labels occur in the block.
newtype UnwindPoints = UnwindPoints [(CLabel, UnwindTable)]
instance Outputable UnwindPoints where
ppr (UnwindPoints pts) = ppr pts
-- | Expressions, used for unwind information -- | Expressions, used for unwind information
data UnwindExpr = UwConst Int -- ^ literal value data UnwindExpr = UwConst Int -- ^ literal value
| UwReg GlobalReg Int -- ^ register plus offset | UwReg GlobalReg Int -- ^ register plus offset
| UwDeref UnwindExpr -- ^ pointer dereferencing | UwDeref UnwindExpr -- ^ pointer dereferencing
| UwLabel CLabel
| UwPlus UnwindExpr UnwindExpr | UwPlus UnwindExpr UnwindExpr
| UwMinus UnwindExpr UnwindExpr | UwMinus UnwindExpr UnwindExpr
| UwTimes UnwindExpr UnwindExpr | UwTimes UnwindExpr UnwindExpr
...@@ -268,6 +298,7 @@ instance Outputable UnwindExpr where ...@@ -268,6 +298,7 @@ instance Outputable UnwindExpr where
pprPrec _ (UwReg g 0) = ppr g pprPrec _ (UwReg g 0) = ppr g
pprPrec p (UwReg g x) = pprPrec p (UwPlus (UwReg g 0) (UwConst x)) pprPrec p (UwReg g x) = pprPrec p (UwPlus (UwReg g 0) (UwConst x))
pprPrec _ (UwDeref e) = char '*' <> pprPrec 3 e pprPrec _ (UwDeref e) = char '*' <> pprPrec 3 e
pprPrec _ (UwLabel l) = pprPrec 3 l
pprPrec p (UwPlus e0 e1) | p <= 0 pprPrec p (UwPlus e0 e1) | p <= 0
= pprPrec 0 e0 <> char '+' <> pprPrec 0 e1 = pprPrec 0 e0 <> char '+' <> pprPrec 0 e1
pprPrec p (UwMinus e0 e1) | p <= 0 pprPrec p (UwMinus e0 e1) | p <= 0
...@@ -276,22 +307,39 @@ instance Outputable UnwindExpr where ...@@ -276,22 +307,39 @@ instance Outputable UnwindExpr where
= pprPrec 2 e0 <> char '*' <> pprPrec 2 e1 = pprPrec 2 e0 <> char '*' <> pprPrec 2 e1
pprPrec _ other = parens (pprPrec 0 other) pprPrec _ other = parens (pprPrec 0 other)
extractUnwind :: CmmBlock -> UnwindTable
extractUnwind b = go $ blockToList mid -- | @addDefaultUnwindings uws points@ adds default unwinding information
where (_, mid, _) = blockSplit b -- from @uws@ to @points@.
go :: [CmmNode O O] -> UnwindTable addDefaultUnwindings :: UnwindTable -> UnwindPoints -> UnwindPoints
go [] = Map.empty addDefaultUnwindings uws (UnwindPoints pts) =
go (x : xs) = case x of UnwindPoints $ map (fmap (`Map.union` uws)) pts
CmmUnwind g so -> Map.insert g (toUnwindExpr so) $! go xs
CmmTick {} -> go xs -- | The unwinding table from the last unwinding point in a block
_other -> Map.empty lastUnwindingPoint :: UnwindPoints -> UnwindTable
-- TODO: Unwind statements after actual instructions lastUnwindingPoint (UnwindPoints pts) = snd $ last pts
extractUnwindTables :: CmmBlock -> UnwindPoints
extractUnwindTables b =
UnwindPoints $ mapMaybe nodeToUnwind $ blockToList mid
where
(_, mid, _) = blockSplit b
nodeToUnwind :: CmmNode O O -> Maybe (CLabel, UnwindTable)
nodeToUnwind (CmmUnwind lbl regs) =
-- FIXME: why a block label if this isn't a block?
Just (mkAsmTempLabel (getUnique lbl'), toUnwindExpr <$> Map.fromList regs)
where
lbl' = case lbl of
NewLabel l -> l
ExistingLabel l -> l
nodeToUnwind _ = Nothing
-- | Conversion of Cmm expressions to unwind expressions. We check for -- | Conversion of Cmm expressions to unwind expressions. We check for
-- unsupported operator usages and simplify the expression as far as -- unsupported operator usages and simplify the expression as far as
-- possible. -- possible.
toUnwindExpr :: CmmExpr -> UnwindExpr toUnwindExpr :: CmmExpr -> UnwindExpr
toUnwindExpr (CmmLit (CmmInt i _)) = UwConst (fromIntegral i) toUnwindExpr (CmmLit (CmmInt i _)) = UwConst (fromIntegral i)
toUnwindExpr (CmmLit (CmmLabel l)) = UwLabel l
toUnwindExpr (CmmRegOff (CmmGlobal g) i) = UwReg g i toUnwindExpr (CmmRegOff (CmmGlobal g) i) = UwReg g i
toUnwindExpr (CmmReg (CmmGlobal g)) = UwReg g 0 toUnwindExpr (CmmReg (CmmGlobal g)) = UwReg g 0
toUnwindExpr (CmmLoad e _) = UwDeref (toUnwindExpr e) toUnwindExpr (CmmLoad e _) = UwDeref (toUnwindExpr e)
......
...@@ -7,7 +7,7 @@ module MkGraph ...@@ -7,7 +7,7 @@ module MkGraph
, lgraphOfAGraph, labelAGraph , lgraphOfAGraph, labelAGraph
, stackStubExpr , stackStubExpr
, mkNop, mkAssign, mkStore, mkUnsafeCall, mkFinalCall, mkCallReturnsTo , mkNop, mkAssign, mkStore, mkUnwind, mkUnsafeCall, mkFinalCall, mkCallReturnsTo
, mkJumpReturnsTo , mkJumpReturnsTo
, mkJump, mkJumpExtra , mkJump, mkJumpExtra
, mkRawJump , mkRawJump
...@@ -196,6 +196,9 @@ mkAssign l r = mkMiddle $ CmmAssign l r ...@@ -196,6 +196,9 @@ mkAssign l r = mkMiddle $ CmmAssign l r
mkStore :: CmmExpr -> CmmExpr -> CmmAGraph mkStore :: CmmExpr -> CmmExpr -> CmmAGraph
mkStore l r = mkMiddle $ CmmStore l r mkStore l r = mkMiddle $ CmmStore l r
mkUnwind :: NewOrExistingLabel -> GlobalReg -> CmmExpr -> CmmAGraph
mkUnwind lbl r e = mkMiddle $ CmmUnwind lbl [(r,e)]
---------- Control transfer ---------- Control transfer
mkJump :: DynFlags -> Convention -> CmmExpr mkJump :: DynFlags -> Convention -> CmmExpr
-> [CmmActual] -> [CmmActual]
......
...@@ -197,7 +197,8 @@ pprNode node = pp_node <+> pp_debug ...@@ -197,7 +197,8 @@ pprNode node = pp_node <+> pp_debug
else empty else empty
-- unwind reg = expr; -- unwind reg = expr;
CmmUnwind r e -> ptext (sLit "unwind ") <> ppr r <+> char '=' <+> ppr e CmmUnwind lbl regs -> ptext (sLit "unwind ") <> commafy (map (\(r,e) -> ppr r <+> char '=' <+> ppr e) regs) <> semi
<+> text "//" <+> ppr lbl
-- reg = expr; -- reg = expr;
CmmAssign reg expr -> ppr reg <+> equals <+> ppr expr <> semi CmmAssign reg expr -> ppr reg <+> equals <+> ppr expr <> semi
......
...@@ -43,13 +43,13 @@ import Cmm ...@@ -43,13 +43,13 @@ import Cmm
import CLabel import CLabel
import MkGraph import MkGraph
-- import BasicTypes
import BlockId import BlockId
import DynFlags import DynFlags
import FastString import FastString
import Module import Module
import UniqFM import UniqFM
import Unique import Unique
import UniqSupply
import Control.Monad (liftM, ap) import Control.Monad (liftM, ap)
...@@ -90,6 +90,12 @@ instance Applicative CmmParse where ...@@ -90,6 +90,12 @@ instance Applicative CmmParse where
instance Monad CmmParse where instance Monad CmmParse where
(>>=) = thenExtFC (>>=) = thenExtFC
instance MonadUnique CmmParse where
getUniqueSupplyM = code getUniqueSupplyM
getUniqueM = EC $ \_ _ decls -> do
u <- getUniqueM
return (decls, u)
instance HasDynFlags CmmParse where instance HasDynFlags CmmParse where
getDynFlags = EC (\_ _ d -> do dflags <- getDynFlags getDynFlags = EC (\_ _ d -> do dflags <- getDynFlags
return (d, dflags)) return (d, dflags))
...@@ -155,9 +161,6 @@ newLabel name = do ...@@ -155,9 +161,6 @@ newLabel name = do
addLabel name (mkBlockId u) addLabel name (mkBlockId u)
return (mkBlockId u) return (mkBlockId u)
newBlockId :: CmmParse BlockId
newBlockId = code F.newLabelC
-- | Add add a local function to the environment. -- | Add add a local function to the environment.
newFunctionName newFunctionName
:: FastString -- ^ name of the function :: FastString -- ^ name of the function
......
...@@ -12,6 +12,7 @@ module StgCmmForeign ( ...@@ -12,6 +12,7 @@ module StgCmmForeign (
cgForeignCall, cgForeignCall,
emitPrimCall, emitCCall, emitPrimCall, emitCCall,
emitForeignCall, -- For CmmParse emitForeignCall, -- For CmmParse
InitialSp,
emitSaveThreadState, emitSaveThreadState,
saveThreadState, saveThreadState,
emitLoadThreadState, emitLoadThreadState,
...@@ -30,6 +31,7 @@ import StgCmmUtils ...@@ -30,6 +31,7 @@ import StgCmmUtils
import StgCmmClosure import StgCmmClosure
import StgCmmLayout import StgCmmLayout
import BlockId (newBlockId)
import Cmm import Cmm
import CmmUtils import CmmUtils
import MkGraph import MkGraph
...@@ -41,6 +43,7 @@ import ForeignCall ...@@ -41,6 +43,7 @@ import ForeignCall
import DynFlags import DynFlags
import Maybes import Maybes
import Outputable import Outputable
import UniqSupply
import BasicTypes import BasicTypes
import Control.Monad import Control.Monad
...@@ -274,22 +277,41 @@ maybe_assign_temp e = do ...@@ -274,22 +277,41 @@ maybe_assign_temp e = do
emitSaveThreadState :: FCode () emitSaveThreadState :: FCode ()
emitSaveThreadState = do emitSaveThreadState = do
dflags <- getDynFlags dflags <- getDynFlags
tso <- newTemp (gcWord dflags) code <- saveThreadState dflags Nothing
cn <- newTemp (bWord dflags) emit code
emit $ saveThreadState dflags tso cn
-- | Given a @initial :: InitialSp@, @initial (CmmReg sp)@ is an expression
-- of the current.
type InitialSp = CmmExpr -> CmmExpr
-- | Produce code to save the current thread state to @CurrentTSO@
saveThreadState :: MonadUnique m => DynFlags -> Maybe InitialSp -> m CmmAGraph
saveThreadState dflags initialSp = do
tso <- newTemp (gcWord dflags)
close_nursery <- closeNursery dflags tso
lbl <- newBlockId
-- saveThreadState must be usable from the stack layout pass, where we pure $ catAGraphs [
-- don't have FCode. Therefore it takes LocalRegs as arguments, so
-- the caller can create these.
saveThreadState :: DynFlags -> LocalReg -> LocalReg -> CmmAGraph
saveThreadState dflags tso cn =
catAGraphs [
-- tso = CurrentTSO; -- tso = CurrentTSO;
mkAssign (CmmLocal tso) stgCurrentTSO, mkAssign (CmmLocal tso) stgCurrentTSO,
-- tso->stackobj->sp = Sp; -- tso->stackobj->sp = Sp;
mkStore (cmmOffset dflags (CmmLoad (cmmOffset dflags (CmmReg (CmmLocal tso)) (tso_stackobj dflags)) (bWord dflags)) (stack_SP dflags)) stgSp, mkStore (cmmOffset dflags
closeNursery dflags tso cn, (CmmLoad (cmmOffset dflags
(CmmReg (CmmLocal tso))
(tso_stackobj dflags))
(bWord dflags))
(stack_SP dflags))
stgSp,
-- unwind Sp = initialSp(tso->stackobj->sp)
case initialSp of
Just initial | debugLevel dflags > 0 ->
let tsoValue =
CmmLoad (cmmOffset dflags stgCurrentTSO (tso_stackobj dflags))
(bWord dflags)
spValue = cmmOffset dflags tsoValue (stack_SP dflags)
in mkUnwind (NewLabel lbl) Sp (initial spValue)
_ -> mkNop,
close_nursery,
-- and save the current cost centre stack in the TSO when profiling: -- and save the current cost centre stack in the TSO when profiling:
if gopt Opt_SccProfilingOn dflags then if gopt Opt_SccProfilingOn dflags then
mkStore (cmmOffset dflags (CmmReg (CmmLocal tso)) (tso_CCCS dflags)) curCCS mkStore (cmmOffset dflags (CmmReg (CmmLocal tso)) (tso_CCCS dflags)) curCCS
...@@ -299,14 +321,18 @@ saveThreadState dflags tso cn = ...@@ -299,14 +321,18 @@ saveThreadState dflags tso cn =
emitCloseNursery :: FCode () emitCloseNursery :: FCode ()
emitCloseNursery = do emitCloseNursery = do
dflags <- getDynFlags dflags <- getDynFlags
tso <- newTemp (gcWord dflags) tso <- newTemp (bWord dflags)
cn <- newTemp (bWord dflags) code <- closeNursery dflags tso
emit $ mkAssign (CmmLocal tso) stgCurrentTSO <*> emit $ mkAssign (CmmLocal tso) stgCurrentTSO <*> code
closeNursery dflags tso cn
{- |
@closeNursery dflags tso@ produces code to close the nursery.
A local register holding the value of @CurrentTSO@ is expected for
efficiency.
{-
Closing the nursery corresponds to the following code: Closing the nursery corresponds to the following code:
@
tso = CurrentTSO; tso = CurrentTSO;
cn = CurrentNuresry; cn = CurrentNuresry;
...@@ -318,15 +344,13 @@ Closing the nursery corresponds to the following code: ...@@ -318,15 +344,13 @@ Closing the nursery corresponds to the following code:
// Set cn->free to the next unoccupied word in the block // Set cn->free to the next unoccupied word in the block
cn->free = Hp + WDS(1); cn->free = Hp + WDS(1);
@
-} -}
closeNursery :: MonadUnique m => DynFlags -> LocalReg -> m CmmAGraph
closeNursery :: DynFlags -> LocalReg -> LocalReg -> CmmAGraph closeNursery df tso = do
closeNursery df tso cn = let tsoreg = CmmLocal tso
let cnreg <- CmmLocal <$> newTemp (bWord df)
tsoreg = CmmLocal tso pure $ catAGraphs [
cnreg = CmmLocal cn
in
catAGraphs [
mkAssign cnreg stgCurrentNursery, mkAssign cnreg stgCurrentNursery,
-- CurrentNursery->free = Hp+1; -- CurrentNursery->free = Hp+1;
...@@ -350,27 +374,28 @@ closeNursery df tso cn = ...@@ -350,27 +374,28 @@ closeNursery df tso cn =
emitLoadThreadState :: FCode () emitLoadThreadState :: FCode ()
emitLoadThreadState = do emitLoadThreadState = do
dflags <- getDynFlags dflags <- getDynFlags
code <- loadThreadState dflags Nothing
emit code
-- | Produce code to load the current thread state from @CurrentTSO@
loadThreadState :: MonadUnique m => DynFlags -> Maybe (CmmExpr -> CmmExpr) -> m CmmAGraph
loadThreadState dflags initialSp = do
tso <- newTemp (gcWord dflags) tso <- newTemp (gcWord dflags)
stack <- newTemp (gcWord dflags) stack <- newTemp (gcWord dflags)
cn <- newTemp (bWord dflags) open_nursery <- openNursery dflags tso
bdfree <- newTemp (bWord dflags) lbl <- newBlockId
bdstart <- newTemp (bWord dflags) pure $ catAGraphs [
emit $ loadThreadState dflags tso stack cn bdfree bdstart
-- loadThreadState must be usable from the stack layout pass, where we
-- don't have FCode. Therefore it takes LocalRegs as arguments, so
-- the caller can create these.
loadThreadState :: DynFlags
-> LocalReg -> LocalReg -> LocalReg -> LocalReg -> LocalReg
-> CmmAGraph
loadThreadState dflags tso stack cn bdfree bdstart =
catAGraphs [
-- tso = CurrentTSO; -- tso = CurrentTSO;
mkAssign (CmmLocal tso) stgCurrentTSO, mkAssign (CmmLocal tso) stgCurrentTSO,
-- stack = tso->stackobj; -- stack = tso->stackobj;
mkAssign (CmmLocal stack) (CmmLoad (cmmOffset dflags (CmmReg (CmmLocal tso)) (tso_stackobj dflags)) (bWord dflags)), mkAssign (CmmLocal stack) (CmmLoad (cmmOffset dflags (CmmReg (CmmLocal tso)) (tso_stackobj dflags)) (bWord dflags)),
-- Sp = stack->sp; -- Sp = stack->sp;
mkAssign sp (CmmLoad (cmmOffset dflags (CmmReg (CmmLocal stack)) (stack_SP dflags)) (bWord dflags)), mkAssign sp (CmmLoad (cmmOffset dflags (CmmReg (CmmLocal stack)) (stack_SP dflags)) (bWord dflags)),
-- unwind Sp = initialSp(Sp);
case initialSp of
Just initial | debugLevel dflags > 0 ->
mkUnwind (NewLabel lbl) Sp (initial (CmmReg sp))
_ -> mkNop,
-- SpLim = stack->stack + RESERVED_STACK_WORDS; -- SpLim = stack->stack + RESERVED_STACK_WORDS;
mkAssign spLim (cmmOffsetW dflags (cmmOffset dflags (CmmReg (CmmLocal stack)) (stack_STACK dflags)) mkAssign spLim (cmmOffsetW dflags (cmmOffset dflags (CmmReg (CmmLocal stack)) (stack_STACK dflags))
(rESERVED_STACK_WORDS dflags)), (rESERVED_STACK_WORDS dflags)),
...@@ -378,7 +403,7 @@ loadThreadState dflags tso stack cn bdfree bdstart = ...@@ -378,7 +403,7 @@ loadThreadState dflags tso stack cn bdfree bdstart =
-- HpAlloc is assumed to be set to non-zero only by a failed -- HpAlloc is assumed to be set to non-zero only by a failed
-- a heap check, see HeapStackCheck.cmm:GC_GENERIC -- a heap check, see HeapStackCheck.cmm:GC_GENERIC
mkAssign hpAlloc (zeroExpr dflags), mkAssign hpAlloc (zeroExpr dflags),
openNursery dflags tso cn bdfree bdstart, open_nursery,
-- and load the current cost centre stack from the TSO when profiling: -- and load the current cost centre stack from the TSO when profiling:
if gopt Opt_SccProfilingOn dflags if gopt Opt_SccProfilingOn dflags
then storeCurCCS then storeCurCCS
...@@ -391,16 +416,17 @@ loadThreadState dflags tso stack cn bdfree bdstart = ...@@ -391,16 +416,17 @@ loadThreadState dflags tso stack cn bdfree bdstart =
emitOpenNursery :: FCode () emitOpenNursery :: FCode ()
emitOpenNursery = do emitOpenNursery = do
dflags <- getDynFlags dflags <- getDynFlags
tso <- newTemp (gcWord dflags) tso <- newTemp (bWord dflags)
cn <- newTemp (bWord dflags) code <- openNursery dflags tso
bdfree <- newTemp (bWord dflags) emit $ mkAssign (CmmLocal tso) stgCurrentTSO <*> code
bdstart <- newTemp (bWord dflags)
emit $ mkAssign (CmmLocal tso) stgCurrentTSO <*> {- |
openNursery dflags tso cn bdfree bdstart @openNursery dflags tso@ produces code to open the nursery. A local register
holding the value of @CurrentTSO@ is expected for efficiency.
{-
Opening the nursery corresponds to the following code: Opening the nursery corresponds to the following code:
@
tso = CurrentTSO; tso = CurrentTSO;
cn = CurrentNursery; cn = CurrentNursery;
bdfree = CurrentNuresry->free; bdfree = CurrentNuresry->free;
...@@ -420,23 +446,20 @@ Opening the nursery corresponds to the following code: ...@@ -420,23 +446,20 @@ Opening the nursery corresponds to the following code:
// Set HpLim to the end of the current nursery block (note that this block // Set HpLim to the end of the current nursery block (note that this block
// might be a block group, consisting of several adjacent blocks. // might be a block group, consisting of several adjacent blocks.
HpLim = bdstart + CurrentNursery->blocks*BLOCK_SIZE_W - 1; HpLim = bdstart + CurrentNursery->blocks*BLOCK_SIZE_W - 1;
@
-} -}
openNursery :: MonadUnique m => DynFlags -> LocalReg -> m CmmAGraph
openNursery df tso = do
let tsoreg = CmmLocal tso
cnreg <- CmmLocal <$> newTemp (bWord df)
bdfreereg <- CmmLocal <$> newTemp (bWord df)
bdstartreg <- CmmLocal <$> newTemp (bWord df)
openNursery :: DynFlags
-> LocalReg -> LocalReg -> LocalReg -> LocalReg
-> CmmAGraph
openNursery df tso cn bdfree bdstart =
let
tsoreg = CmmLocal tso
cnreg = CmmLocal cn
bdfreereg = CmmLocal bdfree
bdstartreg = CmmLocal bdstart
in
-- These assignments are carefully ordered to reduce register -- These assignments are carefully ordered to reduce register
-- pressure and generate not completely awful code on x86. To see -- pressure and generate not completely awful code on x86. To see
-- what code we generate, look at the assembly for -- what code we generate, look at the assembly for
-- stg_returnToStackTop in rts/StgStartup.cmm. -- stg_returnToStackTop in rts/StgStartup.cmm.
catAGraphs [ pure $ catAGraphs [
mkAssign cnreg stgCurrentNursery, mkAssign cnreg stgCurrentNursery,
mkAssign bdfreereg (CmmLoad (nursery_bdescr_free df cnreg) (bWord df)), mkAssign bdfreereg (CmmLoad (nursery_bdescr_free df cnreg) (bWord df)),
......
...@@ -127,6 +127,12 @@ instance Monad FCode where ...@@ -127,6 +127,12 @@ instance Monad FCode where
{-# INLINE thenFC #-} {-# INLINE thenFC #-}
{-# INLINE returnFC #-} {-# INLINE returnFC #-}
instance MonadUnique FCode where
getUniqueSupplyM = cgs_uniqs <$> getState
getUniqueM = FCode $ \_ st ->
let (u, us') = takeUniqFromSupply (cgs_uniqs st)
in (# u, st { cgs_uniqs = us' } #)
initC :: IO CgState initC :: IO CgState
initC = do { uniqs <- mkSplitUniqSupply 'c' initC = do { uniqs <- mkSplitUniqSupply 'c'
; return (initCgState uniqs) } ; return (initCgState uniqs) }
...@@ -728,11 +734,12 @@ emitComment _ = return () ...@@ -728,11 +734,12 @@ emitComment _ = return ()
emitTick :: CmmTickish -> FCode () emitTick :: CmmTickish -> FCode ()
emitTick = emitCgStmt . CgStmt . CmmTick emitTick = emitCgStmt . CgStmt . CmmTick
emitUnwind :: GlobalReg -> CmmExpr -> FCode () emitUnwind :: [(GlobalReg, CmmExpr)] -> FCode ()
emitUnwind g e = do emitUnwind regs = do
dflags <- getDynFlags dflags <- getDynFlags
when (debugLevel dflags > 0) $ when (debugLevel dflags > 0) $ do
emitCgStmt $ CgStmt $ CmmUnwind g e lbl <- newLabelC
emitCgStmt $ CgStmt $ CmmUnwind (NewLabel lbl) regs
emitAssign :: CmmReg -> CmmExpr -> FCode () emitAssign :: CmmReg -> CmmExpr -> FCode ()
emitAssign l r = emitCgStmt (CgStmt (CmmAssign l r)) emitAssign l r = emitCgStmt (CgStmt (CmmAssign l r))
...@@ -742,8 +749,7 @@ emitStore l r = emitCgStmt (CgStmt (CmmStore l r)) ...@@ -742,8 +749,7 @@ emitStore l r = emitCgStmt (CgStmt (CmmStore l r))
newLabelC :: FCode BlockId newLabelC :: FCode BlockId
newLabelC = do { u <- newUnique newLabelC = newBlockId
; return $ mkBlockId u }
emit :: CmmAGraph -> FCode () emit :: CmmAGraph -> FCode ()
emit ag emit ag
......
...@@ -63,6 +63,7 @@ import Literal ...@@ -63,6 +63,7 @@ import Literal
import Digraph import Digraph
import Util import Util
import Unique import Unique
import UniqSupply (MonadUnique(..))
import DynFlags import DynFlags
import FastString import FastString
import Outputable import Outputable
...@@ -345,8 +346,8 @@ assignTemp e = do { dflags <- getDynFlags ...@@ -345,8 +346,8 @@ assignTemp e = do { dflags <- getDynFlags
; emitAssign (CmmLocal reg) e ; emitAssign (CmmLocal reg) e
; return reg } ; return reg }
newTemp :: CmmType -> FCode LocalReg newTemp :: MonadUnique m => CmmType -> m LocalReg
newTemp rep = do { uniq <- newUnique newTemp rep = do { uniq <- getUniqueM
; return (LocalReg uniq rep) } ; return (LocalReg uniq rep) }
newUnboxedTupleRegs :: Type -> FCode ([LocalReg], [ForeignHint]) newUnboxedTupleRegs :: Type -> FCode ([LocalReg], [ForeignHint])
......
...@@ -18,6 +18,7 @@ import UniqSupply ...@@ -18,6 +18,7 @@ import UniqSupply
import Dwarf.Constants import Dwarf.Constants
import Dwarf.Types import Dwarf.Types
import Control.Arrow ( first )
import Control.Monad ( mfilter ) import Control.Monad ( mfilter )
import Data.Maybe import Data.Maybe
import Data.List ( sortBy ) import Data.List ( sortBy )
...@@ -216,20 +217,31 @@ procToFrame :: UnwindTable -> DebugBlock -> DwarfFrameProc ...@@ -216,20 +217,31 @@ procToFrame :: UnwindTable -> DebugBlock -> DwarfFrameProc
procToFrame initUws blk procToFrame initUws blk
= DwarfFrameProc { dwFdeProc = dblCLabel blk = DwarfFrameProc { dwFdeProc = dblCLabel blk
, dwFdeHasInfo = dblHasInfoTbl blk , dwFdeHasInfo = dblHasInfoTbl blk
, dwFdeBlocks = map (uncurry blockToFrame) blockUws , dwFdeBlocks = map (uncurry blockToFrame)
(first setHasInfo blockUw0 : blockUws)
} }
where blockUws :: [(DebugBlock, UnwindTable)] where blockUws :: [(DebugBlock, UnwindPoints)]
blockUws = map snd $ sortBy (comparing fst) $ flatten initUws blk blockUw0:blockUws =
flatten uws0 b@DebugBlock{ dblPosition=pos, dblUnwind=uws, map snd $ sortBy (comparing fst) $ flatten blk
dblBlocks=blocks }
flatten :: DebugBlock
-> [(Int, (DebugBlock, UnwindPoints))]
flatten b@DebugBlock{ dblPosition=pos, dblUnwind=uws, dblBlocks=blocks }
| Just p <- pos = (p, (b, uws')):nested | Just p <- pos = (p, (b, uws')):nested
| otherwise = nested -- block was optimized out | otherwise = nested -- block was optimized out
where uws' = uws `Map.union` uws0 where uws' = addDefaultUnwindings initUws uws
nested = concatMap (flatten uws') blocks nested = concatMap flatten blocks
blockToFrame :: DebugBlock -> UnwindTable -> DwarfFrameBlock -- | If the current procedure has an info table, then we also say that
-- its first block has one to ensure that it gets the necessary -1
-- offset applied to its start address.
-- See Note [Info Offset] in Dwarf.Types.
setHasInfo :: DebugBlock -> DebugBlock
setHasInfo child =
child { dblHasInfoTbl = dblHasInfoTbl child || dblHasInfoTbl blk }
blockToFrame :: DebugBlock -> UnwindPoints -> DwarfFrameBlock
blockToFrame blk uws blockToFrame blk uws
= DwarfFrameBlock { dwFdeBlock = mkAsmTempLabel $ dblLabel blk = DwarfFrameBlock { dwFdeBlkHasInfo = dblHasInfoTbl blk
, dwFdeBlkHasInfo = dblHasInfoTbl blk
, dwFdeUnwind = uws , dwFdeUnwind = uws
} }
...@@ -130,9 +130,10 @@ dW_CFA_val_expression = 0x16 ...@@ -130,9 +130,10 @@ dW_CFA_val_expression = 0x16
dW_CFA_offset = 0x80 dW_CFA_offset = 0x80
-- * Operations -- * Operations
dW_OP_deref, dW_OP_consts, dW_OP_addr, dW_OP_deref, dW_OP_consts,
dW_OP_minus, dW_OP_mul, dW_OP_plus, dW_OP_minus, dW_OP_mul, dW_OP_plus,
dW_OP_lit0, dW_OP_breg0, dW_OP_call_frame_cfa :: Word8 dW_OP_lit0, dW_OP_breg0, dW_OP_call_frame_cfa :: Word8
dW_OP_addr = 0x03
dW_OP_deref = 0x06 dW_OP_deref = 0x06
dW_OP_consts = 0x11 dW_OP_consts = 0x11
dW_OP_minus = 0x1c dW_OP_minus = 0x1c
......
...@@ -35,8 +35,9 @@ import SrcLoc ...@@ -35,8 +35,9 @@ import SrcLoc
import Dwarf.Constants import Dwarf.Constants
import qualified Control.Monad.Trans.State.Strict as S
import Control.Monad (zipWithM)
import Data.Bits import Data.Bits
import Data.List ( mapAccumL )
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.Word import Data.Word
import Data.Char import Data.Char
...@@ -268,11 +269,13 @@ data DwarfFrameProc ...@@ -268,11 +269,13 @@ data DwarfFrameProc
-- containing FDE. -- containing FDE.
data DwarfFrameBlock data DwarfFrameBlock
= DwarfFrameBlock = DwarfFrameBlock
{ dwFdeBlock :: CLabel { dwFdeBlkHasInfo :: Bool
, dwFdeBlkHasInfo :: Bool , dwFdeUnwind :: UnwindPoints
, dwFdeUnwind :: UnwindTable
} }
instance Outputable DwarfFrameBlock where
ppr (DwarfFrameBlock hasInfo unwinds) = braces $ ppr hasInfo <+> ppr unwinds
-- | Header for the @.debug_frame@ section. Here we emit the "Common -- | Header for the @.debug_frame@ section. Here we emit the "Common
-- Information Entry" record that etablishes general call frame -- Information Entry" record that etablishes general call frame
-- parameters and the default stack layout. -- parameters and the default stack layout.
...@@ -285,6 +288,7 @@ pprDwarfFrame DwarfFrame{dwCieLabel=cieLabel,dwCieInit=cieInit,dwCieProcs=procs} ...@@ -285,6 +288,7 @@ pprDwarfFrame DwarfFrame{dwCieLabel=cieLabel,dwCieInit=cieInit,dwCieProcs=procs}
spReg = dwarfGlobalRegNo plat Sp spReg = dwarfGlobalRegNo plat Sp
retReg = dwarfReturnRegNo plat retReg = dwarfReturnRegNo plat
wordSize = platformWordSize plat wordSize = platformWordSize plat
pprInit :: (GlobalReg, UnwindExpr) -> SDoc
pprInit (g, uw) = pprSetUnwind plat g (Nothing, uw) pprInit (g, uw) = pprSetUnwind plat g (Nothing, uw)
-- Preserve C stack pointer: This necessary to override that default -- Preserve C stack pointer: This necessary to override that default
...@@ -337,7 +341,8 @@ pprFrameProc frameLbl initUw (DwarfFrameProc procLbl hasInfo blocks) ...@@ -337,7 +341,8 @@ pprFrameProc frameLbl initUw (DwarfFrameProc procLbl hasInfo blocks)
procEnd = mkAsmTempEndLabel procLbl procEnd = mkAsmTempEndLabel procLbl
ifInfo str = if hasInfo then text str else empty ifInfo str = if hasInfo then text str else empty
-- see [Note: Info Offset] -- see [Note: Info Offset]
in vcat [ pprData4' (ppr fdeEndLabel <> char '-' <> ppr fdeLabel) in pprTrace "FrameProc" (ppr procLbl <+> ppr hasInfo <+> ppr blocks) $
vcat [ pprData4' (ppr fdeEndLabel <> char '-' <> ppr fdeLabel)
, ppr fdeLabel <> colon , ppr fdeLabel <> colon
, pprData4' (ppr frameLbl <> char '-' <> , pprData4' (ppr frameLbl <> char '-' <>
ptext dwarfFrameLabel) -- Reference to CIE ptext dwarfFrameLabel) -- Reference to CIE
...@@ -345,7 +350,7 @@ pprFrameProc frameLbl initUw (DwarfFrameProc procLbl hasInfo blocks) ...@@ -345,7 +350,7 @@ pprFrameProc frameLbl initUw (DwarfFrameProc procLbl hasInfo blocks)
, pprWord (ppr procEnd <> char '-' <> , pprWord (ppr procEnd <> char '-' <>
ppr procLbl <> ifInfo "+1") -- Block byte length ppr procLbl <> ifInfo "+1") -- Block byte length
] $$ ] $$
vcat (snd $ mapAccumL pprFrameBlock initUw blocks) $$ vcat (S.evalState (mapM pprFrameBlock blocks) initUw) $$
wordAlign $$ wordAlign $$
ppr fdeEndLabel <> colon ppr fdeEndLabel <> colon
...@@ -353,22 +358,27 @@ pprFrameProc frameLbl initUw (DwarfFrameProc procLbl hasInfo blocks) ...@@ -353,22 +358,27 @@ pprFrameProc frameLbl initUw (DwarfFrameProc procLbl hasInfo blocks)
-- instructions where unwind information actually changes. This small -- instructions where unwind information actually changes. This small
-- optimisations saves a lot of space, as subsequent blocks often have -- optimisations saves a lot of space, as subsequent blocks often have
-- the same unwind information. -- the same unwind information.
pprFrameBlock :: UnwindTable -> DwarfFrameBlock -> (UnwindTable, SDoc) pprFrameBlock :: DwarfFrameBlock -> S.State UnwindTable SDoc
pprFrameBlock oldUws (DwarfFrameBlock blockLbl hasInfo uws) pprFrameBlock (DwarfFrameBlock hasInfo (UnwindPoints uws0)) =
| uws == oldUws vcat <$> zipWithM pprFrameDecl (True : repeat False) uws0
= (oldUws, empty) where
| otherwise pprFrameDecl :: Bool -> (CLabel, UnwindTable) -> S.State UnwindTable SDoc
= (,) uws $ sdocWithPlatform $ \plat -> pprFrameDecl firstDecl (lbl, uws) = S.state $ \oldUws ->
let lbl = ppr blockLbl <> if hasInfo then text "-1" else empty let isChanged g v | old == Just v = Nothing
-- see [Note: Info Offset] | otherwise = Just (old, v)
isChanged g v | old == Just v = Nothing where old = Map.lookup g oldUws
| otherwise = Just (old, v) changed = Map.toList $ Map.mapMaybeWithKey isChanged uws
where old = Map.lookup g oldUws died = Map.toList $ Map.difference oldUws uws
changed = Map.toList $ Map.mapMaybeWithKey isChanged uws
died = Map.toList $ Map.difference oldUws uws in if oldUws == uws
in pprByte dW_CFA_set_loc $$ pprWord lbl $$ then (empty, oldUws)
vcat (map (uncurry $ pprSetUnwind plat) changed) $$ else let needsOffset = firstDecl && hasInfo -- see [Note: Info Offset]
vcat (map (pprUndefUnwind plat . fst) died) lblDoc = ppr lbl <> if needsOffset then text "-1" else empty
doc = sdocWithPlatform $ \plat ->
pprByte dW_CFA_set_loc $$ pprWord lblDoc $$
vcat (map (uncurry $ pprSetUnwind plat) changed) $$
vcat (map (pprUndefUnwind plat . fst) died)
in (doc, uws)
-- Note [Info Offset] -- Note [Info Offset]
-- --
...@@ -446,6 +456,7 @@ pprUnwindExpr spIsCFA expr ...@@ -446,6 +456,7 @@ pprUnwindExpr spIsCFA expr
pprE (UwReg g i) = pprByte (dW_OP_breg0+dwarfGlobalRegNo plat g) $$ pprE (UwReg g i) = pprByte (dW_OP_breg0+dwarfGlobalRegNo plat g) $$
pprLEBInt i pprLEBInt i
pprE (UwDeref u) = pprE u $$ pprByte dW_OP_deref pprE (UwDeref u) = pprE u $$ pprByte dW_OP_deref
pprE (UwLabel l) = pprByte dW_OP_addr $$ pprWord (ppr l)
pprE (UwPlus u1 u2) = pprE u1 $$ pprE u2 $$ pprByte dW_OP_plus pprE (UwPlus u1 u2) = pprE u1 $$ pprE u2 $$ pprByte dW_OP_plus
pprE (UwMinus u1 u2) = pprE u1 $$ pprE u2 $$ pprByte dW_OP_minus pprE (UwMinus u1 u2) = pprE u1 $$ pprE u2 $$ pprByte dW_OP_minus
pprE (UwTimes u1 u2) = pprE u1 $$ pprE u2 $$ pprByte dW_OP_mul pprE (UwTimes u1 u2) = pprE u1 $$ pprE u2 $$ pprByte dW_OP_mul
......
...@@ -155,9 +155,10 @@ stmtToInstrs stmt = do ...@@ -155,9 +155,10 @@ stmtToInstrs stmt = do
dflags <- getDynFlags dflags <- getDynFlags
is32Bit <- is32BitPlatform is32Bit <- is32BitPlatform
case stmt of case stmt of
CmmComment s -> return (unitOL (COMMENT s)) CmmComment s -> return (unitOL (COMMENT s))
CmmTick {} -> return nilOL CmmTick {} -> return nilOL
CmmUnwind {} -> return nilOL CmmUnwind (NewLabel lbl) regs -> return (unitOL (LABEL lbl))
CmmUnwind {} -> return nilOL
CmmAssign reg src CmmAssign reg src
| isFloatType ty -> assignReg_FltCode format reg src | isFloatType ty -> assignReg_FltCode format reg src
......
...@@ -178,6 +178,10 @@ data Instr ...@@ -178,6 +178,10 @@ data Instr
-- invariants for a BasicBlock (see Cmm). -- invariants for a BasicBlock (see Cmm).
| NEWBLOCK BlockId | NEWBLOCK BlockId
-- define a new label within a block. Used to refer to points within a
-- block during generation of debugging information.
| LABEL BlockId
-- specify current stack offset for -- specify current stack offset for
-- benefit of subsequent passes -- benefit of subsequent passes
| DELTA Int | DELTA Int
...@@ -783,6 +787,7 @@ x86_isMetaInstr instr ...@@ -783,6 +787,7 @@ x86_isMetaInstr instr
LOCATION{} -> True LOCATION{} -> True
LDATA{} -> True LDATA{} -> True
NEWBLOCK{} -> True NEWBLOCK{} -> True
LABEL{} -> True
DELTA{} -> True DELTA{} -> True
_ -> False _ -> False
......
...@@ -488,6 +488,9 @@ pprInstr (DELTA d) ...@@ -488,6 +488,9 @@ pprInstr (DELTA d)
pprInstr (NEWBLOCK _) pprInstr (NEWBLOCK _)
= panic "PprMach.pprInstr: NEWBLOCK" = panic "PprMach.pprInstr: NEWBLOCK"
pprInstr (LABEL lbl)
= pprLabel $ mkAsmTempLabel $ getUnique lbl
pprInstr (LDATA _ _) pprInstr (LDATA _ _)
= panic "PprMach.pprInstr: LDATA" = panic "PprMach.pprInstr: LDATA"
......
...@@ -70,8 +70,8 @@ INFO_TABLE_RET(stg_stop_thread, STOP_FRAME, ...@@ -70,8 +70,8 @@ INFO_TABLE_RET(stg_stop_thread, STOP_FRAME,
for us by StgRun. for us by StgRun.
*/ */
#ifdef x86_64_HOST_ARCH #ifdef x86_64_HOST_ARCH
unwind MachSp = MachSp + RESERVED_C_STACK_BYTES + 0x38 + 8 unwind MachSp = MachSp + RESERVED_C_STACK_BYTES + 0x38 + 8,
unwind UnwindReturnReg = W_[MachSp + RESERVED_C_STACK_BYTES + 0x38] UnwindReturnReg = W_[MachSp + RESERVED_C_STACK_BYTES + 0x38];
#endif #endif
Sp = Sp + SIZEOF_StgStopFrame - WDS(2); Sp = Sp + SIZEOF_StgStopFrame - WDS(2);
......