Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-118306: Update JIT compilation to use LLVM 18 #118307

Merged
merged 32 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fef6cc0
Works for Linux Arm, Mac Arm broken
savannahostrowski Apr 25, 2024
3a5a0e9
uncomment
savannahostrowski Apr 25, 2024
186fef0
Minor updates for windows
savannahostrowski Apr 25, 2024
c0b63d2
llvm in CI
savannahostrowski Apr 25, 2024
8e31869
add brew update to gha
savannahostrowski Apr 25, 2024
ad6d554
remove file
savannahostrowski Apr 25, 2024
d546621
choco?
savannahostrowski Apr 25, 2024
2526e81
debugging windows runners
savannahostrowski Apr 25, 2024
9e0afdf
add -y
savannahostrowski Apr 25, 2024
b0ed125
add -y to choco for emulated windows
savannahostrowski Apr 25, 2024
3eeb3f0
instruction in jit.c and remove -mcmodel=large
savannahostrowski Apr 26, 2024
40bcebf
Fix instructions and MachO parsing
savannahostrowski Apr 26, 2024
c02ec00
remove mcmodel=large for aarch linux
savannahostrowski Apr 26, 2024
5d4dede
add unhandled ELF instructions;
savannahostrowski Apr 26, 2024
bf5aa36
update workflow to install all llvm on native linux
savannahostrowski Apr 26, 2024
a79a39b
remove --with-lto
savannahostrowski Apr 26, 2024
dd283e3
remove lto from emulated linux
savannahostrowski Apr 26, 2024
8d59ff8
update comments
savannahostrowski Apr 26, 2024
9433e30
📜🤖 Added by blurb_it.
blurb-it[bot] Apr 26, 2024
6617ad4
update classes for ELF and MachO symbol types
savannahostrowski Apr 26, 2024
a9ef1f4
Merge branch 'llvm-18' of https://github.com/savannahostrowski/cpytho…
savannahostrowski Apr 26, 2024
02307e4
Merge branch 'main' into llvm-18
savannahostrowski Apr 26, 2024
8d9855f
Update .github/workflows/jit.yml
savannahostrowski Apr 26, 2024
72d366a
Update Tools/jit/_stencils.py
savannahostrowski Apr 26, 2024
fe17f68
Merge branch 'python:main' into llvm-18
savannahostrowski Apr 26, 2024
71954a0
address PR comments
savannahostrowski Apr 26, 2024
3d6d8c7
Merge branch 'llvm-18' of https://github.com/savannahostrowski/cpytho…
savannahostrowski Apr 26, 2024
80b9e1c
add -fPIC
savannahostrowski Apr 27, 2024
1808f6a
fix ordering of args for consistency
savannahostrowski Apr 27, 2024
b2bbeb0
Merge branch 'main' into llvm-18
savannahostrowski Apr 27, 2024
5717a81
Formatting nits
brandtbucher Apr 29, 2024
6c80a31
Merge branch 'main' into llvm-18
brandtbucher Apr 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .github/workflows/jit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- true
- false
llvm:
- 16
- 18
include:
- target: i686-pc-windows-msvc/msvc
architecture: Win32
Expand Down Expand Up @@ -94,6 +94,7 @@ jobs:
- name: Native Windows
if: runner.os == 'Windows' && matrix.architecture != 'ARM64'
run: |
choco upgrade llvm -y
choco install llvm --allow-downgrade --no-progress --version ${{ matrix.llvm }}
./PCbuild/build.bat --experimental-jit ${{ matrix.debug && '-d' || '--pgo' }} -p ${{ matrix.architecture }}
./PCbuild/rt.bat ${{ matrix.debug && '-d' }} -p ${{ matrix.architecture }} -q --exclude ${{ matrix.exclude }} --multiprocess 0 --timeout 4500 --verbose2 --verbose3
Expand All @@ -102,27 +103,31 @@ jobs:
- name: Emulated Windows
if: runner.os == 'Windows' && matrix.architecture == 'ARM64'
run: |
choco upgrade llvm -y
savannahostrowski marked this conversation as resolved.
Show resolved Hide resolved
choco install llvm --allow-downgrade --no-progress --version ${{ matrix.llvm }}
./PCbuild/build.bat --experimental-jit ${{ matrix.debug && '-d' || '' }} -p ${{ matrix.architecture }}

- name: Native macOS
if: runner.os == 'macOS'
run: |
brew update
brew install llvm@${{ matrix.llvm }}
SDKROOT="$(xcrun --show-sdk-path)" \
./configure --enable-experimental-jit ${{ matrix.debug && '--with-pydebug' || '--enable-optimizations --with-lto' }}
make all --jobs 4
./python.exe -m test --exclude ${{ matrix.exclude }} --multiprocess 0 --timeout 4500 --verbose2 --verbose3

# --with-lto has been removed temporarily as a result of an open issue in LLVM 18 (see https://github.com/llvm/llvm-project/issues/87553)
- name: Native Linux
if: runner.os == 'Linux' && matrix.architecture == 'x86_64'
run: |
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" ./llvm.sh ${{ matrix.llvm }}
export PATH="$(llvm-config-${{ matrix.llvm }} --bindir):$PATH"
./configure --enable-experimental-jit ${{ matrix.debug && '--with-pydebug' || '--enable-optimizations --with-lto' }}
./configure --enable-experimental-jit ${{ matrix.debug && '--with-pydebug' || '--enable-optimizations' }}
make all --jobs 4
./python -m test --exclude ${{ matrix.exclude }} --multiprocess 0 --timeout 4500 --verbose2 --verbose3

# --with-lto has been removed temporarily as a result of an open issue in LLVM 18 (see https://github.com/llvm/llvm-project/issues/87553)
- name: Emulated Linux
if: runner.os == 'Linux' && matrix.architecture != 'x86_64'
run: |
Expand All @@ -139,6 +144,6 @@ jobs:
CC="${{ matrix.compiler == 'clang' && 'clang --target=$HOST' || '$HOST-gcc' }}" \
CPP="$CC --preprocess" \
HOSTRUNNER=qemu-${{ matrix.architecture }} \
./configure --enable-experimental-jit ${{ matrix.debug && '--with-pydebug' || '--enable-optimizations --with-lto' }} --build=x86_64-linux-gnu --host="$HOST" --with-build-python=../build/bin/python3 --with-pkg-config=no ac_cv_buggy_getaddrinfo=no ac_cv_file__dev_ptc=no ac_cv_file__dev_ptmx=yes
./configure --enable-experimental-jit ${{ matrix.debug && '--with-pydebug' || '--enable-optimizations ' }} --build=x86_64-linux-gnu --host="$HOST" --with-build-python=../build/bin/python3 --with-pkg-config=no ac_cv_buggy_getaddrinfo=no ac_cv_file__dev_ptc=no ac_cv_file__dev_ptmx=yes
make all --jobs 4
./python -m test --exclude ${{ matrix.exclude }} --multiprocess 0 --timeout 4500 --verbose2 --verbose3
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update JIT compilation to use LLVM 18
3 changes: 3 additions & 0 deletions Python/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ patch(unsigned char *base, const Stencil *stencil, uintptr_t patches[])
assert((int64_t)value < (1LL << 31));
*loc32 = (uint32_t)value;
continue;
case HoleKind_ARM64_RELOC_BRANCH26:
case HoleKind_IMAGE_REL_ARM64_BRANCH26:
case HoleKind_R_AARCH64_CALL26:
case HoleKind_R_AARCH64_JUMP26:
Expand Down Expand Up @@ -278,6 +279,7 @@ patch(unsigned char *base, const Stencil *stencil, uintptr_t patches[])
case HoleKind_ARM64_RELOC_GOT_LOAD_PAGE21:
case HoleKind_IMAGE_REL_ARM64_PAGEBASE_REL21:
case HoleKind_R_AARCH64_ADR_GOT_PAGE:
case HoleKind_R_AARCH64_ADR_PREL_PG_HI21:
// 21-bit count of pages between this page and an absolute address's
// page... I know, I know, it's weird. Pairs nicely with
// ARM64_RELOC_GOT_LOAD_PAGEOFF12 (below).
Expand Down Expand Up @@ -341,6 +343,7 @@ patch(unsigned char *base, const Stencil *stencil, uintptr_t patches[])
case HoleKind_ARM64_RELOC_PAGEOFF12:
case HoleKind_IMAGE_REL_ARM64_PAGEOFFSET_12A:
case HoleKind_IMAGE_REL_ARM64_PAGEOFFSET_12L:
case HoleKind_R_AARCH64_ADD_ABS_LO12_NC:
case HoleKind_R_AARCH64_LD64_GOT_LO12_NC:
// 12-bit low part of an absolute address. Pairs nicely with
// ARM64_RELOC_GOT_LOAD_PAGE21 (above).
Expand Down
10 changes: 7 additions & 3 deletions Tools/jit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,21 @@ sudo ./llvm.sh 16

### macOS

Install LLVM 16 with [Homebrew](https://brew.sh):
Install LLVM 18 with [Homebrew](https://brew.sh):

```sh
brew install llvm@16
brew install llvm@18
```

Homebrew won't add any of the tools to your `$PATH`. That's okay; the build script knows how to find them.

### Windows

Install LLVM 16 [by searching for it on LLVM's GitHub releases page](https://github.com/llvm/llvm-project/releases?q=16), clicking on "Assets", downloading the appropriate Windows installer for your platform (likely the file ending with `-win64.exe`), and running it. **When installing, be sure to select the option labeled "Add LLVM to the system PATH".**
Install LLVM 18 [by searching for it on LLVM's GitHub releases page](https://github.com/llvm/llvm-project/releases?q=18), clicking on "Assets", downloading the appropriate Windows installer for your platform (likely the file ending with `-win64.exe`), and running it. **When installing, be sure to select the option labeled "Add LLVM to the system PATH".**

### Dev Containers

If you are working CPython in a [Codespaces instance](https://devguide.python.org/getting-started/setup-building/#using-codespaces), there's no need to install LLVM as the Fedora 40 base image includes LLVM 18 out of the box.

## Building

Expand Down
2 changes: 1 addition & 1 deletion Tools/jit/_llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import subprocess
import typing

_LLVM_VERSION = 16
_LLVM_VERSION = 18
_LLVM_VERSION_PATTERN = re.compile(rf"version\s+{_LLVM_VERSION}\.\d+\.\d+\s+")

_P = typing.ParamSpec("_P")
Expand Down
9 changes: 6 additions & 3 deletions Tools/jit/_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import typing

HoleKind: typing.TypeAlias = typing.Literal[
"ARM64_RELOC_BRANCH26",
"ARM64_RELOC_GOT_LOAD_PAGE21",
"ARM64_RELOC_GOT_LOAD_PAGEOFF12",
"ARM64_RELOC_PAGE21",
Expand All @@ -16,8 +17,10 @@
"IMAGE_REL_I386_REL32",
"R_AARCH64_ABS64",
"R_AARCH64_ADR_GOT_PAGE",
"R_AARCH64_ADR_PREL_PG_HI21",
"R_AARCH64_CALL26",
"R_AARCH64_JUMP26",
"R_AARCH64_ADD_ABS_LO12_NC",
"R_AARCH64_LD64_GOT_LO12_NC",
"R_AARCH64_MOVW_UABS_G0_NC",
"R_AARCH64_MOVW_UABS_G1_NC",
Expand Down Expand Up @@ -68,12 +71,12 @@ class _COFFSymbol(typing.TypedDict):


class _ELFSymbol(typing.TypedDict):
Name: dict[typing.Literal["Value"], str]
Name: dict[typing.Literal["Name"], str]
Value: int


class _MachOSymbol(typing.TypedDict):
Name: dict[typing.Literal["Value"], str]
Name: dict[typing.Literal["Name"], str]
Value: int


Expand All @@ -99,7 +102,7 @@ class ELFSection(typing.TypedDict):
Relocations: list[dict[typing.Literal["Relocation"], ELFRelocation]]
SectionData: dict[typing.Literal["Bytes"], list[int]]
Symbols: list[dict[typing.Literal["Symbol"], _ELFSymbol]]
Type: dict[typing.Literal["Value"], str]
Type: dict[typing.Literal["Name"], str]


class MachOSection(typing.TypedDict):
Expand Down
4 changes: 3 additions & 1 deletion Tools/jit/_stencils.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,9 @@ def process_relocations(self, *, alignment: int = 1) -> None:
"""Fix up all GOT and internal relocations for this stencil group."""
for hole in self.code.holes.copy():
if (
hole.kind in {"R_AARCH64_CALL26", "R_AARCH64_JUMP26"}
hole.kind in {
"R_AARCH64_CALL26", "R_AARCH64_JUMP26", "ARM64_RELOC_BRANCH26"
}
and hole.value is HoleValue.ZERO
):
self.code.pad(alignment)
Expand Down
52 changes: 26 additions & 26 deletions Tools/jit/_targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def _handle_relocation(
case {
"Offset": offset,
"Symbol": s,
"Type": {"Value": "IMAGE_REL_I386_DIR32" as kind},
"Type": {"Name": "IMAGE_REL_I386_DIR32" as kind},
}:
offset += base
value, symbol = self._unwrap_dllimport(s)
Expand All @@ -230,7 +230,7 @@ def _handle_relocation(
"Offset": offset,
"Symbol": s,
"Type": {
"Value": "IMAGE_REL_AMD64_REL32" | "IMAGE_REL_I386_REL32" as kind
"Name": "IMAGE_REL_AMD64_REL32" | "IMAGE_REL_I386_REL32" as kind
},
}:
offset += base
Expand All @@ -242,7 +242,7 @@ def _handle_relocation(
"Offset": offset,
"Symbol": s,
"Type": {
"Value": "IMAGE_REL_ARM64_BRANCH26"
"Name": "IMAGE_REL_ARM64_BRANCH26"
| "IMAGE_REL_ARM64_PAGEBASE_REL21"
| "IMAGE_REL_ARM64_PAGEOFFSET_12A"
| "IMAGE_REL_ARM64_PAGEOFFSET_12L" as kind
Expand All @@ -262,7 +262,7 @@ class _ELF(
def _handle_section(
self, section: _schema.ELFSection, group: _stencils.StencilGroup
) -> None:
section_type = section["Type"]["Value"]
section_type = section["Type"]["Name"]
flags = {flag["Name"] for flag in section["Flags"]["Flags"]}
if section_type == "SHT_RELA":
assert "SHF_INFO_LINK" in flags, flags
Expand Down Expand Up @@ -290,7 +290,7 @@ def _handle_section(
for wrapped_symbol in section["Symbols"]:
symbol = wrapped_symbol["Symbol"]
offset = len(stencil.body) + symbol["Value"]
name = symbol["Name"]["Value"]
name = symbol["Name"]["Name"]
name = name.removeprefix(self.prefix)
group.symbols[name] = value, offset
stencil.body.extend(section["SectionData"]["Bytes"])
Expand All @@ -312,9 +312,9 @@ def _handle_relocation(
case {
"Addend": addend,
"Offset": offset,
"Symbol": {"Value": s},
"Symbol": {"Name": s},
"Type": {
"Value": "R_AARCH64_ADR_GOT_PAGE"
"Name": "R_AARCH64_ADR_GOT_PAGE"
| "R_AARCH64_LD64_GOT_LO12_NC"
| "R_X86_64_GOTPCREL"
| "R_X86_64_GOTPCRELX"
Expand All @@ -327,8 +327,8 @@ def _handle_relocation(
case {
"Addend": addend,
"Offset": offset,
"Symbol": {"Value": s},
"Type": {"Value": kind},
"Symbol": {"Name": s},
"Type": {"Name": kind},
}:
offset += base
s = s.removeprefix(self.prefix)
Expand Down Expand Up @@ -371,7 +371,7 @@ def _handle_section(
for wrapped_symbol in section["Symbols"]:
symbol = wrapped_symbol["Symbol"]
offset = symbol["Value"] - start_address
name = symbol["Name"]["Value"]
name = symbol["Name"]["Name"]
name = name.removeprefix(self.prefix)
group.symbols[name] = value, offset
assert "Relocations" in section
Expand All @@ -387,9 +387,9 @@ def _handle_relocation(
match relocation:
case {
"Offset": offset,
"Symbol": {"Value": s},
"Symbol": {"Name": s},
"Type": {
"Value": "ARM64_RELOC_GOT_LOAD_PAGE21"
"Name": "ARM64_RELOC_GOT_LOAD_PAGE21"
| "ARM64_RELOC_GOT_LOAD_PAGEOFF12" as kind
},
}:
Expand All @@ -399,8 +399,8 @@ def _handle_relocation(
addend = 0
case {
"Offset": offset,
"Symbol": {"Value": s},
"Type": {"Value": "X86_64_RELOC_GOT" | "X86_64_RELOC_GOT_LOAD" as kind},
"Symbol": {"Name": s},
"Type": {"Name": "X86_64_RELOC_GOT" | "X86_64_RELOC_GOT_LOAD" as kind},
}:
offset += base
s = s.removeprefix(self.prefix)
Expand All @@ -410,13 +410,13 @@ def _handle_relocation(
)
case {
"Offset": offset,
"Section": {"Value": s},
"Type": {"Value": "X86_64_RELOC_SIGNED" as kind},
"Section": {"Name": s},
"Type": {"Name": "X86_64_RELOC_SIGNED" as kind},
} | {
"Offset": offset,
"Symbol": {"Value": s},
"Symbol": {"Name": s},
"Type": {
"Value": "X86_64_RELOC_BRANCH" | "X86_64_RELOC_SIGNED" as kind
"Name": "X86_64_RELOC_BRANCH" | "X86_64_RELOC_SIGNED" as kind
},
}:
offset += base
Expand All @@ -427,12 +427,12 @@ def _handle_relocation(
)
case {
"Offset": offset,
"Section": {"Value": s},
"Type": {"Value": kind},
"Section": {"Name": s},
"Type": {"Name": kind},
} | {
"Offset": offset,
"Symbol": {"Value": s},
"Type": {"Value": kind},
"Symbol": {"Name": s},
"Type": {"Name": kind},
}:
offset += base
s = s.removeprefix(self.prefix)
Expand All @@ -446,13 +446,12 @@ def _handle_relocation(
def get_target(host: str) -> _COFF | _ELF | _MachO:
"""Build a _Target for the given host "triple" and options."""
if re.fullmatch(r"aarch64-apple-darwin.*", host):
args = ["-mcmodel=large"]
return _MachO(host, alignment=8, args=args, prefix="_")
return _MachO(host, alignment=8, prefix="_")
if re.fullmatch(r"aarch64-pc-windows-msvc", host):
args = ["-fms-runtime-lib=dll"]
return _COFF(host, alignment=8, args=args)
if re.fullmatch(r"aarch64-.*-linux-gnu", host):
args = ["-mcmodel=large"]
args = ["-fpic"]
return _ELF(host, alignment=8, args=args)
if re.fullmatch(r"i686-pc-windows-msvc", host):
args = ["-DPy_NO_ENABLE_SHARED"]
Expand All @@ -463,5 +462,6 @@ def get_target(host: str) -> _COFF | _ELF | _MachO:
args = ["-fms-runtime-lib=dll"]
return _COFF(host, args=args)
if re.fullmatch(r"x86_64-.*-linux-gnu", host):
return _ELF(host)
args = ["-fpic"]
return _ELF(host, args=args)
raise ValueError(host)
Loading