Skip to content

Commit

Permalink
llvm: codegen on Apple Silicon
Browse files Browse the repository at this point in the history
  • Loading branch information
mratsim committed Jan 9, 2025
1 parent 8c00b9c commit 3986ad0
Show file tree
Hide file tree
Showing 19 changed files with 246 additions and 58 deletions.
2 changes: 1 addition & 1 deletion constantine/math_compiler/impl_curves_ops_affine.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import
std / typetraits # for distinctBase

## Section name used for `llvmInternalFnDef`
const SectionName = "ctt.curves_affine"
const SectionName = "ctt,curves_affine"

type
EcPointAff* {.borrow: `.`.} = distinct Array
Expand Down
2 changes: 1 addition & 1 deletion constantine/math_compiler/impl_curves_ops_jacobian.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import
std / typetraits # for distinctBase

## Section name used for `llvmInternalFnDef`
const SectionName = "ctt.curves_jacobian"
const SectionName = "ctt,curves_jacobian"

type
EcPointJac* {.borrow: `.`.} = distinct Array
Expand Down
6 changes: 3 additions & 3 deletions constantine/math_compiler/impl_fields_dispatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ import

proc modadd*(asy: Assembler_LLVM, fd: FieldDescriptor, r, a, b, M: ValueRef) =
case asy.backend
of {bkX86_64_Linux, bkAmdGpu}:
of {bkX86_64_Linux, bkArm64_MacOS, bkAmdGpu}:
asy.modadd_sat(fd, r, a, b, M)
of bkNvidiaPTX:
asy.modadd_nvidia(fd, r, a, b, M)

proc modsub*(asy: Assembler_LLVM, fd: FieldDescriptor, r, a, b, M: ValueRef) =
case asy.backend
of {bkX86_64_Linux, bkArm64_MacOS, bkAmdGpu}:
asy.modsub_sat(fd, r, a, b, M)
of bkNvidiaPTX:
asy.modsub_nvidia(fd, r, a, b, M)
else:
doAssert false, "Unimplemented"

proc mtymul*(asy: Assembler_LLVM, fd: FieldDescriptor, r, a, b, M: ValueRef, finalReduce = true) =
case asy.backend
Expand Down
2 changes: 1 addition & 1 deletion constantine/math_compiler/impl_fields_nvidia.nim
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import
#
# We cannot use i256 on Nvidia target: https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp#L244-L276

const SectionName = "ctt.fields"
const SectionName = "ctt,fields"

proc finalSubMayOverflow(asy: Assembler_LLVM, fd: FieldDescriptor, r, a, M: Array) =
## If a >= Modulus: r <- a-M
Expand Down
2 changes: 1 addition & 1 deletion constantine/math_compiler/impl_fields_ops.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import
./impl_fields_dispatch

## Section name used for `llvmInternalFnDef`
const SectionName = "ctt.impl_fields"
const SectionName = "ctt,impl_fields"

template declFieldOps*(asy: Assembler_LLVM, fd: FieldDescriptor): untyped {.dirty.} =
## This template can be used to make operations on `Field` elements
Expand Down
2 changes: 1 addition & 1 deletion constantine/math_compiler/impl_fields_sat.nim
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ import
# And implementing them with i256 / i384 is similarly tricky
# https://github.com/llvm/llvm-project/issues/102868

const SectionName = "ctt.fields"
const SectionName = "ctt,fields"

proc finalSubMayOverflow*(asy: Assembler_LLVM, fd: FieldDescriptor, rr, a, M, carry: ValueRef) =
## If a >= Modulus: r <- a-M
Expand Down
2 changes: 1 addition & 1 deletion constantine/math_compiler/impl_msm_nvidia.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import
std / typetraits # for distinctBase

## Section name used for `llvmInternalFnDef`
const SectionName = "ctt.msm_nvidia"
const SectionName = "ctt,msm_nvidia"

proc msm*(asy: Assembler_LLVM, cd: CurveDescriptor, r, coefs, points: ValueRef,
c, N: int) {.used.} =
Expand Down
5 changes: 4 additions & 1 deletion constantine/math_compiler/ir.nim
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type
bkAmdGpu
bkNvidiaPTX
bkX86_64_Linux
bkArm64_MacOS

proc finalizeAssemblerLLVM(asy: Assembler_LLVM) =
if not asy.isNil:
Expand Down Expand Up @@ -94,6 +95,8 @@ proc configure(asy: var Assembler_LLVM, backend: Backend) =
"n16:32:64")
of bkX86_64_Linux:
asy.module.setTarget("x86_64-pc-linux-gnu")
of bkArm64_MacOS:
asy.module.setTarget("aarch64-apple-darwin")

asy.datalayout = asy.module.getDataLayout()
asy.psize = int32 asy.datalayout.getPointerSize()
Expand Down Expand Up @@ -505,7 +508,7 @@ proc defineGlobalConstant*(
# This has the following benefits:
# - They might all be loaded in memory if they share a cacheline
# - If a section is unused, it can be garbage collected by the linker
g.setSection(cstring("ctt." & section & ".constants"))
g.setSection(cstring("ctt," & section)) # mach-o (MacOS), needs a comma
return g

# ############################################################
Expand Down
4 changes: 2 additions & 2 deletions constantine/math_compiler/pub_curves_affine.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import
./impl_curves_ops_affine

## Section name used for `llvmInternalFnDef`
const SectionName = "ctt.pub_curves_affine"
const SectionName = "ctt,pub_curves_affine"

proc genEcIsNeutralAff*(asy: Assembler_LLVM, cd: CurveDescriptor): string =
## Generate a public elliptic curve point isNeutral proc
Expand All @@ -27,7 +27,7 @@ proc genEcIsNeutralAff*(asy: Assembler_LLVM, cd: CurveDescriptor): string =

let name = cd.name & "isNeutralAff"
let ptrBool = pointer_t(asy.ctx.int1_t())
asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [ptrBool, cd.curveTyAff]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [ptrBool, cd.curveTyAff]):
let (r, a) = llvmParams
asy.isNeutralAff_internal(cd, r, a)
asy.br.retVoid()
Expand Down
22 changes: 11 additions & 11 deletions constantine/math_compiler/pub_curves_jacobian.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import


## Section name used for `llvmInternalFnDef`
const SectionName = "ctt.pub_curves_jacobian"
const SectionName = "ctt,pub_curves_jacobian"

proc genEcFromAffine*(asy: Assembler_LLVM, cd: CurveDescriptor): string =
## Generate a public elliptic curve point `fromAffine` proc
Expand All @@ -30,7 +30,7 @@ proc genEcFromAffine*(asy: Assembler_LLVM, cd: CurveDescriptor): string =
## and return the corresponding name to call it

let name = cd.name & "_isNeutral"
asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [cd.curveTy, cd.curveTyAff]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [cd.curveTy, cd.curveTyAff]):
let (jac, aff) = llvmParams
asy.fromAffine(cd, jac, aff)
asy.br.retVoid()
Expand All @@ -46,7 +46,7 @@ proc genEcIsNeutral*(asy: Assembler_LLVM, cd: CurveDescriptor): string =

let name = cd.name & "_isNeutral"
let ptrBool = pointer_t(asy.ctx.int1_t())
asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [ptrBool, cd.curveTy]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [ptrBool, cd.curveTy]):
let (r, a) = llvmParams
asy.isNeutral(cd, r, a)
asy.br.retVoid()
Expand All @@ -62,7 +62,7 @@ proc genEcSetNeutral*(asy: Assembler_LLVM, cd: CurveDescriptor): string =
## It returns the corresponding name to call it
let name = cd.name & "_setNeutral"
let ptrBool = pointer_t(asy.ctx.int1_t())
asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [cd.curveTy]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [cd.curveTy]):
let r = llvmParams
asy.setNeutral(cd, r)
asy.br.retVoid()
Expand All @@ -79,7 +79,7 @@ proc genEcCcopy*(asy: Assembler_LLVM, cd: CurveDescriptor): string =
## and return the corresponding name to call it

let name = cd.name & "_ccopy"
asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [cd.curveTy, cd.curveTy, asy.ctx.int1_t()]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [cd.curveTy, cd.curveTy, asy.ctx.int1_t()]):
let (a, b, c) = llvmParams
asy.ccopy(cd, a, b, c)
asy.br.retVoid()
Expand All @@ -94,7 +94,7 @@ proc genEcNeg*(asy: Assembler_LLVM, cd: CurveDescriptor): string =
## and return the corresponding name to call it

let name = cd.name & "_neg"
asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [cd.curveTy]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [cd.curveTy]):
let a = llvmParams
asy.neg(cd, a)
asy.br.retVoid()
Expand All @@ -109,7 +109,7 @@ proc genEcCneg*(asy: Assembler_LLVM, cd: CurveDescriptor): string =
## Returns the name to call the kernel.

let name = cd.name & "_neg"
asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [cd.curveTy, asy.ctx.int1_t()]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [cd.curveTy, asy.ctx.int1_t()]):
let (a, c) = llvmParams
asy.cneg(cd, a, c)
asy.br.retVoid()
Expand All @@ -125,7 +125,7 @@ proc genEcSum*(asy: Assembler_LLVM, cd: CurveDescriptor): string =
##
## Returns the name of the produced kernel to call it.
let name = cd.name & "_sum"
asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [cd.curveTy, cd.curveTy, cd.curveTy]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [cd.curveTy, cd.curveTy, cd.curveTy]):
let (ri, pi, qi) = llvmParams
asy.sum(cd, ri, pi, qi)
asy.br.retVoid()
Expand All @@ -139,7 +139,7 @@ proc genEcDouble*(asy: Assembler_LLVM, cd: CurveDescriptor): string =
##
## Returns the name of the produced kernel to call it.
let name = cd.name & "_double"
asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [cd.curveTy, cd.curveTy]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [cd.curveTy, cd.curveTy]):
let (ri, pi) = llvmParams
asy.double(cd, ri, pi)
asy.br.retVoid()
Expand All @@ -155,7 +155,7 @@ proc genEcMixedSum*(asy: Assembler_LLVM, cd: CurveDescriptor): string =
##
## Returns the name of the produced kernel to call it.
let name = cd.name & "_mixedSum"
asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [cd.curveTy, cd.curveTy, cd.curveTyAff]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [cd.curveTy, cd.curveTy, cd.curveTyAff]):
let (ri, pi, qi) = llvmParams
asy.mixedSum(cd, ri, pi, qi)
asy.br.retVoid()
Expand All @@ -175,7 +175,7 @@ proc genEcMSM*(asy: Assembler_LLVM, cd: CurveDescriptor, c, N: int): string =
let cT = array_t(cd.curveTyAff, N)
let name = cd.name & "_msm_public_c_" & $c & "_N_" & $N

asy.llvmPublicFnDef(name, "ctt." & cd.name, asy.void_t, [cd.curveTy, fT, cT]):
asy.llvmPublicFnDef(name, "ctt," & cd.name, asy.void_t, [cd.curveTy, fT, cT]):
let (ri, cs, ps) = llvmParams
asy.msm(cd, ri, cs, ps, c, N)
asy.br.retVoid()
Expand Down
Loading

0 comments on commit 3986ad0

Please sign in to comment.