Revision: 17916
Author: [email protected]
Date: Wed Nov 20 12:33:51 2013 UTC
Log: Experimental parser: more inlining
[email protected]
BUG=
Review URL: https://codereview.chromium.org/77353004
http://code.google.com/p/v8/source/detail?r=17916
Modified:
/branches/experimental/parser/tools/lexer_generator/code_generator.py
=======================================
--- /branches/experimental/parser/tools/lexer_generator/code_generator.py
Tue Nov 19 18:25:42 2013 UTC
+++ /branches/experimental/parser/tools/lexer_generator/code_generator.py
Wed Nov 20 12:33:51 2013 UTC
@@ -114,6 +114,15 @@
transitions = map(f, transitions)
disjoint_keys = sorted(disjoint_keys['value'],
CodeGenerator.__range_cmp)
# dictionary object representing state
+ (class_keys, distinct_keys, ranges) = (0, 0, 0)
+ for (t, r) in disjoint_keys:
+ if t == 'CLASS':
+ class_keys += 1
+ elif t == 'LATIN_1':
+ distinct_keys += r[1] - r[0] + 1
+ ranges += 1
+ else:
+ raise Exception()
return {
'node_number' : state.node_number(),
'original_node_number' : state.node_number(),
@@ -125,6 +134,9 @@
'action' : action,
'entry_action' : entry_action,
'match_action' : match_action,
+ 'class_keys' : class_keys,
+ 'distinct_keys' : distinct_keys,
+ 'ranges' : ranges
}
@staticmethod
@@ -136,13 +148,20 @@
for (k, transition_node) in state['transitions']:
CodeGenerator.__compute_depths(transition_node, depth + 1, id_map)
- @staticmethod
- def __set_inline(count, state):
+ def __set_inline(self, count, state):
assert state['inline'] == None
inline = False
+ # inline terminal states
if not state['transitions']:
inline = True
- # TODO add in 1 or 2 element if blocks
+ # inline next to terminal states with 1 or 2 transitions
+ elif state['distinct_keys'] < 3 and state['class_keys'] == 0:
+ inline = True
+ # ensure state terminates in 1 step
+ for key, state_id in state['transitions']:
+ if self.__dfa_states[state_id]['transitions']:
+ inline = False
+ break
state['inline'] = inline
return count + 1 if inline else count
@@ -151,15 +170,7 @@
'''Goes through the transitions for 'state' and decides which of them
should
use the if statement and which should use the switch statement.'''
assert not state['switch_transitions']
- (class_keys, distinct_keys, ranges) = (0, 0, 0)
- for (t, r) in state['disjoint_keys']:
- if t == 'CLASS':
- class_keys += 1
- elif t == 'LATIN_1':
- distinct_keys += r[1] - r[0] + 1
- ranges += 1
- else:
- raise Exception()
+ (distinct_keys, ranges) = (state['distinct_keys'], state['ranges'])
if distinct_keys <= 7 or float(distinct_keys)/float(ranges) >= 7.0:
return split_count
switch_transitions = []
@@ -196,9 +207,11 @@
state['transitions'] = map(f, state['transitions'])
assert id_map[self.__start_node_number]['node_number'] == 0
assert len(dfa_states) == self.__dfa.node_count()
+ # store states
+ self.__dfa_states = dfa_states
# set nodes to inline
if self.__inline:
- inlined = reduce(CodeGenerator.__set_inline, dfa_states, 0)
+ inlined = reduce(self.__set_inline, dfa_states, 0)
if self.__log:
print "%s states inlined" % inlined
elif self.__log:
@@ -210,8 +223,6 @@
print "%s states use switch (instead of if)" % switched
elif self.__log:
print "no switching"
- # store states
- self.__dfa_states = dfa_states
def process(self):
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.