Repository: compintell/Mooncake.jl
Pull request #512: Put BBCode in module
Author: login: willtebbutt
Created: 2025-03-04T17:44:12Z | Merged: 2025-03-05T19:22:08Z

<!--
    Thank you for opening a pull request to Mooncake.jl!
    Please note that this project operates the following policy: any time a PR is merged
    which modifies code in the src directory, a release must be made.

    Consequently, if your PR modifies something in src, please follow semver to figure out
    how you should modify the version number in Project.toml. If it's unclear to you how the
    version number should be modified, please open your PR without modifying it, and ask for
    assistance -- one of the maintainers will be happy to help figure out what the new
    version number ought to be.
-->
For the sake of hygiene, put BBCode in its own module.

This requires a little bit of formatting / shuffling of code around, but CI needs to run to check that I've refactored everything correctly.


Diff:
diff --git a/Project.toml b/Project.toml
index 6478698677..9634f70a5e 100644
--- a/Project.toml
+++ b/Project.toml
@@ -1,7 +1,7 @@
 name = "Mooncake"
 uuid = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6"
 authors = ["Will Tebbutt, Hong Ge, and contributors"]
-version = "0.4.102"
+version = "0.4.103"
 
 [deps]
 ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
diff --git a/src/Mooncake.jl b/src/Mooncake.jl
index a966574a33..0a8e82b908 100644
--- a/src/Mooncake.jl
+++ b/src/Mooncake.jl
@@ -6,7 +6,6 @@ using ADTypes,
     ChainRules,
     DiffRules,
     ExprTools,
-    Graphs,
     InteractiveUtils,
     LinearAlgebra,
     MistyClosures,
@@ -105,11 +104,13 @@ include("codual.jl")
 include("debug_mode.jl")
 include("stack.jl")
 
+include(joinpath("interpreter", "bbcode.jl"))
+using .BasicBlockCode
+
 include(joinpath("interpreter", "contexts.jl"))
 include(joinpath("interpreter", "abstract_interpretation.jl"))
 include(joinpath("interpreter", "patch_for_319.jl"))
 include(joinpath("interpreter", "ir_utils.jl"))
-include(joinpath("interpreter", "bbcode.jl"))
 include(joinpath("interpreter", "ir_normalisation.jl"))
 include(joinpath("interpreter", "zero_like_rdata.jl"))
 include(joinpath("interpreter", "s2s_reverse_mode_ad.jl"))
diff --git a/src/interpreter/bbcode.jl b/src/interpreter/bbcode.jl
index 46f9920aa7..d4c58a0f75 100644
--- a/src/interpreter/bbcode.jl
+++ b/src/interpreter/bbcode.jl
@@ -1,7 +1,72 @@
-# See the docstring for `BBCode` for some context on this file.
+"""
+    module BasicBlockCode
+
+See the docstring for the `BBCode` `struct` for info on this file.
+"""
+module BasicBlockCode
+
+using Graphs
+
+using Core.Compiler:
+    ReturnNode,
+    PhiNode,
+    GotoIfNot,
+    GotoNode,
+    NewInstruction,
+    IRCode,
+    SSAValue,
+    PiNode,
+    Argument
+const CC = Core.Compiler
+
+export ID,
+    seed_id!,
+    IDPhiNode,
+    IDGotoNode,
+    IDGotoIfNot,
+    Switch,
+    BBlock,
+    phi_nodes,
+    terminator,
+    insert_before_terminator!,
+    collect_stmts,
+    compute_all_predecessors,
+    BBCode,
+    remove_unreachable_blocks!,
+    characterise_used_ids,
+    characterise_unique_predecessor_blocks,
+    sort_blocks!,
+    InstVector,
+    IDInstPair,
+    __line_numbers_to_block_numbers!,
+    is_reachable_return_node,
+    new_inst
 
 const _id_count::Dict{Int,Int32} = Dict{Int,Int32}()
 
+"""
+    new_inst(stmt, type=Any, flag=CC.IR_FLAG_REFINED)::NewInstruction
+
+Create a `NewInstruction` with fields:
+- `stmt` = `stmt`
+- `type` = `type`
+- `info` = `CC.NoCallInfo()`
+- `line` = `Int32(1)`
+- `flag` = `flag`
+"""
+function new_inst(@nospecialize(stmt), @nospecialize(type)=Any, flag=CC.IR_FLAG_REFINED)
+    return NewInstruction(stmt, type, CC.NoCallInfo(), Int32(1), flag)
+end
+
+"""
+    const InstVector = Vector{NewInstruction}
+
+Note: the `CC.NewInstruction` type is used to represent instructions because it has the
+correct fields. While it is only used to represent new instrucdtions in `Core.Compiler`, it
+is used to represent all instructions in `BBCode`.
+"""
+const InstVector = Vector{NewInstruction}
+
 """
     ID()
 
@@ -394,6 +459,47 @@ function _control_flow_graph(blks::Vector{BBlock})::Core.Compiler.CFG
     return Core.Compiler.CFG(basic_blocks, index[2:(end - 1)])
 end
 
+"""
+    _instructions_to_blocks(insts::InstVector, cfg::CC.CFG)::InstVector
+
+Pulls out the instructions from `insts`, and calls `__line_numbers_to_block_numbers!`.
+"""
+function _lines_to_blocks(insts::InstVector, cfg::CC.CFG)::InstVector
+    stmts = __line_numbers_to_block_numbers!(Any[x.stmt for x in insts], cfg)
+    return map((inst, stmt) -> NewInstruction(inst; stmt), insts, stmts)
+end
+
+"""
+    __line_numbers_to_block_numbers!(insts::Vector{Any}, cfg::CC.CFG)
+
+Converts any edges in `GotoNode`s, `GotoIfNot`s, `PhiNode`s, and `:enter` expressions which
+refer to line numbers into references to block numbers. The `cfg` provides the information
+required to perform this conversion.
+
+For context, `CodeInfo` objects have references to line numbers, while `IRCode` uses
+block numbers.
+
+This code is copied over directly from the body of `Core.Compiler.inflate_ir!`.
+"""
+function __line_numbers_to_block_numbers!(insts::Vector{Any}, cfg::CC.CFG)
+    for i in eachindex(insts)
+        stmt = insts[i]
+        if isa(stmt, GotoNode)
+            insts[i] = GotoNode(CC.block_for_inst(cfg, stmt.label))
+        elseif isa(stmt, GotoIfNot)
+            insts[i] = GotoIfNot(stmt.cond, CC.block_for_inst(cfg, stmt.dest))
+        elseif isa(stmt, PhiNode)
+            insts[i] = PhiNode(
+                Int32[CC.block_for_inst(cfg, Int(edge)) for edge in stmt.edges], stmt.values
+            )
+        elseif Meta.isexpr(stmt, :enter)
+            stmt.args[1] = CC.block_for_inst(cfg, stmt.args[1]::Int)
+            insts[i] = stmt
+        end
+    end
+    return insts
+end
+
 #
 # Converting from IRCode to BBCode
 #
@@ -431,7 +537,8 @@ end
 Convert an `Compiler.InstructionStream` into a list of `Compiler.NewInstruction`s.
 """
 function new_inst_vec(x::CC.InstructionStream)
-    return map((v...,) -> NewInstruction(v...), stmt(x), x.type, x.info, x.line, x.flag)
+    stmt = @static VERSION < v"1.11.0-rc4" ? x.inst : x.stmt
+    return map((v...,) -> NewInstruction(v...), stmt, x.type, x.info, x.line, x.flag)
 end
 
 # Maps from positional names (SSAValues for nodes, Integers for basic blocks) to IDs.
@@ -673,7 +780,7 @@ function _distance_to_entry(blks::Vector{BBlock})::Vector{Int}
 end
 
 """
-    _sort_blocks!(ir::BBCode)::BBCode
+    sort_blocks!(ir::BBCode)::BBCode
 
 Ensure that blocks appear in order of distance-from-entry-point, where distance the
 distance from block b to the entry point is defined to be the minimum number of basic
@@ -687,7 +794,7 @@ WARNING: use with care. Only use if you are confident that arbitrary re-ordering
 blocks in `ir` is valid. Notably, this does not hold if you have any `IDGotoIfNot` nodes in
 `ir`.
 """
-function _sort_blocks!(ir::BBCode)::BBCode
+function sort_blocks!(ir::BBCode)::BBCode
     I = sortperm(_distance_to_entry(ir.blocks))
     ir.blocks .= ir.blocks[I]
     return ir
@@ -765,6 +872,15 @@ function characterise_unique_predecessor_blocks(
     return is_unique_pred, pred_is_unique_pred
 end
 
+"""
+    is_reachable_return_node(x::ReturnNode)
+
+Determine whether `x` is a `ReturnNode`, and if it is, if it is also reachable. This is
+purely a function of whether or not its `val` field is defined or not.
+"""
+is_reachable_return_node(x::ReturnNode) = isdefined(x, :val)
+is_reachable_return_node(x) = false
+
 """
     characterise_used_ids(stmts::Vector{IDInstPair})::Dict{ID, Bool}
 
@@ -882,26 +998,4 @@ function _remove_unreachable_blocks!(blks::Vector{BBlock})
     return remaining_blks
 end
 
-"""
-    inc_args(stmt)
-
-Increment by `1` the `n` field of any `Argument`s present in `stmt`.
-"""
-inc_args(x::Expr) = Expr(x.head, map(__inc, x.args)...)
-inc_args(x::ReturnNode) = isdefined(x, :val) ? ReturnNode(__inc(x.val)) : x
-inc_args(x::IDGotoIfNot) = IDGotoIfNot(__inc(x.cond), x.dest)
-inc_args(x::IDGotoNode) = x
-function inc_args(x::IDPhiNode)
-    new_values = Vector{Any}(undef, length(x.values))
-    for n in eachindex(x.values)
-        if isassigned(x.values, n)
-            new_values[n] = __inc(x.values[n])
-        end
-    end
-    return IDPhiNode(x.edges, new_values)
 end
-inc_args(::Nothing) = nothing
-inc_args(x::GlobalRef) = x
-
-__inc(x::Argument) = Argument(x.n + 1)
-__inc(x) = x
diff --git a/src/interpreter/ir_utils.jl b/src/interpreter/ir_utils.jl
index cc21dde6af..eb708e6ede 100644
--- a/src/interpreter/ir_utils.jl
+++ b/src/interpreter/ir_utils.jl
@@ -1,12 +1,3 @@
-"""
-    const InstVector = Vector{NewInstruction}
-
-Note: the `CC.NewInstruction` type is used to represent instructions because it has the
-correct fields. While it is only used to represent new instrucdtions in `Core.Compiler`, it
-is used to represent all instructions in `BBCode`.
-"""
-const InstVector = Vector{NewInstruction}
-
 """
     stmt(ir::CC.InstructionStream)
 
@@ -44,47 +35,6 @@ function ircode(
     return CC.IRCode(stmts, cfg, linetable, argtypes, meta, CC.VarState[])
 end
 
-"""
-    __line_numbers_to_block_numbers!(insts::Vector{Any}, cfg::CC.CFG)
-
-Converts any edges in `GotoNode`s, `GotoIfNot`s, `PhiNode`s, and `:enter` expressions which
-refer to line numbers into references to block numbers. The `cfg` provides the information
-required to perform this conversion.
-
-For context, `CodeInfo` objects have references to line numbers, while `IRCode` uses
-block numbers.
-
-This code is copied over directly from the body of `Core.Compiler.inflate_ir!`.
-"""
-function __line_numbers_to_block_numbers!(insts::Vector{Any}, cfg::CC.CFG)
-    for i in eachindex(insts)
-        stmt = insts[i]
-        if isa(stmt, GotoNode)
-            insts[i] = GotoNode(CC.block_for_inst(cfg, stmt.label))
-        elseif isa(stmt, GotoIfNot)
-            insts[i] = GotoIfNot(stmt.cond, CC.block_for_inst(cfg, stmt.dest))
-        elseif isa(stmt, PhiNode)
-            insts[i] = PhiNode(
-                Int32[CC.block_for_inst(cfg, Int(edge)) for edge in stmt.edges], stmt.values
-            )
-        elseif Meta.isexpr(stmt, :enter)
-            stmt.args[1] = CC.block_for_inst(cfg, stmt.args[1]::Int)
-            insts[i] = stmt
-        end
-    end
-    return insts
-end
-
-"""
-    _instructions_to_blocks(insts::InstVector, cfg::CC.CFG)::InstVector
-
-Pulls out the instructions from `insts`, and calls `__line_numbers_to_block_numbers!`.
-"""
-function _lines_to_blocks(insts::InstVector, cfg::CC.CFG)::InstVector
-    stmts = __line_numbers_to_block_numbers!(Any[x.stmt for x in insts], cfg)
-    return map((inst, stmt) -> NewInstruction(inst; stmt), insts, stmts)
-end
-
 """
     __insts_to_instruction_stream(insts::Vector{Any})
 
@@ -270,15 +220,6 @@ function lookup_ir(
     return CC.typeinf_ircode(interp, mi.def, mi.specTypes, mi.sparam_vals, optimize_until)
 end
 
-"""
-    is_reachable_return_node(x::ReturnNode)
-
-Determine whether `x` is a `ReturnNode`, and if it is, if it is also reachable. This is
-purely a function of whether or not its `val` field is defined or not.
-"""
-is_reachable_return_node(x::ReturnNode) = isdefined(x, :val)
-is_reachable_return_node(x) = false
-
 """
     is_unreachable_return_node(x::ReturnNode)
 
@@ -305,20 +246,6 @@ Throw an `UnhandledLanguageFeatureException` with message `msg`.
 """
 unhandled_feature(msg::String) = throw(UnhandledLanguageFeatureException(msg))
 
-"""
-    new_inst(stmt, type=Any, flag=CC.IR_FLAG_REFINED)::NewInstruction
-
-Create a `NewInstruction` with fields:
-- `stmt` = `stmt`
-- `type` = `type`
-- `info` = `CC.NoCallInfo()`
-- `line` = `Int32(1)`
-- `flag` = `flag`
-"""
-function new_inst(@nospecialize(stmt), @nospecialize(type)=Any, flag=CC.IR_FLAG_REFINED)
-    return NewInstruction(stmt, type, CC.NoCallInfo(), Int32(1), flag)
-end
-
 """
     replace_uses_with!(stmt, def::Union{Argument, SSAValue}, val)
 
diff --git a/src/interpreter/s2s_reverse_mode_ad.jl b/src/interpreter/s2s_reverse_mode_ad.jl
index 995851ad09..5bd07dd239 100644
--- a/src/interpreter/s2s_reverse_mode_ad.jl
+++ b/src/interpreter/s2s_reverse_mode_ad.jl
@@ -353,6 +353,31 @@ function comms_channel(info::ADStmtInfo)
     return only(filter(x -> x[1] == info.comms_id, info.fwds))
 end
 
+"""
+    inc_args(stmt)
+
+Increment by `1` the `n` field of any `Argument`s present in `stmt`.
+Used in `make_ad_stmts!`.
+"""
+inc_args(x::Expr) = Expr(x.head, map(__inc, x.args)...)
+inc_args(x::ReturnNode) = isdefined(x, :val) ? ReturnNode(__inc(x.val)) : x
+inc_args(x::IDGotoIfNot) = IDGotoIfNot(__inc(x.cond), x.dest)
+inc_args(x::IDGotoNode) = x
+function inc_args(x::IDPhiNode)
+    new_values = Vector{Any}(undef, length(x.values))
+    for n in eachindex(x.values)
+        if isassigned(x.values, n)
+            new_values[n] = __inc(x.values[n])
+        end
+    end
+    return IDPhiNode(x.edges, new_values)
+end
+inc_args(::Nothing) = nothing
+inc_args(x::GlobalRef) = x
+
+__inc(x::Argument) = Argument(x.n + 1)
+__inc(x) = x
+
 """
     make_ad_stmts!(inst::NewInstruction, line::ID, info::ADInfo)::ADStmtInfo
 
@@ -1489,7 +1514,7 @@ function pullback_ir(
     # avoid annoying the Julia compiler.
     blks = vcat(entry_block, main_blocks, exit_block)
     pb_ir = BBCode(blks, arg_types, ir.sptypes, ir.linetable, ir.meta)
-    return remove_unreachable_blocks!(_sort_blocks!(pb_ir))
+    return remove_unreachable_blocks!(sort_blocks!(pb_ir))
 end
 
 """
diff --git a/test/interpreter/bbcode.jl b/test/interpreter/bbcode.jl
index 492df0c3b5..9c1adac6db 100644
--- a/test/interpreter/bbcode.jl
+++ b/test/interpreter/bbcode.jl
@@ -62,13 +62,13 @@ end
         @test all(map(==, ir.stmts.line, new_ir.stmts.line))
         @test all(map(==, ir.stmts.flag, new_ir.stmts.flag))
         @test length(Mooncake.collect_stmts(bb_code)) == length(stmt(ir.stmts))
-        @test Mooncake.id_to_line_map(bb_code) isa Dict{ID,Int}
+        @test Mooncake.BasicBlockCode.id_to_line_map(bb_code) isa Dict{ID,Int}
     end
     @testset "control_flow_graph" begin
         ir = Base.code_ircode_by_type(Tuple{typeof(sin),Float64})[1][1]
         bb = BBCode(ir)
         new_ir = Core.Compiler.IRCode(bb)
-        cfg = Mooncake.control_flow_graph(bb)
+        cfg = Mooncake.BasicBlockCode.control_flow_graph(bb)
         @test all(map((l, r) -> l.stmts == r.stmts, ir.cfg.blocks, cfg.blocks))
         @test all(map((l, r) -> sort(l.preds) == sort(r.preds), ir.cfg.blocks, cfg.blocks))
         @test all(map((l, r) -> sort(l.succs) == sort(r.succs), ir.cfg.blocks, cfg.blocks))
@@ -152,51 +152,53 @@ end
             @testset "Expr" begin
                 id = ID()
                 d = Dict{ID,Bool}(id => false)
-                Mooncake._find_id_uses!(d, Expr(:call, sin, 5))
+                Mooncake.BasicBlockCode._find_id_uses!(d, Expr(:call, sin, 5))
                 @test d[id] == false
-                Mooncake._find_id_uses!(d, Expr(:call, sin, id))
+                Mooncake.BasicBlockCode._find_id_uses!(d, Expr(:call, sin, id))
                 @test d[id] == true
             end
             @testset "IDGotoIfNot" begin
                 id = ID()
                 d = Dict{ID,Bool}(id => false)
-                Mooncake._find_id_uses!(d, IDGotoIfNot(ID(), ID()))
+                Mooncake.BasicBlockCode._find_id_uses!(d, IDGotoIfNot(ID(), ID()))
                 @test d[id] == false
-                Mooncake._find_id_uses!(d, IDGotoIfNot(true, ID()))
+                Mooncake.BasicBlockCode._find_id_uses!(d, IDGotoIfNot(true, ID()))
                 @test d[id] == false
-                Mooncake._find_id_uses!(d, IDGotoIfNot(id, ID()))
+                Mooncake.BasicBlockCode._find_id_uses!(d, IDGotoIfNot(id, ID()))
                 @test d[id] == true
             end
             @testset "IDGotoNode" begin
                 id = ID()
                 d = Dict{ID,Bool}(id => false)
-                Mooncake._find_id_uses!(d, IDGotoNode(ID()))
+                Mooncake.BasicBlockCode._find_id_uses!(d, IDGotoNode(ID()))
                 @test d[id] == false
             end
             @testset "IDPhiNode" begin
                 id = ID()
                 d = Dict{ID,Bool}(id => false)
-                Mooncake._find_id_uses!(d, IDPhiNode([ID()], Vector{Any}(undef, 1)))
+                Mooncake.BasicBlockCode._find_id_uses!(
+                    d, IDPhiNode([ID()], Vector{Any}(undef, 1))
+                )
                 @test d[id] == false
-                Mooncake._find_id_uses!(d, IDPhiNode([ID()], Any[id]))
+                Mooncake.BasicBlockCode._find_id_uses!(d, IDPhiNode([ID()], Any[id]))
                 @test d[id] == true
             end
             @testset "PiNode" begin
                 id = ID()
                 d = Dict{ID,Bool}(id => false)
-                Mooncake._find_id_uses!(d, PiNode(false, Bool))
+                Mooncake.BasicBlockCode._find_id_uses!(d, PiNode(false, Bool))
                 @test d[id] == false
-                Mooncake._find_id_uses!(d, PiNode(id, Bool))
+                Mooncake.BasicBlockCode._find_id_uses!(d, PiNode(id, Bool))
                 @test d[id] == true
             end
             @testset "ReturnNode" begin
                 id = ID()
                 d = Dict{ID,Bool}(id => false)
-                Mooncake._find_id_uses!(d, ReturnNode())
+                Mooncake.BasicBlockCode._find_id_uses!(d, ReturnNode())
                 @test d[id] == false
-                Mooncake._find_id_uses!(d, ReturnNode(5))
+                Mooncake.BasicBlockCode._find_id_uses!(d, ReturnNode(5))
                 @test d[id] == false
-                Mooncake._find_id_uses!(d, ReturnNode(id))
+                Mooncake.BasicBlockCode._find_id_uses!(d, ReturnNode(id))
                 @test d[id] == true
             end
         end
@@ -225,7 +227,8 @@ end
             ],
             Any[Any for _ in 1:4],
         )
-        @test Mooncake._is_reachable(BBCode(ir).blocks) == [true, false, false]
+        @test Mooncake.BasicBlockCode._is_reachable(BBCode(ir).blocks) ==
+            [true, false, false]
     end
     @testset "remove_unreachable_blocks!" begin
 
@@ -266,20 +269,4 @@ end
         ]
         @test Mooncake.stmt(new_ir.stmts) == expected_stmts
     end
-    @testset "inc_args" begin
-        @test Mooncake.inc_args(Expr(:call, sin, Argument(4))) ==
-            Expr(:call, sin, Argument(5))
-        @test Mooncake.inc_args(ReturnNode(Argument(2))) == ReturnNode(Argument(3))
-        id = ID()
-        @test Mooncake.inc_args(IDGotoIfNot(Argument(1), id)) ==
-            IDGotoIfNot(Argument(2), id)
-        @test Mooncake.inc_args(IDGotoNode(id)) == IDGotoNode(id)
-        ids = [id, ID()]
-        @test ==(
-            Mooncake.inc_args(IDPhiNode(ids, Any[Argument(1), 4])),
-            IDPhiNode(ids, Any[Argument(2), 4]),
-        )
-        @test Mooncake.inc_args(nothing) === nothing
-        @test Mooncake.inc_args(GlobalRef(Base, :sin)) == GlobalRef(Base, :sin)
-    end
 end
diff --git a/test/interpreter/s2s_reverse_mode_ad.jl b/test/interpreter/s2s_reverse_mode_ad.jl
index 6c80c9aeed..569152f73e 100644
--- a/test/interpreter/s2s_reverse_mode_ad.jl
+++ b/test/interpreter/s2s_reverse_mode_ad.jl
@@ -67,6 +67,22 @@ end
         # pass, then this constructor ought to error.
         @test_throws ArgumentError ad_stmt_info(ID(), ID(), nothing, nothing)
     end
+    @testset "inc_args" begin
+        @test Mooncake.inc_args(Expr(:call, sin, Argument(4))) ==
+            Expr(:call, sin, Argument(5))
+        @test Mooncake.inc_args(ReturnNode(Argument(2))) == ReturnNode(Argument(3))
+        id = ID()
+        @test Mooncake.inc_args(IDGotoIfNot(Argument(1), id)) ==
+            IDGotoIfNot(Argument(2), id)
+        @test Mooncake.inc_args(IDGotoNode(id)) == IDGotoNode(id)
+        ids = [id, ID()]
+        @test ==(
+            Mooncake.inc_args(IDPhiNode(ids, Any[Argument(1), 4])),
+            IDPhiNode(ids, Any[Argument(2), 4]),
+        )
+        @test Mooncake.inc_args(nothing) === nothing
+        @test Mooncake.inc_args(GlobalRef(Base, :sin)) == GlobalRef(Base, :sin)
+    end
     @testset "make_ad_stmts!" begin
 
         # Set up ADInfo -- this state is required by `make_ad_stmts!`, and the


Reviews:
user: login: yebai
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-05T10:17:19Z
user: login: willtebbutt
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-05T13:17:53Z
user: login: yebai
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-05T14:17:34Z

Review comments:
diff_hunk: @@ -1,7 +1,47 @@
-# See the docstring for `BBCode` for some context on this file.
+"""
+    module BBCode
path: src/interpreter/bbcode.jl
user: login: yebai
body: Gemini [suggests](https://g.co/gemini/share/261dc2571263) 

```suggestion
    module BasicBlockIR
```
created_at: 2025-03-05T10:17:19Z
author_association: MEMBER
diff_hunk: @@ -1,7 +1,47 @@
-# See the docstring for `BBCode` for some context on this file.
+"""
+    module BBCode
path: src/interpreter/bbcode.jl
user: login: willtebbutt
body: I'll tweak the module name to `BasicBlockCode`, since that's what the acronym `BBCode` stands for. We can rename to e.g. `NamedIRCode` or `NIRCode` at a later point in time.
created_at: 2025-03-05T13:17:53Z
author_association: COLLABORATOR
diff_hunk: @@ -1,7 +1,72 @@
-# See the docstring for `BBCode` for some context on this file.
+"""
+    module BBCode
path: src/interpreter/bbcode.jl
user: login: yebai
body: ```suggestion
    module BasicBlockCode
```
created_at: 2025-03-05T14:17:34Z
author_association: MEMBER

PR comments:
user: login: codecov[bot]
created_at: 2025-03-04T17:48:53Z
body: ## [Codecov](https://app.codecov.io/gh/compintell/Mooncake.jl/pull/512?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=compintell) Report
Attention: Patch coverage is `95.00000%` with `2 lines` in your changes missing coverage. Please review.

| [Files with missing lines](https://app.codecov.io/gh/compintell/Mooncake.jl/pull/512?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=compintell) | Patch % | Lines |
|---|---|---|
| [src/interpreter/bbcode.jl](https://app.codecov.io/gh/compintell/Mooncake.jl/pull/512?src=pr&el=tree&filepath=src%2Finterpreter%2Fbbcode.jl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=compintell#diff-c3JjL2ludGVycHJldGVyL2JiY29kZS5qbA==) | 91.66% | [2 Missing :warning: ](https://app.codecov.io/gh/compintell/Mooncake.jl/pull/512?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=compintell) |

| [Files with missing lines](https://app.codecov.io/gh/compintell/Mooncake.jl/pull/512?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=compintell) | Coverage Δ | |
|---|---|---|
| [src/Mooncake.jl](https://app.codecov.io/gh/compintell/Mooncake.jl/pull/512?src=pr&el=tree&filepath=src%2FMooncake.jl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=compintell#diff-c3JjL01vb25jYWtlLmps) | `100.00% <ø> (ø)` | |
| [src/interpreter/ir\_utils.jl](https://app.codecov.io/gh/compintell/Mooncake.jl/pull/512?src=pr&el=tree&filepath=src%2Finterpreter%2Fir_utils.jl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=compintell#diff-c3JjL2ludGVycHJldGVyL2lyX3V0aWxzLmps) | `86.86% <ø> (-0.64%)` | :arrow_down: |
| [src/interpreter/s2s\_reverse\_mode\_ad.jl](https://app.codecov.io/gh/compintell/Mooncake.jl/pull/512?src=pr&el=tree&filepath=src%2Finterpreter%2Fs2s_reverse_mode_ad.jl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=compintell#diff-c3JjL2ludGVycHJldGVyL3Myc19yZXZlcnNlX21vZGVfYWQuamw=) | `96.60% <100.00%> (+0.09%)` | :arrow_up: |
| [src/interpreter/bbcode.jl](https://app.codecov.io/gh/compintell/Mooncake.jl/pull/512?src=pr&el=tree&filepath=src%2Finterpreter%2Fbbcode.jl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=compintell#diff-c3JjL2ludGVycHJldGVyL2JiY29kZS5qbA==) | `95.48% <91.66%> (-0.60%)` | :arrow_down: |

<details><summary>🚀 New features to boost your workflow: </summary>

- ❄ [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-03-04T18:05:06Z
body: Performance Ratio:
Ratio of time to compute gradient and time to compute function.
Warning: results are very approximate! See [here](https://github.com/compintell/Mooncake.jl/tree/main/bench#inter-framework-benchmarking) for more context.
```
┌────────────────────────────┬──────────┬──────────┬─────────┬─────────────┬─────────┐
│                      Label │   Primal │ Mooncake │  Zygote │ ReverseDiff │  Enzyme │
│                     String │   String │   String │  String │      String │  String │
├────────────────────────────┼──────────┼──────────┼─────────┼─────────────┼─────────┤
│                   sum_1000 │ 100.0 ns │      1.8 │     1.0 │        5.71 │    8.21 │
│                  _sum_1000 │ 941.0 ns │     6.74 │  1610.0 │        33.9 │    1.09 │
│               sum_sin_1000 │  6.56 μs │      2.2 │    1.68 │        10.4 │    1.98 │
│              _sum_sin_1000 │  5.08 μs │     2.69 │   315.0 │        13.6 │    2.53 │
│                   kron_sum │ 340.0 μs │     40.7 │    4.84 │       196.0 │    11.5 │
│              kron_view_sum │ 343.0 μs │     40.7 │    10.8 │       225.0 │    95.7 │
│      naive_map_sin_cos_exp │  2.16 μs │     2.16 │ missing │        7.11 │    2.33 │
│            map_sin_cos_exp │  2.12 μs │      2.4 │     1.5 │        6.07 │    2.92 │
│      broadcast_sin_cos_exp │  2.25 μs │     2.27 │    2.39 │        1.48 │    2.27 │
│                 simple_mlp │ 170.0 μs │     6.77 │    1.73 │        11.4 │    3.71 │
│                     gp_lml │ 194.0 μs │     10.6 │    4.34 │     missing │    5.29 │
│ turing_broadcast_benchmark │  1.97 ms │     3.49 │ missing │        26.3 │ missing │
│         large_single_block │ 390.0 ns │     4.39 │  4560.0 │        30.0 │    2.18 │
└────────────────────────────┴──────────┴──────────┴─────────┴─────────────┴─────────┘
```
author_association: CONTRIBUTOR
user: login: willtebbutt
created_at: 2025-03-05T17:50:20Z
body: Will merge when CI passes.
author_association: COLLABORATOR
user: login: penelopeysm
created_at: 2025-03-06T20:47:27Z
body: I know that BBCode is something different, but I'm always reminded of https://en.wikipedia.org/wiki/BBCode!
author_association: COLLABORATOR
user: login: willtebbutt
created_at: 2025-03-06T21:25:48Z
body: TIL!
author_association: COLLABORATOR