Skip to content

Commit

Permalink
fix doctests (#123)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pangoraw authored Apr 8, 2024
1 parent 7fab055 commit 538a96d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 15 deletions.
27 changes: 22 additions & 5 deletions docs/src/dynamo.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,19 @@ julia> @code_ir roundtrip mul(1, 2)

Now we can recreate our `foo` macro. It's a little more verbose since simple symbols like `*` are resolved to `GlobalRef`s in lowered code, but it's broadly the same as our macro.

```jldoctest main
julia> using MacroTools
```@meta
DocTestSetup = quote
using IRTools
using IRTools: @dynamo, IR
mul(a, b) = a * b
end
```

```jldoctest main2
julia> using MacroTools, IRTools
julia> using IRTools: @dynamo, IR
julia> @dynamo function foo(a...)
ir = IR(a...)
Expand All @@ -100,9 +111,13 @@ julia> @dynamo function foo(a...)
end
```

```@meta
DocTestSetup = nothing
```

It behaves identically, too.

```jldoctest main
```jldoctest main2
julia> foo() do
10*5
end
Expand All @@ -122,7 +137,7 @@ A key difference between macros and dynamos is that dynamos get passed *function

So what if `foo` actually inserted calls to itself when modifying a function? In other words, `prod([1, 2, 3])` would become `foo(prod, [1, 2, 3])`, and so on for each call inside a function. This lets us get the "dynamic extent" property that we talked about earlier.

```jldoctest main
```jldoctest main2
julia> using IRTools: xcall
julia> @dynamo function foo2(a...)
Expand Down Expand Up @@ -161,7 +176,7 @@ julia> @code_ir foo2 mul_wrapped(5, 10)

And that it works as expected:

```jldoctest main
```jldoctest main2
julia> foo() do # Does not work (since there is no literal `*` here)
mul(5, 10)
end
Expand All @@ -185,6 +200,8 @@ This, we have rewritten the `prod` function to actually calculate `sum`, by *int
We can make our `foo2` dynamo simpler in a couple of ways. Firstly, IRTools provides a built-in utility `recurse!` which makes it easy to recurse into code.

```jldoctest main
julia> using MacroTools
julia> using IRTools: recurse!
julia> @dynamo function foo2(a...)
Expand Down
28 changes: 18 additions & 10 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Note that before even attempting to understand IRTools, you should have a good h

It's easiest to understand the IRTools IR by seeing some examples. We provide the macro `@code_ir` which behaves much like `@code_lowered`.

```jldoctest main
```jldoctest
julia> using IRTools
julia> f(x) = x+x
Expand All @@ -30,7 +30,9 @@ First things first. All variables are numbered (`%1`, `%2`, `%3` ...). IR will u

The main reason that there are a lot of intermediates is that, in IR, we only allow one function call per line. You can see how a nested Julia expression becomes a sequence of single instructions, kind of like an assembly language.

```jldoctest main
```jldoctest
julia> using IRTools
julia> f(x) = 3x*x + 2x + 1
f (generic function with 1 method)
Expand All @@ -51,7 +53,9 @@ Beyond that, this is essentially just very verbosely-written Julia code.

The most significant difference between `IR` and `Expr` is how control flow is handled. There are no such thing as nested if statements, while loops and so on in IR, only *branches*.

```jldoctest main
```jldoctest
julia> using IRTools
julia> f(x) = x > 0 ? x : 0
f (generic function with 1 method)
Expand All @@ -70,7 +74,9 @@ IR is composed of a series of *basic blocks* that jump between each other like t

Here's a more interesting example.

```jldoctest main
```jldoctest
julia> using IRTools
julia> function f(x)
if x < 0
x = -x
Expand All @@ -97,7 +103,9 @@ Why not just write this as `%2 = -%2`? It's important to understand that variabl

Loops work this way too: they are visible in the IR by branches that jump backwards, i.e. the `br 2` here. Variables that were modified inside the loop in the original code are explicitly passed between blocks.

```jldoctest main
```jldoctest envpow
julia> using IRTools
julia> function pow(x, n)
r = 1
while n > 0
Expand Down Expand Up @@ -129,7 +137,7 @@ julia> @code_ir pow(1, 1)

It's easy to get started by creating an empty fragment of IR.

```jldoctest main
```jldoctest ir_example
julia> using IRTools: IR, var, argument!, xcall
julia> ir = IR()
Expand All @@ -138,7 +146,7 @@ julia> ir = IR()

We can push new statements into the IR. `push!` returns a variable name that we can reuse later on.

```jldoctest main
```jldoctest ir_example
julia> x = argument!(ir)
%1
Expand All @@ -152,7 +160,7 @@ julia> ir

The IR can be viewed as a mapping from variables to statements, and indexing and iteration are consistent with that.

```julia
```julia ir_example
julia> ir[var(2)]
IRTools.Statement(:(%1 * %1), Any, 0)

Expand All @@ -167,7 +175,7 @@ There are a few other functions that do obvious things: `pushfirst!`, `insert!`,

In most cases you won't build IR from scratch, but will start from an existing function and modify its IR.

```jldoctest main
```jldoctest envpow
julia> ir = @code_ir pow(1, 1)
1: (%1, %2, %3)
br 2 (%3, 1)
Expand All @@ -187,7 +195,7 @@ julia> ir = @code_ir pow(1, 1)

You can work with a block at a time with `block(ir, n)` (all of them with `blocks(ir)`). Blocks similarly support functions like `push!`.

```jldoctest main
```jldoctest envpow
julia> using IRTools: block
julia> block(ir, 2)
Expand Down

0 comments on commit 538a96d

Please sign in to comment.