... | ... | @@ -83,30 +83,9 @@ instructions). |
|
|
|
|
|
Unfortunately, this means that all these heap checks will make our program run slower. Our goal is to get the heap check out of the "hot" path - we would like to put it in alts.
|
|
|
|
|
|
In this particular case we fall into the first branch because our program uses comparison operator (See `Note [GC for conditionals]`). We can push the heap check into the branch by removing the first guard in `do_gc`:
|
|
|
|
|
|
In this particular case we fall into the first branch because our program uses comparison operator (See `Note [GC for conditionals]`). We generate this Cmm for this program:
|
|
|
```
|
|
|
diff --git a/compiler/GHC/StgToCmm/Expr.hs b/compiler/GHC/StgToCmm/Expr.hs
|
|
|
index eb56a6ad09..2265876a4d 100644
|
|
|
--- a/compiler/GHC/StgToCmm/Expr.hs
|
|
|
+++ b/compiler/GHC/StgToCmm/Expr.hs
|
|
|
@@ -430,8 +430,7 @@ cgCase scrut bndr alt_type alts
|
|
|
; let ret_bndrs = chooseReturnBndrs bndr alt_type alts
|
|
|
alt_regs = map (idToReg platform) ret_bndrs
|
|
|
; simple_scrut <- isSimpleScrut scrut alt_type
|
|
|
- ; let do_gc | is_cmp_op scrut = False -- See Note [GC for conditionals]
|
|
|
- | not simple_scrut = True
|
|
|
+ ; let do_gc | not simple_scrut = True
|
|
|
| isSingleton alts = False
|
|
|
| up_hp_usg > 0 = False
|
|
|
| otherwise = True
|
|
|
```
|
|
|
|
|
|
We will refer to this patch as `GcInAlts_Patch`.
|
|
|
|
|
|
| header | header |
|
|
|
| ------ | ------ |
|
|
|
| [Main.$wgo_entry() { // [R2]
|
|
|
[Main.$wgo_entry() { // [R2]
|
|
|
{ info_tbls: [(c27w,
|
|
|
label: Main.$wgo_info
|
|
|
rep: HeapRep static { Fun {arity: 1 fun_type: ArgSpec 4} }
|
... | ... | @@ -141,58 +120,38 @@ We will refer to this patch as `GcInAlts_Patch`. |
|
|
section ""data" . Main.$wgo_closure" {
|
|
|
Main.$wgo_closure:
|
|
|
const Main.$wgo_info;
|
|
|
}] | [Main.$wgo_entry() { // [R2]
|
|
|
{ info_tbls: [(c27w,
|
|
|
label: Main.$wgo_info
|
|
|
rep: HeapRep static { Fun {arity: 1 fun_type: ArgSpec 4} }
|
|
|
srt: Nothing),
|
|
|
(c27A,
|
|
|
label: block_c27A_info
|
|
|
rep: StackRep [True]
|
|
|
srt: Nothing)]
|
|
|
stack_info: arg_space: 8
|
|
|
}
|
|
|
{offset
|
|
|
c27w: // global
|
|
|
_s26y::I64 = R2;
|
|
|
c27o: // global
|
|
|
_s26z::I64 = %MO_S_Gt_W64(_s26y::I64, 0);
|
|
|
if (_s26z::I64 != 1) goto c27B; else goto c27v;
|
|
|
c27B: // global
|
|
|
Hp = Hp + 16;
|
|
|
if (Hp > HpLim) (likely: False) goto c27G; else goto c27F;
|
|
|
c27G: // global
|
|
|
HpAlloc = 16;
|
|
|
I64[Sp - 16] = c27A;
|
|
|
R1 = _s26z::I64;
|
|
|
I64[Sp - 8] = _s26y::I64;
|
|
|
Sp = Sp - 16;
|
|
|
call stg_gc_unbx_r1(R1) returns to c27A, args: 8, res: 8, upd: 8;
|
|
|
c27A: // global
|
|
|
_s26y::I64 = I64[Sp + 8];
|
|
|
Sp = Sp + 16;
|
|
|
_s26z::I64 = R1;
|
|
|
goto c27B;
|
|
|
c27F: // global
|
|
|
I64[Hp - 8] = GHC.Types.I#_con_info;
|
|
|
I64[Hp] = _s26y::I64;
|
|
|
R1 = Hp - 7;
|
|
|
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
|
|
|
c27v: // global
|
|
|
_s26y::I64 = _s26y::I64 - 1;
|
|
|
goto c27o;
|
|
|
c27x: // global
|
|
|
R2 = _s26y::I64;
|
|
|
R1 = Main.$wgo_closure;
|
|
|
call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
|
|
|
}
|
|
|
},
|
|
|
section ""data" . Main.$wgo_closure" {
|
|
|
Main.$wgo_closure:
|
|
|
const Main.$wgo_info;
|
|
|
}] if ((Sp + -16) >= SpLim) (likely: True) goto c27o; else goto c27x;
|
|
|
|
|
|
|
| cell | cell |
|
|
|
}]
|
|
|
```
|
|
|
| HEAD | GC_IN_ALTS |
|
|
|
| ------ | ------ |
|
|
|
| [Generated Cmm](uploads/01cba099560bdd650e3fc4ebc2b219a4/T16064.dump-cmm-HEAD) | [Generated Cmm](uploads/af64f3bb565f0494f2054813b8b9de33/T16064.dump-cmm-GC_IN_ALTS) |
|
|
|
| [Compiling Cabal (Cachegrind stats)](uploads/02bb81013526792b56d0f311956d2d17/cabal-cachegrind-stats-summary-HEAD) | [Compiling Cabal (Cachegrind stats)](uploads/6997d85fe4d7950cb30cd1d2cae0cfc4/cabal-cachegrind-stats-summary-GC_IN_ALTS) |
|
|
|
| [Compiling Cabal (Compiler RTS)](uploads/10b00658dc04d15a77de2aee8dc6d38b/cabal-stats-HEAD) | [Compiling Cabal (Compiler RTS)](uploads/e40570d331453aa7e1f21145dd56bfcb/cabal-stats-GC_IN_ALTS) |
|
|
|
| [Ticky](uploads/73a8ec5e79476f7eb3d17ac2d20590cd/HEAD.ticky) | [Ticky](uploads/7c4b328af52d58c24ed690e4270cbf47/GC_IN_ALTS.ticky) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
We can push the heap check into the branch by removing the first guard in `do_gc`:
|
|
|
|
|
|
```
|
|
|
diff --git a/compiler/GHC/StgToCmm/Expr.hs b/compiler/GHC/StgToCmm/Expr.hs
|
|
|
index eb56a6ad09..2265876a4d 100644
|
|
|
--- a/compiler/GHC/StgToCmm/Expr.hs
|
|
|
+++ b/compiler/GHC/StgToCmm/Expr.hs
|
|
|
@@ -430,8 +430,7 @@ cgCase scrut bndr alt_type alts
|
|
|
; let ret_bndrs = chooseReturnBndrs bndr alt_type alts
|
|
|
alt_regs = map (idToReg platform) ret_bndrs
|
|
|
; simple_scrut <- isSimpleScrut scrut alt_type
|
|
|
- ; let do_gc | is_cmp_op scrut = False -- See Note [GC for conditionals]
|
|
|
- | not simple_scrut = True
|
|
|
+ ; let do_gc | not simple_scrut = True
|
|
|
| isSingleton alts = False
|
|
|
| up_hp_usg > 0 = False
|
|
|
| otherwise = True
|
|
|
```
|
|
|
|
|
|
We will refer to this patch as `GcInAlts_Patch`.
|
|
|
|
|
|
### New Proposed Strategy
|
|
|
|
... | ... | |