Add tool to generate intrinsics conversion automatically
This commit is contained in:
parent
035ac03521
commit
af9149a1c6
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,3 +20,4 @@ res
|
||||
test-backend
|
||||
gcc_path
|
||||
benchmarks
|
||||
tools/llvm-project
|
||||
|
119
tools/generate_intrinsics.py
Normal file
119
tools/generate_intrinsics.py
Normal file
@ -0,0 +1,119 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
from os import walk
|
||||
|
||||
|
||||
LLVM_PATH = llvm_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"llvm-project",
|
||||
)
|
||||
|
||||
def run_command(command, cwd=None):
|
||||
p = subprocess.Popen(command, cwd=cwd)
|
||||
if p.wait() != 0:
|
||||
print("command `{}` failed...".format(" ".join(command)))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def clone_llvm_repository():
|
||||
if os.path.exists(LLVM_PATH):
|
||||
while True:
|
||||
choice = input("There is already a llvm-project folder, do you want to update it? [y/N]")
|
||||
if choice == "" or choice.lower() == "n":
|
||||
print("Skipping repository update.")
|
||||
return
|
||||
elif choice.lower() == "y":
|
||||
print("Updating repository...")
|
||||
run_command(["git", "pull", "origin"], cwd="llvm-project")
|
||||
return
|
||||
else:
|
||||
print("Didn't understand answer...")
|
||||
print("Cloning LLVM repository...")
|
||||
run_command(["git", "clone", "https://github.com/llvm/llvm-project", "--depth", "1", LLVM_PATH])
|
||||
|
||||
|
||||
def extract_instrinsics(intrinsics, file):
|
||||
print("Extracting intrinsics from `{}`...".format(file))
|
||||
with open(file, "r", encoding="utf8") as f:
|
||||
content = f.read()
|
||||
|
||||
lines = content.splitlines()
|
||||
pos = 0
|
||||
current_arch = None
|
||||
while pos < len(lines):
|
||||
line = lines[pos].strip()
|
||||
if line.startswith("let TargetPrefix ="):
|
||||
current_arch = line.split('"')[1].strip()
|
||||
if len(current_arch) == 0:
|
||||
current_arch = None
|
||||
elif current_arch is None:
|
||||
pass
|
||||
elif line == "}":
|
||||
current_arch = None
|
||||
elif line.startswith("def "):
|
||||
content = ""
|
||||
while not content.endswith(";") and pos < len(lines):
|
||||
line = lines[pos].split(" // ")[0].strip()
|
||||
content += line
|
||||
pos += 1
|
||||
entries = re.findall('GCCBuiltin<"(\\w+)">', content)
|
||||
if len(entries) > 0:
|
||||
intrinsic = content.split(":")[0].split(" ")[1].strip()
|
||||
intrinsic = intrinsic.split("_")
|
||||
if len(intrinsic) < 2 or intrinsic[0] != "int":
|
||||
continue
|
||||
intrinsic[0] = "llvm"
|
||||
intrinsic = ".".join(intrinsic)
|
||||
if current_arch not in intrinsics:
|
||||
intrinsics[current_arch] = []
|
||||
for entry in entries:
|
||||
intrinsics[current_arch].append('"{}" => "{}",'.format(intrinsic, entry))
|
||||
continue
|
||||
pos += 1
|
||||
continue
|
||||
print("Done!")
|
||||
|
||||
|
||||
def update_intrinsics():
|
||||
files = []
|
||||
intrinsics_path = os.path.join(LLVM_PATH, "llvm/include/llvm/IR")
|
||||
for (dirpath, dirnames, filenames) in walk(intrinsics_path):
|
||||
files.extend([os.path.join(intrinsics_path, f) for f in filenames if f.endswith(".td")])
|
||||
|
||||
intrinsics = {}
|
||||
for file in files:
|
||||
extract_instrinsics(intrinsics, file)
|
||||
|
||||
archs = [arch for arch in intrinsics]
|
||||
archs.sort()
|
||||
output_file = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"../src/intrinsic/archs.rs",
|
||||
)
|
||||
print("Updating content of `{}`...".format(output_file))
|
||||
with open(output_file, "w", encoding="utf8") as out:
|
||||
out.write("// File generated by `rustc_codegen_gcc/tools/generate_intrinsics.py`\n")
|
||||
out.write("// DO NOT EDIT IT!\n")
|
||||
out.write("match name {\n")
|
||||
for arch in archs:
|
||||
if len(intrinsics[arch]) == 0:
|
||||
continue
|
||||
intrinsics[arch].sort()
|
||||
out.write(' // {}\n'.format(arch))
|
||||
out.write('\n'.join([' {}'.format(x) for x in intrinsics[arch]]))
|
||||
out.write('\n')
|
||||
out.write(' _ => unimplemented!("***** unsupported LLVM intrinsic {}", name),\n')
|
||||
out.write("}\n")
|
||||
print("Done!")
|
||||
|
||||
|
||||
def main():
|
||||
# First, we clone the LLVM repository if it's not already here.
|
||||
clone_llvm_repository()
|
||||
update_intrinsics()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
Loading…
x
Reference in New Issue
Block a user