Opened 7 years ago

Last modified 4 years ago

#6047 new bug

GHC retains unnecessary binding

Reported by: simonmar Owned by: simonpj
Priority: normal Milestone:
Component: Compiler Version: 7.4.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Compile-time performance bug Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

milan posted this example on #6042, I'm making a separate ticket for it. He says:


BTW, when I preparing for the advanced functional programming course, I found out that the following code

module Test where
factorial :: Int -> Int
factorial n | n > 0 = f n 1
  where f 0 acc = acc
        f n acc = f (n-1) (n * acc)

produces the following STG, on both GHC 7.0.4 and 7.4.1, with unused method factorial_f:

Test.factorial2 =
    \u srt:(0,*bitmap*) []
        Control.Exception.Base.patError
            "a.hs:(4,1)-(6,35)|function factorial";
SRT(Test.factorial2): [Control.Exception.Base.patError]
Test.$wf =
    \r [ww_srk ww1_sro]
        case ww_srk of wild_srm {
          __DEFAULT ->
              case *# [wild_srm ww1_sro] of sat_srK {
                __DEFAULT ->
                    case -# [wild_srm 1] of sat_srL {
                      __DEFAULT -> Test.$wf sat_srL sat_srK;
                    };
              };
          0 -> ww1_sro;
        };
SRT(Test.$wf): []
Test.factorial_f =
    \r [w_srs w1_srv]
        case w_srs of w2_srN {
          GHC.Types.I# ww_sry ->
              case w1_srv of w3_srM {
                GHC.Types.I# ww1_srz ->
                    case Test.$wf ww_sry ww1_srz of ww2_srB {
                      __DEFAULT -> GHC.Types.I# [ww2_srB];
                    };
              };
        };
SRT(Test.factorial_f): []
Test.factorial1 = NO_CCS GHC.Types.I#! [1];
SRT(Test.factorial1): []
Test.factorial =
    \r srt:(0,*bitmap*) [n_srD]
        case n_srD of wild_srP {
          GHC.Types.I# x_srG ->
              case ># [x_srG 0] of wild1_srO {
                GHC.Types.False -> Test.factorial2;
                GHC.Types.True ->
                    case Test.$wf x_srG 1 of ww_srJ {
                      __DEFAULT -> GHC.Types.I# [ww_srJ];
                    };
              };
        };
SRT(Test.factorial): [Test.factorial2]

The Test.factorial_f appears also in asm and in the object file.


simonpj explained to me why this is happening: factorial_f is being retained because it is referenced in an INLINE pragma for factorial. In fact it will never be used, because factorial_f itself is also INLINE.

We're going to investigate possible workarounds/solutions.

Note it's only a code size issue, performance is not affected (compile time is affected a little though). We're not sure how much it happens.

Change History (6)

comment:1 Changed 7 years ago by igloo

Milestone: 7.6.17.6.2

comment:2 Changed 5 years ago by thoughtpolice

Milestone: 7.6.27.10.1

Moving to 7.10.1.

comment:3 Changed 5 years ago by thoughtpolice

Milestone: 7.10.17.12.1

Moving to 7.12.1 milestone; if you feel this is an error and should be addressed sooner, please move it back to the 7.10.1 milestone.

comment:4 Changed 4 years ago by thoughtpolice

Milestone: 7.12.18.0.1

Milestone renamed

comment:5 Changed 4 years ago by thomie

Type of failure: None/UnknownCompile-time performance bug

comment:6 Changed 4 years ago by thomie

Milestone: 8.0.1
Note: See TracTickets for help on using tickets.