14
14
# limitations under the License.
15
15
"""ModuleSpec definition and utility command line parsing functions."""
16
16
17
+ from absl import logging
17
18
from dataclasses import dataclass
18
- from typing import Iterable , Optional , Tuple , List
19
+ from typing import List , Dict , Tuple , Any
19
20
21
+ import json
20
22
import os
21
- import tensorflow as tf
23
+
24
+ from compiler_opt .rl import constant
22
25
23
26
24
27
@dataclass (frozen = True )
@@ -34,77 +37,91 @@ def build_modulespecs_from_datapath(
34
37
additional_flags : Tuple [str , ...] = (),
35
38
delete_flags : Tuple [str , ...] = ()
36
39
) -> List [ModuleSpec ]:
37
- module_paths : List [str ] = _load_module_paths (data_path )
38
-
39
- has_thinlto : bool = _has_thinlto_index (module_paths )
40
+ # TODO: (b/233935329) Per-corpus *fdo profile paths can be read into
41
+ # {additional|delete}_flags here
42
+ with open (
43
+ os .path .join (data_path , 'corpus_description.json' ), 'r' ,
44
+ encoding = 'utf-8' ) as f :
45
+ corpus_description : Dict [str , Any ] = json .load (f )
46
+
47
+ module_paths = corpus_description ['modules' ]
48
+ if len (module_paths ) == 0 :
49
+ raise ValueError (f'{ data_path } \' s corpus_description contains no modules.' )
50
+
51
+ has_thinlto : bool = corpus_description ['has_thinlto' ]
52
+
53
+ cmd_override = ()
54
+ if 'global_command_override' in corpus_description :
55
+ if corpus_description [
56
+ 'global_command_override' ] == constant .UNSPECIFIED_OVERRIDE :
57
+ raise ValueError (
58
+ 'global_command_override in corpus_description.json not filled.' )
59
+ cmd_override = tuple (corpus_description ['global_command_override' ])
60
+ if len (additional_flags ) > 0 :
61
+ logging .warning ('Additional flags are specified together with override.' )
62
+ if len (delete_flags ) > 0 :
63
+ logging .warning ('Delete flags are specified together with override.' )
40
64
41
65
module_specs : List [ModuleSpec ] = []
42
66
43
67
# This takes ~7s for 30k modules
44
68
for module_path in module_paths :
45
69
exec_cmd = _load_and_parse_command (
46
- ir_file = module_path + '.bc' ,
47
- cmd_file = (module_path + '.cmd' ),
48
- thinlto_file = (module_path + '.thinlto.bc' ) if has_thinlto else None ,
70
+ module_path = os .path .join (data_path , module_path ),
71
+ has_thinlto = has_thinlto ,
49
72
additional_flags = additional_flags ,
50
- delete_flags = delete_flags )
73
+ delete_flags = delete_flags ,
74
+ cmd_override = cmd_override )
51
75
module_specs .append (ModuleSpec (name = module_path , exec_cmd = tuple (exec_cmd )))
52
76
53
77
return module_specs
54
78
55
79
56
- def _has_thinlto_index (module_paths : Iterable [str ]) -> bool :
57
- return tf .io .gfile .exists (next (iter (module_paths )) + '.thinlto.bc' )
58
-
59
-
60
- def _load_module_paths (data_path ) -> List [str ]:
61
- module_paths_path = os .path .join (data_path , 'module_paths' )
62
- with open (module_paths_path , 'r' , encoding = 'utf-8' ) as f :
63
- ret = [os .path .join (data_path , name .rstrip ('\n ' )) for name in f ]
64
- if len (ret ) == 0 :
65
- raise ValueError (f'{ module_paths_path } is empty.' )
66
- return ret
67
-
68
-
69
80
def _load_and_parse_command (
70
- ir_file : str ,
71
- cmd_file : str ,
72
- thinlto_file : Optional [str ] = None ,
81
+ module_path : str ,
82
+ has_thinlto : bool ,
73
83
additional_flags : Tuple [str , ...] = (),
74
- delete_flags : Tuple [str , ...] = ()
84
+ delete_flags : Tuple [str , ...] = (),
85
+ cmd_override : Tuple [str , ...] = ()
75
86
) -> List [str ]:
76
87
"""Cleans up base command line.
77
88
78
89
Remove certain unnecessary flags, and add the .bc file to compile and, if
79
90
given, the thinlto index.
80
91
81
92
Args:
82
- cmd_file: Path to a .cmd file (from corpus).
83
- ir_file: The path to the ir file to compile.
84
- thinlto_file: The path to the thinlto index, or None.
93
+ module_path: Absolute path to the module without extension (from corpus).
94
+ has_thinlto: Whether to add thinlto flags.
85
95
additional_flags: Tuple of clang flags to add.
86
96
delete_flags: Tuple of clang flags to remove.
97
+ cmd_override: Tuple of strings to use as the base command line.
87
98
88
99
Returns:
89
100
The argument list to pass to the compiler process.
90
101
"""
91
102
cmdline = []
92
103
93
- with open (cmd_file , encoding = 'utf-8' ) as f :
94
- option_iterator = iter (f .read ().split ('\0 ' ))
104
+ if cmd_override :
105
+ option_iterator = iter (cmd_override )
106
+ else :
107
+ with open (module_path + '.cmd' , encoding = 'utf-8' ) as f :
108
+ option_iterator = iter (f .read ().split ('\0 ' ))
109
+ option = next (option_iterator , None )
110
+
111
+ while option is not None :
112
+ if any (option .startswith (flag ) for flag in delete_flags ):
113
+ if '=' not in option :
114
+ next (option_iterator , None )
115
+ else :
116
+ cmdline .append (option )
95
117
option = next (option_iterator , None )
96
- while option is not None :
97
- if any (option .startswith (flag ) for flag in delete_flags ):
98
- if '=' not in option :
99
- next (option_iterator , None )
100
- else :
101
- cmdline .append (option )
102
- option = next (option_iterator , None )
103
- cmdline .extend (['-x' , 'ir' , ir_file ])
104
-
105
- if thinlto_file :
106
- cmdline .extend (
107
- [f'-fthinlto-index={ thinlto_file } ' , '-mllvm' , '-thinlto-assume-merged' ])
118
+ cmdline .extend (['-x' , 'ir' , module_path + '.bc' ])
119
+
120
+ if has_thinlto :
121
+ cmdline .extend ([
122
+ f'-fthinlto-index={ module_path } .thinlto.bc' , '-mllvm' ,
123
+ '-thinlto-assume-merged'
124
+ ])
108
125
109
126
cmdline .extend (additional_flags )
110
127
0 commit comments