diff options
Diffstat (limited to 'tools/checker/file_format/c1visualizer/parser.py')
-rw-r--r-- | tools/checker/file_format/c1visualizer/parser.py | 105 |
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 |