| 1 | {-# LANGUAGE CPP #-} |
|---|
| 2 | |
|---|
| 3 | #define F_BODY if a then (x + x + x + x + x + x) else (x + if b then x else 0) |
|---|
| 4 | |
|---|
| 5 | #define F_USE(f) if b then (if a then f 3 else f 5) else f 0 |
|---|
| 6 | |
|---|
| 7 | module FVDiscountSim (outer_BAD, outer_GOOD) where |
|---|
| 8 | |
|---|
| 9 | -- This example is abstracted from nofib boyer2, onewayunify1. |
|---|
| 10 | |
|---|
| 11 | -- With a local definition, having a free variable, local_f is not inlined |
|---|
| 12 | -- But it should be, because at the call site in F_USE, 'b' is known |
|---|
| 13 | -- to be True or False respectively |
|---|
| 14 | outer_BAD a b = |
|---|
| 15 | let local_f :: Integer -> Integer |
|---|
| 16 | local_f x = F_BODY |
|---|
| 17 | in F_USE( local_f ) |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | -- With a top-level defintion, floated_f is inlined |
|---|
| 21 | -- because we get a discount for 'b'. |
|---|
| 22 | floated_f :: Bool -> Bool -> Integer -> Integer |
|---|
| 23 | floated_f a b x = F_BODY |
|---|
| 24 | |
|---|
| 25 | outer_GOOD a b = F_USE(floated_f a b) |
|---|