Skip to content

Commit

Permalink
implement riscv_isa_info backend
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippvK committed Feb 16, 2024
1 parent 987ad8b commit ff225f1
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 3 deletions.
Empty file.
152 changes: 152 additions & 0 deletions seal5/backends/riscv_isa_info/writer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# SPDX-License-Identifier: Apache-2.0
#
# This file is part of the M2-ISA-R project: https://github.com/tum-ei-eda/M2-ISA-R
#
# Copyright (C) 2022
# Chair of Electrical Design Automation
# Technical University of Munich

"""Clean M2-ISA-R/Seal5 metamodel to .core_desc file."""

import argparse
import logging
import pathlib
import pickle
from typing import Union

from mako.template import Template

from m2isar.metamodel import arch

from seal5.index import NamedPatch, write_index_yaml
from seal5.settings import ExtensionsSettings

logger = logging.getLogger("riscv_isa_info")


MAKO_TEMPLATE = " {\"${arch}\", RISCVExtensionVersion{${version_major}, ${version_minor}}},"


def gen_riscv_isa_info_str(name: str, ext_settings: ExtensionsSettings):
print("name", name)
print("ext_settings", ext_settings)
arch = ext_settings.get_arch(name=name)
version = ext_settings.get_version()
assert isinstance(version, float)
version_major, version_minor = str(version).split(".", 1)

content_template = Template(MAKO_TEMPLATE)
content_text = content_template.render(arch=arch, version_major=version_major, version_minor=version_minor)
# content_text = content_text.rstrip("\n")
return content_text


def main():
"""Main app entrypoint."""

# read command line args
parser = argparse.ArgumentParser()
parser.add_argument("top_level", help="A .m2isarmodel or .seal5model file.")
parser.add_argument("--log", default="info", choices=["critical", "error", "warning", "info", "debug"])
parser.add_argument("--output", "-o", type=str, default=None)
parser.add_argument("--splitted", action="store_true", help="Split per set")
parser.add_argument("--formats", action="store_true", help="Also generate instruction formats")
parser.add_argument("--metrics", default=None, help="Output metrics to file")
parser.add_argument("--index", default=None, help="Output index to file")
parser.add_argument("--ext", type=str, default="td", help="Default file extension (if using --splitted)")
args = parser.parse_args()

# initialize logging
logging.basicConfig(level=getattr(logging, args.log.upper()))

# resolve model paths
top_level = pathlib.Path(args.top_level)
# abs_top_level = top_level.resolve()

is_seal5_model = False
# print("top_level", top_level)
# print("suffix", top_level.suffix)
if top_level.suffix == ".seal5model":
is_seal5_model = True
if args.output is None:
assert top_level.suffix in [".m2isarmodel", ".seal5model"], "Can not infer model type from file extension."
raise NotImplementedError

# out_path = top_level.parent / (top_level.stem + ".core_desc")
else:
out_path = pathlib.Path(args.output)

logger.info("loading models")
if not is_seal5_model:
raise NotImplementedError

# load models
with open(top_level, "rb") as f:
# models: "dict[str, arch.CoreDef]" = pickle.load(f)
if is_seal5_model:
model: "dict[str, Union[arch.InstructionSet, ...]]" = pickle.load(f)
model["cores"] = {}
else: # TODO: core vs. set!
temp: "dict[str, Union[arch.InstructionSet, arch.CoreDef]]" = pickle.load(f)
assert len(temp) > 0, "Empty model!"
if isinstance(list(temp.values())[0], arch.CoreDef):
model = {"cores": temp, "sets": {}}
elif isinstance(list(temp.values())[0], arch.InstructionSet):
model = {"sets": temp, "cores": {}}
else:
assert False

metrics = {
"n_sets": 0,
"n_skipped": 0,
"n_failed": 0,
"n_success": 0,
}
# preprocess model
# print("model", model)
artifacts = {}
artifacts[None] = [] # used for global artifacts
if args.splitted:
raise NotImplementedError
else:
content = ""
# errs = []
for set_name, set_def in model["sets"].items():
artifacts[set_name] = []
metrics["n_sets"] += 1
ext_settings = set_def.settings
if ext_settings is None:
metrics["n_skipped"] += 1
continue
metrics["n_success"] += 1
content += gen_riscv_isa_info_str(set_name, ext_settings)
if len(content) > 0:
with open(out_path, "w") as f:
f.write(content)
if ext_settings.experimental:
key = "riscv_isa_info_experimental"
else:
key = "riscv_isa_info"
riscv_isa_info_patch = NamedPatch(
"llvm/lib/Support/RISCVISAInfo.cpp", key=key, src_path=out_path
)
artifacts[None].append(riscv_isa_info_patch)
if args.metrics:
metrics_file = args.metrics
with open(metrics_file, "w") as f:
f.write(",".join(metrics.keys()))
f.write("\n")
f.write(",".join(map(str, metrics.values())))
f.write("\n")
if args.index:
if sum(map(lambda x: len(x), artifacts.values())) > 0:
global_artifacts = artifacts.get(None, [])
set_artifacts = {key: value for key, value in artifacts.items() if key is not None}
index_file = args.index
write_index_yaml(index_file, global_artifacts, set_artifacts, content=True)
else:
logger.warning("No patches generated. No index file will be written.")


if __name__ == "__main__":
main()
58 changes: 57 additions & 1 deletion seal5/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,7 @@ def gen_riscv_features_patch(self, verbose: bool = False, split: bool = False):
)
if gen_index_file:
if index_file.is_file():
patch_name = f"tblgen_riscv_features_{input_file.stem}"
patch_name = f"riscv_features_{input_file.stem}"
patch_settings = PatchSettings(
name=patch_name,
stage=int(PatchStage.PHASE_1),
Expand All @@ -1027,6 +1027,60 @@ def gen_riscv_features_patch(self, verbose: bool = False, split: bool = False):
else:
logger.warning("No patches found!")

def gen_riscv_isa_info_patch(self, verbose: bool = False, split: bool = False):
assert not split, "TODO"
input_files = list(self.models_dir.glob("*.seal5model"))
assert len(input_files) > 0, "No Seal5 models found!"
formats = True
gen_metrics_file = True
gen_index_file = True
for input_file in input_files:
name = input_file.name
new_name = name.replace(".seal5model", "")
logger.info("Writing RISCVISAInfo.cpp patch for %s", name)
out_dir = self.patches_dir / new_name
out_dir.mkdir(exist_ok=True)

args = [
self.models_dir / name,
"--log",
# "info",
"debug",
"--output",
out_dir / "riscv_isa_info.patch",
]
if split:
args.append("--splitted")
if gen_metrics_file:
metrics_file = out_dir / ("riscv_isa_info_metrics.csv")
args.extend(["--metrics", metrics_file])
if gen_index_file:
index_file = out_dir / ("riscv_isa_info_index.yml")
args.extend(["--index", index_file])
utils.python(
"-m",
"seal5.backends.riscv_isa_info.writer",
*args,
env=self.prepare_environment(),
print_func=logger.info if verbose else logger.debug,
live=True,
)
if gen_index_file:
if index_file.is_file():
patch_name = f"riscv_isa_info_{input_file.stem}"
patch_settings = PatchSettings(
name=patch_name,
stage=int(PatchStage.PHASE_1),
comment=f"Generated RISCVISAInfo.cpp patch for {input_file.name}",
index=str(index_file),
generated=True,
target="llvm",
)
self.settings.patches.append(patch_settings)
self.settings.to_yaml_file(self.settings_file)
else:
logger.warning("No patches found!")

# def convert_behav_to_tablegen_splitted(self, verbose: bool = False, inplace: bool = True):
# assert inplace
# # input_files = list(self.models_dir.glob("*.seal5model"))
Expand Down Expand Up @@ -1212,6 +1266,8 @@ def generate(self, verbose: bool = False):
# # General
if "riscv_features" not in skip:
self.gen_riscv_features_patch()
if "riscv_isa_infos" not in skip:
self.gen_riscv_isa_infos_patch()
# if "subtarget_tests" not in skip:
# patches.extend(self.gen_subtarget_tests_patches())

Expand Down
14 changes: 12 additions & 2 deletions seal5/resources/patches/llvm/insert_markers_llvm17.patch
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,22 @@ diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.c
{"xtheadvdot", RISCVExtensionVersion{1, 0}},
{"xventanacondops", RISCVExtensionVersion{1, 0}},

+// RISCVISAInfo.cpp - INSERTION_START
+// RISCVISAInfo.cpp - INSERTION_END
+// RISCVISAInfo.cpp - riscv_isa_info - INSERTION_START
+// RISCVISAInfo.cpp - riscv_isa_info - INSERTION_END
+
{"zawrs", RISCVExtensionVersion{1, 0}},

{"zba", RISCVExtensionVersion{1, 0}},
@@ -162,6 +162,9 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
{"smaia", RISCVExtensionVersion{1, 0}},
{"ssaia", RISCVExtensionVersion{1, 0}},

+// RISCVISAInfo.cpp - riscv_isa_info_experimental - INSERTION_START
+// RISCVISAInfo.cpp - riscv_isa_info_experimental - INSERTION_END
+
{"zacas", RISCVExtensionVersion{1, 0}},

{"zfa", RISCVExtensionVersion{0, 2}},
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Expand Down

0 comments on commit ff225f1

Please sign in to comment.