Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

GH-135904: JIT compiler: Support 19 bit branch instructions on AArch64 for Mach-O.#140453

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
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
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
Add special labels to the assembly created during stencil creation to
support relocations that the native object file format does not support.
Specifically, 19 bit branches for AArch64 in Mach-O object files.
61 changes: 45 additions & 16 deletionsTools/jit/_optimizers.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@
_RE_NEVER_MATCH = re.compile(r"(?!)")
# Dictionary mapping branch instructions to their inverted branch instructions.
# If a branch cannot be inverted, the value is None:
_X86_BRANCHES = {
_X86_BRANCH_NAMES = {
# https://www.felixcloutier.com/x86/jcc
"ja": "jna",
"jae": "jnae",
Expand DownExpand Up@@ -37,7 +37,11 @@
"loopz": None,
}
# Update with all of the inverted branches, too:
_X86_BRANCHES |= {v: k for k, v in _X86_BRANCHES.items() if v}
_X86_BRANCH_NAMES |= {v: k for k, v in _X86_BRANCH_NAMES.items() if v}
# No custom relocations needed
_X86_BRANCHES: dict[str, tuple[str | None, str | None]] = {
k: (v, None) for k, v in _X86_BRANCH_NAMES.items()
}

_AARCH64_COND_CODES = {
# https://developer.arm.com/documentation/dui0801/b/CJAJIHAD?lang=en
Expand All@@ -58,12 +62,15 @@
"hi": "ls",
"ls": "hi",
}
# MyPy doesn't understand that a invariant variable can be initialized by a covariant value
CUSTOM_AARCH64_BRANCH19: str | None = "CUSTOM_AARCH64_BRANCH19"

# Branches are either b.{cond} or bc.{cond}
_AARCH64_BRANCHES = {
"b." + cond: ("b." + inverse if inverse else None)
_AARCH64_BRANCHES: dict[str, tuple[str | None, str | None]] = {
"b." + cond: (("b." + inverse if inverse else None), CUSTOM_AARCH64_BRANCH19)
for (cond, inverse) in _AARCH64_COND_CODES.items()
} | {
"bc." + cond: ("bc." + inverse if inverse else None)
"bc." + cond: (("bc." + inverse if inverse else None), CUSTOM_AARCH64_BRANCH19)
for (cond, inverse) in _AARCH64_COND_CODES.items()
}

Expand DownExpand Up@@ -113,7 +120,8 @@ class Optimizer:
r'\s*(?P<label>[\w."$?@]+):'
)
# Override everything that follows in subclasses:
_branches: typing.ClassVar[dict[str, str | None]] = {}
_supports_external_relocations = True
_branches: typing.ClassVar[dict[str, tuple[str | None, str | None]]] = {}
# Two groups (instruction and target):
_re_branch: typing.ClassVar[re.Pattern[str]] = _RE_NEVER_MATCH
# One group (target):
Expand DownExpand Up@@ -170,7 +178,10 @@ def _preprocess(self, text: str) -> str:
def _invert_branch(cls, line: str, target: str) -> str | None:
match = cls._re_branch.match(line)
assert match
inverted = cls._branches.get(match["instruction"])
inverted_reloc = cls._branches.get(match["instruction"])
if inverted_reloc is None:
return None
inverted = inverted_reloc[0]
if not inverted:
return None
(a, b), (c, d) = match.span("instruction"), match.span("target")
Expand DownExpand Up@@ -302,27 +313,45 @@ def _remove_redundant_jumps(self) -> None:
block.fallthrough = True
block.instructions.pop()

def _fixup_external_labels(self) -> None:
if self._supports_external_relocations:
# Nothing to fix up
return
for block in self._blocks():
if block.target and block.fallthrough:
branch = block.instructions[-1]
match = self._re_branch.match(branch)
assert match is not None
target = match["target"]
reloc = self._branches[match["instruction"]][1]
if reloc is not None and not target.startswith(self.label_prefix):
name = target[len(self.symbol_prefix) :]
block.instructions[-1] = (
f"// target='{target}' prefix='{self.label_prefix}'"
)
block.instructions.append(
f"{self.symbol_prefix}{reloc}_JIT_RELOCATION_{name}:"
)
a, b = match.span("target")
branch = "".join([branch[:a], "0", branch[b:]])
block.instructions.append(branch)

def run(self) -> None:
"""Run this optimizer."""
self._insert_continue_label()
self._mark_hot_blocks()
self._invert_hot_branches()
self._remove_redundant_jumps()
self._fixup_external_labels()
self.path.write_text(self._body())


# Mach-O does not support the 19 bit branch locations needed for branch reordering
class OptimizerAArch64_MachO(Optimizer): # pylint: disable = too-few-public-methods
"""aarch64-apple-darwin"""

# https://developer.arm.com/documentation/ddi0602/2025-03/Base-Instructions/B--Branch-
_re_jump = re.compile(r"\s*b\s+(?P<target>[\w.]+)")


class OptimizerAArch64(Optimizer): # pylint: disable = too-few-public-methods
"""aarch64-pc-windows-msvc/aarch64-unknown-linux-gnu"""
"""aarch64-pc-windows-msvc/aarch64-apple-darwin/aarch64-unknown-linux-gnu"""

_branches = _AARCH64_BRANCHES
# Mach-O does not support the 19 bit branch locations needed for branch reordering
_supports_external_relocations = False
_re_branch = re.compile(
rf"\s*(?P<instruction>{'|'.join(_AARCH64_BRANCHES)})\s+(.+,\s+)*(?P<target>[\w.]+)"
)
Expand Down
12 changes: 12 additions & 0 deletionsTools/jit/_stencils.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,7 @@ class HoleValue(enum.Enum):
"ARM64_RELOC_PAGE21": "patch_aarch64_21r",
"ARM64_RELOC_PAGEOFF12": "patch_aarch64_12",
"ARM64_RELOC_UNSIGNED": "patch_64",
"CUSTOM_AARCH64_BRANCH19": "patch_aarch64_19r",
# x86_64-pc-windows-msvc:
"IMAGE_REL_AMD64_REL32": "patch_x86_64_32rx",
# aarch64-pc-windows-msvc:
Expand DownExpand Up@@ -221,6 +222,17 @@ class StencilGroup:
_got: dict[str, int] = dataclasses.field(default_factory=dict, init=False)
_trampolines: set[int] = dataclasses.field(default_factory=set, init=False)

def convert_labels_to_relocations(self) -> None:
for name, hole_plus in self.symbols.items():
if isinstance(name, str) and "_JIT_RELOCATION_" in name:
_, offset = hole_plus
reloc, target = name.split("_JIT_RELOCATION_")
value, symbol = symbol_to_value(target)
hole = Hole(
int(offset), typing.cast(_schema.HoleKind, reloc), value, symbol, 0
)
self.code.holes.append(hole)

def process_relocations(self, known_symbols: dict[str, int]) -> None:
"""Fix up all GOT and internal relocations for this stencil group."""
for hole in self.code.holes.copy():
Expand Down
3 changes: 2 additions & 1 deletionTools/jit/_targets.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -218,6 +218,7 @@ async def _build_stencils(self) -> dict[str, _stencils.StencilGroup]:
tasks.append(group.create_task(coro, name=opname))
stencil_groups = {task.get_name(): task.result() for task in tasks}
for stencil_group in stencil_groups.values():
stencil_group.convert_labels_to_relocations()
stencil_group.process_relocations(self.known_symbols)
return stencil_groups

Expand DownExpand Up@@ -565,7 +566,7 @@ def get_target(host: str) -> _COFF32 | _COFF64 | _ELF | _MachO:
if re.fullmatch(r"aarch64-apple-darwin.*", host):
host = "aarch64-apple-darwin"
condition = "defined(__aarch64__) && defined(__APPLE__)"
optimizer = _optimizers.OptimizerAArch64_MachO
optimizer = _optimizers.OptimizerAArch64
target = _MachO(host, condition, optimizer=optimizer)
elif re.fullmatch(r"aarch64-pc-windows-msvc", host):
host = "aarch64-pc-windows-msvc"
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp