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,89 @@
1
+ """MIR optimization pipeline integration.
2
+
3
+ This module provides the main entry point for optimizing MIR modules
4
+ using the pass management infrastructure.
5
+ """
6
+
7
+ from machine_dialect.mir.mir_module import MIRModule
8
+ from machine_dialect.mir.optimization_config import (
9
+ OptimizationConfig,
10
+ OptimizationPipeline,
11
+ )
12
+ from machine_dialect.mir.optimizations import register_all_passes
13
+ from machine_dialect.mir.pass_manager import PassManager
14
+
15
+
16
+ def optimize_mir(
17
+ module: MIRModule,
18
+ optimization_level: int = 1,
19
+ config: OptimizationConfig | None = None,
20
+ debug: bool = False,
21
+ custom_passes: list[str] | None = None,
22
+ ) -> tuple[MIRModule, dict[str, dict[str, int]]]:
23
+ """Optimize a MIR module using the optimization framework.
24
+
25
+ Args:
26
+ module: The MIR module to optimize.
27
+ optimization_level: Optimization level (0-3).
28
+ config: Optional custom optimization configuration.
29
+ debug: Enable debug output.
30
+ custom_passes: Optional list of custom passes to run instead of default pipeline.
31
+
32
+ Returns:
33
+ Tuple of (optimized module, pass statistics).
34
+ """
35
+ # Use provided config or create from level
36
+ if config is None:
37
+ config = OptimizationConfig.from_level(optimization_level)
38
+
39
+ # Create pass manager
40
+ pass_manager = PassManager()
41
+ pass_manager.debug_mode = debug or config.debug_passes
42
+
43
+ # Register all available passes
44
+ register_all_passes(pass_manager)
45
+
46
+ # Get optimization pipeline
47
+ if custom_passes is not None:
48
+ # Use custom passes if provided
49
+ passes = custom_passes
50
+ else:
51
+ # Use default pipeline based on config
52
+ passes = OptimizationPipeline.get_passes(config)
53
+
54
+ if debug:
55
+ print(f"Running optimization level {optimization_level}")
56
+ print(f"Passes: {passes}")
57
+
58
+ # Run optimization passes
59
+ modified = pass_manager.run_passes(module, passes, optimization_level)
60
+
61
+ if debug:
62
+ print(f"Module modified: {modified}")
63
+
64
+ # Get statistics
65
+ stats = pass_manager.get_statistics()
66
+
67
+ if debug and config.pass_statistics:
68
+ print("\nOptimization Statistics:")
69
+ for pass_name, pass_stats in stats.items():
70
+ if pass_stats:
71
+ print(f" {pass_name}:")
72
+ for stat_name, value in pass_stats.items():
73
+ print(f" {stat_name}: {value}")
74
+
75
+ return module, stats
76
+
77
+
78
+ def optimize_mir_simple(module: MIRModule, level: int = 1) -> MIRModule:
79
+ """Simple interface for MIR optimization.
80
+
81
+ Args:
82
+ module: The MIR module to optimize.
83
+ level: Optimization level (0-3).
84
+
85
+ Returns:
86
+ The optimized module.
87
+ """
88
+ optimized, _ = optimize_mir(module, level)
89
+ return optimized
@@ -0,0 +1,391 @@
1
+ """Pass manager for orchestrating optimization and analysis passes.
2
+
3
+ This module implements the pass management infrastructure for scheduling,
4
+ executing, and managing dependencies between passes.
5
+ """
6
+
7
+ from collections import defaultdict
8
+ from typing import Any
9
+
10
+ from machine_dialect.mir.mir_function import MIRFunction
11
+ from machine_dialect.mir.mir_module import MIRModule
12
+ from machine_dialect.mir.optimization_pass import (
13
+ AnalysisPass,
14
+ FunctionAnalysisPass,
15
+ FunctionPass,
16
+ ModuleAnalysisPass,
17
+ ModulePass,
18
+ OptimizationPass,
19
+ Pass,
20
+ PassInfo,
21
+ PassType,
22
+ PreservationLevel,
23
+ )
24
+
25
+
26
+ class PassRegistry:
27
+ """Registry for available passes."""
28
+
29
+ def __init__(self) -> None:
30
+ """Initialize the pass registry."""
31
+ self._passes: dict[str, type[Pass]] = {}
32
+ self._pass_info: dict[str, PassInfo] = {}
33
+
34
+ def register(self, pass_class: type[Pass]) -> None:
35
+ """Register a pass.
36
+
37
+ Args:
38
+ pass_class: The pass class to register.
39
+ """
40
+ instance = pass_class()
41
+ info = instance.get_info()
42
+ self._passes[info.name] = pass_class
43
+ self._pass_info[info.name] = info
44
+
45
+ def get_pass(self, name: str) -> Pass | None:
46
+ """Get a pass instance by name.
47
+
48
+ Args:
49
+ name: Pass name.
50
+
51
+ Returns:
52
+ Pass instance or None.
53
+ """
54
+ pass_class = self._passes.get(name)
55
+ if pass_class:
56
+ return pass_class()
57
+ return None
58
+
59
+ def get_info(self, name: str) -> PassInfo | None:
60
+ """Get pass information by name.
61
+
62
+ Args:
63
+ name: Pass name.
64
+
65
+ Returns:
66
+ Pass information or None.
67
+ """
68
+ return self._pass_info.get(name)
69
+
70
+ def list_passes(self, pass_type: PassType | None = None) -> list[str]:
71
+ """List available passes.
72
+
73
+ Args:
74
+ pass_type: Optional filter by pass type.
75
+
76
+ Returns:
77
+ List of pass names.
78
+ """
79
+ if pass_type is None:
80
+ return list(self._passes.keys())
81
+
82
+ result = []
83
+ for name, info in self._pass_info.items():
84
+ # Handle both single PassType and list of PassTypes
85
+ if isinstance(info.pass_type, list):
86
+ if pass_type in info.pass_type:
87
+ result.append(name)
88
+ elif info.pass_type == pass_type:
89
+ result.append(name)
90
+ return result
91
+
92
+
93
+ class AnalysisManager:
94
+ """Manager for analysis passes and their results."""
95
+
96
+ def __init__(self) -> None:
97
+ """Initialize the analysis manager."""
98
+ self._analyses: dict[str, AnalysisPass] = {}
99
+ self._dependencies: dict[str, set[str]] = defaultdict(set)
100
+
101
+ def register_analysis(self, name: str, analysis: AnalysisPass) -> None:
102
+ """Register an analysis pass.
103
+
104
+ Args:
105
+ name: Analysis name.
106
+ analysis: Analysis pass instance.
107
+ """
108
+ self._analyses[name] = analysis
109
+
110
+ def get_analysis(
111
+ self,
112
+ name: str,
113
+ target: MIRModule | MIRFunction,
114
+ ) -> Any:
115
+ """Get analysis results.
116
+
117
+ Args:
118
+ name: Analysis name.
119
+ target: Module or function to analyze.
120
+
121
+ Returns:
122
+ Analysis results.
123
+
124
+ Raises:
125
+ KeyError: If analysis not found.
126
+ """
127
+ if name not in self._analyses:
128
+ raise KeyError(f"Analysis '{name}' not found")
129
+
130
+ analysis = self._analyses[name]
131
+
132
+ if isinstance(analysis, ModuleAnalysisPass) and isinstance(target, MIRModule):
133
+ return analysis.get_analysis(target)
134
+ elif isinstance(analysis, FunctionAnalysisPass) and isinstance(
135
+ target,
136
+ MIRFunction,
137
+ ):
138
+ return analysis.get_analysis(target)
139
+ else:
140
+ raise TypeError("Incompatible analysis and target types")
141
+
142
+ def invalidate(self, names: list[str] | None = None) -> None:
143
+ """Invalidate analyses.
144
+
145
+ Args:
146
+ names: Specific analyses to invalidate, or None for all.
147
+ """
148
+ if names is None:
149
+ for analysis in self._analyses.values():
150
+ analysis.invalidate()
151
+ else:
152
+ for name in names:
153
+ if name in self._analyses:
154
+ self._analyses[name].invalidate()
155
+ # Invalidate dependent analyses
156
+ for dep_name, deps in self._dependencies.items():
157
+ if name in deps and dep_name in self._analyses:
158
+ self._analyses[dep_name].invalidate()
159
+
160
+ def preserve_analyses(self, level: PreservationLevel) -> None:
161
+ """Preserve analyses based on preservation level.
162
+
163
+ Args:
164
+ level: Preservation level.
165
+ """
166
+ if level == PreservationLevel.NONE:
167
+ self.invalidate()
168
+ elif level == PreservationLevel.CFG:
169
+ # Invalidate analyses that depend on CFG changes
170
+ to_invalidate = []
171
+ for name, analysis in self._analyses.items():
172
+ info = analysis.get_info()
173
+ if "cfg" not in info.requires:
174
+ to_invalidate.append(name)
175
+ self.invalidate(to_invalidate)
176
+ elif level == PreservationLevel.DOMINANCE:
177
+ # Invalidate analyses that depend on dominance
178
+ to_invalidate = []
179
+ for name, analysis in self._analyses.items():
180
+ info = analysis.get_info()
181
+ if "dominance" not in info.requires:
182
+ to_invalidate.append(name)
183
+ self.invalidate(to_invalidate)
184
+ # PreservationLevel.ALL preserves everything
185
+
186
+
187
+ class PassScheduler:
188
+ """Schedules passes based on dependencies and optimization level."""
189
+
190
+ def __init__(self, registry: PassRegistry) -> None:
191
+ """Initialize the pass scheduler.
192
+
193
+ Args:
194
+ registry: Pass registry.
195
+ """
196
+ self.registry = registry
197
+
198
+ def schedule_passes(
199
+ self,
200
+ pass_names: list[str],
201
+ optimization_level: int = 1,
202
+ ) -> list[str]:
203
+ """Schedule passes in optimal order.
204
+
205
+ Args:
206
+ pass_names: Requested passes.
207
+ optimization_level: Optimization level (0-3).
208
+
209
+ Returns:
210
+ Ordered list of passes to run.
211
+ """
212
+ # Build dependency graph
213
+ dependencies: dict[str, set[str]] = {}
214
+ for name in pass_names:
215
+ info = self.registry.get_info(name)
216
+ if info:
217
+ dependencies[name] = set(info.requires)
218
+
219
+ # Topological sort with cycle detection
220
+ scheduled = []
221
+ visited = set()
222
+ visiting = set()
223
+
224
+ def visit(name: str) -> None:
225
+ if name in visited:
226
+ return
227
+ if name in visiting:
228
+ raise ValueError(f"Circular dependency detected involving {name}")
229
+
230
+ visiting.add(name)
231
+
232
+ # Visit dependencies first
233
+ for dep in dependencies.get(name, set()):
234
+ if dep not in pass_names:
235
+ # Add required dependency
236
+ pass_names.append(dep)
237
+ dep_info = self.registry.get_info(dep)
238
+ if dep_info:
239
+ dependencies[dep] = set(dep_info.requires)
240
+ visit(dep)
241
+
242
+ visiting.remove(name)
243
+ visited.add(name)
244
+ scheduled.append(name)
245
+
246
+ for name in pass_names:
247
+ visit(name)
248
+
249
+ # Apply optimization level heuristics
250
+ if optimization_level == 0:
251
+ # No optimizations
252
+ scheduled = [
253
+ n for n in scheduled if (info := self.registry.get_info(n)) and info.pass_type != PassType.OPTIMIZATION
254
+ ]
255
+ elif optimization_level >= 2:
256
+ # Add aggressive optimizations
257
+ # Could add more passes based on level
258
+ pass
259
+
260
+ return scheduled
261
+
262
+
263
+ class PassManager:
264
+ """Main pass manager for running optimization pipelines."""
265
+
266
+ def __init__(self) -> None:
267
+ """Initialize the pass manager."""
268
+ self.registry = PassRegistry()
269
+ self.analysis_manager = AnalysisManager()
270
+ self.scheduler = PassScheduler(self.registry)
271
+ self.stats: dict[str, dict[str, int]] = {}
272
+ self.debug_mode = False
273
+
274
+ def register_pass(self, pass_class: type[Pass]) -> None:
275
+ """Register a pass with the manager.
276
+
277
+ Args:
278
+ pass_class: Pass class to register.
279
+ """
280
+ self.registry.register(pass_class)
281
+
282
+ def run_passes(
283
+ self,
284
+ module: MIRModule,
285
+ pass_names: list[str],
286
+ optimization_level: int = 1,
287
+ ) -> bool:
288
+ """Run a sequence of passes on a module.
289
+
290
+ Args:
291
+ module: Module to optimize.
292
+ pass_names: List of pass names to run.
293
+ optimization_level: Optimization level (0-3).
294
+
295
+ Returns:
296
+ True if the module was modified.
297
+ """
298
+ # Schedule passes
299
+ scheduled = self.scheduler.schedule_passes(pass_names, optimization_level)
300
+
301
+ if self.debug_mode:
302
+ print(f"Scheduled passes: {scheduled}")
303
+
304
+ modified = False
305
+ for pass_name in scheduled:
306
+ pass_instance = self.registry.get_pass(pass_name)
307
+ if not pass_instance:
308
+ print(f"Warning: Pass '{pass_name}' not found")
309
+ continue
310
+
311
+ # Set up analysis manager for optimization passes
312
+ if isinstance(pass_instance, OptimizationPass):
313
+ pass_instance.analysis_manager = self.analysis_manager
314
+
315
+ # Initialize pass
316
+ pass_instance.initialize()
317
+ pass_instance.debug_mode = self.debug_mode
318
+
319
+ # Run pass
320
+ pass_info = pass_instance.get_info()
321
+ if pass_info.pass_type == PassType.ANALYSIS:
322
+ # Register analysis
323
+ if isinstance(pass_instance, AnalysisPass):
324
+ self.analysis_manager.register_analysis(
325
+ pass_name,
326
+ pass_instance,
327
+ )
328
+ # Run analysis to populate cache
329
+ if isinstance(pass_instance, ModuleAnalysisPass):
330
+ pass_instance.run_on_module(module)
331
+ elif isinstance(pass_instance, FunctionAnalysisPass):
332
+ for function in module.functions.values():
333
+ pass_instance.run_on_function(function)
334
+ else:
335
+ # Run optimization/utility pass
336
+ if isinstance(pass_instance, ModulePass):
337
+ if pass_instance.run_on_module(module):
338
+ modified = True
339
+ elif isinstance(pass_instance, FunctionPass):
340
+ if pass_instance.run_on_module(module):
341
+ modified = True
342
+
343
+ # Handle analysis preservation
344
+ self.analysis_manager.preserve_analyses(pass_info.preserves)
345
+
346
+ # Finalize pass
347
+ pass_instance.finalize()
348
+
349
+ # Collect statistics
350
+ self.stats[pass_name] = pass_instance.get_stats()
351
+
352
+ if self.debug_mode and self.stats[pass_name]:
353
+ print(f" {pass_name}: {self.stats[pass_name]}")
354
+
355
+ return modified
356
+
357
+ def run_function_pass(
358
+ self,
359
+ function: MIRFunction,
360
+ pass_name: str,
361
+ ) -> bool:
362
+ """Run a single function pass.
363
+
364
+ Args:
365
+ function: Function to optimize.
366
+ pass_name: Pass name.
367
+
368
+ Returns:
369
+ True if the function was modified.
370
+ """
371
+ pass_instance = self.registry.get_pass(pass_name)
372
+ if not pass_instance or not isinstance(pass_instance, FunctionPass):
373
+ return False
374
+
375
+ pass_instance.initialize()
376
+ modified = pass_instance.run_on_function(function)
377
+ pass_instance.finalize()
378
+
379
+ return modified
380
+
381
+ def get_statistics(self) -> dict[str, dict[str, int]]:
382
+ """Get statistics from all passes.
383
+
384
+ Returns:
385
+ Dictionary of pass statistics.
386
+ """
387
+ return self.stats.copy()
388
+
389
+ def reset_statistics(self) -> None:
390
+ """Reset all statistics."""
391
+ self.stats.clear()
@@ -0,0 +1,26 @@
1
+ """Profiling infrastructure for MIR optimization.
2
+
3
+ This module provides profile-guided optimization (PGO) support for the MIR
4
+ optimization framework, enabling data-driven optimization decisions based on
5
+ runtime behavior.
6
+ """
7
+
8
+ from machine_dialect.mir.profiling.profile_collector import ProfileCollector
9
+ from machine_dialect.mir.profiling.profile_data import (
10
+ BranchProfile,
11
+ FunctionProfile,
12
+ LoopProfile,
13
+ ProfileData,
14
+ )
15
+ from machine_dialect.mir.profiling.profile_reader import ProfileReader
16
+ from machine_dialect.mir.profiling.profile_writer import ProfileWriter
17
+
18
+ __all__ = [
19
+ "BranchProfile",
20
+ "FunctionProfile",
21
+ "LoopProfile",
22
+ "ProfileCollector",
23
+ "ProfileData",
24
+ "ProfileReader",
25
+ "ProfileWriter",
26
+ ]