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.
- machine_dialect/__main__.py +667 -0
- machine_dialect/agent/__init__.py +5 -0
- machine_dialect/agent/agent.py +360 -0
- machine_dialect/ast/__init__.py +95 -0
- machine_dialect/ast/ast_node.py +35 -0
- machine_dialect/ast/call_expression.py +82 -0
- machine_dialect/ast/dict_extraction.py +60 -0
- machine_dialect/ast/expressions.py +439 -0
- machine_dialect/ast/literals.py +309 -0
- machine_dialect/ast/program.py +35 -0
- machine_dialect/ast/statements.py +1433 -0
- machine_dialect/ast/tests/test_ast_string_representation.py +62 -0
- machine_dialect/ast/tests/test_boolean_literal.py +29 -0
- machine_dialect/ast/tests/test_collection_hir.py +138 -0
- machine_dialect/ast/tests/test_define_statement.py +142 -0
- machine_dialect/ast/tests/test_desugar.py +541 -0
- machine_dialect/ast/tests/test_foreach_desugar.py +245 -0
- machine_dialect/cfg/__init__.py +6 -0
- machine_dialect/cfg/config.py +156 -0
- machine_dialect/cfg/examples.py +221 -0
- machine_dialect/cfg/generate_with_ai.py +187 -0
- machine_dialect/cfg/openai_generation.py +200 -0
- machine_dialect/cfg/parser.py +94 -0
- machine_dialect/cfg/tests/__init__.py +1 -0
- machine_dialect/cfg/tests/test_cfg_parser.py +252 -0
- machine_dialect/cfg/tests/test_config.py +188 -0
- machine_dialect/cfg/tests/test_examples.py +391 -0
- machine_dialect/cfg/tests/test_generate_with_ai.py +354 -0
- machine_dialect/cfg/tests/test_openai_generation.py +256 -0
- machine_dialect/codegen/__init__.py +5 -0
- machine_dialect/codegen/bytecode_module.py +89 -0
- machine_dialect/codegen/bytecode_serializer.py +300 -0
- machine_dialect/codegen/opcodes.py +101 -0
- machine_dialect/codegen/register_codegen.py +1996 -0
- machine_dialect/codegen/symtab.py +208 -0
- machine_dialect/codegen/tests/__init__.py +1 -0
- machine_dialect/codegen/tests/test_array_operations_codegen.py +295 -0
- machine_dialect/codegen/tests/test_bytecode_serializer.py +185 -0
- machine_dialect/codegen/tests/test_register_codegen_ssa.py +324 -0
- machine_dialect/codegen/tests/test_symtab.py +418 -0
- machine_dialect/codegen/vm_serializer.py +621 -0
- machine_dialect/compiler/__init__.py +18 -0
- machine_dialect/compiler/compiler.py +197 -0
- machine_dialect/compiler/config.py +149 -0
- machine_dialect/compiler/context.py +149 -0
- machine_dialect/compiler/phases/__init__.py +19 -0
- machine_dialect/compiler/phases/bytecode_optimization.py +90 -0
- machine_dialect/compiler/phases/codegen.py +40 -0
- machine_dialect/compiler/phases/hir_generation.py +39 -0
- machine_dialect/compiler/phases/mir_generation.py +86 -0
- machine_dialect/compiler/phases/optimization.py +110 -0
- machine_dialect/compiler/phases/parsing.py +39 -0
- machine_dialect/compiler/pipeline.py +143 -0
- machine_dialect/compiler/tests/__init__.py +1 -0
- machine_dialect/compiler/tests/test_compiler.py +568 -0
- machine_dialect/compiler/vm_runner.py +173 -0
- machine_dialect/errors/__init__.py +32 -0
- machine_dialect/errors/exceptions.py +369 -0
- machine_dialect/errors/messages.py +82 -0
- machine_dialect/errors/tests/__init__.py +0 -0
- machine_dialect/errors/tests/test_expected_token_errors.py +188 -0
- machine_dialect/errors/tests/test_name_errors.py +118 -0
- machine_dialect/helpers/__init__.py +0 -0
- machine_dialect/helpers/stopwords.py +225 -0
- machine_dialect/helpers/validators.py +30 -0
- machine_dialect/lexer/__init__.py +9 -0
- machine_dialect/lexer/constants.py +23 -0
- machine_dialect/lexer/lexer.py +907 -0
- machine_dialect/lexer/tests/__init__.py +0 -0
- machine_dialect/lexer/tests/helpers.py +86 -0
- machine_dialect/lexer/tests/test_apostrophe_identifiers.py +122 -0
- machine_dialect/lexer/tests/test_backtick_identifiers.py +140 -0
- machine_dialect/lexer/tests/test_boolean_literals.py +108 -0
- machine_dialect/lexer/tests/test_case_insensitive_keywords.py +188 -0
- machine_dialect/lexer/tests/test_comments.py +200 -0
- machine_dialect/lexer/tests/test_double_asterisk_keywords.py +127 -0
- machine_dialect/lexer/tests/test_lexer_position.py +113 -0
- machine_dialect/lexer/tests/test_list_tokens.py +282 -0
- machine_dialect/lexer/tests/test_stopwords.py +80 -0
- machine_dialect/lexer/tests/test_strict_equality.py +129 -0
- machine_dialect/lexer/tests/test_token.py +41 -0
- machine_dialect/lexer/tests/test_tokenization.py +294 -0
- machine_dialect/lexer/tests/test_underscore_literals.py +343 -0
- machine_dialect/lexer/tests/test_url_literals.py +169 -0
- machine_dialect/lexer/tokens.py +487 -0
- machine_dialect/linter/__init__.py +10 -0
- machine_dialect/linter/__main__.py +144 -0
- machine_dialect/linter/linter.py +154 -0
- machine_dialect/linter/rules/__init__.py +8 -0
- machine_dialect/linter/rules/base.py +112 -0
- machine_dialect/linter/rules/statement_termination.py +99 -0
- machine_dialect/linter/tests/__init__.py +1 -0
- machine_dialect/linter/tests/mdrules/__init__.py +0 -0
- machine_dialect/linter/tests/mdrules/test_md101_statement_termination.py +181 -0
- machine_dialect/linter/tests/test_linter.py +81 -0
- machine_dialect/linter/tests/test_rules.py +110 -0
- machine_dialect/linter/tests/test_violations.py +71 -0
- machine_dialect/linter/violations.py +51 -0
- machine_dialect/mir/__init__.py +69 -0
- machine_dialect/mir/analyses/__init__.py +20 -0
- machine_dialect/mir/analyses/alias_analysis.py +315 -0
- machine_dialect/mir/analyses/dominance_analysis.py +49 -0
- machine_dialect/mir/analyses/escape_analysis.py +286 -0
- machine_dialect/mir/analyses/loop_analysis.py +272 -0
- machine_dialect/mir/analyses/tests/test_type_analysis.py +736 -0
- machine_dialect/mir/analyses/type_analysis.py +448 -0
- machine_dialect/mir/analyses/use_def_chains.py +232 -0
- machine_dialect/mir/basic_block.py +385 -0
- machine_dialect/mir/dataflow.py +445 -0
- machine_dialect/mir/debug_info.py +208 -0
- machine_dialect/mir/hir_to_mir.py +1738 -0
- machine_dialect/mir/mir_dumper.py +366 -0
- machine_dialect/mir/mir_function.py +167 -0
- machine_dialect/mir/mir_instructions.py +1877 -0
- machine_dialect/mir/mir_interpreter.py +556 -0
- machine_dialect/mir/mir_module.py +225 -0
- machine_dialect/mir/mir_printer.py +480 -0
- machine_dialect/mir/mir_transformer.py +410 -0
- machine_dialect/mir/mir_types.py +367 -0
- machine_dialect/mir/mir_validation.py +455 -0
- machine_dialect/mir/mir_values.py +268 -0
- machine_dialect/mir/optimization_config.py +233 -0
- machine_dialect/mir/optimization_pass.py +251 -0
- machine_dialect/mir/optimization_pipeline.py +355 -0
- machine_dialect/mir/optimizations/__init__.py +84 -0
- machine_dialect/mir/optimizations/algebraic_simplification.py +733 -0
- machine_dialect/mir/optimizations/branch_prediction.py +372 -0
- machine_dialect/mir/optimizations/constant_propagation.py +634 -0
- machine_dialect/mir/optimizations/cse.py +398 -0
- machine_dialect/mir/optimizations/dce.py +288 -0
- machine_dialect/mir/optimizations/inlining.py +551 -0
- machine_dialect/mir/optimizations/jump_threading.py +487 -0
- machine_dialect/mir/optimizations/licm.py +405 -0
- machine_dialect/mir/optimizations/loop_unrolling.py +366 -0
- machine_dialect/mir/optimizations/strength_reduction.py +422 -0
- machine_dialect/mir/optimizations/tail_call.py +207 -0
- machine_dialect/mir/optimizations/tests/test_loop_unrolling.py +483 -0
- machine_dialect/mir/optimizations/type_narrowing.py +397 -0
- machine_dialect/mir/optimizations/type_specialization.py +447 -0
- machine_dialect/mir/optimizations/type_specific.py +906 -0
- machine_dialect/mir/optimize_mir.py +89 -0
- machine_dialect/mir/pass_manager.py +391 -0
- machine_dialect/mir/profiling/__init__.py +26 -0
- machine_dialect/mir/profiling/profile_collector.py +318 -0
- machine_dialect/mir/profiling/profile_data.py +372 -0
- machine_dialect/mir/profiling/profile_reader.py +272 -0
- machine_dialect/mir/profiling/profile_writer.py +226 -0
- machine_dialect/mir/register_allocation.py +302 -0
- machine_dialect/mir/reporting/__init__.py +17 -0
- machine_dialect/mir/reporting/optimization_reporter.py +314 -0
- machine_dialect/mir/reporting/report_formatter.py +289 -0
- machine_dialect/mir/ssa_construction.py +342 -0
- machine_dialect/mir/tests/__init__.py +1 -0
- machine_dialect/mir/tests/test_algebraic_associativity.py +204 -0
- machine_dialect/mir/tests/test_algebraic_complex_patterns.py +221 -0
- machine_dialect/mir/tests/test_algebraic_division.py +126 -0
- machine_dialect/mir/tests/test_algebraic_simplification.py +863 -0
- machine_dialect/mir/tests/test_basic_block.py +425 -0
- machine_dialect/mir/tests/test_branch_prediction.py +459 -0
- machine_dialect/mir/tests/test_call_lowering.py +168 -0
- machine_dialect/mir/tests/test_collection_lowering.py +604 -0
- machine_dialect/mir/tests/test_cross_block_constant_propagation.py +255 -0
- machine_dialect/mir/tests/test_custom_passes.py +166 -0
- machine_dialect/mir/tests/test_debug_info.py +285 -0
- machine_dialect/mir/tests/test_dict_extraction_lowering.py +192 -0
- machine_dialect/mir/tests/test_dictionary_lowering.py +299 -0
- machine_dialect/mir/tests/test_double_negation.py +231 -0
- machine_dialect/mir/tests/test_escape_analysis.py +233 -0
- machine_dialect/mir/tests/test_hir_to_mir.py +465 -0
- machine_dialect/mir/tests/test_hir_to_mir_complete.py +389 -0
- machine_dialect/mir/tests/test_hir_to_mir_simple.py +130 -0
- machine_dialect/mir/tests/test_inlining.py +435 -0
- machine_dialect/mir/tests/test_licm.py +472 -0
- machine_dialect/mir/tests/test_mir_dumper.py +313 -0
- machine_dialect/mir/tests/test_mir_instructions.py +445 -0
- machine_dialect/mir/tests/test_mir_module.py +860 -0
- machine_dialect/mir/tests/test_mir_printer.py +387 -0
- machine_dialect/mir/tests/test_mir_types.py +123 -0
- machine_dialect/mir/tests/test_mir_types_enhanced.py +132 -0
- machine_dialect/mir/tests/test_mir_validation.py +378 -0
- machine_dialect/mir/tests/test_mir_values.py +168 -0
- machine_dialect/mir/tests/test_one_based_indexing.py +202 -0
- machine_dialect/mir/tests/test_optimization_helpers.py +60 -0
- machine_dialect/mir/tests/test_optimization_pipeline.py +554 -0
- machine_dialect/mir/tests/test_optimization_reporter.py +318 -0
- machine_dialect/mir/tests/test_pass_manager.py +294 -0
- machine_dialect/mir/tests/test_pass_registration.py +64 -0
- machine_dialect/mir/tests/test_profiling.py +356 -0
- machine_dialect/mir/tests/test_register_allocation.py +307 -0
- machine_dialect/mir/tests/test_report_formatters.py +372 -0
- machine_dialect/mir/tests/test_ssa_construction.py +433 -0
- machine_dialect/mir/tests/test_tail_call.py +236 -0
- machine_dialect/mir/tests/test_type_annotated_instructions.py +192 -0
- machine_dialect/mir/tests/test_type_narrowing.py +277 -0
- machine_dialect/mir/tests/test_type_specialization.py +421 -0
- machine_dialect/mir/tests/test_type_specific_optimization.py +545 -0
- machine_dialect/mir/tests/test_type_specific_optimization_advanced.py +382 -0
- machine_dialect/mir/type_inference.py +368 -0
- machine_dialect/parser/__init__.py +12 -0
- machine_dialect/parser/enums.py +45 -0
- machine_dialect/parser/parser.py +3655 -0
- machine_dialect/parser/protocols.py +11 -0
- machine_dialect/parser/symbol_table.py +169 -0
- machine_dialect/parser/tests/__init__.py +0 -0
- machine_dialect/parser/tests/helper_functions.py +193 -0
- machine_dialect/parser/tests/test_action_statements.py +334 -0
- machine_dialect/parser/tests/test_boolean_literal_expressions.py +152 -0
- machine_dialect/parser/tests/test_call_statements.py +154 -0
- machine_dialect/parser/tests/test_call_statements_errors.py +187 -0
- machine_dialect/parser/tests/test_collection_mutations.py +264 -0
- machine_dialect/parser/tests/test_conditional_expressions.py +343 -0
- machine_dialect/parser/tests/test_define_integration.py +468 -0
- machine_dialect/parser/tests/test_define_statements.py +311 -0
- machine_dialect/parser/tests/test_dict_extraction.py +115 -0
- machine_dialect/parser/tests/test_empty_literal.py +155 -0
- machine_dialect/parser/tests/test_float_literal_expressions.py +163 -0
- machine_dialect/parser/tests/test_identifier_expressions.py +57 -0
- machine_dialect/parser/tests/test_if_empty_block.py +61 -0
- machine_dialect/parser/tests/test_if_statements.py +299 -0
- machine_dialect/parser/tests/test_illegal_tokens.py +86 -0
- machine_dialect/parser/tests/test_infix_expressions.py +680 -0
- machine_dialect/parser/tests/test_integer_literal_expressions.py +137 -0
- machine_dialect/parser/tests/test_interaction_statements.py +269 -0
- machine_dialect/parser/tests/test_list_literals.py +277 -0
- machine_dialect/parser/tests/test_no_none_in_ast.py +94 -0
- machine_dialect/parser/tests/test_panic_mode_recovery.py +171 -0
- machine_dialect/parser/tests/test_parse_errors.py +114 -0
- machine_dialect/parser/tests/test_possessive_syntax.py +182 -0
- machine_dialect/parser/tests/test_prefix_expressions.py +415 -0
- machine_dialect/parser/tests/test_program.py +13 -0
- machine_dialect/parser/tests/test_return_statements.py +89 -0
- machine_dialect/parser/tests/test_set_statements.py +152 -0
- machine_dialect/parser/tests/test_strict_equality.py +258 -0
- machine_dialect/parser/tests/test_symbol_table.py +217 -0
- machine_dialect/parser/tests/test_url_literal_expressions.py +209 -0
- machine_dialect/parser/tests/test_utility_statements.py +423 -0
- machine_dialect/parser/token_buffer.py +159 -0
- machine_dialect/repl/__init__.py +3 -0
- machine_dialect/repl/repl.py +426 -0
- machine_dialect/repl/tests/__init__.py +0 -0
- machine_dialect/repl/tests/test_repl.py +606 -0
- machine_dialect/semantic/__init__.py +12 -0
- machine_dialect/semantic/analyzer.py +906 -0
- machine_dialect/semantic/error_messages.py +189 -0
- machine_dialect/semantic/tests/__init__.py +1 -0
- machine_dialect/semantic/tests/test_analyzer.py +364 -0
- machine_dialect/semantic/tests/test_error_messages.py +104 -0
- machine_dialect/tests/edge_cases/__init__.py +10 -0
- machine_dialect/tests/edge_cases/test_boundary_access.py +256 -0
- machine_dialect/tests/edge_cases/test_empty_collections.py +166 -0
- machine_dialect/tests/edge_cases/test_invalid_operations.py +243 -0
- machine_dialect/tests/edge_cases/test_named_list_edge_cases.py +295 -0
- machine_dialect/tests/edge_cases/test_nested_structures.py +313 -0
- machine_dialect/tests/edge_cases/test_type_mixing.py +277 -0
- machine_dialect/tests/integration/test_array_operations_emulation.py +248 -0
- machine_dialect/tests/integration/test_list_compilation.py +395 -0
- machine_dialect/tests/integration/test_lists_and_dictionaries.py +322 -0
- machine_dialect/type_checking/__init__.py +21 -0
- machine_dialect/type_checking/tests/__init__.py +1 -0
- machine_dialect/type_checking/tests/test_type_system.py +230 -0
- machine_dialect/type_checking/type_system.py +270 -0
- machine_dialect-0.1.0a1.dist-info/METADATA +128 -0
- machine_dialect-0.1.0a1.dist-info/RECORD +268 -0
- machine_dialect-0.1.0a1.dist-info/WHEEL +5 -0
- machine_dialect-0.1.0a1.dist-info/entry_points.txt +3 -0
- machine_dialect-0.1.0a1.dist-info/licenses/LICENSE +201 -0
- machine_dialect-0.1.0a1.dist-info/top_level.txt +2 -0
- machine_dialect_vm/__init__.pyi +15 -0
@@ -0,0 +1,733 @@
|
|
1
|
+
"""Advanced algebraic simplification optimization pass.
|
2
|
+
|
3
|
+
This module implements advanced algebraic simplifications at the MIR level,
|
4
|
+
applying mathematical identities and algebraic laws to simplify expressions.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from machine_dialect.mir.basic_block import BasicBlock
|
8
|
+
from machine_dialect.mir.mir_function import MIRFunction
|
9
|
+
from machine_dialect.mir.mir_instructions import (
|
10
|
+
BinaryOp,
|
11
|
+
Copy,
|
12
|
+
LoadConst,
|
13
|
+
MIRInstruction,
|
14
|
+
UnaryOp,
|
15
|
+
)
|
16
|
+
from machine_dialect.mir.mir_transformer import MIRTransformer
|
17
|
+
from machine_dialect.mir.mir_types import MIRType
|
18
|
+
from machine_dialect.mir.mir_values import Constant, MIRValue, Temp
|
19
|
+
from machine_dialect.mir.optimization_pass import (
|
20
|
+
OptimizationPass,
|
21
|
+
PassInfo,
|
22
|
+
PassType,
|
23
|
+
PreservationLevel,
|
24
|
+
)
|
25
|
+
|
26
|
+
|
27
|
+
class AlgebraicSimplification(OptimizationPass):
|
28
|
+
"""Advanced algebraic simplification optimization pass."""
|
29
|
+
|
30
|
+
def get_info(self) -> PassInfo:
|
31
|
+
"""Get pass information.
|
32
|
+
|
33
|
+
Returns:
|
34
|
+
Pass information.
|
35
|
+
"""
|
36
|
+
return PassInfo(
|
37
|
+
name="algebraic-simplification",
|
38
|
+
description="Apply advanced algebraic simplifications and mathematical identities",
|
39
|
+
pass_type=PassType.OPTIMIZATION,
|
40
|
+
requires=[],
|
41
|
+
preserves=PreservationLevel.CFG,
|
42
|
+
)
|
43
|
+
|
44
|
+
def run_on_function(self, function: MIRFunction) -> bool:
|
45
|
+
"""Run algebraic simplification on a function.
|
46
|
+
|
47
|
+
Args:
|
48
|
+
function: The function to optimize.
|
49
|
+
|
50
|
+
Returns:
|
51
|
+
True if the function was modified.
|
52
|
+
"""
|
53
|
+
transformer = MIRTransformer(function)
|
54
|
+
|
55
|
+
for block in function.cfg.blocks.values():
|
56
|
+
self._simplify_block(block, transformer)
|
57
|
+
|
58
|
+
return transformer.modified
|
59
|
+
|
60
|
+
def _simplify_block(self, block: BasicBlock, transformer: MIRTransformer) -> None:
|
61
|
+
"""Apply algebraic simplifications to a block.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
block: The block to optimize.
|
65
|
+
transformer: MIR transformer.
|
66
|
+
"""
|
67
|
+
for inst in list(block.instructions):
|
68
|
+
if isinstance(inst, BinaryOp):
|
69
|
+
self._simplify_binary_op(inst, block, transformer)
|
70
|
+
elif isinstance(inst, UnaryOp):
|
71
|
+
self._simplify_unary_op(inst, block, transformer)
|
72
|
+
|
73
|
+
def _simplify_binary_op(
|
74
|
+
self,
|
75
|
+
inst: BinaryOp,
|
76
|
+
block: BasicBlock,
|
77
|
+
transformer: MIRTransformer,
|
78
|
+
) -> None:
|
79
|
+
"""Apply algebraic simplifications to a binary operation.
|
80
|
+
|
81
|
+
Args:
|
82
|
+
inst: Binary operation instruction.
|
83
|
+
block: Containing block.
|
84
|
+
transformer: MIR transformer.
|
85
|
+
"""
|
86
|
+
# Comparison simplifications
|
87
|
+
if inst.op in ["==", "!=", "<", ">", "<=", ">="]:
|
88
|
+
if self._simplify_comparison(inst, block, transformer):
|
89
|
+
return
|
90
|
+
|
91
|
+
# Bitwise operation simplifications
|
92
|
+
if inst.op in ["&", "|", "^", "<<", ">>"]:
|
93
|
+
if self._simplify_bitwise(inst, block, transformer):
|
94
|
+
return
|
95
|
+
|
96
|
+
# Power operation simplifications
|
97
|
+
if inst.op == "**":
|
98
|
+
if self._simplify_power(inst, block, transformer):
|
99
|
+
return
|
100
|
+
|
101
|
+
# Modulo simplifications
|
102
|
+
if inst.op == "%":
|
103
|
+
if self._simplify_modulo(inst, block, transformer):
|
104
|
+
return
|
105
|
+
|
106
|
+
# Division simplifications
|
107
|
+
if inst.op in ["/", "//"]:
|
108
|
+
if self._simplify_division(inst, block, transformer):
|
109
|
+
return
|
110
|
+
|
111
|
+
# Advanced arithmetic simplifications
|
112
|
+
if inst.op in ["+", "-", "*", "/"]:
|
113
|
+
if self._simplify_advanced_arithmetic(inst, block, transformer):
|
114
|
+
return
|
115
|
+
|
116
|
+
# Complex pattern matching
|
117
|
+
if self._simplify_complex_patterns(inst, block, transformer):
|
118
|
+
return
|
119
|
+
|
120
|
+
def _simplify_unary_op(
|
121
|
+
self,
|
122
|
+
inst: UnaryOp,
|
123
|
+
block: BasicBlock,
|
124
|
+
transformer: MIRTransformer,
|
125
|
+
) -> None:
|
126
|
+
"""Apply algebraic simplifications to a unary operation.
|
127
|
+
|
128
|
+
Args:
|
129
|
+
inst: Unary operation instruction.
|
130
|
+
block: Containing block.
|
131
|
+
transformer: MIR transformer.
|
132
|
+
"""
|
133
|
+
# Double negation elimination: -(-x) = x
|
134
|
+
if inst.op == "-":
|
135
|
+
# Check if operand is result of another negation
|
136
|
+
# This requires def-use chain analysis
|
137
|
+
defining_inst = self._get_defining_instruction(inst.operand, block)
|
138
|
+
if isinstance(defining_inst, UnaryOp) and defining_inst.op == "-":
|
139
|
+
new_inst = Copy(inst.dest, defining_inst.operand, inst.source_location)
|
140
|
+
transformer.replace_instruction(block, inst, new_inst)
|
141
|
+
self.stats["double_negation_eliminated"] = self.stats.get("double_negation_eliminated", 0) + 1
|
142
|
+
return
|
143
|
+
|
144
|
+
# Boolean not simplification: not(not(x)) = x
|
145
|
+
elif inst.op == "not":
|
146
|
+
defining_inst = self._get_defining_instruction(inst.operand, block)
|
147
|
+
if isinstance(defining_inst, UnaryOp) and defining_inst.op == "not":
|
148
|
+
new_inst = Copy(inst.dest, defining_inst.operand, inst.source_location)
|
149
|
+
transformer.replace_instruction(block, inst, new_inst)
|
150
|
+
self.stats["double_not_eliminated"] = self.stats.get("double_not_eliminated", 0) + 1
|
151
|
+
return
|
152
|
+
|
153
|
+
def _simplify_comparison(
|
154
|
+
self,
|
155
|
+
inst: BinaryOp,
|
156
|
+
block: BasicBlock,
|
157
|
+
transformer: MIRTransformer,
|
158
|
+
) -> bool:
|
159
|
+
"""Simplify comparison operations.
|
160
|
+
|
161
|
+
Args:
|
162
|
+
inst: Comparison instruction.
|
163
|
+
block: Containing block.
|
164
|
+
transformer: MIR transformer.
|
165
|
+
|
166
|
+
Returns:
|
167
|
+
True if simplified.
|
168
|
+
"""
|
169
|
+
# x == x → true, x != x → false
|
170
|
+
if self._values_equal(inst.left, inst.right):
|
171
|
+
if inst.op == "==":
|
172
|
+
true_const = Constant(True, MIRType.BOOL)
|
173
|
+
new_inst = LoadConst(inst.dest, true_const, inst.source_location)
|
174
|
+
transformer.replace_instruction(block, inst, new_inst)
|
175
|
+
self.stats["comparison_simplified"] = self.stats.get("comparison_simplified", 0) + 1
|
176
|
+
return True
|
177
|
+
elif inst.op == "!=":
|
178
|
+
false_const = Constant(False, MIRType.BOOL)
|
179
|
+
new_inst = LoadConst(inst.dest, false_const, inst.source_location)
|
180
|
+
transformer.replace_instruction(block, inst, new_inst)
|
181
|
+
self.stats["comparison_simplified"] = self.stats.get("comparison_simplified", 0) + 1
|
182
|
+
return True
|
183
|
+
elif inst.op in ["<", ">"]:
|
184
|
+
# x < x → false, x > x → false
|
185
|
+
false_const = Constant(False, MIRType.BOOL)
|
186
|
+
new_inst = LoadConst(inst.dest, false_const, inst.source_location)
|
187
|
+
transformer.replace_instruction(block, inst, new_inst)
|
188
|
+
self.stats["comparison_simplified"] = self.stats.get("comparison_simplified", 0) + 1
|
189
|
+
return True
|
190
|
+
elif inst.op in ["<=", ">="]:
|
191
|
+
# x <= x → true, x >= x → true
|
192
|
+
true_const = Constant(True, MIRType.BOOL)
|
193
|
+
new_inst = LoadConst(inst.dest, true_const, inst.source_location)
|
194
|
+
transformer.replace_instruction(block, inst, new_inst)
|
195
|
+
self.stats["comparison_simplified"] = self.stats.get("comparison_simplified", 0) + 1
|
196
|
+
return True
|
197
|
+
|
198
|
+
return False
|
199
|
+
|
200
|
+
def _simplify_bitwise(
|
201
|
+
self,
|
202
|
+
inst: BinaryOp,
|
203
|
+
block: BasicBlock,
|
204
|
+
transformer: MIRTransformer,
|
205
|
+
) -> bool:
|
206
|
+
"""Simplify bitwise operations.
|
207
|
+
|
208
|
+
Args:
|
209
|
+
inst: Bitwise operation instruction.
|
210
|
+
block: Containing block.
|
211
|
+
transformer: MIR transformer.
|
212
|
+
|
213
|
+
Returns:
|
214
|
+
True if simplified.
|
215
|
+
"""
|
216
|
+
new_inst: MIRInstruction
|
217
|
+
|
218
|
+
# x & 0 → 0
|
219
|
+
if inst.op == "&":
|
220
|
+
if self._is_zero(inst.right) or self._is_zero(inst.left):
|
221
|
+
zero = Constant(0, MIRType.INT)
|
222
|
+
new_inst = LoadConst(inst.dest, zero, inst.source_location)
|
223
|
+
transformer.replace_instruction(block, inst, new_inst)
|
224
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
225
|
+
return True
|
226
|
+
# x & x → x
|
227
|
+
elif self._values_equal(inst.left, inst.right):
|
228
|
+
new_inst = Copy(inst.dest, inst.left, inst.source_location)
|
229
|
+
transformer.replace_instruction(block, inst, new_inst)
|
230
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
231
|
+
return True
|
232
|
+
# x & ~0 → x (all ones)
|
233
|
+
elif self._is_all_ones(inst.right):
|
234
|
+
new_inst = Copy(inst.dest, inst.left, inst.source_location)
|
235
|
+
transformer.replace_instruction(block, inst, new_inst)
|
236
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
237
|
+
return True
|
238
|
+
elif self._is_all_ones(inst.left):
|
239
|
+
new_inst = Copy(inst.dest, inst.right, inst.source_location)
|
240
|
+
transformer.replace_instruction(block, inst, new_inst)
|
241
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
242
|
+
return True
|
243
|
+
|
244
|
+
# x | 0 → x
|
245
|
+
elif inst.op == "|":
|
246
|
+
if self._is_zero(inst.right):
|
247
|
+
new_inst = Copy(inst.dest, inst.left, inst.source_location)
|
248
|
+
transformer.replace_instruction(block, inst, new_inst)
|
249
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
250
|
+
return True
|
251
|
+
elif self._is_zero(inst.left):
|
252
|
+
new_inst = Copy(inst.dest, inst.right, inst.source_location)
|
253
|
+
transformer.replace_instruction(block, inst, new_inst)
|
254
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
255
|
+
return True
|
256
|
+
# x | x → x
|
257
|
+
elif self._values_equal(inst.left, inst.right):
|
258
|
+
new_inst = Copy(inst.dest, inst.left, inst.source_location)
|
259
|
+
transformer.replace_instruction(block, inst, new_inst)
|
260
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
261
|
+
return True
|
262
|
+
# x | ~0 → ~0 (all ones)
|
263
|
+
elif self._is_all_ones(inst.right) or self._is_all_ones(inst.left):
|
264
|
+
all_ones = Constant(-1, MIRType.INT)
|
265
|
+
new_inst = LoadConst(inst.dest, all_ones, inst.source_location)
|
266
|
+
transformer.replace_instruction(block, inst, new_inst)
|
267
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
268
|
+
return True
|
269
|
+
|
270
|
+
# x ^ 0 → x
|
271
|
+
elif inst.op == "^":
|
272
|
+
if self._is_zero(inst.right):
|
273
|
+
new_inst = Copy(inst.dest, inst.left, inst.source_location)
|
274
|
+
transformer.replace_instruction(block, inst, new_inst)
|
275
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
276
|
+
return True
|
277
|
+
elif self._is_zero(inst.left):
|
278
|
+
new_inst = Copy(inst.dest, inst.right, inst.source_location)
|
279
|
+
transformer.replace_instruction(block, inst, new_inst)
|
280
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
281
|
+
return True
|
282
|
+
# x ^ x → 0
|
283
|
+
elif self._values_equal(inst.left, inst.right):
|
284
|
+
zero = Constant(0, MIRType.INT)
|
285
|
+
new_inst = LoadConst(inst.dest, zero, inst.source_location)
|
286
|
+
transformer.replace_instruction(block, inst, new_inst)
|
287
|
+
self.stats["bitwise_simplified"] = self.stats.get("bitwise_simplified", 0) + 1
|
288
|
+
return True
|
289
|
+
|
290
|
+
# x << 0 → x, x >> 0 → x
|
291
|
+
elif inst.op in ["<<", ">>"]:
|
292
|
+
if self._is_zero(inst.right):
|
293
|
+
new_inst = Copy(inst.dest, inst.left, inst.source_location)
|
294
|
+
transformer.replace_instruction(block, inst, new_inst)
|
295
|
+
self.stats["shift_simplified"] = self.stats.get("shift_simplified", 0) + 1
|
296
|
+
return True
|
297
|
+
|
298
|
+
return False
|
299
|
+
|
300
|
+
def _simplify_power(
|
301
|
+
self,
|
302
|
+
inst: BinaryOp,
|
303
|
+
block: BasicBlock,
|
304
|
+
transformer: MIRTransformer,
|
305
|
+
) -> bool:
|
306
|
+
"""Simplify power operations.
|
307
|
+
|
308
|
+
Args:
|
309
|
+
inst: Power operation instruction.
|
310
|
+
block: Containing block.
|
311
|
+
transformer: MIR transformer.
|
312
|
+
|
313
|
+
Returns:
|
314
|
+
True if simplified.
|
315
|
+
"""
|
316
|
+
new_inst: MIRInstruction
|
317
|
+
|
318
|
+
# x ** 0 → 1
|
319
|
+
if self._is_zero(inst.right):
|
320
|
+
one = Constant(1, MIRType.INT)
|
321
|
+
new_inst = LoadConst(inst.dest, one, inst.source_location)
|
322
|
+
transformer.replace_instruction(block, inst, new_inst)
|
323
|
+
self.stats["power_simplified"] = self.stats.get("power_simplified", 0) + 1
|
324
|
+
return True
|
325
|
+
|
326
|
+
# x ** 1 → x
|
327
|
+
elif self._is_one(inst.right):
|
328
|
+
new_inst = Copy(inst.dest, inst.left, inst.source_location)
|
329
|
+
transformer.replace_instruction(block, inst, new_inst)
|
330
|
+
self.stats["power_simplified"] = self.stats.get("power_simplified", 0) + 1
|
331
|
+
return True
|
332
|
+
|
333
|
+
# x ** 2 → x * x (more efficient)
|
334
|
+
elif self._is_constant_value(inst.right, 2):
|
335
|
+
new_inst = BinaryOp(inst.dest, "*", inst.left, inst.left, inst.source_location)
|
336
|
+
transformer.replace_instruction(block, inst, new_inst)
|
337
|
+
self.stats["power_to_multiply"] = self.stats.get("power_to_multiply", 0) + 1
|
338
|
+
return True
|
339
|
+
|
340
|
+
# 0 ** x → 0 (for x > 0)
|
341
|
+
elif self._is_zero(inst.left):
|
342
|
+
zero = Constant(0, MIRType.INT)
|
343
|
+
new_inst = LoadConst(inst.dest, zero, inst.source_location)
|
344
|
+
transformer.replace_instruction(block, inst, new_inst)
|
345
|
+
self.stats["power_simplified"] = self.stats.get("power_simplified", 0) + 1
|
346
|
+
return True
|
347
|
+
|
348
|
+
# 1 ** x → 1
|
349
|
+
elif self._is_one(inst.left):
|
350
|
+
one = Constant(1, MIRType.INT)
|
351
|
+
new_inst = LoadConst(inst.dest, one, inst.source_location)
|
352
|
+
transformer.replace_instruction(block, inst, new_inst)
|
353
|
+
self.stats["power_simplified"] = self.stats.get("power_simplified", 0) + 1
|
354
|
+
return True
|
355
|
+
|
356
|
+
return False
|
357
|
+
|
358
|
+
def _simplify_modulo(
|
359
|
+
self,
|
360
|
+
inst: BinaryOp,
|
361
|
+
block: BasicBlock,
|
362
|
+
transformer: MIRTransformer,
|
363
|
+
) -> bool:
|
364
|
+
"""Simplify modulo operations.
|
365
|
+
|
366
|
+
Args:
|
367
|
+
inst: Modulo operation instruction.
|
368
|
+
block: Containing block.
|
369
|
+
transformer: MIR transformer.
|
370
|
+
|
371
|
+
Returns:
|
372
|
+
True if simplified.
|
373
|
+
"""
|
374
|
+
new_inst: MIRInstruction
|
375
|
+
|
376
|
+
# x % 1 → 0
|
377
|
+
if self._is_one(inst.right):
|
378
|
+
zero = Constant(0, MIRType.INT)
|
379
|
+
new_inst = LoadConst(inst.dest, zero, inst.source_location)
|
380
|
+
transformer.replace_instruction(block, inst, new_inst)
|
381
|
+
self.stats["modulo_simplified"] = self.stats.get("modulo_simplified", 0) + 1
|
382
|
+
return True
|
383
|
+
|
384
|
+
# x % x → 0 (assuming x != 0)
|
385
|
+
elif self._values_equal(inst.left, inst.right):
|
386
|
+
zero = Constant(0, MIRType.INT)
|
387
|
+
new_inst = LoadConst(inst.dest, zero, inst.source_location)
|
388
|
+
transformer.replace_instruction(block, inst, new_inst)
|
389
|
+
self.stats["modulo_simplified"] = self.stats.get("modulo_simplified", 0) + 1
|
390
|
+
return True
|
391
|
+
|
392
|
+
# 0 % x → 0
|
393
|
+
elif self._is_zero(inst.left):
|
394
|
+
zero = Constant(0, MIRType.INT)
|
395
|
+
new_inst = LoadConst(inst.dest, zero, inst.source_location)
|
396
|
+
transformer.replace_instruction(block, inst, new_inst)
|
397
|
+
self.stats["modulo_simplified"] = self.stats.get("modulo_simplified", 0) + 1
|
398
|
+
return True
|
399
|
+
|
400
|
+
return False
|
401
|
+
|
402
|
+
def _simplify_division(
|
403
|
+
self,
|
404
|
+
inst: BinaryOp,
|
405
|
+
block: BasicBlock,
|
406
|
+
transformer: MIRTransformer,
|
407
|
+
) -> bool:
|
408
|
+
"""Simplify division operations.
|
409
|
+
|
410
|
+
Args:
|
411
|
+
inst: Division operation instruction.
|
412
|
+
block: Containing block.
|
413
|
+
transformer: MIR transformer.
|
414
|
+
|
415
|
+
Returns:
|
416
|
+
True if simplified.
|
417
|
+
"""
|
418
|
+
new_inst: MIRInstruction
|
419
|
+
|
420
|
+
# x / 1 → x
|
421
|
+
if self._is_one(inst.right):
|
422
|
+
new_inst = Copy(inst.dest, inst.left, inst.source_location)
|
423
|
+
transformer.replace_instruction(block, inst, new_inst)
|
424
|
+
self.stats["division_simplified"] = self.stats.get("division_simplified", 0) + 1
|
425
|
+
return True
|
426
|
+
|
427
|
+
# x / x → 1 (assuming x != 0)
|
428
|
+
elif self._values_equal(inst.left, inst.right):
|
429
|
+
one = Constant(1, inst.dest.type if hasattr(inst.dest, "type") else MIRType.INT)
|
430
|
+
new_inst = LoadConst(inst.dest, one, inst.source_location)
|
431
|
+
transformer.replace_instruction(block, inst, new_inst)
|
432
|
+
self.stats["division_simplified"] = self.stats.get("division_simplified", 0) + 1
|
433
|
+
return True
|
434
|
+
|
435
|
+
# 0 / x → 0 (assuming x != 0)
|
436
|
+
elif self._is_zero(inst.left):
|
437
|
+
zero = Constant(0, inst.dest.type if hasattr(inst.dest, "type") else MIRType.INT)
|
438
|
+
new_inst = LoadConst(inst.dest, zero, inst.source_location)
|
439
|
+
transformer.replace_instruction(block, inst, new_inst)
|
440
|
+
self.stats["division_simplified"] = self.stats.get("division_simplified", 0) + 1
|
441
|
+
return True
|
442
|
+
|
443
|
+
# x / -1 → -x
|
444
|
+
elif self._is_constant_value(inst.right, -1):
|
445
|
+
new_inst = UnaryOp(inst.dest, "-", inst.left, inst.source_location)
|
446
|
+
transformer.replace_instruction(block, inst, new_inst)
|
447
|
+
self.stats["division_simplified"] = self.stats.get("division_simplified", 0) + 1
|
448
|
+
return True
|
449
|
+
|
450
|
+
return False
|
451
|
+
|
452
|
+
def _simplify_complex_patterns(
|
453
|
+
self,
|
454
|
+
inst: BinaryOp,
|
455
|
+
block: BasicBlock,
|
456
|
+
transformer: MIRTransformer,
|
457
|
+
) -> bool:
|
458
|
+
"""Apply complex pattern matching across instructions.
|
459
|
+
|
460
|
+
Args:
|
461
|
+
inst: Binary operation instruction.
|
462
|
+
block: Containing block.
|
463
|
+
transformer: MIR transformer.
|
464
|
+
|
465
|
+
Returns:
|
466
|
+
True if simplified.
|
467
|
+
"""
|
468
|
+
# Pattern: (a + b) - b → a
|
469
|
+
if inst.op == "-":
|
470
|
+
left_def = self._get_defining_instruction(inst.left, block)
|
471
|
+
if isinstance(left_def, BinaryOp) and left_def.op == "+":
|
472
|
+
if self._values_equal(left_def.right, inst.right):
|
473
|
+
new_inst = Copy(inst.dest, left_def.left, inst.source_location)
|
474
|
+
transformer.replace_instruction(block, inst, new_inst)
|
475
|
+
self.stats["complex_pattern_matched"] = self.stats.get("complex_pattern_matched", 0) + 1
|
476
|
+
return True
|
477
|
+
elif self._values_equal(left_def.left, inst.right):
|
478
|
+
new_inst = Copy(inst.dest, left_def.right, inst.source_location)
|
479
|
+
transformer.replace_instruction(block, inst, new_inst)
|
480
|
+
self.stats["complex_pattern_matched"] = self.stats.get("complex_pattern_matched", 0) + 1
|
481
|
+
return True
|
482
|
+
|
483
|
+
# Pattern: (a - b) - c → a - (b + c) when b and c are constants
|
484
|
+
if isinstance(left_def, BinaryOp) and left_def.op == "-":
|
485
|
+
if isinstance(left_def.right, Constant) and isinstance(inst.right, Constant):
|
486
|
+
new_const_val = left_def.right.value + inst.right.value
|
487
|
+
new_const = Constant(new_const_val, inst.right.type)
|
488
|
+
binary_inst: MIRInstruction = BinaryOp(
|
489
|
+
inst.dest, "-", left_def.left, new_const, inst.source_location
|
490
|
+
)
|
491
|
+
transformer.replace_instruction(block, inst, binary_inst)
|
492
|
+
self.stats["complex_pattern_matched"] = self.stats.get("complex_pattern_matched", 0) + 1
|
493
|
+
return True
|
494
|
+
|
495
|
+
# Pattern: (a - b) + b → a
|
496
|
+
elif inst.op == "+":
|
497
|
+
left_def = self._get_defining_instruction(inst.left, block)
|
498
|
+
if isinstance(left_def, BinaryOp) and left_def.op == "-":
|
499
|
+
if self._values_equal(left_def.right, inst.right):
|
500
|
+
new_inst = Copy(inst.dest, left_def.left, inst.source_location)
|
501
|
+
transformer.replace_instruction(block, inst, new_inst)
|
502
|
+
self.stats["complex_pattern_matched"] = self.stats.get("complex_pattern_matched", 0) + 1
|
503
|
+
return True
|
504
|
+
|
505
|
+
# Check right side: b + (a - b) → a
|
506
|
+
right_def = self._get_defining_instruction(inst.right, block)
|
507
|
+
if isinstance(right_def, BinaryOp) and right_def.op == "-":
|
508
|
+
if self._values_equal(right_def.right, inst.left):
|
509
|
+
copy_inst: MIRInstruction = Copy(inst.dest, right_def.left, inst.source_location)
|
510
|
+
transformer.replace_instruction(block, inst, copy_inst)
|
511
|
+
self.stats["complex_pattern_matched"] = self.stats.get("complex_pattern_matched", 0) + 1
|
512
|
+
return True
|
513
|
+
|
514
|
+
# Pattern: (a * b) / b → a
|
515
|
+
elif inst.op in ["/", "//"]:
|
516
|
+
left_def = self._get_defining_instruction(inst.left, block)
|
517
|
+
if isinstance(left_def, BinaryOp) and left_def.op == "*":
|
518
|
+
if self._values_equal(left_def.right, inst.right):
|
519
|
+
new_inst = Copy(inst.dest, left_def.left, inst.source_location)
|
520
|
+
transformer.replace_instruction(block, inst, new_inst)
|
521
|
+
self.stats["complex_pattern_matched"] = self.stats.get("complex_pattern_matched", 0) + 1
|
522
|
+
return True
|
523
|
+
elif self._values_equal(left_def.left, inst.right):
|
524
|
+
new_inst = Copy(inst.dest, left_def.right, inst.source_location)
|
525
|
+
transformer.replace_instruction(block, inst, new_inst)
|
526
|
+
self.stats["complex_pattern_matched"] = self.stats.get("complex_pattern_matched", 0) + 1
|
527
|
+
return True
|
528
|
+
|
529
|
+
# Pattern: (a / b) * b → a
|
530
|
+
elif inst.op == "*":
|
531
|
+
left_def = self._get_defining_instruction(inst.left, block)
|
532
|
+
if isinstance(left_def, BinaryOp) and left_def.op in ["/", "//"]:
|
533
|
+
if self._values_equal(left_def.right, inst.right):
|
534
|
+
new_inst = Copy(inst.dest, left_def.left, inst.source_location)
|
535
|
+
transformer.replace_instruction(block, inst, new_inst)
|
536
|
+
self.stats["complex_pattern_matched"] = self.stats.get("complex_pattern_matched", 0) + 1
|
537
|
+
return True
|
538
|
+
|
539
|
+
# Check right side: b * (a / b) → a
|
540
|
+
right_def = self._get_defining_instruction(inst.right, block)
|
541
|
+
if isinstance(right_def, BinaryOp) and right_def.op in ["/", "//"]:
|
542
|
+
if self._values_equal(right_def.right, inst.left):
|
543
|
+
new_inst = Copy(inst.dest, right_def.left, inst.source_location)
|
544
|
+
transformer.replace_instruction(block, inst, new_inst)
|
545
|
+
self.stats["complex_pattern_matched"] = self.stats.get("complex_pattern_matched", 0) + 1
|
546
|
+
return True
|
547
|
+
|
548
|
+
# Pattern: 0 - x → -x
|
549
|
+
if inst.op == "-" and self._is_zero(inst.left):
|
550
|
+
unary_inst: MIRInstruction = UnaryOp(inst.dest, "-", inst.right, inst.source_location)
|
551
|
+
transformer.replace_instruction(block, inst, unary_inst)
|
552
|
+
self.stats["complex_pattern_matched"] = self.stats.get("complex_pattern_matched", 0) + 1
|
553
|
+
return True
|
554
|
+
|
555
|
+
return False
|
556
|
+
|
557
|
+
def _simplify_advanced_arithmetic(
|
558
|
+
self,
|
559
|
+
inst: BinaryOp,
|
560
|
+
block: BasicBlock,
|
561
|
+
transformer: MIRTransformer,
|
562
|
+
) -> bool:
|
563
|
+
"""Apply advanced arithmetic simplifications.
|
564
|
+
|
565
|
+
Args:
|
566
|
+
inst: Arithmetic operation instruction.
|
567
|
+
block: Containing block.
|
568
|
+
transformer: MIR transformer.
|
569
|
+
|
570
|
+
Returns:
|
571
|
+
True if simplified.
|
572
|
+
"""
|
573
|
+
# Check for associativity opportunities
|
574
|
+
# (a + b) + c where b and c are constants → a + (b + c)
|
575
|
+
if inst.op in ["+", "*"]:
|
576
|
+
left_def = self._get_defining_instruction(inst.left, block)
|
577
|
+
if (
|
578
|
+
isinstance(left_def, BinaryOp)
|
579
|
+
and left_def.op == inst.op
|
580
|
+
and isinstance(inst.right, Constant)
|
581
|
+
and isinstance(left_def.right, Constant)
|
582
|
+
):
|
583
|
+
# Compute (b op c)
|
584
|
+
if inst.op == "+":
|
585
|
+
new_const_val = left_def.right.value + inst.right.value
|
586
|
+
else: # "*"
|
587
|
+
new_const_val = left_def.right.value * inst.right.value
|
588
|
+
|
589
|
+
new_const = Constant(new_const_val, inst.right.type)
|
590
|
+
new_inst = BinaryOp(inst.dest, inst.op, left_def.left, new_const, inst.source_location)
|
591
|
+
transformer.replace_instruction(block, inst, new_inst)
|
592
|
+
self.stats["associativity_applied"] = self.stats.get("associativity_applied", 0) + 1
|
593
|
+
return True
|
594
|
+
|
595
|
+
# Also check right side for commutativity: c + (a + b) → (c + b) + a when b and c are constants
|
596
|
+
right_def = self._get_defining_instruction(inst.right, block)
|
597
|
+
if (
|
598
|
+
isinstance(right_def, BinaryOp)
|
599
|
+
and right_def.op == inst.op
|
600
|
+
and isinstance(inst.left, Constant)
|
601
|
+
and isinstance(right_def.right, Constant)
|
602
|
+
):
|
603
|
+
# Compute (c op b)
|
604
|
+
if inst.op == "+":
|
605
|
+
new_const_val = inst.left.value + right_def.right.value
|
606
|
+
else: # "*"
|
607
|
+
new_const_val = inst.left.value * right_def.right.value
|
608
|
+
|
609
|
+
new_const = Constant(new_const_val, inst.left.type)
|
610
|
+
new_inst = BinaryOp(inst.dest, inst.op, new_const, right_def.left, inst.source_location)
|
611
|
+
transformer.replace_instruction(block, inst, new_inst)
|
612
|
+
self.stats["associativity_applied"] = self.stats.get("associativity_applied", 0) + 1
|
613
|
+
return True
|
614
|
+
|
615
|
+
# Check for subtraction associativity: (a - b) - c → a - (b + c) when b and c are constants
|
616
|
+
# This is already handled in _simplify_complex_patterns
|
617
|
+
|
618
|
+
# Apply De Morgan's laws for bitwise operations
|
619
|
+
if self._apply_demorgan_laws(inst, block, transformer):
|
620
|
+
return True
|
621
|
+
|
622
|
+
return False
|
623
|
+
|
624
|
+
def _apply_demorgan_laws(
|
625
|
+
self,
|
626
|
+
inst: BinaryOp,
|
627
|
+
block: BasicBlock,
|
628
|
+
transformer: MIRTransformer,
|
629
|
+
) -> bool:
|
630
|
+
"""Apply De Morgan's laws for bitwise operations.
|
631
|
+
|
632
|
+
Args:
|
633
|
+
inst: Binary operation instruction.
|
634
|
+
block: Containing block.
|
635
|
+
transformer: MIR transformer.
|
636
|
+
|
637
|
+
Returns:
|
638
|
+
True if transformed.
|
639
|
+
"""
|
640
|
+
# De Morgan's Law: ~(a & b) = ~a | ~b
|
641
|
+
# De Morgan's Law: ~(a | b) = ~a & ~b
|
642
|
+
# We look for patterns where the result of AND/OR is negated
|
643
|
+
|
644
|
+
# For now, we'll skip this as it requires tracking how the result is used
|
645
|
+
# This would be better implemented with a pattern matching framework
|
646
|
+
|
647
|
+
return False
|
648
|
+
|
649
|
+
def _get_defining_instruction(
|
650
|
+
self,
|
651
|
+
value: MIRValue,
|
652
|
+
block: BasicBlock,
|
653
|
+
) -> MIRInstruction | None:
|
654
|
+
"""Get the instruction that defines a value.
|
655
|
+
|
656
|
+
Args:
|
657
|
+
value: The value to find definition for.
|
658
|
+
block: The block to search in.
|
659
|
+
|
660
|
+
Returns:
|
661
|
+
Defining instruction or None.
|
662
|
+
"""
|
663
|
+
if not isinstance(value, Temp):
|
664
|
+
return None
|
665
|
+
|
666
|
+
# Search backward in the block for the defining instruction
|
667
|
+
for inst in reversed(block.instructions):
|
668
|
+
if hasattr(inst, "dest") and inst.dest == value:
|
669
|
+
return inst
|
670
|
+
|
671
|
+
return None
|
672
|
+
|
673
|
+
def _is_zero(self, value: MIRValue) -> bool:
|
674
|
+
"""Check if value is zero.
|
675
|
+
|
676
|
+
Args:
|
677
|
+
value: Value to check.
|
678
|
+
|
679
|
+
Returns:
|
680
|
+
True if value is zero.
|
681
|
+
"""
|
682
|
+
return isinstance(value, Constant) and value.value == 0
|
683
|
+
|
684
|
+
def _is_one(self, value: MIRValue) -> bool:
|
685
|
+
"""Check if value is one.
|
686
|
+
|
687
|
+
Args:
|
688
|
+
value: Value to check.
|
689
|
+
|
690
|
+
Returns:
|
691
|
+
True if value is one.
|
692
|
+
"""
|
693
|
+
return isinstance(value, Constant) and value.value == 1
|
694
|
+
|
695
|
+
def _is_all_ones(self, value: MIRValue) -> bool:
|
696
|
+
"""Check if value is all ones (-1 for signed integers).
|
697
|
+
|
698
|
+
Args:
|
699
|
+
value: Value to check.
|
700
|
+
|
701
|
+
Returns:
|
702
|
+
True if value is all ones.
|
703
|
+
"""
|
704
|
+
return isinstance(value, Constant) and value.value == -1
|
705
|
+
|
706
|
+
def _is_constant_value(self, value: MIRValue, expected: int | float) -> bool:
|
707
|
+
"""Check if value is a specific constant.
|
708
|
+
|
709
|
+
Args:
|
710
|
+
value: Value to check.
|
711
|
+
expected: Expected constant value.
|
712
|
+
|
713
|
+
Returns:
|
714
|
+
True if value matches expected.
|
715
|
+
"""
|
716
|
+
return isinstance(value, Constant) and value.value == expected
|
717
|
+
|
718
|
+
def _values_equal(self, v1: MIRValue, v2: MIRValue) -> bool:
|
719
|
+
"""Check if two values are equal.
|
720
|
+
|
721
|
+
Args:
|
722
|
+
v1: First value.
|
723
|
+
v2: Second value.
|
724
|
+
|
725
|
+
Returns:
|
726
|
+
True if values are equal.
|
727
|
+
"""
|
728
|
+
# Simple equality check
|
729
|
+
return v1 == v2
|
730
|
+
|
731
|
+
def finalize(self) -> None:
|
732
|
+
"""Finalize the pass."""
|
733
|
+
pass
|