1818from cython .cimports .tadashi .codegen import codegen
1919from cython .cimports .tadashi .scop import Scop
2020
21+ from .passesparser import PassParser
22+
2123ABC_ERROR_MSG = "Translator is an abstract base class, use a derived class."
2224DOUBLE_SET_SOURCE = "Translator.set_source() should only be called once."
2325
@@ -219,9 +221,16 @@ class Polly(Translator):
219221 compiler : str
220222 json_paths : list [Path ]
221223 cwd : Path
224+ before_polly_passes : str
225+ after_polly_passes : str
222226
223227 def __init__ (self , compiler : str = "clang" ):
224228 self .compiler = str (compiler )
229+ pp = PassParser ()
230+ locs = pp .find ("loop-rotate" )
231+ before , after = pp .split (locs [1 ])
232+ self .before_polly_passes = pp .reassemble (before )
233+ self .after_polly_passes = pp .reassemble (after )
225234
226235 def _run (self , cmd : list [str ], description : str , cwd : str = None ):
227236 """cmd is command list, description is verb-ing, cwd defailts to self.cwd"""
@@ -259,43 +268,35 @@ def populate_ccscops(self, options: list[str]):
259268 raise MemoryError ()
260269 timestamp = datetime .datetime .now ().strftime ("%Y%m%d-%H%M%S" )
261270 self .cwd = Path (tempfile .mkdtemp (prefix = f"tadashi-{ timestamp } -" ))
262- self ._get_preopt_bitcode (options )
271+ self ._get_pre_polly_bc (options )
263272 stderr = self ._export_jscops (options )
264273 self .json_paths = self ._fill_json_paths (stderr )
265274 for file in self .json_paths :
266275 with open (self .cwd / file ) as fp :
267276 jscop = json .load (fp )
268277 self ._proc_jscop (jscop )
269278
270- def _get_preopt_bitcode (self , options : list [str ]) -> Path :
271- output = self .cwd / self .source .with_suffix (".O1.bc" ).name
272- if output .exists ():
273- return output
279+ def _get_pre_polly_bc (self , options : list [str ]) -> Path :
280+ compile_O0_bc = self .cwd / self .source .with_suffix (".pre_polly.bc" ).name
281+ pre_polly_bc = self .cwd / self .source .with_suffix (".pre_polly.bc" ).name
282+ if pre_polly_bc .exists ():
283+ return pre_polly_bc
274284
275285 compiler_opts = {
276- "clang" : [
277- "-O0" ,
278- "-Xclang" ,
279- "-disable-O0-optnone" ,
280- ],
281- "flang" : ["-O1" ],
286+ "clang" : ["-O0" , "-Xclang" , "-disable-O0-optnone" ],
287+ "flang" : ["-O0" ],
282288 }
283- cmd = [
284- self .compiler ,
285- * options ,
286- "-c" ,
287- "-emit-llvm" ,
288- str (self .source ),
289- * compiler_opts [self .compiler [:5 ]],
290- "-o" ,
291- str (output ),
292- ]
293- self ._run (cmd , "parsing" )
294- return output
289+ compile_cmd = [self .compiler , * options , "-c" , "-emit-llvm" , str (self .source )]
290+ compile_cmd += [* compiler_opts [self .compiler [:5 ]], "-o" , str (compile_O0_bc )]
291+ self ._run (compile_cmd , "compiling with O0" )
292+ opt_cmd = ["opt" , f"-passes={ self .before_polly_passes } " ]
293+ opt_cmd += [str (compile_O0_bc ), f"-o={ str (pre_polly_bc )} " ]
294+ self ._run (opt_cmd , "running pre polly opt passes" )
295+ return pre_polly_bc
295296
296297 def _export_jscops (self , options : list [str ]) -> str :
297298 cmd = self ._polly () + [
298- str (self ._get_preopt_bitcode (options )),
299+ str (self ._get_pre_polly_bc (options )),
299300 "-polly-export-jscop" ,
300301 "-o=/dev/null" ,
301302 ]
@@ -351,22 +352,28 @@ def _proc_jscop(self, jscop):
351352 self .ccscops .emplace_back (domain , sched , read , write )
352353
353354 def legal (self ) -> bool :
354- input_path = str (self ._get_preopt_bitcode ([]))
355+ input_path = str (self ._get_pre_polly_bc ([]))
355356 cmd = self ._polly () + [input_path , "-polly-import-jscop" , "-o=/dev/null" ]
356357 proc = self ._run (cmd , "checking legality" )
357358 return proc .returncode == 0
358359
359360 def _import_jscops (self , options : list [str ]) -> Path :
360- input_path = str (self ._get_preopt_bitcode (options ))
361- output = self .cwd / self .source .with_suffix (".bc" ).name
362- cmd = self . _polly () + [
363- input_path ,
364- "-polly-import-jscop" ,
361+ input_path = str (self ._get_pre_polly_bc (options ))
362+ post_polly_bc = self .cwd / self .source .with_suffix (".post_opt .bc" ).name
363+
364+ polly_cmd = self . _polly () + [ input_path , "-polly-import-jscop" ]
365+ polly_cmd += [
365366 "-polly-codegen" ,
366- f"-o={ str (output )} " ,
367+ f"-o={ str (post_polly_bc )} " ,
367368 "-disable-polly-legality" ,
368369 ]
369- self ._run (cmd , "imnporting jscops" )
370+ self ._run (polly_cmd , "importing jscops" )
371+
372+ output = self .cwd / self .source .with_suffix (".bc" ).name
373+
374+ opt_cmd = ["opt" , f"-passes={ self .after_polly_passes } " ]
375+ opt_cmd += [str (post_polly_bc ), f"-o={ str (output )} " ]
376+ opt_proc = self ._run (opt_cmd , "running opt after jscops import" )
370377 return output
371378
372379 @cython .ccall
@@ -375,39 +382,33 @@ def generate_code(
375382 ) -> Path :
376383 for scop_idx , jscop_path in enumerate (self .json_paths ):
377384 jscop_path = self .cwd / jscop_path
378- ccscop = self .ccscops [scop_idx ]
379- sched = isl .isl_schedule_node_get_schedule (ccscop .current_node )
380- umap = isl .isl_schedule_get_map (sched )
381- isl .isl_schedule_free (sched )
382- sched_str = isl .isl_union_map_to_str (umap ).decode ()
383385 backup_path = jscop_path .with_suffix (jscop_path .suffix + ".bak" )
384386 shutil .copy2 (jscop_path , backup_path )
385- with jscop_path .open ("r" , encoding = "utf-8" ) as f :
386- jscop = json .load (f )
387- for stmt in jscop ["statements" ]:
388- name = stmt ["name" ]
389- uset = isl .isl_union_set_read_from_str (
390- self .ctx , stmt ["domain" ].encode ()
391- )
392- stmt_map = isl .isl_union_map_intersect_domain_union_set (
393- isl .isl_union_map_copy (umap ), uset
394- )
395- stmt ["schedule" ] = isl .isl_union_map_to_str (stmt_map ).decode ()
396- isl .isl_union_map_free (stmt_map )
397- isl .isl_union_map_free (umap )
398- with jscop_path .open ("w" , encoding = "utf-8" ) as f :
399- json .dump (jscop , f , indent = 2 )
400- output_path = Path (output_path ).with_suffix (".s" )
401- self ._generate_assembly (output_path , options )
402- return output_path
387+ self ._update_jscop (jscop_path , scop_idx )
388+ return self ._compile_to_obj (output_path , options )
403389
404- def _generate_assembly (self , output : Path , options : list [str ]):
390+ @cython .cfunc
391+ def _update_jscop (self , jscop_path : Path , scop_idx : int ):
392+ ccscop = self .ccscops [scop_idx ]
393+ sched = isl .isl_schedule_node_get_schedule (ccscop .current_node )
394+ isl .isl_schedule_free (sched )
395+ umap = isl .isl_schedule_get_map (sched )
396+ with jscop_path .open ("r" , encoding = "utf-8" ) as f :
397+ jscop = json .load (f )
398+ for stmt in jscop ["statements" ]:
399+ uset = isl .isl_union_set_read_from_str (self .ctx , stmt ["domain" ].encode ())
400+ tmp = isl .isl_union_map_copy (umap )
401+ stmt_map = isl .isl_union_map_intersect_domain_union_set (tmp , uset )
402+ stmt ["schedule" ] = isl .isl_union_map_to_str (stmt_map ).decode ()
403+ isl .isl_union_map_free (stmt_map )
404+ with jscop_path .open ("w" , encoding = "utf-8" ) as f :
405+ json .dump (jscop , f , indent = 2 )
406+ isl .isl_union_map_free (umap )
407+
408+ def _compile_to_obj (self , output : Path , options : list [str ]):
409+ output_path = Path (output ).with_suffix (".o" )
405410 input_path = str (self ._import_jscops (options ))
406- cmd = [
407- "llc" ,
408- "-relocation-model=pic" ,
409- # *options,
410- input_path ,
411- f"-o={ str (output )} " ,
412- ]
411+ cmd = ["llc" , "-relocation-model=pic" , "--filetype=obj" ]
412+ cmd += [input_path , f"-o={ str (output_path )} " ]
413413 self ._run (cmd , "generating assembly" )
414+ return output_path
0 commit comments