summaryrefslogtreecommitdiff
path: root/tools/checker/file_format/c1visualizer/parser.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/checker/file_format/c1visualizer/parser.py')
-rw-r--r--tools/checker/file_format/c1visualizer/parser.py105
1 files changed, 65 insertions, 40 deletions
diff --git a/tools/checker/file_format/c1visualizer/parser.py b/tools/checker/file_format/c1visualizer/parser.py
index bdcde9db51..55efbd74ea 100644
--- a/tools/checker/file_format/c1visualizer/parser.py
+++ b/tools/checker/file_format/c1visualizer/parser.py
@@ -12,20 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from common.logger import Logger
-from file_format.common import SplitStream
+from common.logger import Logger
+from file_format.common import split_stream
from file_format.c1visualizer.struct import C1visualizerFile, C1visualizerPass
import re
+
class C1ParserState:
- OutsideBlock, InsideCompilationBlock, StartingCfgBlock, InsideCfgBlock = range(4)
+ OUTSIDE_BLOCK, INSIDE_COMPILATION_BLOCK, STARTING_CFG_BLOCK, INSIDE_CFG_BLOCK = range(4)
def __init__(self):
- self.currentState = C1ParserState.OutsideBlock
- self.lastMethodName = None
+ self.current_state = C1ParserState.OUTSIDE_BLOCK
+ self.last_method_name = None
+
-def __parseC1Line(line, lineNo, state, fileName):
+def _parse_c1_line(c1_file, line, line_no, state, filename):
""" This function is invoked on each line of the output file and returns
a triplet which instructs the parser how the line should be handled. If the
line is to be included in the current group, it is returned in the first
@@ -34,57 +36,80 @@ def __parseC1Line(line, lineNo, state, fileName):
function prototype compatible with `SplitStream` and is always set to
`None` here.
"""
- if state.currentState == C1ParserState.StartingCfgBlock:
+ if state.current_state == C1ParserState.STARTING_CFG_BLOCK:
# Previous line started a new 'cfg' block which means that this one must
# contain the name of the pass (this is enforced by C1visualizer).
- if re.match("name\s+\"[^\"]+\"", line):
+ if re.match(r'name\s+"[^"]+"', line):
# Extract the pass name, prepend it with the name of the method and
# return as the beginning of a new group.
- state.currentState = C1ParserState.InsideCfgBlock
- return (None, state.lastMethodName + " " + line.split("\"")[1], None)
+ state.current_state = C1ParserState.INSIDE_CFG_BLOCK
+ return None, state.last_method_name + " " + line.split('"')[1], None
else:
- Logger.fail("Expected output group name", fileName, lineNo)
+ Logger.fail("Expected output group name", filename, line_no)
- elif state.currentState == C1ParserState.InsideCfgBlock:
+ elif state.current_state == C1ParserState.INSIDE_CFG_BLOCK:
if line == "end_cfg":
- state.currentState = C1ParserState.OutsideBlock
- return (None, None, None)
+ state.current_state = C1ParserState.OUTSIDE_BLOCK
+ return None, None, None
else:
- return (line, None, None)
+ return line, None, None
- elif state.currentState == C1ParserState.InsideCompilationBlock:
+ elif state.current_state == C1ParserState.INSIDE_COMPILATION_BLOCK:
# Search for the method's name. Format: method "<name>"
- if re.match("method\s+\"[^\"]*\"", line):
- methodName = line.split("\"")[1].strip()
- if not methodName:
- Logger.fail("Empty method name in output", fileName, lineNo)
- state.lastMethodName = methodName
+ if re.match(r'method\s+"[^"]*"', line):
+ method_name = line.split('"')[1].strip()
+ if not method_name:
+ Logger.fail("Empty method name in output", filename, line_no)
+
+ match = re.search(r"isa_features:([\w,-]+)", method_name)
+ if match:
+ raw_features = match.group(1).split(",")
+ # Create a map of features in the form {feature_name: is_enabled}.
+ features = {}
+ for rf in raw_features:
+ feature_name = rf
+ is_enabled = True
+ # A '-' in front of the feature name indicates that the feature wasn't enabled at compile
+ # time.
+ if rf[0] == "-":
+ feature_name = rf[1:]
+ is_enabled = False
+ features[feature_name] = is_enabled
+
+ c1_file.set_isa_features(features)
+ else:
+ state.last_method_name = method_name
elif line == "end_compilation":
- state.currentState = C1ParserState.OutsideBlock
- return (None, None, None)
+ state.current_state = C1ParserState.OUTSIDE_BLOCK
+ return None, None, None
else:
- assert state.currentState == C1ParserState.OutsideBlock
+ assert state.current_state == C1ParserState.OUTSIDE_BLOCK
if line == "begin_cfg":
# The line starts a new group but we'll wait until the next line from
# which we can extract the name of the pass.
- if state.lastMethodName is None:
- Logger.fail("Expected method header", fileName, lineNo)
- state.currentState = C1ParserState.StartingCfgBlock
- return (None, None, None)
+ if state.last_method_name is None:
+ Logger.fail("Expected method header", filename, line_no)
+ state.current_state = C1ParserState.STARTING_CFG_BLOCK
+ return None, None, None
elif line == "begin_compilation":
- state.currentState = C1ParserState.InsideCompilationBlock
- return (None, None, None)
+ state.current_state = C1ParserState.INSIDE_COMPILATION_BLOCK
+ return None, None, None
else:
- Logger.fail("C1visualizer line not inside a group", fileName, lineNo)
+ Logger.fail("C1visualizer line not inside a group", filename, line_no)
-def ParseC1visualizerStream(fileName, stream):
- c1File = C1visualizerFile(fileName)
+
+def parse_c1_visualizer_stream(filename, stream):
+ c1_file = C1visualizerFile(filename)
state = C1ParserState()
- fnProcessLine = lambda line, lineNo: __parseC1Line(line, lineNo, state, fileName)
- fnLineOutsideChunk = lambda line, lineNo: \
- Logger.fail("C1visualizer line not inside a group", fileName, lineNo)
- for passName, passLines, startLineNo, testArch in \
- SplitStream(stream, fnProcessLine, fnLineOutsideChunk):
- C1visualizerPass(c1File, passName, passLines, startLineNo + 1)
- return c1File
+
+ def fn_process_line(line, line_no):
+ return _parse_c1_line(c1_file, line, line_no, state, c1_file.base_file_name)
+
+ def fn_line_outside_chunk(line, line_no):
+ Logger.fail("C1visualizer line not inside a group", c1_file.base_file_name, line_no)
+
+ for pass_name, pass_lines, start_line_no, test_arch in split_stream(stream, fn_process_line,
+ fn_line_outside_chunk):
+ C1visualizerPass(c1_file, pass_name, pass_lines, start_line_no + 1)
+ return c1_file