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,268 @@
1
+ """MIR Value Representations.
2
+
3
+ This module defines the various value types used in MIR instructions,
4
+ including temporaries, variables, constants, and function references.
5
+ """
6
+
7
+ from abc import ABC, abstractmethod
8
+ from enum import Enum
9
+ from typing import Any
10
+
11
+ from .mir_types import MIRType, MIRUnionType, infer_type
12
+
13
+
14
+ class VariableScope(Enum):
15
+ """Scope of a variable in the program."""
16
+
17
+ GLOBAL = "global" # Module-level variables
18
+ PARAMETER = "param" # Function parameters
19
+ LOCAL = "local" # Function-local variables
20
+
21
+
22
+ class MIRValue(ABC):
23
+ """Base class for all MIR values with rich metadata."""
24
+
25
+ def __init__(self, mir_type: MIRType | MIRUnionType) -> None:
26
+ """Initialize a MIR value with rich metadata.
27
+
28
+ Args:
29
+ mir_type: The type of the value (can be union type).
30
+ """
31
+ self.type = mir_type
32
+ # Additional metadata for union types
33
+ self.union_type: MIRUnionType | None = None
34
+ if isinstance(mir_type, MIRUnionType):
35
+ self.union_type = mir_type
36
+ self.type = MIRType.UNKNOWN # Base type is unknown for unions
37
+
38
+ # Rich metadata fields
39
+ from machine_dialect.mir.dataflow import Range
40
+
41
+ self.known_range: Range | None = None # Value range for numeric types
42
+ self.is_non_null: bool = False # Guaranteed non-null/non-empty
43
+ self.is_non_zero: bool = False # Guaranteed non-zero
44
+ self.alignment: int | None = None # Memory alignment in bytes
45
+ self.provenance: str | None = None # Source of this value (e.g., "user_input", "constant")
46
+ self.is_loop_invariant: bool = False # True if value doesn't change in loops
47
+ self.is_pure: bool = True # True if computing this value has no side effects
48
+
49
+ @abstractmethod
50
+ def __str__(self) -> str:
51
+ """Return string representation of the value."""
52
+ pass
53
+
54
+ @abstractmethod
55
+ def __eq__(self, other: object) -> bool:
56
+ """Check equality with another value."""
57
+ pass
58
+
59
+ @abstractmethod
60
+ def __hash__(self) -> int:
61
+ """Return hash of the value."""
62
+ pass
63
+
64
+
65
+ class Temp(MIRValue):
66
+ """Temporary value in SSA form.
67
+
68
+ Temporaries are compiler-generated values used to hold intermediate
69
+ results in three-address code.
70
+ """
71
+
72
+ _next_id = 0
73
+
74
+ def __init__(self, mir_type: MIRType | MIRUnionType, temp_id: int | None = None) -> None:
75
+ """Initialize a temporary.
76
+
77
+ Args:
78
+ mir_type: The type of the temporary (can be union type).
79
+ temp_id: Optional explicit ID. If None, auto-generated.
80
+ """
81
+ super().__init__(mir_type)
82
+ if temp_id is None:
83
+ self.id = Temp._next_id
84
+ Temp._next_id += 1
85
+ else:
86
+ self.id = temp_id
87
+
88
+ def __str__(self) -> str:
89
+ """Return string representation (e.g., 't1')."""
90
+ return f"t{self.id}"
91
+
92
+ def __eq__(self, other: object) -> bool:
93
+ """Check equality based on ID."""
94
+ return isinstance(other, Temp) and self.id == other.id
95
+
96
+ def __hash__(self) -> int:
97
+ """Hash based on ID."""
98
+ return hash(("temp", self.id))
99
+
100
+ @classmethod
101
+ def reset_counter(cls) -> None:
102
+ """Reset the temporary ID counter (useful for tests)."""
103
+ cls._next_id = 0
104
+
105
+
106
+ class Variable(MIRValue):
107
+ """User-defined variable.
108
+
109
+ Variables represent named values from the source program.
110
+ In SSA form, these may be versioned (e.g., x_1, x_2).
111
+ """
112
+
113
+ def __init__(self, name: str, mir_type: MIRType | MIRUnionType, version: int = 0) -> None:
114
+ """Initialize a variable.
115
+
116
+ Args:
117
+ name: The variable name.
118
+ mir_type: The type of the variable (can be union type).
119
+ version: SSA version number (0 for non-SSA).
120
+ """
121
+ super().__init__(mir_type)
122
+ self.name = name
123
+ self.version = version
124
+
125
+ def __str__(self) -> str:
126
+ """Return string representation."""
127
+ if self.version > 0:
128
+ return f"{self.name}.{self.version}"
129
+ return self.name
130
+
131
+ def __eq__(self, other: object) -> bool:
132
+ """Check equality based on name and version."""
133
+ return isinstance(other, Variable) and self.name == other.name and self.version == other.version
134
+
135
+ def __hash__(self) -> int:
136
+ """Hash based on name and version."""
137
+ return hash(("var", self.name, self.version))
138
+
139
+ def with_version(self, version: int) -> "Variable":
140
+ """Create a new variable with a different version.
141
+
142
+ Args:
143
+ version: The new version number.
144
+
145
+ Returns:
146
+ A new Variable with the same name and type but different version.
147
+ """
148
+ return Variable(self.name, self.type, version)
149
+
150
+
151
+ class ScopedVariable(Variable):
152
+ """Variable with explicit scope information.
153
+
154
+ This extends Variable to track whether it's a global, parameter, or local variable.
155
+ """
156
+
157
+ def __init__(
158
+ self,
159
+ name: str,
160
+ scope: VariableScope,
161
+ mir_type: MIRType | MIRUnionType,
162
+ version: int = 0,
163
+ ) -> None:
164
+ """Initialize a scoped variable.
165
+
166
+ Args:
167
+ name: The variable name.
168
+ scope: The scope of the variable.
169
+ mir_type: The type of the variable.
170
+ version: SSA version number (0 for non-SSA).
171
+ """
172
+ super().__init__(name, mir_type, version)
173
+ self.scope = scope
174
+
175
+ def __str__(self) -> str:
176
+ """Return string representation."""
177
+ base = super().__str__()
178
+ if self.scope == VariableScope.LOCAL:
179
+ return f"{base}[local]"
180
+ elif self.scope == VariableScope.PARAMETER:
181
+ return f"{base}[param]"
182
+ return base
183
+
184
+ def __eq__(self, other: object) -> bool:
185
+ """Check equality based on name, version, and scope."""
186
+ if not isinstance(other, ScopedVariable):
187
+ # Allow comparison with regular Variable for compatibility
188
+ return super().__eq__(other)
189
+ return self.name == other.name and self.version == other.version and self.scope == other.scope
190
+
191
+ def __hash__(self) -> int:
192
+ """Hash based on name, version, and scope."""
193
+ return hash(("scoped_var", self.name, self.version, self.scope))
194
+
195
+ def with_version(self, version: int) -> "ScopedVariable":
196
+ """Create a new scoped variable with a different version.
197
+
198
+ Args:
199
+ version: The new version number.
200
+
201
+ Returns:
202
+ A new ScopedVariable with the same name, type, and scope but different version.
203
+ """
204
+ return ScopedVariable(self.name, self.scope, self.type, version)
205
+
206
+
207
+ class Constant(MIRValue):
208
+ """Constant value.
209
+
210
+ Constants represent literal values from the source program.
211
+ """
212
+
213
+ def __init__(self, value: Any, mir_type: MIRType | MIRUnionType | None = None) -> None:
214
+ """Initialize a constant.
215
+
216
+ Args:
217
+ value: The constant value.
218
+ mir_type: Optional explicit type. If None, inferred from value.
219
+ """
220
+ if mir_type is None:
221
+ mir_type = infer_type(value)
222
+ super().__init__(mir_type)
223
+ self.value = value
224
+
225
+ def __str__(self) -> str:
226
+ """Return string representation."""
227
+ if self.type == MIRType.STRING:
228
+ return f'"{self.value}"'
229
+ elif self.type == MIRType.EMPTY:
230
+ return "null"
231
+ else:
232
+ return str(self.value)
233
+
234
+ def __eq__(self, other: object) -> bool:
235
+ """Check equality based on value and type."""
236
+ return isinstance(other, Constant) and self.value == other.value and self.type == other.type
237
+
238
+ def __hash__(self) -> int:
239
+ """Hash based on value and type."""
240
+ return hash(("const", self.value, self.type))
241
+
242
+
243
+ class FunctionRef(MIRValue):
244
+ """Function reference.
245
+
246
+ Represents a reference to a function that can be called.
247
+ """
248
+
249
+ def __init__(self, name: str) -> None:
250
+ """Initialize a function reference.
251
+
252
+ Args:
253
+ name: The function name.
254
+ """
255
+ super().__init__(MIRType.FUNCTION)
256
+ self.name = name
257
+
258
+ def __str__(self) -> str:
259
+ """Return string representation."""
260
+ return f"@{self.name}"
261
+
262
+ def __eq__(self, other: object) -> bool:
263
+ """Check equality based on name."""
264
+ return isinstance(other, FunctionRef) and self.name == other.name
265
+
266
+ def __hash__(self) -> int:
267
+ """Hash based on name."""
268
+ return hash(("func", self.name))
@@ -0,0 +1,233 @@
1
+ """Optimization configuration for MIR passes.
2
+
3
+ This module defines optimization levels and pass configurations
4
+ for the MIR optimization pipeline.
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+ from typing import TYPE_CHECKING
9
+
10
+ if TYPE_CHECKING:
11
+ pass
12
+
13
+
14
+ @dataclass
15
+ class OptimizationConfig:
16
+ """Configuration for optimization passes.
17
+
18
+ Attributes:
19
+ level: Optimization level (0-3).
20
+ enable_inlining: Enable function inlining.
21
+ inline_threshold: Maximum size for inlining.
22
+ enable_loop_opts: Enable loop optimizations.
23
+ unroll_threshold: Maximum iterations for unrolling.
24
+ enable_aggressive_opts: Enable aggressive optimizations.
25
+ debug_passes: Enable debug output from passes.
26
+ pass_statistics: Collect pass statistics.
27
+ """
28
+
29
+ level: int = 1
30
+ enable_inlining: bool = True
31
+ inline_threshold: int = 50
32
+ enable_loop_opts: bool = True
33
+ unroll_threshold: int = 4
34
+ enable_aggressive_opts: bool = False
35
+ debug_passes: bool = False
36
+ pass_statistics: bool = True
37
+
38
+ @classmethod
39
+ def from_level(cls, level: int) -> "OptimizationConfig":
40
+ """Create configuration from optimization level.
41
+
42
+ Args:
43
+ level: Optimization level (0-3).
44
+
45
+ Returns:
46
+ Optimization configuration.
47
+ """
48
+ if level == 0:
49
+ # No optimizations
50
+ return cls(
51
+ level=0,
52
+ enable_inlining=False,
53
+ enable_loop_opts=False,
54
+ enable_aggressive_opts=False,
55
+ )
56
+ elif level == 1:
57
+ # Basic optimizations
58
+ return cls(
59
+ level=1,
60
+ enable_inlining=False,
61
+ inline_threshold=25,
62
+ enable_loop_opts=False,
63
+ enable_aggressive_opts=False,
64
+ )
65
+ elif level == 2:
66
+ # Standard optimizations
67
+ return cls(
68
+ level=2,
69
+ enable_inlining=True,
70
+ inline_threshold=50,
71
+ enable_loop_opts=True,
72
+ unroll_threshold=4,
73
+ enable_aggressive_opts=False,
74
+ )
75
+ elif level >= 3:
76
+ # Aggressive optimizations
77
+ return cls(
78
+ level=3,
79
+ enable_inlining=True,
80
+ inline_threshold=100,
81
+ enable_loop_opts=True,
82
+ unroll_threshold=8,
83
+ enable_aggressive_opts=True,
84
+ )
85
+ else:
86
+ raise ValueError(f"Invalid optimization level: {level}")
87
+
88
+
89
+ class OptimizationPipeline:
90
+ """Defines optimization pass pipelines for different levels."""
91
+
92
+ @staticmethod
93
+ def get_passes(config: OptimizationConfig) -> list[str]:
94
+ """Get list of passes for a configuration.
95
+
96
+ Args:
97
+ config: Optimization configuration.
98
+
99
+ Returns:
100
+ List of pass names to run.
101
+ """
102
+ if config.level == 0:
103
+ # No optimizations, just validation
104
+ return []
105
+
106
+ passes = []
107
+
108
+ # Analysis passes (always needed)
109
+ passes.extend(
110
+ [
111
+ "use-def-chains",
112
+ ]
113
+ )
114
+
115
+ if config.level >= 1:
116
+ # Basic optimizations
117
+ passes.extend(
118
+ [
119
+ "constant-propagation",
120
+ "strength-reduction",
121
+ "dce", # Dead code elimination
122
+ ]
123
+ )
124
+
125
+ if config.level >= 2:
126
+ # Standard optimizations
127
+ passes.extend(
128
+ [
129
+ "cse", # Common subexpression elimination
130
+ ]
131
+ )
132
+
133
+ if config.enable_loop_opts:
134
+ passes.extend(
135
+ [
136
+ "dominance", # Required for loop analysis (also available via DominanceInfo)
137
+ "loop-analysis",
138
+ "licm", # Loop invariant code motion
139
+ "loop-unrolling", # Unroll small loops
140
+ ]
141
+ )
142
+
143
+ # Run another DCE pass after other optimizations
144
+ passes.append("dce")
145
+
146
+ if config.level >= 3:
147
+ # Aggressive optimizations
148
+ if config.enable_aggressive_opts:
149
+ # Advanced analyses
150
+ passes.extend(
151
+ [
152
+ "alias-analysis", # Alias analysis
153
+ "escape-analysis", # Escape analysis for stack allocation
154
+ ]
155
+ )
156
+ # More aggressive versions of passes
157
+ passes.append("constant-propagation") # Run again
158
+ passes.append("cse") # Run again
159
+
160
+ if config.enable_inlining:
161
+ passes.append("inline") # Function inlining
162
+
163
+ # Final cleanup
164
+ passes.extend(
165
+ [
166
+ "strength-reduction",
167
+ "dce",
168
+ ]
169
+ )
170
+
171
+ return passes
172
+
173
+ @staticmethod
174
+ def get_analysis_passes() -> list[str]:
175
+ """Get list of available analysis passes.
176
+
177
+ Note: This function provides a catalog of available passes but is not
178
+ currently used in the optimization pipeline. The main entry point is
179
+ get_passes() which selects passes based on optimization level.
180
+
181
+ Returns:
182
+ List of analysis pass names.
183
+ """
184
+ from machine_dialect.mir.optimization_pass import PassType
185
+ from machine_dialect.mir.optimizations import register_all_passes
186
+ from machine_dialect.mir.pass_manager import PassManager
187
+
188
+ pm = PassManager()
189
+ register_all_passes(pm)
190
+ return pm.registry.list_passes(PassType.ANALYSIS)
191
+
192
+ @staticmethod
193
+ def get_optimization_passes() -> list[str]:
194
+ """Get list of available optimization passes.
195
+
196
+ Returns:
197
+ List of optimization pass names.
198
+ """
199
+ from machine_dialect.mir.optimization_pass import PassType
200
+ from machine_dialect.mir.optimizations import register_all_passes
201
+ from machine_dialect.mir.pass_manager import PassManager
202
+
203
+ pm = PassManager()
204
+ register_all_passes(pm)
205
+ return pm.registry.list_passes(PassType.OPTIMIZATION)
206
+
207
+ @staticmethod
208
+ def get_cleanup_passes() -> list[str]:
209
+ """Get list of cleanup passes.
210
+
211
+ Cleanup passes are lightweight optimizations safe to run at the end
212
+ of the optimization pipeline. Passes can be both optimization and cleanup.
213
+
214
+ Returns:
215
+ List of cleanup pass names.
216
+ """
217
+ from machine_dialect.mir.optimization_pass import PassType
218
+ from machine_dialect.mir.optimizations import register_all_passes
219
+ from machine_dialect.mir.pass_manager import PassManager
220
+
221
+ pm = PassManager()
222
+ register_all_passes(pm)
223
+ return pm.registry.list_passes(PassType.CLEANUP)
224
+
225
+
226
+ # Predefined configurations
227
+ NO_OPT_CONFIG = OptimizationConfig.from_level(0)
228
+ BASIC_OPT_CONFIG = OptimizationConfig.from_level(1)
229
+ STANDARD_OPT_CONFIG = OptimizationConfig.from_level(2)
230
+ AGGRESSIVE_OPT_CONFIG = OptimizationConfig.from_level(3)
231
+
232
+ # Default configuration
233
+ DEFAULT_CONFIG = BASIC_OPT_CONFIG