machine-dialect 0.1.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. machine_dialect/__main__.py +667 -0
  2. machine_dialect/agent/__init__.py +5 -0
  3. machine_dialect/agent/agent.py +360 -0
  4. machine_dialect/ast/__init__.py +95 -0
  5. machine_dialect/ast/ast_node.py +35 -0
  6. machine_dialect/ast/call_expression.py +82 -0
  7. machine_dialect/ast/dict_extraction.py +60 -0
  8. machine_dialect/ast/expressions.py +439 -0
  9. machine_dialect/ast/literals.py +309 -0
  10. machine_dialect/ast/program.py +35 -0
  11. machine_dialect/ast/statements.py +1433 -0
  12. machine_dialect/ast/tests/test_ast_string_representation.py +62 -0
  13. machine_dialect/ast/tests/test_boolean_literal.py +29 -0
  14. machine_dialect/ast/tests/test_collection_hir.py +138 -0
  15. machine_dialect/ast/tests/test_define_statement.py +142 -0
  16. machine_dialect/ast/tests/test_desugar.py +541 -0
  17. machine_dialect/ast/tests/test_foreach_desugar.py +245 -0
  18. machine_dialect/cfg/__init__.py +6 -0
  19. machine_dialect/cfg/config.py +156 -0
  20. machine_dialect/cfg/examples.py +221 -0
  21. machine_dialect/cfg/generate_with_ai.py +187 -0
  22. machine_dialect/cfg/openai_generation.py +200 -0
  23. machine_dialect/cfg/parser.py +94 -0
  24. machine_dialect/cfg/tests/__init__.py +1 -0
  25. machine_dialect/cfg/tests/test_cfg_parser.py +252 -0
  26. machine_dialect/cfg/tests/test_config.py +188 -0
  27. machine_dialect/cfg/tests/test_examples.py +391 -0
  28. machine_dialect/cfg/tests/test_generate_with_ai.py +354 -0
  29. machine_dialect/cfg/tests/test_openai_generation.py +256 -0
  30. machine_dialect/codegen/__init__.py +5 -0
  31. machine_dialect/codegen/bytecode_module.py +89 -0
  32. machine_dialect/codegen/bytecode_serializer.py +300 -0
  33. machine_dialect/codegen/opcodes.py +101 -0
  34. machine_dialect/codegen/register_codegen.py +1996 -0
  35. machine_dialect/codegen/symtab.py +208 -0
  36. machine_dialect/codegen/tests/__init__.py +1 -0
  37. machine_dialect/codegen/tests/test_array_operations_codegen.py +295 -0
  38. machine_dialect/codegen/tests/test_bytecode_serializer.py +185 -0
  39. machine_dialect/codegen/tests/test_register_codegen_ssa.py +324 -0
  40. machine_dialect/codegen/tests/test_symtab.py +418 -0
  41. machine_dialect/codegen/vm_serializer.py +621 -0
  42. machine_dialect/compiler/__init__.py +18 -0
  43. machine_dialect/compiler/compiler.py +197 -0
  44. machine_dialect/compiler/config.py +149 -0
  45. machine_dialect/compiler/context.py +149 -0
  46. machine_dialect/compiler/phases/__init__.py +19 -0
  47. machine_dialect/compiler/phases/bytecode_optimization.py +90 -0
  48. machine_dialect/compiler/phases/codegen.py +40 -0
  49. machine_dialect/compiler/phases/hir_generation.py +39 -0
  50. machine_dialect/compiler/phases/mir_generation.py +86 -0
  51. machine_dialect/compiler/phases/optimization.py +110 -0
  52. machine_dialect/compiler/phases/parsing.py +39 -0
  53. machine_dialect/compiler/pipeline.py +143 -0
  54. machine_dialect/compiler/tests/__init__.py +1 -0
  55. machine_dialect/compiler/tests/test_compiler.py +568 -0
  56. machine_dialect/compiler/vm_runner.py +173 -0
  57. machine_dialect/errors/__init__.py +32 -0
  58. machine_dialect/errors/exceptions.py +369 -0
  59. machine_dialect/errors/messages.py +82 -0
  60. machine_dialect/errors/tests/__init__.py +0 -0
  61. machine_dialect/errors/tests/test_expected_token_errors.py +188 -0
  62. machine_dialect/errors/tests/test_name_errors.py +118 -0
  63. machine_dialect/helpers/__init__.py +0 -0
  64. machine_dialect/helpers/stopwords.py +225 -0
  65. machine_dialect/helpers/validators.py +30 -0
  66. machine_dialect/lexer/__init__.py +9 -0
  67. machine_dialect/lexer/constants.py +23 -0
  68. machine_dialect/lexer/lexer.py +907 -0
  69. machine_dialect/lexer/tests/__init__.py +0 -0
  70. machine_dialect/lexer/tests/helpers.py +86 -0
  71. machine_dialect/lexer/tests/test_apostrophe_identifiers.py +122 -0
  72. machine_dialect/lexer/tests/test_backtick_identifiers.py +140 -0
  73. machine_dialect/lexer/tests/test_boolean_literals.py +108 -0
  74. machine_dialect/lexer/tests/test_case_insensitive_keywords.py +188 -0
  75. machine_dialect/lexer/tests/test_comments.py +200 -0
  76. machine_dialect/lexer/tests/test_double_asterisk_keywords.py +127 -0
  77. machine_dialect/lexer/tests/test_lexer_position.py +113 -0
  78. machine_dialect/lexer/tests/test_list_tokens.py +282 -0
  79. machine_dialect/lexer/tests/test_stopwords.py +80 -0
  80. machine_dialect/lexer/tests/test_strict_equality.py +129 -0
  81. machine_dialect/lexer/tests/test_token.py +41 -0
  82. machine_dialect/lexer/tests/test_tokenization.py +294 -0
  83. machine_dialect/lexer/tests/test_underscore_literals.py +343 -0
  84. machine_dialect/lexer/tests/test_url_literals.py +169 -0
  85. machine_dialect/lexer/tokens.py +487 -0
  86. machine_dialect/linter/__init__.py +10 -0
  87. machine_dialect/linter/__main__.py +144 -0
  88. machine_dialect/linter/linter.py +154 -0
  89. machine_dialect/linter/rules/__init__.py +8 -0
  90. machine_dialect/linter/rules/base.py +112 -0
  91. machine_dialect/linter/rules/statement_termination.py +99 -0
  92. machine_dialect/linter/tests/__init__.py +1 -0
  93. machine_dialect/linter/tests/mdrules/__init__.py +0 -0
  94. machine_dialect/linter/tests/mdrules/test_md101_statement_termination.py +181 -0
  95. machine_dialect/linter/tests/test_linter.py +81 -0
  96. machine_dialect/linter/tests/test_rules.py +110 -0
  97. machine_dialect/linter/tests/test_violations.py +71 -0
  98. machine_dialect/linter/violations.py +51 -0
  99. machine_dialect/mir/__init__.py +69 -0
  100. machine_dialect/mir/analyses/__init__.py +20 -0
  101. machine_dialect/mir/analyses/alias_analysis.py +315 -0
  102. machine_dialect/mir/analyses/dominance_analysis.py +49 -0
  103. machine_dialect/mir/analyses/escape_analysis.py +286 -0
  104. machine_dialect/mir/analyses/loop_analysis.py +272 -0
  105. machine_dialect/mir/analyses/tests/test_type_analysis.py +736 -0
  106. machine_dialect/mir/analyses/type_analysis.py +448 -0
  107. machine_dialect/mir/analyses/use_def_chains.py +232 -0
  108. machine_dialect/mir/basic_block.py +385 -0
  109. machine_dialect/mir/dataflow.py +445 -0
  110. machine_dialect/mir/debug_info.py +208 -0
  111. machine_dialect/mir/hir_to_mir.py +1738 -0
  112. machine_dialect/mir/mir_dumper.py +366 -0
  113. machine_dialect/mir/mir_function.py +167 -0
  114. machine_dialect/mir/mir_instructions.py +1877 -0
  115. machine_dialect/mir/mir_interpreter.py +556 -0
  116. machine_dialect/mir/mir_module.py +225 -0
  117. machine_dialect/mir/mir_printer.py +480 -0
  118. machine_dialect/mir/mir_transformer.py +410 -0
  119. machine_dialect/mir/mir_types.py +367 -0
  120. machine_dialect/mir/mir_validation.py +455 -0
  121. machine_dialect/mir/mir_values.py +268 -0
  122. machine_dialect/mir/optimization_config.py +233 -0
  123. machine_dialect/mir/optimization_pass.py +251 -0
  124. machine_dialect/mir/optimization_pipeline.py +355 -0
  125. machine_dialect/mir/optimizations/__init__.py +84 -0
  126. machine_dialect/mir/optimizations/algebraic_simplification.py +733 -0
  127. machine_dialect/mir/optimizations/branch_prediction.py +372 -0
  128. machine_dialect/mir/optimizations/constant_propagation.py +634 -0
  129. machine_dialect/mir/optimizations/cse.py +398 -0
  130. machine_dialect/mir/optimizations/dce.py +288 -0
  131. machine_dialect/mir/optimizations/inlining.py +551 -0
  132. machine_dialect/mir/optimizations/jump_threading.py +487 -0
  133. machine_dialect/mir/optimizations/licm.py +405 -0
  134. machine_dialect/mir/optimizations/loop_unrolling.py +366 -0
  135. machine_dialect/mir/optimizations/strength_reduction.py +422 -0
  136. machine_dialect/mir/optimizations/tail_call.py +207 -0
  137. machine_dialect/mir/optimizations/tests/test_loop_unrolling.py +483 -0
  138. machine_dialect/mir/optimizations/type_narrowing.py +397 -0
  139. machine_dialect/mir/optimizations/type_specialization.py +447 -0
  140. machine_dialect/mir/optimizations/type_specific.py +906 -0
  141. machine_dialect/mir/optimize_mir.py +89 -0
  142. machine_dialect/mir/pass_manager.py +391 -0
  143. machine_dialect/mir/profiling/__init__.py +26 -0
  144. machine_dialect/mir/profiling/profile_collector.py +318 -0
  145. machine_dialect/mir/profiling/profile_data.py +372 -0
  146. machine_dialect/mir/profiling/profile_reader.py +272 -0
  147. machine_dialect/mir/profiling/profile_writer.py +226 -0
  148. machine_dialect/mir/register_allocation.py +302 -0
  149. machine_dialect/mir/reporting/__init__.py +17 -0
  150. machine_dialect/mir/reporting/optimization_reporter.py +314 -0
  151. machine_dialect/mir/reporting/report_formatter.py +289 -0
  152. machine_dialect/mir/ssa_construction.py +342 -0
  153. machine_dialect/mir/tests/__init__.py +1 -0
  154. machine_dialect/mir/tests/test_algebraic_associativity.py +204 -0
  155. machine_dialect/mir/tests/test_algebraic_complex_patterns.py +221 -0
  156. machine_dialect/mir/tests/test_algebraic_division.py +126 -0
  157. machine_dialect/mir/tests/test_algebraic_simplification.py +863 -0
  158. machine_dialect/mir/tests/test_basic_block.py +425 -0
  159. machine_dialect/mir/tests/test_branch_prediction.py +459 -0
  160. machine_dialect/mir/tests/test_call_lowering.py +168 -0
  161. machine_dialect/mir/tests/test_collection_lowering.py +604 -0
  162. machine_dialect/mir/tests/test_cross_block_constant_propagation.py +255 -0
  163. machine_dialect/mir/tests/test_custom_passes.py +166 -0
  164. machine_dialect/mir/tests/test_debug_info.py +285 -0
  165. machine_dialect/mir/tests/test_dict_extraction_lowering.py +192 -0
  166. machine_dialect/mir/tests/test_dictionary_lowering.py +299 -0
  167. machine_dialect/mir/tests/test_double_negation.py +231 -0
  168. machine_dialect/mir/tests/test_escape_analysis.py +233 -0
  169. machine_dialect/mir/tests/test_hir_to_mir.py +465 -0
  170. machine_dialect/mir/tests/test_hir_to_mir_complete.py +389 -0
  171. machine_dialect/mir/tests/test_hir_to_mir_simple.py +130 -0
  172. machine_dialect/mir/tests/test_inlining.py +435 -0
  173. machine_dialect/mir/tests/test_licm.py +472 -0
  174. machine_dialect/mir/tests/test_mir_dumper.py +313 -0
  175. machine_dialect/mir/tests/test_mir_instructions.py +445 -0
  176. machine_dialect/mir/tests/test_mir_module.py +860 -0
  177. machine_dialect/mir/tests/test_mir_printer.py +387 -0
  178. machine_dialect/mir/tests/test_mir_types.py +123 -0
  179. machine_dialect/mir/tests/test_mir_types_enhanced.py +132 -0
  180. machine_dialect/mir/tests/test_mir_validation.py +378 -0
  181. machine_dialect/mir/tests/test_mir_values.py +168 -0
  182. machine_dialect/mir/tests/test_one_based_indexing.py +202 -0
  183. machine_dialect/mir/tests/test_optimization_helpers.py +60 -0
  184. machine_dialect/mir/tests/test_optimization_pipeline.py +554 -0
  185. machine_dialect/mir/tests/test_optimization_reporter.py +318 -0
  186. machine_dialect/mir/tests/test_pass_manager.py +294 -0
  187. machine_dialect/mir/tests/test_pass_registration.py +64 -0
  188. machine_dialect/mir/tests/test_profiling.py +356 -0
  189. machine_dialect/mir/tests/test_register_allocation.py +307 -0
  190. machine_dialect/mir/tests/test_report_formatters.py +372 -0
  191. machine_dialect/mir/tests/test_ssa_construction.py +433 -0
  192. machine_dialect/mir/tests/test_tail_call.py +236 -0
  193. machine_dialect/mir/tests/test_type_annotated_instructions.py +192 -0
  194. machine_dialect/mir/tests/test_type_narrowing.py +277 -0
  195. machine_dialect/mir/tests/test_type_specialization.py +421 -0
  196. machine_dialect/mir/tests/test_type_specific_optimization.py +545 -0
  197. machine_dialect/mir/tests/test_type_specific_optimization_advanced.py +382 -0
  198. machine_dialect/mir/type_inference.py +368 -0
  199. machine_dialect/parser/__init__.py +12 -0
  200. machine_dialect/parser/enums.py +45 -0
  201. machine_dialect/parser/parser.py +3655 -0
  202. machine_dialect/parser/protocols.py +11 -0
  203. machine_dialect/parser/symbol_table.py +169 -0
  204. machine_dialect/parser/tests/__init__.py +0 -0
  205. machine_dialect/parser/tests/helper_functions.py +193 -0
  206. machine_dialect/parser/tests/test_action_statements.py +334 -0
  207. machine_dialect/parser/tests/test_boolean_literal_expressions.py +152 -0
  208. machine_dialect/parser/tests/test_call_statements.py +154 -0
  209. machine_dialect/parser/tests/test_call_statements_errors.py +187 -0
  210. machine_dialect/parser/tests/test_collection_mutations.py +264 -0
  211. machine_dialect/parser/tests/test_conditional_expressions.py +343 -0
  212. machine_dialect/parser/tests/test_define_integration.py +468 -0
  213. machine_dialect/parser/tests/test_define_statements.py +311 -0
  214. machine_dialect/parser/tests/test_dict_extraction.py +115 -0
  215. machine_dialect/parser/tests/test_empty_literal.py +155 -0
  216. machine_dialect/parser/tests/test_float_literal_expressions.py +163 -0
  217. machine_dialect/parser/tests/test_identifier_expressions.py +57 -0
  218. machine_dialect/parser/tests/test_if_empty_block.py +61 -0
  219. machine_dialect/parser/tests/test_if_statements.py +299 -0
  220. machine_dialect/parser/tests/test_illegal_tokens.py +86 -0
  221. machine_dialect/parser/tests/test_infix_expressions.py +680 -0
  222. machine_dialect/parser/tests/test_integer_literal_expressions.py +137 -0
  223. machine_dialect/parser/tests/test_interaction_statements.py +269 -0
  224. machine_dialect/parser/tests/test_list_literals.py +277 -0
  225. machine_dialect/parser/tests/test_no_none_in_ast.py +94 -0
  226. machine_dialect/parser/tests/test_panic_mode_recovery.py +171 -0
  227. machine_dialect/parser/tests/test_parse_errors.py +114 -0
  228. machine_dialect/parser/tests/test_possessive_syntax.py +182 -0
  229. machine_dialect/parser/tests/test_prefix_expressions.py +415 -0
  230. machine_dialect/parser/tests/test_program.py +13 -0
  231. machine_dialect/parser/tests/test_return_statements.py +89 -0
  232. machine_dialect/parser/tests/test_set_statements.py +152 -0
  233. machine_dialect/parser/tests/test_strict_equality.py +258 -0
  234. machine_dialect/parser/tests/test_symbol_table.py +217 -0
  235. machine_dialect/parser/tests/test_url_literal_expressions.py +209 -0
  236. machine_dialect/parser/tests/test_utility_statements.py +423 -0
  237. machine_dialect/parser/token_buffer.py +159 -0
  238. machine_dialect/repl/__init__.py +3 -0
  239. machine_dialect/repl/repl.py +426 -0
  240. machine_dialect/repl/tests/__init__.py +0 -0
  241. machine_dialect/repl/tests/test_repl.py +606 -0
  242. machine_dialect/semantic/__init__.py +12 -0
  243. machine_dialect/semantic/analyzer.py +906 -0
  244. machine_dialect/semantic/error_messages.py +189 -0
  245. machine_dialect/semantic/tests/__init__.py +1 -0
  246. machine_dialect/semantic/tests/test_analyzer.py +364 -0
  247. machine_dialect/semantic/tests/test_error_messages.py +104 -0
  248. machine_dialect/tests/edge_cases/__init__.py +10 -0
  249. machine_dialect/tests/edge_cases/test_boundary_access.py +256 -0
  250. machine_dialect/tests/edge_cases/test_empty_collections.py +166 -0
  251. machine_dialect/tests/edge_cases/test_invalid_operations.py +243 -0
  252. machine_dialect/tests/edge_cases/test_named_list_edge_cases.py +295 -0
  253. machine_dialect/tests/edge_cases/test_nested_structures.py +313 -0
  254. machine_dialect/tests/edge_cases/test_type_mixing.py +277 -0
  255. machine_dialect/tests/integration/test_array_operations_emulation.py +248 -0
  256. machine_dialect/tests/integration/test_list_compilation.py +395 -0
  257. machine_dialect/tests/integration/test_lists_and_dictionaries.py +322 -0
  258. machine_dialect/type_checking/__init__.py +21 -0
  259. machine_dialect/type_checking/tests/__init__.py +1 -0
  260. machine_dialect/type_checking/tests/test_type_system.py +230 -0
  261. machine_dialect/type_checking/type_system.py +270 -0
  262. machine_dialect-0.1.0a1.dist-info/METADATA +128 -0
  263. machine_dialect-0.1.0a1.dist-info/RECORD +268 -0
  264. machine_dialect-0.1.0a1.dist-info/WHEEL +5 -0
  265. machine_dialect-0.1.0a1.dist-info/entry_points.txt +3 -0
  266. machine_dialect-0.1.0a1.dist-info/licenses/LICENSE +201 -0
  267. machine_dialect-0.1.0a1.dist-info/top_level.txt +2 -0
  268. machine_dialect_vm/__init__.pyi +15 -0
@@ -0,0 +1,251 @@
1
+ """Base classes and interfaces for MIR optimization and analysis passes.
2
+
3
+ This module provides the foundation for all optimization and analysis passes
4
+ in the MIR optimization framework.
5
+ """
6
+
7
+ import abc
8
+ from abc import ABC, abstractmethod
9
+ from dataclasses import dataclass
10
+ from enum import Enum
11
+ from typing import Any
12
+
13
+ from machine_dialect.mir.mir_function import MIRFunction
14
+ from machine_dialect.mir.mir_module import MIRModule
15
+
16
+
17
+ class PassType(Enum):
18
+ """Type of pass."""
19
+
20
+ ANALYSIS = "analysis"
21
+ OPTIMIZATION = "optimization"
22
+ CLEANUP = "cleanup" # Cleanup passes that can run after optimizations
23
+ UTILITY = "utility"
24
+
25
+
26
+ class PreservationLevel(Enum):
27
+ """Level of preservation for analyses."""
28
+
29
+ NONE = "none" # Invalidates everything
30
+ CFG = "cfg" # Preserves CFG structure
31
+ DOMINANCE = "dominance" # Preserves dominance info
32
+ ALL = "all" # Preserves all analyses
33
+
34
+
35
+ @dataclass
36
+ class PassInfo:
37
+ """Information about a pass.
38
+
39
+ Attributes:
40
+ name: Pass name.
41
+ description: Pass description.
42
+ pass_type: Type(s) of pass - can be single type or list of types.
43
+ requires: List of required analysis passes.
44
+ preserves: What analyses this pass preserves.
45
+ """
46
+
47
+ name: str
48
+ description: str
49
+ pass_type: PassType | list[PassType]
50
+ requires: list[str]
51
+ preserves: PreservationLevel
52
+
53
+
54
+ class Pass(ABC):
55
+ """Base class for all passes."""
56
+
57
+ def __init__(self) -> None:
58
+ """Initialize the pass."""
59
+ self.stats: dict[str, int] = {}
60
+ self.debug_mode = False
61
+
62
+ @abstractmethod
63
+ def get_info(self) -> PassInfo:
64
+ """Get information about this pass.
65
+
66
+ Returns:
67
+ Pass information.
68
+ """
69
+ pass
70
+
71
+ def initialize(self) -> None:
72
+ """Initialize the pass before running.
73
+
74
+ Override this for pass-specific initialization.
75
+ """
76
+ self.stats.clear()
77
+
78
+ @abc.abstractmethod
79
+ def finalize(self) -> None:
80
+ """Finalize the pass after running.
81
+
82
+ Override this for pass-specific finalization.
83
+ """
84
+
85
+ def get_stats(self) -> dict[str, int]:
86
+ """Get pass statistics.
87
+
88
+ Returns:
89
+ Dictionary of statistics.
90
+ """
91
+ return self.stats.copy()
92
+
93
+
94
+ class ModulePass(Pass):
95
+ """Base class for module-level passes."""
96
+
97
+ @abstractmethod
98
+ def run_on_module(self, module: MIRModule) -> bool:
99
+ """Run the pass on a module.
100
+
101
+ Args:
102
+ module: The module to process.
103
+
104
+ Returns:
105
+ True if the module was modified.
106
+ """
107
+ pass
108
+
109
+
110
+ class FunctionPass(Pass):
111
+ """Base class for function-level passes."""
112
+
113
+ @abstractmethod
114
+ def run_on_function(self, function: MIRFunction) -> bool:
115
+ """Run the pass on a function.
116
+
117
+ Args:
118
+ function: The function to process.
119
+
120
+ Returns:
121
+ True if the function was modified.
122
+ """
123
+ pass
124
+
125
+ def run_on_module(self, module: MIRModule) -> bool:
126
+ """Run the pass on all functions in a module.
127
+
128
+ Args:
129
+ module: The module to process.
130
+
131
+ Returns:
132
+ True if any function was modified.
133
+ """
134
+ modified = False
135
+ for function in module.functions.values():
136
+ if self.run_on_function(function):
137
+ modified = True
138
+ return modified
139
+
140
+
141
+ class AnalysisPass(Pass):
142
+ """Base class for analysis passes."""
143
+
144
+ def __init__(self) -> None:
145
+ """Initialize the analysis pass."""
146
+ super().__init__()
147
+ self._cache: dict[str, Any] = {}
148
+ self._valid = False
149
+
150
+ def invalidate(self) -> None:
151
+ """Invalidate the analysis cache."""
152
+ self._cache.clear()
153
+ self._valid = False
154
+
155
+ def is_valid(self) -> bool:
156
+ """Check if the analysis is valid.
157
+
158
+ Returns:
159
+ True if the analysis is valid.
160
+ """
161
+ return self._valid
162
+
163
+
164
+ class ModuleAnalysisPass(AnalysisPass):
165
+ """Base class for module-level analysis passes."""
166
+
167
+ @abstractmethod
168
+ def run_on_module(self, module: MIRModule) -> Any:
169
+ """Run analysis on a module.
170
+
171
+ Args:
172
+ module: The module to analyze.
173
+
174
+ Returns:
175
+ Analysis results.
176
+ """
177
+ pass
178
+
179
+ def get_analysis(self, module: MIRModule) -> Any:
180
+ """Get cached analysis results or compute them.
181
+
182
+ Args:
183
+ module: The module to analyze.
184
+
185
+ Returns:
186
+ Analysis results.
187
+ """
188
+ if not self._valid:
189
+ result = self.run_on_module(module)
190
+ self._cache[module.name] = result
191
+ self._valid = True
192
+ return result
193
+ return self._cache.get(module.name)
194
+
195
+
196
+ class FunctionAnalysisPass(AnalysisPass):
197
+ """Base class for function-level analysis passes."""
198
+
199
+ @abstractmethod
200
+ def run_on_function(self, function: MIRFunction) -> Any:
201
+ """Run analysis on a function.
202
+
203
+ Args:
204
+ function: The function to analyze.
205
+
206
+ Returns:
207
+ Analysis results.
208
+ """
209
+ pass
210
+
211
+ def get_analysis(self, function: MIRFunction) -> Any:
212
+ """Get cached analysis results or compute them.
213
+
214
+ Args:
215
+ function: The function to analyze.
216
+
217
+ Returns:
218
+ Analysis results.
219
+ """
220
+ if not self._valid or function.name not in self._cache:
221
+ result = self.run_on_function(function)
222
+ self._cache[function.name] = result
223
+ self._valid = True
224
+ return result
225
+ return self._cache[function.name]
226
+
227
+
228
+ class OptimizationPass(FunctionPass):
229
+ """Base class for optimization passes."""
230
+
231
+ def __init__(self) -> None:
232
+ """Initialize the optimization pass."""
233
+ super().__init__()
234
+ self.analysis_manager: Any = None # Set by pass manager
235
+
236
+ def get_analysis(self, analysis_name: str, function: MIRFunction) -> Any:
237
+ """Get analysis results from the analysis manager.
238
+
239
+ Args:
240
+ analysis_name: Name of the analysis.
241
+ function: The function to analyze.
242
+
243
+ Returns:
244
+ Analysis results.
245
+
246
+ Raises:
247
+ RuntimeError: If analysis manager is not set.
248
+ """
249
+ if self.analysis_manager is None:
250
+ raise RuntimeError("Analysis manager not set")
251
+ return self.analysis_manager.get_analysis(analysis_name, function)
@@ -0,0 +1,355 @@
1
+ """Optimization pipeline configuration for MIR.
2
+
3
+ This module defines optimization levels and pass pipelines for different
4
+ compilation scenarios.
5
+ """
6
+
7
+ from enum import Enum
8
+ from typing import Any
9
+
10
+ from machine_dialect.mir.analyses.dominance_analysis import DominanceAnalysis
11
+ from machine_dialect.mir.analyses.loop_analysis import LoopAnalysis
12
+ from machine_dialect.mir.analyses.use_def_chains import UseDefChainsAnalysis
13
+ from machine_dialect.mir.mir_module import MIRModule
14
+ from machine_dialect.mir.optimization_pass import ModulePass, Pass
15
+ from machine_dialect.mir.optimizations.constant_propagation import ConstantPropagation
16
+ from machine_dialect.mir.optimizations.cse import CommonSubexpressionElimination
17
+ from machine_dialect.mir.optimizations.dce import DeadCodeElimination
18
+ from machine_dialect.mir.optimizations.inlining import FunctionInlining
19
+ from machine_dialect.mir.optimizations.jump_threading import JumpThreadingPass
20
+ from machine_dialect.mir.optimizations.licm import LoopInvariantCodeMotion
21
+
22
+ # from machine_dialect.mir.optimizations.peephole_optimizer import PeepholePass # Disabled
23
+ from machine_dialect.mir.optimizations.strength_reduction import StrengthReduction
24
+ from machine_dialect.mir.pass_manager import PassManager
25
+
26
+
27
+ class OptimizationLevel(Enum):
28
+ """Optimization levels for compilation."""
29
+
30
+ O0 = "O0" # No optimization
31
+ O1 = "O1" # Basic optimization
32
+ O2 = "O2" # Standard optimization
33
+ O3 = "O3" # Aggressive optimization
34
+ Os = "Os" # Optimize for size
35
+
36
+
37
+ class OptimizationPipeline:
38
+ """Manages optimization pipelines for different optimization levels."""
39
+
40
+ def __init__(self) -> None:
41
+ """Initialize the optimization pipeline.
42
+
43
+ Creates a pass manager and registers all available optimization
44
+ and analysis passes.
45
+ """
46
+ self.pass_manager = PassManager()
47
+ self._register_all_passes()
48
+ self.stats: dict[str, Any] = {}
49
+
50
+ def _register_all_passes(self) -> None:
51
+ """Register all available passes with the pass manager.
52
+
53
+ Registers both analysis passes (dominance, loop, use-def chains)
54
+ and optimization passes (constant propagation, DCE, CSE, etc.).
55
+ """
56
+ # Register analysis passes
57
+ self.pass_manager.register_pass(DominanceAnalysis)
58
+ self.pass_manager.register_pass(LoopAnalysis)
59
+ self.pass_manager.register_pass(UseDefChainsAnalysis)
60
+
61
+ # Register optimization passes
62
+ self.pass_manager.register_pass(ConstantPropagation)
63
+ self.pass_manager.register_pass(DeadCodeElimination)
64
+ self.pass_manager.register_pass(CommonSubexpressionElimination)
65
+ self.pass_manager.register_pass(StrengthReduction)
66
+ self.pass_manager.register_pass(JumpThreadingPass)
67
+ # self.pass_manager.register_pass(PeepholePass) # Disabled
68
+ self.pass_manager.register_pass(LoopInvariantCodeMotion)
69
+ self.pass_manager.register_pass(FunctionInlining)
70
+
71
+ def get_passes_for_level(self, level: OptimizationLevel) -> list[Pass]:
72
+ """Get the list of passes for an optimization level.
73
+
74
+ Args:
75
+ level: The optimization level.
76
+
77
+ Returns:
78
+ List of pass instances to run.
79
+ """
80
+ passes: list[Pass] = []
81
+
82
+ if level == OptimizationLevel.O0:
83
+ # No optimization
84
+ return passes
85
+
86
+ elif level == OptimizationLevel.O1:
87
+ # Basic optimization
88
+ # Focus on simple, fast optimizations
89
+ o1_passes = [
90
+ self.pass_manager.registry.get_pass("constant-propagation"),
91
+ self.pass_manager.registry.get_pass("strength-reduction"),
92
+ self.pass_manager.registry.get_pass("dce"),
93
+ self.pass_manager.registry.get_pass("peephole"),
94
+ ]
95
+ passes.extend([p for p in o1_passes if p is not None])
96
+
97
+ elif level == OptimizationLevel.O2:
98
+ # Standard optimization
99
+ # Add more expensive optimizations
100
+ o2_passes: list[Pass | None] = [
101
+ # First pass: basic cleanup
102
+ self.pass_manager.registry.get_pass("constant-propagation"),
103
+ self.pass_manager.registry.get_pass("strength-reduction"),
104
+ self.pass_manager.registry.get_pass("dce"),
105
+ # Inlining (small functions only)
106
+ FunctionInlining(size_threshold=30),
107
+ # After inlining, more opportunities
108
+ self.pass_manager.registry.get_pass("constant-propagation"),
109
+ self.pass_manager.registry.get_pass("cse"),
110
+ self.pass_manager.registry.get_pass("licm"),
111
+ self.pass_manager.registry.get_pass("dce"),
112
+ # Final cleanup
113
+ self.pass_manager.registry.get_pass("jump-threading"),
114
+ self.pass_manager.registry.get_pass("peephole"),
115
+ ]
116
+ passes.extend([p for p in o2_passes if p is not None])
117
+
118
+ elif level == OptimizationLevel.O3:
119
+ # Aggressive optimization
120
+ # More aggressive thresholds and multiple iterations
121
+ o3_passes: list[Pass | None] = [
122
+ # First pass: aggressive inlining
123
+ FunctionInlining(size_threshold=100),
124
+ # Full optimization suite
125
+ self.pass_manager.registry.get_pass("constant-propagation"),
126
+ self.pass_manager.registry.get_pass("strength-reduction"),
127
+ self.pass_manager.registry.get_pass("cse"),
128
+ self.pass_manager.registry.get_pass("licm"),
129
+ self.pass_manager.registry.get_pass("dce"),
130
+ # Second iteration after first round
131
+ self.pass_manager.registry.get_pass("constant-propagation"),
132
+ self.pass_manager.registry.get_pass("cse"),
133
+ self.pass_manager.registry.get_pass("dce"),
134
+ # Control flow optimization
135
+ self.pass_manager.registry.get_pass("jump-threading"),
136
+ self.pass_manager.registry.get_pass("peephole"),
137
+ # Final DCE to clean up
138
+ self.pass_manager.registry.get_pass("dce"),
139
+ ]
140
+ passes.extend([p for p in o3_passes if p is not None])
141
+
142
+ elif level == OptimizationLevel.Os:
143
+ # Optimize for size
144
+ # Focus on reducing code size
145
+ os_passes = [
146
+ # No inlining (increases size)
147
+ self.pass_manager.registry.get_pass("constant-propagation"),
148
+ self.pass_manager.registry.get_pass("cse"), # Reduces duplicate code
149
+ self.pass_manager.registry.get_pass("dce"), # Removes dead code
150
+ self.pass_manager.registry.get_pass("jump-threading"), # Simplifies control flow
151
+ self.pass_manager.registry.get_pass("peephole"),
152
+ ]
153
+ passes.extend([p for p in os_passes if p is not None])
154
+
155
+ # Already filtered out None passes
156
+ return passes
157
+
158
+ def optimize(self, module: MIRModule, level: OptimizationLevel = OptimizationLevel.O2) -> bool:
159
+ """Run optimization pipeline on a module.
160
+
161
+ Args:
162
+ module: The module to optimize.
163
+ level: The optimization level.
164
+
165
+ Returns:
166
+ True if the module was modified.
167
+ """
168
+ passes = self.get_passes_for_level(level)
169
+ modified = False
170
+
171
+ # Reset statistics
172
+ self.stats = {
173
+ "level": level.value,
174
+ "passes_run": [],
175
+ "total_modifications": 0,
176
+ "pass_stats": {},
177
+ }
178
+
179
+ for pass_instance in passes:
180
+ pass_info = pass_instance.get_info()
181
+ pass_name = pass_info.name
182
+
183
+ # Run the pass
184
+ pass_modified = False
185
+ if isinstance(pass_instance, ModulePass):
186
+ pass_modified = pass_instance.run_on_module(module)
187
+
188
+ # Track statistics
189
+ self.stats["passes_run"].append(pass_name)
190
+ if pass_modified:
191
+ modified = True
192
+ self.stats["total_modifications"] += 1
193
+
194
+ # Get pass-specific statistics if available
195
+ if hasattr(pass_instance, "get_statistics"):
196
+ self.stats["pass_stats"][pass_name] = pass_instance.get_statistics()
197
+
198
+ return modified
199
+
200
+ def optimize_with_custom_pipeline(self, module: MIRModule, pass_names: list[str]) -> bool:
201
+ """Run a custom optimization pipeline.
202
+
203
+ Args:
204
+ module: The module to optimize.
205
+ pass_names: List of pass names to run in order.
206
+
207
+ Returns:
208
+ True if the module was modified.
209
+ """
210
+ modified = False
211
+
212
+ for pass_name in pass_names:
213
+ pass_instance = self.pass_manager.registry.get_pass(pass_name)
214
+ if pass_instance:
215
+ if isinstance(pass_instance, ModulePass):
216
+ if pass_instance.run_on_module(module):
217
+ modified = True
218
+
219
+ return modified
220
+
221
+ def get_statistics(self) -> dict[str, Any]:
222
+ """Get statistics from the last optimization run.
223
+
224
+ Returns:
225
+ Dictionary containing optimization level, passes run,
226
+ total modifications made, and per-pass statistics.
227
+ """
228
+ return self.stats
229
+
230
+
231
+ class PipelineBuilder:
232
+ """Builder for creating custom optimization pipelines."""
233
+
234
+ def __init__(self) -> None:
235
+ """Initialize the pipeline builder.
236
+
237
+ Creates an empty pipeline ready for pass configuration.
238
+ """
239
+ self.passes: list[str] = []
240
+ self.pass_configs: dict[str, dict[str, Any]] = {}
241
+
242
+ def add_pass(self, pass_name: str, **config: Any) -> "PipelineBuilder":
243
+ """Add a pass to the pipeline.
244
+
245
+ Args:
246
+ pass_name: Name of the pass.
247
+ **config: Configuration for the pass.
248
+
249
+ Returns:
250
+ Self for chaining.
251
+ """
252
+ self.passes.append(pass_name)
253
+ if config:
254
+ self.pass_configs[pass_name] = config
255
+ return self
256
+
257
+ def add_cleanup_passes(self) -> "PipelineBuilder":
258
+ """Add standard cleanup passes.
259
+
260
+ Returns:
261
+ Self for chaining.
262
+ """
263
+ self.passes.extend(["dce", "jump-threading", "peephole"])
264
+ return self
265
+
266
+ def add_algebraic_passes(self) -> "PipelineBuilder":
267
+ """Add algebraic optimization passes.
268
+
269
+ Returns:
270
+ Self for chaining.
271
+ """
272
+ self.passes.extend(["constant-propagation", "strength-reduction", "cse"])
273
+ return self
274
+
275
+ def add_loop_passes(self) -> "PipelineBuilder":
276
+ """Add loop optimization passes.
277
+
278
+ Returns:
279
+ Self for chaining.
280
+ """
281
+ self.passes.append("licm")
282
+ return self
283
+
284
+ def repeat(self, times: int = 2) -> "PipelineBuilder":
285
+ """Repeat the current pipeline multiple times.
286
+
287
+ Args:
288
+ times: Number of times to repeat.
289
+
290
+ Returns:
291
+ Self for chaining.
292
+ """
293
+ current_passes = self.passes.copy()
294
+ for _ in range(times - 1):
295
+ self.passes.extend(current_passes)
296
+ return self
297
+
298
+ def build(self) -> list[str]:
299
+ """Build the pipeline.
300
+
301
+ Returns:
302
+ List of pass names.
303
+ """
304
+ return self.passes.copy()
305
+
306
+
307
+ # Convenience functions
308
+ def create_o0_pipeline() -> OptimizationPipeline:
309
+ """Create a pipeline with no optimization.
310
+
311
+ Returns:
312
+ Pipeline configured for O0 (no optimization passes).
313
+ """
314
+ pipeline = OptimizationPipeline()
315
+ return pipeline
316
+
317
+
318
+ def create_o1_pipeline() -> OptimizationPipeline:
319
+ """Create a pipeline with basic optimization.
320
+
321
+ Returns:
322
+ Pipeline configured for O1 (fast, simple optimizations).
323
+ """
324
+ pipeline = OptimizationPipeline()
325
+ return pipeline
326
+
327
+
328
+ def create_o2_pipeline() -> OptimizationPipeline:
329
+ """Create a pipeline with standard optimization.
330
+
331
+ Returns:
332
+ Pipeline configured for O2 (balanced performance/compile time).
333
+ """
334
+ pipeline = OptimizationPipeline()
335
+ return pipeline
336
+
337
+
338
+ def create_o3_pipeline() -> OptimizationPipeline:
339
+ """Create a pipeline with aggressive optimization.
340
+
341
+ Returns:
342
+ Pipeline configured for O3 (maximum performance optimization).
343
+ """
344
+ pipeline = OptimizationPipeline()
345
+ return pipeline
346
+
347
+
348
+ def create_size_pipeline() -> OptimizationPipeline:
349
+ """Create a pipeline optimized for code size.
350
+
351
+ Returns:
352
+ Pipeline configured for Os (minimize code size).
353
+ """
354
+ pipeline = OptimizationPipeline()
355
+ return pipeline
@@ -0,0 +1,84 @@
1
+ """MIR optimization passes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from machine_dialect.mir.optimizations.algebraic_simplification import AlgebraicSimplification
8
+ from machine_dialect.mir.optimizations.branch_prediction import BranchPredictionOptimization
9
+ from machine_dialect.mir.optimizations.constant_propagation import ConstantPropagation
10
+ from machine_dialect.mir.optimizations.cse import CommonSubexpressionElimination
11
+ from machine_dialect.mir.optimizations.dce import DeadCodeElimination
12
+ from machine_dialect.mir.optimizations.inlining import FunctionInlining
13
+ from machine_dialect.mir.optimizations.jump_threading import JumpThreadingOptimizer, JumpThreadingPass
14
+ from machine_dialect.mir.optimizations.licm import LoopInvariantCodeMotion
15
+ from machine_dialect.mir.optimizations.loop_unrolling import LoopUnrolling
16
+
17
+ # from machine_dialect.mir.optimizations.peephole_optimizer import PeepholeOptimizer # Disabled - needs update
18
+ from machine_dialect.mir.optimizations.strength_reduction import StrengthReduction
19
+ from machine_dialect.mir.optimizations.tail_call import TailCallOptimization
20
+ from machine_dialect.mir.optimizations.type_narrowing import TypeNarrowing
21
+ from machine_dialect.mir.optimizations.type_specialization import TypeSpecialization
22
+ from machine_dialect.mir.optimizations.type_specific import TypeSpecificOptimization
23
+
24
+ if TYPE_CHECKING:
25
+ from machine_dialect.mir.pass_manager import PassManager
26
+
27
+ __all__ = [
28
+ "AlgebraicSimplification",
29
+ "BranchPredictionOptimization",
30
+ "CommonSubexpressionElimination",
31
+ "ConstantPropagation",
32
+ "DeadCodeElimination",
33
+ "FunctionInlining",
34
+ "JumpThreadingOptimizer",
35
+ "JumpThreadingPass",
36
+ "LoopInvariantCodeMotion",
37
+ "LoopUnrolling",
38
+ # "PeepholeOptimizer", # Disabled
39
+ # "PeepholePass", # Disabled
40
+ "StrengthReduction",
41
+ "TailCallOptimization",
42
+ "TypeNarrowing",
43
+ "TypeSpecialization",
44
+ "TypeSpecificOptimization",
45
+ ]
46
+
47
+
48
+ def register_all_passes(pass_manager: PassManager) -> None:
49
+ """Register all optimization passes with the pass manager.
50
+
51
+ Args:
52
+ pass_manager: Pass manager to register with.
53
+ """
54
+ from machine_dialect.mir.analyses.alias_analysis import AliasAnalysis
55
+ from machine_dialect.mir.analyses.dominance_analysis import DominanceAnalysis
56
+ from machine_dialect.mir.analyses.escape_analysis import EscapeAnalysis
57
+ from machine_dialect.mir.analyses.loop_analysis import LoopAnalysis
58
+ from machine_dialect.mir.analyses.type_analysis import TypeAnalysis
59
+ from machine_dialect.mir.analyses.use_def_chains import UseDefChainsAnalysis
60
+
61
+ # Register analysis passes
62
+ pass_manager.register_pass(DominanceAnalysis)
63
+ pass_manager.register_pass(UseDefChainsAnalysis)
64
+ pass_manager.register_pass(LoopAnalysis)
65
+ pass_manager.register_pass(AliasAnalysis)
66
+ pass_manager.register_pass(EscapeAnalysis)
67
+ pass_manager.register_pass(TypeAnalysis)
68
+
69
+ # Register optimization passes
70
+ pass_manager.register_pass(TypeSpecificOptimization) # Run early to benefit other passes
71
+ pass_manager.register_pass(TypeNarrowing) # Run after type-specific to narrow union types
72
+ pass_manager.register_pass(ConstantPropagation)
73
+ pass_manager.register_pass(CommonSubexpressionElimination)
74
+ pass_manager.register_pass(DeadCodeElimination)
75
+ pass_manager.register_pass(StrengthReduction)
76
+ pass_manager.register_pass(AlgebraicSimplification)
77
+ pass_manager.register_pass(TailCallOptimization)
78
+ pass_manager.register_pass(TypeSpecialization)
79
+ pass_manager.register_pass(FunctionInlining)
80
+ pass_manager.register_pass(LoopInvariantCodeMotion)
81
+ pass_manager.register_pass(LoopUnrolling)
82
+ pass_manager.register_pass(BranchPredictionOptimization)
83
+ pass_manager.register_pass(JumpThreadingPass)
84
+ # pass_manager.register_pass(PeepholePass) # Disabled - needs update for new opcodes