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

Implementing mypyc support pt. 2 #2431

Merged
merged 28 commits into from
Nov 16, 2021
Merged
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9531e1b
Initial mypyc support changes
ichard26 Jun 6, 2021
6e9e0fb
Make the test suite usable for testing
ichard26 Jun 6, 2021
acb77f7
Fix mypyc KeyError on src/black/parsing.py
ichard26 Jun 12, 2021
a37fb77
Saves ~100 kB on my Linux machine :)
ichard26 Jun 30, 2021
2ccc774
Strings specific micro-optimization (1-10% perf boost)
ichard26 Jun 30, 2021
6f60e6e
Looks like I'll be marking more and more tests
ichard26 Jul 1, 2021
f508be4
Fix mypyc + Black on Windows
ichard26 Jul 10, 2021
94dcddb
Ask mypy to warn on unreachable code
ichard26 Jul 10, 2021
57a25ed
Clean up mypyc setup in setup.py
ichard26 Jul 10, 2021
8f42f28
Merge branch 'main' into mypyc-support-pt2
ichard26 Jul 17, 2021
f6a3e78
Initial mypyc optimizations - 5% faster parsing
ichard26 Jul 27, 2021
911d0d8
More parsing optimizations - 4% faster
ichard26 Jul 27, 2021
1f0df05
Just some cleanup
ichard26 Jul 31, 2021
58fbe9c
--version now indicates whether black is compiled
ichard26 Aug 1, 2021
c7de2ea
Round 3 of optimizations - 95% black + 5% blib2to3
ichard26 Aug 3, 2021
b956802
Merge branch 'main' into mypyc-support-pt2
ichard26 Aug 8, 2021
eaa4f6c
Fix crashes and errors since merge from main
ichard26 Aug 7, 2021
e9834e0
Mild hack so mypyc doesn't break diff-shades + cleanup
ichard26 Aug 11, 2021
f103dc0
Address feedback & cleanup comments
ichard26 Aug 21, 2021
5fc39fe
Merge branch 'main' into mypyc-support-pt2
ichard26 Oct 28, 2021
2f238ca
Skip a few more monkeypatching tests
ichard26 Oct 28, 2021
f561b0c
Bring back ignore for unused type ignore
ichard26 Oct 28, 2021
11b4f09
Merge branch 'main' into mypyc-support-pt2
ichard26 Oct 30, 2021
b0b3709
Merge branch 'main' into mypyc-support-pt2
ichard26 Oct 31, 2021
bb86dcf
Merge branch 'main' into mypyc-support-pt2
ichard26 Nov 14, 2021
5ef46f4
Optimizations + compatiblity fixes
ichard26 Nov 14, 2021
7c52cdb
Merge branch 'main' into mypyc-support-pt2
ichard26 Nov 14, 2021
f5f1099
Fix crash on PyPy by deoptimizing :(
ichard26 Nov 16, 2021
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
Prev Previous commit
Next Next commit
More parsing optimizations - 4% faster
- early binding; plus
- reordering of if checks to reduce work / hit the happy case more
  often; plus
- a few more tiny mypyc-specific tweaks
ichard26 committed Jul 27, 2021
commit 911d0d8601318fcc04069f2af91a066e499f0db0
59 changes: 31 additions & 28 deletions src/blib2to3/pgen2/parse.py
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@
Set,
)
from blib2to3.pgen2.grammar import Grammar
from blib2to3.pytree import NL, Context, RawNode, Leaf, Node
from blib2to3.pytree import convert, NL, Context, RawNode, Leaf, Node


Results = Dict[Text, NL]
@@ -100,6 +100,11 @@ def __init__(self, grammar: Grammar, convert: Optional[Convert] = None) -> None:
to be converted. The syntax tree is converted from the bottom
up.

**post-note: the convert argument is ignored since for Black's
usage, convert will always be blib2to3.pytree.convert. Allowing
this to be dynamic hurts mypyc's ability to use early binding.
These docs are left for historical and informational value.

A concrete syntax tree node is a (type, value, context, nodes)
tuple, where type is the node type (a token or symbol number),
value is None for symbols and a string for tokens, context is
@@ -112,6 +117,7 @@ def __init__(self, grammar: Grammar, convert: Optional[Convert] = None) -> None:

"""
self.grammar = grammar
# See note in docstring above. TL;DR this is ignored.
self.convert = convert or lam_sub

def setup(self, start: Optional[int] = None) -> None:
@@ -149,10 +155,18 @@ def addtoken(self, type: int, value: Text, context: Context) -> bool:
arcs = states[state]
# Look for a state with this label
for i, newstate in arcs:
t, v = self.grammar.labels[i]
if ilabel == i:
t = self.grammar.labels[i][0]
if t >= 256:
# See if it's a symbol and if we're in its first set
itsdfa = self.grammar.dfas[t]
itsstates, itsfirst = itsdfa
if ilabel in itsfirst:
# Push a symbol
self.push(t, itsdfa, newstate, context)
break # To continue the outer while loop

elif ilabel == i:
# Look it up in the list of labels
assert t < 256
# Shift a token; we're done with it
self.shift(type, value, newstate, context)
# Pop while we are in an accept-only state
@@ -166,14 +180,7 @@ def addtoken(self, type: int, value: Text, context: Context) -> bool:
states, first = dfa
# Done with this token
return False
elif t >= 256:
# See if it's a symbol and if we're in its first set
itsdfa = self.grammar.dfas[t]
itsstates, itsfirst = itsdfa
if ilabel in itsfirst:
# Push a symbol
self.push(t, self.grammar.dfas[t], newstate, context)
break # To continue the outer while loop

else:
if (0, state) in arcs:
# An accepting state, pop it and try something else
@@ -199,16 +206,13 @@ def classify(self, type: int, value: Text, context: Context) -> int:
raise ParseError("bad token", type, value, context)
return ilabel

def shift(
self, type: int, value: Text, newstate: int, context: Context
) -> None:
def shift(self, type: int, value: Text, newstate: int, context: Context) -> None:
"""Shift a token. (Internal)"""
dfa, state, node = self.stack[-1]
rawnode: RawNode = (type, value, context, None)
newnode = self.convert(self.grammar, rawnode)
if newnode is not None:
assert node[-1] is not None
node[-1].append(newnode)
newnode = convert(self.grammar, rawnode)
assert node[-1] is not None
node[-1].append(newnode)
self.stack[-1] = (dfa, newstate, node)

def push(self, type: int, newdfa: DFAS, newstate: int, context: Context) -> None:
@@ -221,12 +225,11 @@ def push(self, type: int, newdfa: DFAS, newstate: int, context: Context) -> None
def pop(self) -> None:
"""Pop a nonterminal. (Internal)"""
popdfa, popstate, popnode = self.stack.pop()
newnode = self.convert(self.grammar, popnode)
if newnode is not None:
if self.stack:
dfa, state, node = self.stack[-1]
assert node[-1] is not None
node[-1].append(newnode)
else:
self.rootnode = newnode
self.rootnode.used_names = self.used_names
newnode = convert(self.grammar, popnode)
if self.stack:
dfa, state, node = self.stack[-1]
assert node[-1] is not None
node[-1].append(newnode)
else:
self.rootnode = newnode
self.rootnode.used_names = self.used_names