Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
GHC
GHC
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,263
    • Issues 4,263
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
    • Iterations
  • Merge Requests 417
    • Merge Requests 417
  • Requirements
    • Requirements
    • List
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Security & Compliance
    • Security & Compliance
    • Dependency List
    • License Compliance
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Code Review
    • Insights
    • Issue
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Glasgow Haskell Compiler
  • GHCGHC
  • Wiki
    • Nested cpr
  • wave4main

Last edited by Tobias Dammers Mar 29, 2019
Page history New page

wave4main

wave4main

Baseline: [0e2fd3/ghc], Tested: nested-cpr (without nesting inside sum-types, without join-point detection).

Found a 11% increase in allocation, around 9000000 bytes.

The most obvious change in ticky-ticky-number are:

  • FUNCTION ENTRIES and ENTERS increasing by ~100000
  • RETURNS doubling from 140745 to 280795
  • ALLOC_FUN_ctr and ALLOC_FUN_gds almost doubling, by ~18000 resp. 9000000

So we are allocating more function closures. First guess: Join point property destroyed somewhere.

The ticky output shows a $wgo{v s60k} (main:Main) appearing that was not there before, with 140016 enters and 23522688 allocations. This appears in $wtabulate, and indeed corresponds to a go1 that is a join-point before. So what is happening? We are changing

go1 [Occ=LoopBreaker]                                      
  :: GHC.Prim.Int#                                         
     -> GHC.Prim.State# s                                  
     -> (# GHC.Prim.State# s, GHC.Arr.Array GHC.Types.Int x #)

to

$wgo [Occ=LoopBreaker]          
  :: GHC.Prim.Int#
     -> GHC.Prim.State# s
     -> (# GHC.Prim.State# s,   
           GHC.Prim.Int#,       
           GHC.Prim.Int#,       
           GHC.Prim.Int#,       
           GHC.Prim.Array# x #) 

go1 is recursive, but tail-recursive, so the worker and wrapper indeed cancel for the recursive call. But where it is being used, we simply apply the Array constructor to the second component. So nothing is gained, but a join-point is lost.

My attempt below to detect join points does not help: The CPR information for go1 is the same as for let go1 = rhs in body, as body is just go1 ww ipv.

The problem is that this is being passed as an argument to a function (in this case runSTRep), and there is not much that can be done about this at this point.

Summary with simple expressions

Original code:

f a x = case a of
  True -> case foo of b -> foo $
    let go 0 = (1,(2,3))
        go n = go (n-1)
    in go b
  False -> undefined

which after CPR transformation yields, where $go is no longer a join-point for the argument to snd.

f a x = case a of
  True -> case foo of b -> foo $
    let $wgo 0 = (# 1, 2, 3 #)
        $wgo n = go (n-1)
    in case $wgo b of (# a, b, c #) -> (a, (b,c))
  False -> undefined
Clone repository

GHC Home
GHC User's Guide

Joining In

Newcomers info
Mailing Lists & IRC
The GHC Team

Documentation

GHC Status Info
Working conventions
Building Guide
Debugging
Commentary

Wiki

Title Index
Recent Changes