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

Commitfc9819e

Browse files
markshannonStanFromIreland
authored andcommitted
pythonGH-135904: JIT compiler: Support 19 bit branch instructions on AArch64 for Mach-O. (pythonGH-140453)
* Insert labels into assembly for custom relocation during stencil creation.
1 parent0e6e91e commitfc9819e

File tree

4 files changed

+62
-17
lines changed

4 files changed

+62
-17
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add special labels to the assembly created during stencil creation to
2+
support relocations that the native object file format does not support.
3+
Specifically, 19 bit branches for AArch64 in Mach-O object files.

‎Tools/jit/_optimizers.py‎

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
_RE_NEVER_MATCH=re.compile(r"(?!)")
1010
# Dictionary mapping branch instructions to their inverted branch instructions.
1111
# If a branch cannot be inverted, the value is None:
12-
_X86_BRANCHES= {
12+
_X86_BRANCH_NAMES= {
1313
# https://www.felixcloutier.com/x86/jcc
1414
"ja":"jna",
1515
"jae":"jnae",
@@ -37,7 +37,11 @@
3737
"loopz":None,
3838
}
3939
# Update with all of the inverted branches, too:
40-
_X86_BRANCHES|= {v:kfork,vin_X86_BRANCHES.items()ifv}
40+
_X86_BRANCH_NAMES|= {v:kfork,vin_X86_BRANCH_NAMES.items()ifv}
41+
# No custom relocations needed
42+
_X86_BRANCHES:dict[str,tuple[str|None,str|None]]= {
43+
k: (v,None)fork,vin_X86_BRANCH_NAMES.items()
44+
}
4145

4246
_AARCH64_COND_CODES= {
4347
# https://developer.arm.com/documentation/dui0801/b/CJAJIHAD?lang=en
@@ -58,12 +62,15 @@
5862
"hi":"ls",
5963
"ls":"hi",
6064
}
65+
# MyPy doesn't understand that a invariant variable can be initialized by a covariant value
66+
CUSTOM_AARCH64_BRANCH19:str|None="CUSTOM_AARCH64_BRANCH19"
67+
6168
# Branches are either b.{cond} or bc.{cond}
62-
_AARCH64_BRANCHES= {
63-
"b."+cond: ("b."+inverseifinverseelseNone)
69+
_AARCH64_BRANCHES:dict[str,tuple[str|None,str|None]]= {
70+
"b."+cond: (("b."+inverseifinverseelseNone),CUSTOM_AARCH64_BRANCH19)
6471
for (cond,inverse)in_AARCH64_COND_CODES.items()
6572
}| {
66-
"bc."+cond: ("bc."+inverseifinverseelseNone)
73+
"bc."+cond: (("bc."+inverseifinverseelseNone),CUSTOM_AARCH64_BRANCH19)
6774
for (cond,inverse)in_AARCH64_COND_CODES.items()
6875
}
6976

@@ -113,7 +120,8 @@ class Optimizer:
113120
r'\s*(?P<label>[\w."$?@]+):'
114121
)
115122
# Override everything that follows in subclasses:
116-
_branches:typing.ClassVar[dict[str,str|None]]= {}
123+
_supports_external_relocations=True
124+
_branches:typing.ClassVar[dict[str,tuple[str|None,str|None]]]= {}
117125
# Two groups (instruction and target):
118126
_re_branch:typing.ClassVar[re.Pattern[str]]=_RE_NEVER_MATCH
119127
# One group (target):
@@ -170,7 +178,10 @@ def _preprocess(self, text: str) -> str:
170178
def_invert_branch(cls,line:str,target:str)->str|None:
171179
match=cls._re_branch.match(line)
172180
assertmatch
173-
inverted=cls._branches.get(match["instruction"])
181+
inverted_reloc=cls._branches.get(match["instruction"])
182+
ifinverted_relocisNone:
183+
returnNone
184+
inverted=inverted_reloc[0]
174185
ifnotinverted:
175186
returnNone
176187
(a,b), (c,d)=match.span("instruction"),match.span("target")
@@ -302,27 +313,45 @@ def _remove_redundant_jumps(self) -> None:
302313
block.fallthrough=True
303314
block.instructions.pop()
304315

316+
def_fixup_external_labels(self)->None:
317+
ifself._supports_external_relocations:
318+
# Nothing to fix up
319+
return
320+
forblockinself._blocks():
321+
ifblock.targetandblock.fallthrough:
322+
branch=block.instructions[-1]
323+
match=self._re_branch.match(branch)
324+
assertmatchisnotNone
325+
target=match["target"]
326+
reloc=self._branches[match["instruction"]][1]
327+
ifrelocisnotNoneandnottarget.startswith(self.label_prefix):
328+
name=target[len(self.symbol_prefix) :]
329+
block.instructions[-1]= (
330+
f"// target='{target}' prefix='{self.label_prefix}'"
331+
)
332+
block.instructions.append(
333+
f"{self.symbol_prefix}{reloc}_JIT_RELOCATION_{name}:"
334+
)
335+
a,b=match.span("target")
336+
branch="".join([branch[:a],"0",branch[b:]])
337+
block.instructions.append(branch)
338+
305339
defrun(self)->None:
306340
"""Run this optimizer."""
307341
self._insert_continue_label()
308342
self._mark_hot_blocks()
309343
self._invert_hot_branches()
310344
self._remove_redundant_jumps()
345+
self._fixup_external_labels()
311346
self.path.write_text(self._body())
312347

313348

314-
# Mach-O does not support the 19 bit branch locations needed for branch reordering
315-
classOptimizerAArch64_MachO(Optimizer):# pylint: disable = too-few-public-methods
316-
"""aarch64-apple-darwin"""
317-
318-
# https://developer.arm.com/documentation/ddi0602/2025-03/Base-Instructions/B--Branch-
319-
_re_jump=re.compile(r"\s*b\s+(?P<target>[\w.]+)")
320-
321-
322349
classOptimizerAArch64(Optimizer):# pylint: disable = too-few-public-methods
323-
"""aarch64-pc-windows-msvc/aarch64-unknown-linux-gnu"""
350+
"""aarch64-pc-windows-msvc/aarch64-apple-darwin/aarch64-unknown-linux-gnu"""
324351

325352
_branches=_AARCH64_BRANCHES
353+
# Mach-O does not support the 19 bit branch locations needed for branch reordering
354+
_supports_external_relocations=False
326355
_re_branch=re.compile(
327356
rf"\s*(?P<instruction>{'|'.join(_AARCH64_BRANCHES)})\s+(.+,\s+)*(?P<target>[\w.]+)"
328357
)

‎Tools/jit/_stencils.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class HoleValue(enum.Enum):
5858
"ARM64_RELOC_PAGE21":"patch_aarch64_21r",
5959
"ARM64_RELOC_PAGEOFF12":"patch_aarch64_12",
6060
"ARM64_RELOC_UNSIGNED":"patch_64",
61+
"CUSTOM_AARCH64_BRANCH19":"patch_aarch64_19r",
6162
# x86_64-pc-windows-msvc:
6263
"IMAGE_REL_AMD64_REL32":"patch_x86_64_32rx",
6364
# aarch64-pc-windows-msvc:
@@ -221,6 +222,17 @@ class StencilGroup:
221222
_got:dict[str,int]=dataclasses.field(default_factory=dict,init=False)
222223
_trampolines:set[int]=dataclasses.field(default_factory=set,init=False)
223224

225+
defconvert_labels_to_relocations(self)->None:
226+
forname,hole_plusinself.symbols.items():
227+
ifisinstance(name,str)and"_JIT_RELOCATION_"inname:
228+
_,offset=hole_plus
229+
reloc,target=name.split("_JIT_RELOCATION_")
230+
value,symbol=symbol_to_value(target)
231+
hole=Hole(
232+
int(offset),typing.cast(_schema.HoleKind,reloc),value,symbol,0
233+
)
234+
self.code.holes.append(hole)
235+
224236
defprocess_relocations(self,known_symbols:dict[str,int])->None:
225237
"""Fix up all GOT and internal relocations for this stencil group."""
226238
forholeinself.code.holes.copy():

‎Tools/jit/_targets.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ async def _build_stencils(self) -> dict[str, _stencils.StencilGroup]:
218218
tasks.append(group.create_task(coro,name=opname))
219219
stencil_groups= {task.get_name():task.result()fortaskintasks}
220220
forstencil_groupinstencil_groups.values():
221+
stencil_group.convert_labels_to_relocations()
221222
stencil_group.process_relocations(self.known_symbols)
222223
returnstencil_groups
223224

@@ -565,7 +566,7 @@ def get_target(host: str) -> _COFF32 | _COFF64 | _ELF | _MachO:
565566
ifre.fullmatch(r"aarch64-apple-darwin.*",host):
566567
host="aarch64-apple-darwin"
567568
condition="defined(__aarch64__) && defined(__APPLE__)"
568-
optimizer=_optimizers.OptimizerAArch64_MachO
569+
optimizer=_optimizers.OptimizerAArch64
569570
target=_MachO(host,condition,optimizer=optimizer)
570571
elifre.fullmatch(r"aarch64-pc-windows-msvc",host):
571572
host="aarch64-pc-windows-msvc"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp