Skip to content

Commit 11a0493

Browse files
authored
tray midtier 002 (#266)
2 parents 99f0aa1 + 609b7ce commit 11a0493

14 files changed

Lines changed: 105 additions & 48 deletions

File tree

docs/jit/AGNIPATH.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Agnipath
2+
Agnipath (literally means "path of fire" in Hindi, I like to think of it as "hotpath") is the highest-tier JIT compiler in Bali. It aims to minimize boxing+unboxing and also produce the best quality code possible, no matter how much time it takes.
3+
4+
It uses a SSA IR form to make certain optimizations trivial.
5+
6+
**It currently does not exist, I am planning to work on it soon.**

shell.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ mkShell {
1313
act
1414
boa
1515
mimalloc
16+
ltrace
1617
];
1718

1819
LD_LIBRARY_PATH = lib.makeLibraryPath [

src/bali/internal/assembler/amd64.nim

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,18 @@ const BaseAssemblerSize* {.intdefine: "BaliBaseAssemblerSize".} = 0x10000
194194
proc curAdr*(assembler: AssemblerX64): int64 =
195195
cast[int64](assembler.data) + assembler.offset
196196

197+
proc dump*(s: AssemblerX64, file: string) =
198+
assert(s.offset < s.capacity)
199+
200+
var data = newSeqOfCap[uint8](s.offset)
201+
var i = 0
202+
203+
while i < s.offset:
204+
data &= s.data[i]
205+
inc i
206+
207+
writeFile(file, ensureMove(data))
208+
197209
proc initAssemblerX64*(data: ptr UncheckedArray[byte], capacity: int): AssemblerX64 =
198210
result.data = data
199211
result.capacity = capacity
@@ -352,7 +364,7 @@ proc writeModrm[T, U](assembler: var AssemblerX64, rm: Rm[T], reg: U): int =
352364
of rmDirect:
353365
when T isnot void:
354366
assembler.writeField 0b11, byte(reg), byte(rm.directReg)
355-
-1
367+
return -1
356368
else:
357369
raiseAssert(
358370
"memory only operand. Direct register not allowed (how was this constructed?)"
@@ -387,7 +399,7 @@ proc writeModrm[T, U](assembler: var AssemblerX64, rm: Rm[T], reg: U): int =
387399
assembler.writeField 0b00, byte(reg), 0b100
388400
assembler.writeField byte(rm.simpleScale), byte(rm.simpleIndex), 0b101
389401
assembler.write rm.simpleDisp
390-
-1
402+
return -1
391403
of rmIndirectScaledAndBase:
392404
assert rm.baseIndex != regRsp, "rsp cannot be scaled"
393405
if rm.baseDisp == 0 and rm.base != regRbp and rm.base != regR13:
@@ -401,12 +413,12 @@ proc writeModrm[T, U](assembler: var AssemblerX64, rm: Rm[T], reg: U): int =
401413
assembler.writeField 0b10, byte(reg), 0b100
402414
assembler.writeField byte(rm.baseScale), byte(rm.baseIndex), byte(rm.base)
403415
assembler.write rm.baseDisp
404-
-1
416+
return -1
405417
of rmIndirectGlobal:
406418
assembler.writeField 0b00, byte(reg), 0b101
407419
let offset = assembler.offset
408420
assembler.write 0'i32
409-
offset
421+
return offset
410422

411423
proc fixupRip[T](assembler: var AssemblerX64, modrm: Rm[T], location: int) =
412424
if location != -1:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Types for Agnipath IR
2+
##
3+
## Copyright (C) 2025 Trayambak Rai (xtrayambak at disroot dot org)

src/bali/runtime/compiler/amd64/midtier.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,10 @@ proc compile*(
323323

324324
var pipeline = Pipeline(fn: &lowered)
325325
pipeline.optimize(
326-
{
326+
@[
327327
Passes.NaiveDeadCodeElim, Passes.AlgebraicSimplification, Passes.EscapeAnalysis,
328328
Passes.CopyPropagation,
329-
}
329+
]
330330
)
331331

332332
return compileLowered(cgen, pipeline)

src/bali/runtime/compiler/madhyasthal/copy_propagation.nim

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,16 @@ func eliminateUnmutatedCopies*(
5353
# Any attempts to eliminate this copy will cause semantic breakage.
5454
continue
5555

56-
if copy.dest notin pipeline.info.esc.locals:
56+
if copy.source notin pipeline.info.esc.locals:
57+
# debugecho "Can't optimize escapee %" & $copy.source & " -> %" & $copy.dest
5758
# If the register is not locally owned, we cannot
5859
# safely alias the copy as it might end up mutating
5960
# a global state, which'd cause semantic breakage.
6061
continue
6162

63+
# print pipeline.info.esc.locals
64+
# debugecho "Optimizing local %" & $copy.source & " -> %" & $copy.dest
65+
6266
unmutated.incl(copy)
6367

6468
ensureMove(unmutated)

src/bali/runtime/compiler/madhyasthal/naive_dce.nim

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ func markDef(pipeline: var pipeline.Pipeline, reg: ir.Reg, at: SomeNumber) =
99
pipeline.info.dce.defs.incl(
1010
Definition(reg: reg, inst: uint32(at))
1111
)
12+
pipeline.info.dce.rawDefs.incl(reg)
1213
#!fmt: on
1314

1415
func markUse(pipeline: var pipeline.Pipeline, reg: ir.Reg, at: SomeNumber) =
@@ -135,9 +136,19 @@ func scanAndElimDeadRefs*(pipeline: var pipeline.Pipeline, dead: HashSet[ir.Reg]
135136
pipeline.fn.insts &= inst
136137

137138
if inst.args[0].kind == avkPos:
139+
if inst.args[0].vreg notin pipeline.info.dce.rawDefs:
140+
# We cannot determine if a global is alive,
141+
# and we needn't care either.
142+
continue
143+
138144
pipeline.info.dce.alive.incl(inst.args[0].vreg)
139145

140146
if inst.args[1].kind == avkPos:
147+
if inst.args[1].vreg notin pipeline.info.dce.rawDefs:
148+
# We cannot determine if a global is alive,
149+
# and we needn't care either.
150+
continue
151+
141152
pipeline.info.dce.alive.incl(inst.args[1].vreg)
142153

143154
func eliminateDeadCodeNaive*(pipeline: var pipeline.Pipeline) =

src/bali/runtime/compiler/madhyasthal/optimizer.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import
1010
]
1111
import pkg/[shakar]
1212

13-
func optimize*(pipeline: var pipeline.Pipeline, passes: set[Passes] = {}) =
13+
func optimize*(pipeline: var pipeline.Pipeline, passes: seq[Passes]) =
1414
for pass in passes:
1515
case pass
1616
of Passes.NaiveDeadCodeElim:

src/bali/runtime/compiler/madhyasthal/pipeline.nim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type
1818

1919
DCEPassInfo* = object
2020
defs*: HashSet[Definition]
21+
rawDefs*: HashSet[ir.Reg]
2122
uses*: HashSet[Use]
2223
alive*: HashSet[ir.Reg]
2324

@@ -45,3 +46,8 @@ type
4546
EscapeAnalysis
4647

4748
OptimizationPass* = proc(state: var Pipeline): bool
49+
50+
func isUsedBeyond*(dce: DCEPassInfo, reg: ir.Reg, inst: uint32): bool {.inline.} =
51+
for use in dce.uses:
52+
if use.reg == reg and use.inst > inst:
53+
return true

src/bali/runtime/vm/heap/bump_allocator.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ proc release*(allocator: var BumpAllocator) =
3636
proc initBumpAllocator*(
3737
size: uint64 = DefaultAllocatorBufferSize
3838
): BumpAllocator {.sideEffect.} =
39-
result = BumpAllocator(pool: malloc(size), cap: size)
39+
BumpAllocator(pool: malloc(size), cap: size)

0 commit comments

Comments
 (0)