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-115869: Make jit_stencils.h reproducible #127166

Merged
merged 6 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make ``jit_stencils.h`` (which is produced during JIT builds) reproducible.
3 changes: 2 additions & 1 deletion Tools/jit/_stencils.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ def pad(self, alignment: int) -> None:
"""Pad the stencil to the given alignment."""
offset = len(self.body)
padding = -offset % alignment
self.disassembly.append(f"{offset:x}: {' '.join(['00'] * padding)}")
if padding:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unrelated cleanup.

self.disassembly.append(f"{offset:x}: {' '.join(['00'] * padding)}")
self.body.extend([0] * padding)

def remove_jump(self, *, alignment: int = 1) -> None:
Expand Down
19 changes: 13 additions & 6 deletions Tools/jit/_targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ async def _parse(self, path: pathlib.Path) -> _stencils.StencilGroup:
args = ["--disassemble", "--reloc", f"{path}"]
output = await _llvm.maybe_run("llvm-objdump", args, echo=self.verbose)
if output is not None:
# Make sure that full paths don't leak out (for reproducibility):
long, short = str(path), str(path.name)
group.code.disassembly.extend(
line.expandtabs().strip()
line.expandtabs().strip().replace(long, short)
for line in output.splitlines()
if not line.isspace()
)
args = [
"--elf-output-style=JSON",
Expand All @@ -90,9 +91,6 @@ async def _parse(self, path: pathlib.Path) -> _stencils.StencilGroup:
if group.data.body:
line = f"0: {str(bytes(group.data.body)).removeprefix('b')}"
group.data.disassembly.append(line)
group.process_relocations(
known_symbols=self.known_symbols, alignment=self.alignment
)
return group

def _handle_section(self, section: _S, group: _stencils.StencilGroup) -> None:
Expand Down Expand Up @@ -122,6 +120,10 @@ async def _compile(
f"-I{CPYTHON / 'Tools' / 'jit'}",
"-O3",
"-c",
# Shorten full absolute file paths in the generated code (like the
# __FILE__ macro and assert failure messages) for reproducibility:
f"-ffile-prefix-map={CPYTHON}=.",
f"-ffile-prefix-map={tempdir}=.",
# This debug info isn't necessary, and bloats out the JIT'ed code.
# We *may* be able to re-enable this, process it, and JIT it for a
# nicer debugging experience... but that needs a lot more research:
Expand Down Expand Up @@ -167,7 +169,12 @@ async def _build_stencils(self) -> dict[str, _stencils.StencilGroup]:
c.write_text(template.replace("CASE", case))
coro = self._compile(opname, c, work)
tasks.append(group.create_task(coro, name=opname))
return {task.get_name(): task.result() for task in tasks}
stencil_groups = {task.get_name(): task.result() for task in tasks}
for stencil_group in stencil_groups.values():
stencil_group.process_relocations(
known_symbols=self.known_symbols, alignment=self.alignment
)
return stencil_groups

def build(
self, out: pathlib.Path, *, comment: str = "", force: bool = False
Expand Down
2 changes: 1 addition & 1 deletion Tools/jit/_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,6 @@ def dump(
groups: dict[str, _stencils.StencilGroup], symbols: dict[str, int]
) -> typing.Iterator[str]:
"""Yield a JIT compiler line-by-line as a C header file."""
for opname, group in sorted(groups.items()):
for opname, group in groups.items():
yield from _dump_stencil(opname, group)
yield from _dump_footer(groups, symbols)
2 changes: 1 addition & 1 deletion Tools/jit/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import _targets

if __name__ == "__main__":
comment = f"$ {shlex.join([sys.executable] + sys.argv)}"
comment = f"$ {shlex.join([pathlib.Path(sys.executable).name] + sys.argv)}"
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"target", type=_targets.get_target, help="a PEP 11 target triple to compile for"
Expand Down
Loading