Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,869
    • Issues 4,869
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 456
    • Merge requests 456
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #17570
Closed
Open
Created Dec 12, 2019 by Ömer Sinan Ağacan@osa1Maintainer

Refactor CafInfo type for better compiler error checking

Motivation

Currently the CafInfo type is defined like this:

data CafInfo
    = MayHaveCafRefs -- i.e. CAFFY
    | NoCafRefs -- i.e. not CAFFY

Every Id has a CafInfo in its IdInfo:

data IdInfo = IdInfo
    { ...
    , cafInfo :: CafInfo
      ...
    }

The problem is this type forces us to give every Id a CafInfo on initialization even though in practice most of the time we only know CafInfos of Ids after the relevant analysis.

(There are cases where we know the CafInfo on initialization, but those are exceptions rather than the norm)

Becuase it's safe to assume an Id CAFFY the default CafInfo value is MayHaveCafRefs and most Ids are thus initialized as CAFFY.

The problem is that if we have a bug in the compiler and don't assign a CafInfo to an Id (maybe the analysis missed the Id, or there are bugs in the plumbing code) everything silently works beucase assuming a non-CAFFY Id CAFFY does not cause any problems in the generated code.

Proposal

I propose adding one more constructor to the type:

data CafInfo
    = MayHaveCafRefs
    | NoCafRefs

    -- New constructor:
    | UnknownCafInfo -- verbose name to avoid name clashes (sigh)

and initialize most Ids with UnknownCafInfo:

vanillaCafInfo :: CafInfo
vanillaCafInfo = UnknownCafInfo

CafInfo queries on these Ids would then fail:

mayHaveCafRefs :: HasCallStack => CafInfo -> Bool
mayHaveCafRefs MayHaveCafRefs = True
mayHaveCafRefs NoCafRefs = False
mayHaveCafRefs UnknownCafInfo = pprPanic "mayHaveCafRefs" (text "Unknown CafInfo")

Implementation details

As of today it's a little bit tricky to implement this because CafInfo is used in various parts of the simplifier and code generator.

However after !2100 (closed) and !1304 (merged) merged this will be almost trivial to implement: after those patches CafInfos will only be used by the SRT analysis pass (CmmBuildInfoTables). CLabels of the current module will have UnknownCafInfo as their CafInfos, and CmmBuildInfoTables will be updated to handle UnknownCafInfo (those will be considered definitions in the current module).

Imported Ids are expected to have accurate (non-UnknownCafInfo) CafInfos.

Interface file syntax does not need to change, but interface file generator will be changed to make sure no Ids written to an interface file will have UnknownCafInfo: if an Id is in an interface file it needs to be analyzed by CmmBuildInfoTables and have an accurate CafInfo.

(That does not imply that we'll be writing the CafInfos to the interface files with -fomit-iface-pragmas -- we'll simply check that Ids have accurate CafInfos)

(See also https://gitlab.haskell.org/ghc/ghc/wikis/CafInfo-rework for the progress !2100 (closed) and !1304 (merged))

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking