Skip to content
GitLab
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 5,247
    • Issues 5,247
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 577
    • Merge requests 577
  • 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 CompilerGlasgow Haskell Compiler
  • GHCGHC
  • Merge requests
  • !5755

Cmm: fix sinking after suspendThread (#19237)

  • Review changes

  • Download
  • Email patches
  • Plain diff
Closed Sylvain Henry requested to merge hsyl20/ghc:hsyl20/unreg/clobber into master May 14, 2021
  • Overview 7
  • Commits 1
  • Pipelines 2
  • Changes 12
Suppose a safe call: myCall(x,y,z)

It is lowered into three unsafe calls in Cmm:

  r = suspendThread(...);
  myCall(x,y,z);
  resumeThread(r);

Consider the following situation for myCall arguments:

  x = Sp[..] -- stack
  y = Hp[..] -- heap
  z = R1     -- global register
  r = suspendThread(...);
  myCall(x,y,z);
  resumeThread(r);

The sink pass assumes that unsafe calls clobber memory (heap and stack),
hence x and y assignments are not sunk after `suspendThread`. The sink
pass also correctly handles global register clobbering for all unsafe
calls, except `suspendThread`!

`suspendThread` is special because it releases the capability the thread
is running on. Hence the sink pass must also take into account global
registers that are mapped into memory (in the capability).

In the example above, we could get:

  r = suspendThread(...);
  z = R1
  myCall(x,y,z);
  resumeThread(r);

But this transformation isn't valid if R1 is (BaseReg->rR1) as BaseReg
is invalid between suspendThread and resumeThread. This caused argument
corruption at least with the C backend ("unregisterised") in #19237.
Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: hsyl20/unreg/clobber