@@ -12,7 +12,7 @@ def run_command(command, cwd=None):
1212 sys .exit (1 )
1313
1414
15- def clone_repository (repo_name , path , repo_url , branch = "master" , sub_paths = None ):
15+ def clone_repository (repo_name , path , repo_url , sub_paths ):
1616 if os .path .exists (path ):
1717 while True :
1818 choice = input ("There is already a `{}` folder, do you want to update it? [y/N]" .format (path ))
@@ -21,18 +21,15 @@ def clone_repository(repo_name, path, repo_url, branch="master", sub_paths=None)
2121 return
2222 elif choice .lower () == "y" :
2323 print ("Updating repository..." )
24- run_command (["git" , "pull" , "origin" , branch ], cwd = path )
24+ run_command (["git" , "pull" , "origin" , "main" ], cwd = path )
2525 return
2626 else :
2727 print ("Didn't understand answer..." )
2828 print ("Cloning {} repository..." .format (repo_name ))
29- if sub_paths is None :
30- run_command (["git" , "clone" , repo_url , "--depth" , "1" , path ])
31- else :
32- run_command (["git" , "clone" , repo_url , "--filter=tree:0" , "--no-checkout" , path ])
33- run_command (["git" , "sparse-checkout" , "init" ], cwd = path )
34- run_command (["git" , "sparse-checkout" , "set" , * sub_paths ], cwd = path )
35- run_command (["git" , "checkout" ], cwd = path )
29+ run_command (["git" , "clone" , repo_url , "--filter=tree:0" , "--no-checkout" , path ])
30+ run_command (["git" , "sparse-checkout" , "init" ], cwd = path )
31+ run_command (["git" , "sparse-checkout" , "set" , * sub_paths ], cwd = path )
32+ run_command (["git" , "checkout" ], cwd = path )
3633
3734
3835def append_intrinsic (array , intrinsic_name , translation ):
@@ -45,119 +42,36 @@ def convert_to_string(content):
4542 return content
4643
4744
48- def extract_intrinsics_from_llvm (llvm_path , intrinsics ):
49- command = ["llvm-tblgen" , "llvm/IR/Intrinsics.td" ]
45+ def extract_intrinsics_from_llvm (llvm_path ):
46+ intrinsics = {}
47+ command = ["llvm-tblgen" , "llvm/IR/Intrinsics.td" , "--dump-json" ]
5048 cwd = os .path .join (llvm_path , "llvm/include" )
5149 print ("=> Running command `{}` from `{}`" .format (command , cwd ))
5250 p = subprocess .Popen (command , cwd = cwd , stdout = subprocess .PIPE )
5351 output , err = p .communicate ()
54- lines = convert_to_string (output ).splitlines ()
55- pos = 0
56- while pos < len (lines ):
57- line = lines [pos ]
58- if not line .startswith ("def " ):
59- pos += 1
52+ content = json .loads (convert_to_string (output ))
53+ for intrinsic in content :
54+ data = content [intrinsic ]
55+ if not isinstance (data , dict ):
6056 continue
61- intrinsic = line .split (" " )[1 ].strip ()
62- content = line
63- while pos < len (lines ):
64- line = lines [pos ].split (" // " )[0 ].strip ()
65- content += line
66- pos += 1
67- if line == "}" :
68- break
69- entries = re .findall ('string ClangBuiltinName = "(\\ w+)";' , content )
70- current_arch = re .findall ('string TargetPrefix = "(\\ w+)";' , content )
71- if len (entries ) == 1 and len (current_arch ) == 1 :
72- current_arch = current_arch [0 ]
73- intrinsic = intrinsic .split ("_" )
74- if len (intrinsic ) < 2 or intrinsic [0 ] != "int" :
75- continue
76- intrinsic [0 ] = "llvm"
77- intrinsic = "." .join (intrinsic )
78- if current_arch not in intrinsics :
79- intrinsics [current_arch ] = []
80- append_intrinsic (intrinsics [current_arch ], intrinsic , entries [0 ])
81-
82-
83- def append_translation (json_data , p , array ):
84- it = json_data ["index" ][p ]
85- content = it ["docs" ].split ('`' )
86- if len (content ) != 5 :
87- return
88- append_intrinsic (array , content [1 ], content [3 ])
89-
90-
91- def extract_intrinsics_from_llvmint (llvmint , intrinsics ):
92- archs = [
93- "AMDGPU" ,
94- "aarch64" ,
95- "arm" ,
96- "cuda" ,
97- "hexagon" ,
98- "mips" ,
99- "nvvm" ,
100- "ppc" ,
101- "ptx" ,
102- "x86" ,
103- "xcore" ,
104- ]
105-
106- json_file = os .path .join (llvmint , "target/doc/llvmint.json" )
107- # We need to regenerate the documentation!
108- run_command (
109- ["cargo" , "rustdoc" , "--" , "-Zunstable-options" , "--output-format" , "json" ],
110- cwd = llvmint ,
111- )
112- with open (json_file , "r" , encoding = "utf8" ) as f :
113- json_data = json .loads (f .read ())
114- for p in json_data ["paths" ]:
115- it = json_data ["paths" ][p ]
116- if it ["crate_id" ] != 0 :
117- # This is from an external crate.
57+ current_arch = data .get ("TargetPrefix" )
58+ builtin_name = data .get ("ClangBuiltinName" )
59+ if current_arch is None or current_arch == "" or builtin_name is None :
11860 continue
119- if it [ "kind" ] != "function" :
120- # We're only looking for functions.
61+ intrinsic = intrinsic . split ( "_" )
62+ if len ( intrinsic ) < 2 or intrinsic [ 0 ] != "int" :
12163 continue
122- # if len(it["path"]) == 2:
123- # # This is a "general" intrinsic, not bound to a specific arch.
124- # append_translation(json_data, p, general)
125- # continue
126- if len (it ["path" ]) != 3 or it ["path" ][1 ] not in archs :
127- continue
128- arch = it ["path" ][1 ]
129- if arch not in intrinsics :
130- intrinsics [arch ] = []
131- append_translation (json_data , p , intrinsics [arch ])
132-
133-
134- def fill_intrinsics (intrinsics , from_intrinsics , all_intrinsics ):
135- for arch in from_intrinsics :
136- if arch not in intrinsics :
137- intrinsics [arch ] = []
138- for entry in from_intrinsics [arch ]:
139- if entry [0 ] in all_intrinsics :
140- if all_intrinsics [entry [0 ]] == entry [1 ]:
141- # This is a "full" duplicate, both the LLVM instruction and the GCC
142- # translation are the same.
143- continue
144- intrinsics [arch ].append ((entry [0 ], entry [1 ], True ))
145- else :
146- intrinsics [arch ].append ((entry [0 ], entry [1 ], False ))
147- all_intrinsics [entry [0 ]] = entry [1 ]
64+ intrinsic [0 ] = "llvm"
65+ intrinsic = "." .join (intrinsic )
66+ if current_arch not in intrinsics :
67+ intrinsics [current_arch ] = []
68+ append_intrinsic (intrinsics [current_arch ], intrinsic , builtin_name )
14869
70+ return intrinsics
14971
150- def update_intrinsics (llvm_path ):
151- intrinsics_llvm = {}
152- intrinsics_llvmint = {}
153- all_intrinsics = {}
154-
155- extract_intrinsics_from_llvm (llvm_path , intrinsics_llvm )
15672
157- intrinsics = {}
158- # We give priority to translations from LLVM over the ones from llvmint.
159- fill_intrinsics (intrinsics , intrinsics_llvm , all_intrinsics )
160- fill_intrinsics (intrinsics , intrinsics_llvmint , all_intrinsics )
73+ def update_intrinsics (llvm_path ):
74+ intrinsics = extract_intrinsics_from_llvm (llvm_path )
16175
16276 archs = [arch for arch in intrinsics ]
16377 archs .sort ()
@@ -187,15 +101,13 @@ def update_intrinsics(llvm_path):
187101 continue
188102 attribute = "#[expect(non_snake_case)]" if arch [0 ].isupper () else ""
189103 out .write ("\" {}\" => {{ {} fn {}(name: &str,full_name:&str) -> &'static str {{ match name {{" .format (arch , attribute , arch ))
190- intrinsics [arch ].sort (key = lambda x : (x [0 ], x [2 ]))
104+ intrinsics [arch ].sort (key = lambda x : (x [0 ], x [1 ]))
191105 out .write (' // {}\n ' .format (arch ))
192106 for entry in intrinsics [arch ]:
193107 llvm_name = entry [0 ].removeprefix ("llvm." );
194108 llvm_name = llvm_name .removeprefix (arch );
195109 llvm_name = llvm_name .removeprefix ("." );
196- if entry [2 ] is True : # if it is a duplicate
197- out .write (' // [DUPLICATE]: "{}" => "{}",\n ' .format (llvm_name , entry [1 ]))
198- elif "_round_mask" in entry [1 ]:
110+ if "_round_mask" in entry [1 ]:
199111 out .write (' // [INVALID CONVERSION]: "{}" => "{}",\n ' .format (llvm_name , entry [1 ]))
200112 else :
201113 out .write (' "{}" => "{}",\n ' .format (llvm_name , entry [1 ]))
@@ -224,11 +136,15 @@ def main():
224136 "llvm-project" ,
225137 llvm_path ,
226138 "https://github.com/llvm/llvm-project" ,
227- branch = "main" ,
228- sub_paths = ["llvm/include/llvm/IR" , "llvm/include/llvm/CodeGen/" ],
139+ ["llvm/include/llvm/IR" , "llvm/include/llvm/CodeGen/" ],
229140 )
230141 update_intrinsics (llvm_path )
231142
143+ # llvm-tblgen can be built with:
144+ #
145+ # mkdir llvm-tblgen-build && cd llvm-tblgen-build
146+ # cmake -G Ninja -DLLVM_ENABLE_PROJECTS="llvm" -DCMAKE_BUILD_TYPE=Release ../llvm
147+ # ninja llvm-tblgen
232148
233149if __name__ == "__main__" :
234150 sys .exit (main ())
0 commit comments