Nix flake for RPython interpreters
Revision | d34260f8d53fb00903e33949e55629456f7eaf16 (tree) |
---|---|
Time | 2024-04-09 05:53:34 |
Author | Corbin <cds@corb...> |
Commiter | Corbin |
Add JIT to DIVSPL interpreter.
I only saw a minor speedup in my testing, but the assembly code is
well-structured and should do a decent job for small numbers of rules.
The number of failed guards is exponential in the number of rules, so
I'm not sure if there's any good solution.
@@ -1,9 +1,12 @@ | ||
1 | 1 | import sys |
2 | 2 | |
3 | +from rpython.jit.codewriter.policy import JitPolicy | |
4 | +from rpython.rlib.jit import JitDriver | |
5 | + | |
3 | 6 | # This is a basic interpreter for DIVSPL, as described at |
4 | 7 | # https://www.promptworks.com/blog/the-fastest-fizzbuzz-in-the-west |
5 | 8 | # Version 0: Initial functionality |
6 | -# Version 1: Port to RPython | |
9 | +# Version 1: Port to RPython, add JIT | |
7 | 10 | |
8 | 11 | def parseAssignment(line): |
9 | 12 | word, number = [w.strip() for w in line.rsplit("=", 1)] |
@@ -12,13 +15,22 @@ def parseAssignment(line): | ||
12 | 15 | def parse(lines): |
13 | 16 | # The first line must be the range. |
14 | 17 | start, stop = [int(n.strip()) for n in lines[0].split("...")] |
15 | - assignments = [parseAssignment(line) for line in lines[1:]] | |
18 | + # Skip empty lines, usually at EOF. | |
19 | + assignments = [parseAssignment(line) for line in lines[1:] if line] | |
16 | 20 | return start, stop, assignments |
17 | 21 | |
22 | +def location(stop, assignments): | |
23 | + return "%d rules, stop at %d" % (len(assignments), stop) | |
24 | +driver = JitDriver(greens=["stop", "assignments"], reds=["i"], | |
25 | + get_printable_location=location) | |
26 | + | |
18 | 27 | def run(start, stop, assignments): |
19 | - for i in range(start, stop + 1): | |
28 | + i = start | |
29 | + while i <= stop: | |
30 | + driver.jit_merge_point(stop=stop, assignments=assignments, i=i) | |
20 | 31 | s = [w for w, n in assignments if not i % n] |
21 | 32 | print ("".join(s) if s else str(i)) |
33 | + i += 1 | |
22 | 34 | |
23 | 35 | # NB: programs should already be split into lines |
24 | 36 | def main(argv): |
@@ -31,6 +43,6 @@ def main(argv): | ||
31 | 43 | return 0 |
32 | 44 | |
33 | 45 | def target(*args): return main, None |
46 | +def jitpolicy(driver): return JitPolicy() | |
34 | 47 | |
35 | -if __name__ == "__main__": | |
36 | - sys.exit(main(sys.argv)) | |
48 | +if __name__ == "__main__": sys.exit(main(sys.argv)) |
@@ -131,7 +131,6 @@ | ||
131 | 131 | entrypoint = "divspl.py"; |
132 | 132 | binName = "divspl-c"; |
133 | 133 | binInstallName = "divspl"; |
134 | - optLevel = "2"; | |
135 | 134 | } { |
136 | 135 | pname = "divspl"; |
137 | 136 | version = "1"; |