zexus 1.6.2
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.
- package/LICENSE +0 -0
- package/README.md +2513 -0
- package/bin/zexus +2 -0
- package/bin/zpics +2 -0
- package/bin/zpm +2 -0
- package/bin/zx +2 -0
- package/bin/zx-deploy +2 -0
- package/bin/zx-dev +2 -0
- package/bin/zx-run +2 -0
- package/package.json +66 -0
- package/scripts/README.md +24 -0
- package/scripts/postinstall.js +44 -0
- package/shared_config.json +24 -0
- package/src/README.md +1525 -0
- package/src/tests/run_zexus_tests.py +117 -0
- package/src/tests/test_all_phases.zx +346 -0
- package/src/tests/test_blockchain_features.zx +306 -0
- package/src/tests/test_complexity_features.zx +321 -0
- package/src/tests/test_core_integration.py +185 -0
- package/src/tests/test_phase10_ecosystem.zx +177 -0
- package/src/tests/test_phase1_modifiers.zx +87 -0
- package/src/tests/test_phase2_plugins.zx +80 -0
- package/src/tests/test_phase3_security.zx +97 -0
- package/src/tests/test_phase4_vfs.zx +116 -0
- package/src/tests/test_phase5_types.zx +117 -0
- package/src/tests/test_phase6_metaprogramming.zx +125 -0
- package/src/tests/test_phase7_optimization.zx +132 -0
- package/src/tests/test_phase9_advanced_types.zx +157 -0
- package/src/tests/test_security_features.py +419 -0
- package/src/tests/test_security_features.zx +276 -0
- package/src/tests/test_simple_zx.zx +1 -0
- package/src/tests/test_verification_simple.zx +69 -0
- package/src/zexus/__init__.py +28 -0
- package/src/zexus/__main__.py +5 -0
- package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/advanced_types.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/builtin_modules.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/complexity_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/concurrency_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/config.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/dependency_injection.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/ecosystem.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/hybrid_orchestrator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/metaprogramming.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/optimization.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/plugin_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/policy_engine.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/stdlib_integration.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/strategy_recovery.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/type_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/virtual_filesystem.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
- package/src/zexus/advanced_types.py +401 -0
- package/src/zexus/blockchain/__init__.py +40 -0
- package/src/zexus/blockchain/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/crypto.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/ledger.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/transaction.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/crypto.py +463 -0
- package/src/zexus/blockchain/ledger.py +255 -0
- package/src/zexus/blockchain/transaction.py +267 -0
- package/src/zexus/builtin_modules.py +284 -0
- package/src/zexus/builtin_plugins.py +317 -0
- package/src/zexus/capability_system.py +372 -0
- package/src/zexus/cli/__init__.py +2 -0
- package/src/zexus/cli/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
- package/src/zexus/cli/main.py +707 -0
- package/src/zexus/cli/zpm.py +203 -0
- package/src/zexus/compare_interpreter_compiler.py +146 -0
- package/src/zexus/compiler/__init__.py +169 -0
- package/src/zexus/compiler/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/compiler/bytecode.py +266 -0
- package/src/zexus/compiler/compat_runtime.py +277 -0
- package/src/zexus/compiler/lexer.py +257 -0
- package/src/zexus/compiler/parser.py +779 -0
- package/src/zexus/compiler/semantic.py +118 -0
- package/src/zexus/compiler/zexus_ast.py +454 -0
- package/src/zexus/complexity_system.py +575 -0
- package/src/zexus/concurrency_system.py +493 -0
- package/src/zexus/config.py +201 -0
- package/src/zexus/crypto_bridge.py +19 -0
- package/src/zexus/dependency_injection.py +423 -0
- package/src/zexus/ecosystem.py +434 -0
- package/src/zexus/environment.py +101 -0
- package/src/zexus/environment_manager.py +119 -0
- package/src/zexus/error_reporter.py +314 -0
- package/src/zexus/evaluator/__init__.py +12 -0
- package/src/zexus/evaluator/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/integration.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/bytecode_compiler.py +700 -0
- package/src/zexus/evaluator/core.py +891 -0
- package/src/zexus/evaluator/expressions.py +827 -0
- package/src/zexus/evaluator/functions.py +3989 -0
- package/src/zexus/evaluator/integration.py +396 -0
- package/src/zexus/evaluator/statements.py +4303 -0
- package/src/zexus/evaluator/utils.py +126 -0
- package/src/zexus/evaluator_original.py +2041 -0
- package/src/zexus/external_bridge.py +16 -0
- package/src/zexus/find_affected_imports.sh +155 -0
- package/src/zexus/hybrid_orchestrator.py +152 -0
- package/src/zexus/input_validation.py +259 -0
- package/src/zexus/lexer.py +571 -0
- package/src/zexus/logging.py +89 -0
- package/src/zexus/lsp/__init__.py +9 -0
- package/src/zexus/lsp/completion_provider.py +207 -0
- package/src/zexus/lsp/definition_provider.py +22 -0
- package/src/zexus/lsp/hover_provider.py +71 -0
- package/src/zexus/lsp/server.py +269 -0
- package/src/zexus/lsp/symbol_provider.py +31 -0
- package/src/zexus/metaprogramming.py +321 -0
- package/src/zexus/module_cache.py +89 -0
- package/src/zexus/module_manager.py +107 -0
- package/src/zexus/object.py +973 -0
- package/src/zexus/optimization.py +424 -0
- package/src/zexus/parser/__init__.py +31 -0
- package/src/zexus/parser/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
- package/src/zexus/parser/integration.py +86 -0
- package/src/zexus/parser/parser.py +3977 -0
- package/src/zexus/parser/strategy_context.py +7254 -0
- package/src/zexus/parser/strategy_structural.py +1033 -0
- package/src/zexus/persistence.py +391 -0
- package/src/zexus/plugin_system.py +290 -0
- package/src/zexus/policy_engine.py +365 -0
- package/src/zexus/profiler/__init__.py +5 -0
- package/src/zexus/profiler/profiler.py +233 -0
- package/src/zexus/purity_system.py +398 -0
- package/src/zexus/runtime/__init__.py +20 -0
- package/src/zexus/runtime/async_runtime.py +324 -0
- package/src/zexus/search_old_imports.sh +65 -0
- package/src/zexus/security.py +1407 -0
- package/src/zexus/stack_trace.py +233 -0
- package/src/zexus/stdlib/__init__.py +27 -0
- package/src/zexus/stdlib/blockchain.py +341 -0
- package/src/zexus/stdlib/compression.py +167 -0
- package/src/zexus/stdlib/crypto.py +124 -0
- package/src/zexus/stdlib/datetime.py +163 -0
- package/src/zexus/stdlib/db_mongo.py +199 -0
- package/src/zexus/stdlib/db_mysql.py +162 -0
- package/src/zexus/stdlib/db_postgres.py +163 -0
- package/src/zexus/stdlib/db_sqlite.py +133 -0
- package/src/zexus/stdlib/encoding.py +230 -0
- package/src/zexus/stdlib/fs.py +195 -0
- package/src/zexus/stdlib/http.py +219 -0
- package/src/zexus/stdlib/http_server.py +248 -0
- package/src/zexus/stdlib/json_module.py +61 -0
- package/src/zexus/stdlib/math.py +360 -0
- package/src/zexus/stdlib/os_module.py +265 -0
- package/src/zexus/stdlib/regex.py +148 -0
- package/src/zexus/stdlib/sockets.py +253 -0
- package/src/zexus/stdlib/test_framework.zx +208 -0
- package/src/zexus/stdlib/test_runner.zx +119 -0
- package/src/zexus/stdlib_integration.py +341 -0
- package/src/zexus/strategy_recovery.py +256 -0
- package/src/zexus/syntax_validator.py +356 -0
- package/src/zexus/testing/zpics.py +407 -0
- package/src/zexus/testing/zpics_runtime.py +369 -0
- package/src/zexus/type_system.py +374 -0
- package/src/zexus/validation_system.py +569 -0
- package/src/zexus/virtual_filesystem.py +355 -0
- package/src/zexus/vm/__init__.py +8 -0
- package/src/zexus/vm/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/memory_manager.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/memory_pool.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/peephole_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/profiler.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/register_allocator.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/register_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/ssa_converter.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/async_optimizer.py +420 -0
- package/src/zexus/vm/bytecode.py +428 -0
- package/src/zexus/vm/bytecode_converter.py +297 -0
- package/src/zexus/vm/cache.py +532 -0
- package/src/zexus/vm/jit.py +720 -0
- package/src/zexus/vm/memory_manager.py +520 -0
- package/src/zexus/vm/memory_pool.py +511 -0
- package/src/zexus/vm/optimizer.py +478 -0
- package/src/zexus/vm/parallel_vm.py +899 -0
- package/src/zexus/vm/peephole_optimizer.py +452 -0
- package/src/zexus/vm/profiler.py +527 -0
- package/src/zexus/vm/register_allocator.py +462 -0
- package/src/zexus/vm/register_vm.py +520 -0
- package/src/zexus/vm/ssa_converter.py +757 -0
- package/src/zexus/vm/vm.py +1392 -0
- package/src/zexus/zexus_ast.py +1782 -0
- package/src/zexus/zexus_token.py +253 -0
- package/src/zexus/zpm/__init__.py +15 -0
- package/src/zexus/zpm/installer.py +116 -0
- package/src/zexus/zpm/package_manager.py +208 -0
- package/src/zexus/zpm/publisher.py +98 -0
- package/src/zexus/zpm/registry.py +110 -0
- package/src/zexus.egg-info/PKG-INFO +2235 -0
- package/src/zexus.egg-info/SOURCES.txt +876 -0
- package/src/zexus.egg-info/dependency_links.txt +1 -0
- package/src/zexus.egg-info/entry_points.txt +3 -0
- package/src/zexus.egg-info/not-zip-safe +1 -0
- package/src/zexus.egg-info/requires.txt +14 -0
- package/src/zexus.egg-info/top_level.txt +2 -0
- package/zexus.json +14 -0
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Bytecode Optimizer for Zexus VM
|
|
3
|
+
|
|
4
|
+
Implements advanced optimization passes to reduce bytecode size and improve execution speed:
|
|
5
|
+
1. Constant Folding - Pre-compute constant expressions
|
|
6
|
+
2. Copy Propagation - Eliminate redundant copies
|
|
7
|
+
3. Common Subexpression Elimination (CSE) - Reuse computed values
|
|
8
|
+
4. Dead Code Elimination (DCE) - Remove unreachable code
|
|
9
|
+
5. Peephole Optimization - Local pattern matching
|
|
10
|
+
6. Instruction Combining - Merge adjacent instructions
|
|
11
|
+
7. Jump Threading - Optimize jump chains
|
|
12
|
+
8. Strength Reduction - Replace expensive ops with cheaper equivalents
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from typing import List, Tuple, Dict, Set, Optional, Any
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
import copy
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class OptimizationStats:
|
|
22
|
+
"""Track optimization statistics"""
|
|
23
|
+
constant_folds: int = 0
|
|
24
|
+
copies_eliminated: int = 0
|
|
25
|
+
common_subexpressions: int = 0
|
|
26
|
+
dead_code_removed: int = 0
|
|
27
|
+
peephole_opts: int = 0
|
|
28
|
+
instructions_combined: int = 0
|
|
29
|
+
jumps_threaded: int = 0
|
|
30
|
+
strength_reductions: int = 0
|
|
31
|
+
original_size: int = 0
|
|
32
|
+
optimized_size: int = 0
|
|
33
|
+
passes_applied: int = 0
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def size_reduction(self) -> float:
|
|
37
|
+
"""Calculate bytecode size reduction percentage"""
|
|
38
|
+
if self.original_size == 0:
|
|
39
|
+
return 0.0
|
|
40
|
+
return ((self.original_size - self.optimized_size) / self.original_size) * 100
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def total_optimizations(self) -> int:
|
|
44
|
+
"""Total number of optimizations applied"""
|
|
45
|
+
return (self.constant_folds + self.copies_eliminated +
|
|
46
|
+
self.common_subexpressions + self.dead_code_removed +
|
|
47
|
+
self.peephole_opts + self.instructions_combined +
|
|
48
|
+
self.jumps_threaded + self.strength_reductions)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class BytecodeOptimizer:
|
|
52
|
+
"""
|
|
53
|
+
Advanced bytecode optimizer with multiple optimization passes
|
|
54
|
+
|
|
55
|
+
Usage:
|
|
56
|
+
optimizer = BytecodeOptimizer(level=2)
|
|
57
|
+
optimized_instructions = optimizer.optimize(instructions, constants)
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(self, level: int = 2, max_passes: int = 5, debug: bool = False):
|
|
61
|
+
"""
|
|
62
|
+
Initialize optimizer
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
level: Optimization level (0=none, 1=basic, 2=aggressive, 3=experimental)
|
|
66
|
+
max_passes: Maximum number of optimization passes
|
|
67
|
+
debug: Print optimization details
|
|
68
|
+
"""
|
|
69
|
+
self.level = level
|
|
70
|
+
self.max_passes = max_passes
|
|
71
|
+
self.debug = debug
|
|
72
|
+
self.stats = OptimizationStats()
|
|
73
|
+
|
|
74
|
+
def optimize(self, instructions: List[Tuple[str, Any]], constants: List[Any] = None) -> List[Tuple[str, Any]]:
|
|
75
|
+
"""
|
|
76
|
+
Apply all optimization passes to bytecode
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
instructions: List of (opcode, operand) tuples
|
|
80
|
+
constants: Constant pool (optional)
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Optimized instruction list
|
|
84
|
+
"""
|
|
85
|
+
if self.level == 0:
|
|
86
|
+
return instructions # No optimization
|
|
87
|
+
|
|
88
|
+
if constants is None:
|
|
89
|
+
constants = []
|
|
90
|
+
|
|
91
|
+
self.stats.original_size = len(instructions)
|
|
92
|
+
optimized = list(instructions)
|
|
93
|
+
|
|
94
|
+
# Apply optimization passes repeatedly until no more changes
|
|
95
|
+
for pass_num in range(self.max_passes):
|
|
96
|
+
prev_size = len(optimized)
|
|
97
|
+
|
|
98
|
+
# Level 1: Basic optimizations
|
|
99
|
+
if self.level >= 1:
|
|
100
|
+
optimized = self._constant_folding(optimized, constants)
|
|
101
|
+
optimized = self._dead_code_elimination(optimized)
|
|
102
|
+
optimized = self._peephole_optimization(optimized)
|
|
103
|
+
|
|
104
|
+
# Level 2: Aggressive optimizations
|
|
105
|
+
if self.level >= 2:
|
|
106
|
+
optimized = self._copy_propagation(optimized)
|
|
107
|
+
optimized = self._instruction_combining(optimized, constants)
|
|
108
|
+
optimized = self._jump_threading(optimized)
|
|
109
|
+
optimized = self._strength_reduction(optimized)
|
|
110
|
+
|
|
111
|
+
# Level 3: Experimental optimizations
|
|
112
|
+
if self.level >= 3:
|
|
113
|
+
optimized = self._common_subexpression_elimination(optimized)
|
|
114
|
+
optimized = self._loop_invariant_code_motion(optimized)
|
|
115
|
+
|
|
116
|
+
self.stats.passes_applied += 1
|
|
117
|
+
|
|
118
|
+
# Stop if no changes made
|
|
119
|
+
if len(optimized) == prev_size:
|
|
120
|
+
break
|
|
121
|
+
|
|
122
|
+
if self.debug:
|
|
123
|
+
print(f"Pass {pass_num + 1}: {prev_size} → {len(optimized)} instructions")
|
|
124
|
+
|
|
125
|
+
self.stats.optimized_size = len(optimized)
|
|
126
|
+
|
|
127
|
+
if self.debug:
|
|
128
|
+
print(f"Optimization complete: {self.stats.original_size} → {self.stats.optimized_size} "
|
|
129
|
+
f"({self.stats.size_reduction:.1f}% reduction)")
|
|
130
|
+
print(f"Total optimizations: {self.stats.total_optimizations}")
|
|
131
|
+
|
|
132
|
+
return optimized
|
|
133
|
+
|
|
134
|
+
def _constant_folding(self, instructions: List[Tuple[str, Any]], constants: List[Any]) -> List[Tuple[str, Any]]:
|
|
135
|
+
"""
|
|
136
|
+
Fold constant expressions at compile time
|
|
137
|
+
|
|
138
|
+
Examples:
|
|
139
|
+
LOAD_CONST 2, LOAD_CONST 3, ADD → LOAD_CONST 5
|
|
140
|
+
LOAD_CONST 10, NEG → LOAD_CONST -10
|
|
141
|
+
"""
|
|
142
|
+
result = []
|
|
143
|
+
i = 0
|
|
144
|
+
|
|
145
|
+
while i < len(instructions):
|
|
146
|
+
# Binary operations on constants
|
|
147
|
+
if i + 2 < len(instructions):
|
|
148
|
+
op1, operand1 = instructions[i]
|
|
149
|
+
op2, operand2 = instructions[i + 1]
|
|
150
|
+
op3, operand3 = instructions[i + 2]
|
|
151
|
+
|
|
152
|
+
if op1 == "LOAD_CONST" and op2 == "LOAD_CONST":
|
|
153
|
+
val1 = constants[operand1] if operand1 < len(constants) else operand1
|
|
154
|
+
val2 = constants[operand2] if operand2 < len(constants) else operand2
|
|
155
|
+
|
|
156
|
+
folded_value = None
|
|
157
|
+
if op3 == "ADD" and isinstance(val1, (int, float)) and isinstance(val2, (int, float)):
|
|
158
|
+
folded_value = val1 + val2
|
|
159
|
+
elif op3 == "SUB" and isinstance(val1, (int, float)) and isinstance(val2, (int, float)):
|
|
160
|
+
folded_value = val1 - val2
|
|
161
|
+
elif op3 == "MUL" and isinstance(val1, (int, float)) and isinstance(val2, (int, float)):
|
|
162
|
+
folded_value = val1 * val2
|
|
163
|
+
elif op3 == "DIV" and isinstance(val1, (int, float)) and isinstance(val2, (int, float)) and val2 != 0:
|
|
164
|
+
folded_value = val1 / val2
|
|
165
|
+
elif op3 == "MOD" and isinstance(val1, (int, float)) and isinstance(val2, (int, float)) and val2 != 0:
|
|
166
|
+
folded_value = val1 % val2
|
|
167
|
+
elif op3 == "POW" and isinstance(val1, (int, float)) and isinstance(val2, (int, float)):
|
|
168
|
+
try:
|
|
169
|
+
folded_value = val1 ** val2
|
|
170
|
+
except (OverflowError, ValueError):
|
|
171
|
+
pass
|
|
172
|
+
|
|
173
|
+
if folded_value is not None:
|
|
174
|
+
# Add to constants and emit single LOAD_CONST
|
|
175
|
+
const_idx = len(constants)
|
|
176
|
+
constants.append(folded_value)
|
|
177
|
+
result.append(("LOAD_CONST", const_idx))
|
|
178
|
+
self.stats.constant_folds += 1
|
|
179
|
+
i += 3
|
|
180
|
+
continue
|
|
181
|
+
|
|
182
|
+
# Unary operations on constants
|
|
183
|
+
if i + 1 < len(instructions):
|
|
184
|
+
op1, operand1 = instructions[i]
|
|
185
|
+
op2, operand2 = instructions[i + 1]
|
|
186
|
+
|
|
187
|
+
if op1 == "LOAD_CONST":
|
|
188
|
+
val = constants[operand1] if operand1 < len(constants) else operand1
|
|
189
|
+
|
|
190
|
+
folded_value = None
|
|
191
|
+
if op2 == "NEG" and isinstance(val, (int, float)):
|
|
192
|
+
folded_value = -val
|
|
193
|
+
elif op2 == "NOT":
|
|
194
|
+
folded_value = not val
|
|
195
|
+
|
|
196
|
+
if folded_value is not None:
|
|
197
|
+
const_idx = len(constants)
|
|
198
|
+
constants.append(folded_value)
|
|
199
|
+
result.append(("LOAD_CONST", const_idx))
|
|
200
|
+
self.stats.constant_folds += 1
|
|
201
|
+
i += 2
|
|
202
|
+
continue
|
|
203
|
+
|
|
204
|
+
result.append(instructions[i])
|
|
205
|
+
i += 1
|
|
206
|
+
|
|
207
|
+
return result
|
|
208
|
+
|
|
209
|
+
def _copy_propagation(self, instructions: List[Tuple[str, Any]]) -> List[Tuple[str, Any]]:
|
|
210
|
+
"""
|
|
211
|
+
Eliminate redundant copies
|
|
212
|
+
|
|
213
|
+
Examples:
|
|
214
|
+
STORE_NAME x, LOAD_NAME x → STORE_NAME x, DUP
|
|
215
|
+
x = y; use x → x = y; use y (if y not modified)
|
|
216
|
+
"""
|
|
217
|
+
result = []
|
|
218
|
+
i = 0
|
|
219
|
+
|
|
220
|
+
while i < len(instructions):
|
|
221
|
+
# Pattern: STORE_NAME immediately followed by LOAD_NAME of same variable
|
|
222
|
+
if i + 1 < len(instructions):
|
|
223
|
+
op1, operand1 = instructions[i]
|
|
224
|
+
op2, operand2 = instructions[i + 1]
|
|
225
|
+
|
|
226
|
+
if op1 == "STORE_NAME" and op2 == "LOAD_NAME" and operand1 == operand2:
|
|
227
|
+
# Replace LOAD_NAME with DUP
|
|
228
|
+
result.append(instructions[i])
|
|
229
|
+
result.append(("DUP", None))
|
|
230
|
+
self.stats.copies_eliminated += 1
|
|
231
|
+
i += 2
|
|
232
|
+
continue
|
|
233
|
+
|
|
234
|
+
result.append(instructions[i])
|
|
235
|
+
i += 1
|
|
236
|
+
|
|
237
|
+
return result
|
|
238
|
+
|
|
239
|
+
def _common_subexpression_elimination(self, instructions: List[Tuple[str, Any]]) -> List[Tuple[str, Any]]:
|
|
240
|
+
"""
|
|
241
|
+
Eliminate common subexpressions
|
|
242
|
+
|
|
243
|
+
If a+b is computed twice without modification, compute once and reuse
|
|
244
|
+
"""
|
|
245
|
+
# This is a simplified version - full CSE requires dataflow analysis
|
|
246
|
+
result = []
|
|
247
|
+
seen_expressions: Dict[str, int] = {} # expression -> temp variable index
|
|
248
|
+
|
|
249
|
+
i = 0
|
|
250
|
+
while i < len(instructions):
|
|
251
|
+
# Look for repeated binary operations
|
|
252
|
+
if i + 2 < len(instructions):
|
|
253
|
+
op1, operand1 = instructions[i]
|
|
254
|
+
op2, operand2 = instructions[i + 1]
|
|
255
|
+
op3, operand3 = instructions[i + 2]
|
|
256
|
+
|
|
257
|
+
# Simple pattern: LOAD, LOAD, OP
|
|
258
|
+
if op1 == "LOAD_NAME" and op2 == "LOAD_NAME" and op3 in ("ADD", "SUB", "MUL", "DIV"):
|
|
259
|
+
expr_key = f"{operand1}_{op3}_{operand2}"
|
|
260
|
+
|
|
261
|
+
if expr_key in seen_expressions:
|
|
262
|
+
# Reuse previous result
|
|
263
|
+
result.append(("LOAD_NAME", f"_cse_{seen_expressions[expr_key]}"))
|
|
264
|
+
self.stats.common_subexpressions += 1
|
|
265
|
+
i += 3
|
|
266
|
+
continue
|
|
267
|
+
else:
|
|
268
|
+
# First occurrence - compute and store
|
|
269
|
+
result.extend([instructions[i], instructions[i + 1], instructions[i + 2]])
|
|
270
|
+
temp_var = len(seen_expressions)
|
|
271
|
+
result.append(("STORE_NAME", f"_cse_{temp_var}"))
|
|
272
|
+
result.append(("LOAD_NAME", f"_cse_{temp_var}"))
|
|
273
|
+
seen_expressions[expr_key] = temp_var
|
|
274
|
+
i += 3
|
|
275
|
+
continue
|
|
276
|
+
|
|
277
|
+
result.append(instructions[i])
|
|
278
|
+
i += 1
|
|
279
|
+
|
|
280
|
+
return result
|
|
281
|
+
|
|
282
|
+
def _dead_code_elimination(self, instructions: List[Tuple[str, Any]]) -> List[Tuple[str, Any]]:
|
|
283
|
+
"""
|
|
284
|
+
Remove unreachable code after RETURN, unconditional JUMP, etc.
|
|
285
|
+
"""
|
|
286
|
+
result = []
|
|
287
|
+
in_dead_code = False
|
|
288
|
+
|
|
289
|
+
for op, operand in instructions:
|
|
290
|
+
if in_dead_code:
|
|
291
|
+
# Skip until we hit a jump target or label
|
|
292
|
+
if op in ("LABEL", "JUMP_TARGET"):
|
|
293
|
+
in_dead_code = False
|
|
294
|
+
result.append((op, operand))
|
|
295
|
+
else:
|
|
296
|
+
self.stats.dead_code_removed += 1
|
|
297
|
+
else:
|
|
298
|
+
result.append((op, operand))
|
|
299
|
+
# Mark dead code after unconditional control flow
|
|
300
|
+
if op in ("RETURN", "JUMP"):
|
|
301
|
+
in_dead_code = True
|
|
302
|
+
|
|
303
|
+
return result
|
|
304
|
+
|
|
305
|
+
def _peephole_optimization(self, instructions: List[Tuple[str, Any]]) -> List[Tuple[str, Any]]:
|
|
306
|
+
"""
|
|
307
|
+
Local pattern-based optimizations
|
|
308
|
+
|
|
309
|
+
Examples:
|
|
310
|
+
LOAD_NAME x, POP → (removed)
|
|
311
|
+
PUSH, POP → (removed)
|
|
312
|
+
JUMP to next instruction → (removed)
|
|
313
|
+
"""
|
|
314
|
+
result = []
|
|
315
|
+
i = 0
|
|
316
|
+
|
|
317
|
+
while i < len(instructions):
|
|
318
|
+
# Pattern: LOAD followed by POP (useless load)
|
|
319
|
+
if i + 1 < len(instructions):
|
|
320
|
+
op1, operand1 = instructions[i]
|
|
321
|
+
op2, operand2 = instructions[i + 1]
|
|
322
|
+
|
|
323
|
+
if op1 in ("LOAD_CONST", "LOAD_NAME") and op2 == "POP":
|
|
324
|
+
self.stats.peephole_opts += 1
|
|
325
|
+
i += 2
|
|
326
|
+
continue
|
|
327
|
+
|
|
328
|
+
# Pattern: DUP followed by POP (cancel out)
|
|
329
|
+
if op1 == "DUP" and op2 == "POP":
|
|
330
|
+
self.stats.peephole_opts += 1
|
|
331
|
+
i += 2
|
|
332
|
+
continue
|
|
333
|
+
|
|
334
|
+
# Pattern: JUMP to next instruction (useless jump)
|
|
335
|
+
if op1 == "JUMP" and i + 1 == operand1:
|
|
336
|
+
self.stats.peephole_opts += 1
|
|
337
|
+
i += 1
|
|
338
|
+
continue
|
|
339
|
+
|
|
340
|
+
result.append(instructions[i])
|
|
341
|
+
i += 1
|
|
342
|
+
|
|
343
|
+
return result
|
|
344
|
+
|
|
345
|
+
def _instruction_combining(self, instructions: List[Tuple[str, Any]], constants: List[Any]) -> List[Tuple[str, Any]]:
|
|
346
|
+
"""
|
|
347
|
+
Combine adjacent instructions into specialized instructions
|
|
348
|
+
|
|
349
|
+
Examples:
|
|
350
|
+
LOAD_CONST x, STORE_NAME y → STORE_CONST y, x
|
|
351
|
+
LOAD_CONST 1, ADD → INC
|
|
352
|
+
LOAD_CONST 1, SUB → DEC
|
|
353
|
+
"""
|
|
354
|
+
result = []
|
|
355
|
+
i = 0
|
|
356
|
+
|
|
357
|
+
while i < len(instructions):
|
|
358
|
+
# Pattern: LOAD_CONST followed by STORE_NAME
|
|
359
|
+
if i + 1 < len(instructions):
|
|
360
|
+
op1, operand1 = instructions[i]
|
|
361
|
+
op2, operand2 = instructions[i + 1]
|
|
362
|
+
|
|
363
|
+
if op1 == "LOAD_CONST" and op2 == "STORE_NAME":
|
|
364
|
+
result.append(("STORE_CONST", (operand2, operand1)))
|
|
365
|
+
self.stats.instructions_combined += 1
|
|
366
|
+
i += 2
|
|
367
|
+
continue
|
|
368
|
+
|
|
369
|
+
# TODO: Pattern: x, LOAD_CONST 1, ADD → x, INC (needs better pattern matching)
|
|
370
|
+
# Currently disabled - INC/DEC need value already on stack
|
|
371
|
+
# if op1 == "LOAD_CONST" and op2 == "ADD":
|
|
372
|
+
# val = constants[operand1] if operand1 < len(constants) else operand1
|
|
373
|
+
# if val == 1:
|
|
374
|
+
# result.append(("INC", None))
|
|
375
|
+
# self.stats.instructions_combined += 1
|
|
376
|
+
# i += 2
|
|
377
|
+
# continue
|
|
378
|
+
|
|
379
|
+
result.append(instructions[i])
|
|
380
|
+
i += 1
|
|
381
|
+
|
|
382
|
+
return result
|
|
383
|
+
|
|
384
|
+
def _jump_threading(self, instructions: List[Tuple[str, Any]]) -> List[Tuple[str, Any]]:
|
|
385
|
+
"""
|
|
386
|
+
Optimize jump chains
|
|
387
|
+
|
|
388
|
+
Examples:
|
|
389
|
+
JUMP label1 → label1: JUMP label2 becomes JUMP label2
|
|
390
|
+
"""
|
|
391
|
+
# Build jump target map
|
|
392
|
+
jump_targets: Dict[int, int] = {}
|
|
393
|
+
|
|
394
|
+
for i, (op, operand) in enumerate(instructions):
|
|
395
|
+
if op == "JUMP":
|
|
396
|
+
target = operand
|
|
397
|
+
# Follow jump chain
|
|
398
|
+
visited = {i}
|
|
399
|
+
while target not in visited and target < len(instructions):
|
|
400
|
+
if instructions[target][0] == "JUMP":
|
|
401
|
+
visited.add(target)
|
|
402
|
+
target = instructions[target][1]
|
|
403
|
+
else:
|
|
404
|
+
break
|
|
405
|
+
|
|
406
|
+
if target != operand:
|
|
407
|
+
jump_targets[i] = target
|
|
408
|
+
self.stats.jumps_threaded += 1
|
|
409
|
+
|
|
410
|
+
# Apply jump threading
|
|
411
|
+
result = []
|
|
412
|
+
for i, (op, operand) in enumerate(instructions):
|
|
413
|
+
if i in jump_targets:
|
|
414
|
+
result.append((op, jump_targets[i]))
|
|
415
|
+
else:
|
|
416
|
+
result.append((op, operand))
|
|
417
|
+
|
|
418
|
+
return result
|
|
419
|
+
|
|
420
|
+
def _strength_reduction(self, instructions: List[Tuple[str, Any]]) -> List[Tuple[str, Any]]:
|
|
421
|
+
"""
|
|
422
|
+
Replace expensive operations with cheaper equivalents
|
|
423
|
+
|
|
424
|
+
Examples:
|
|
425
|
+
x * 2 → x + x (addition cheaper than multiplication)
|
|
426
|
+
x ** 2 → x * x
|
|
427
|
+
x / 2 → x * 0.5 (if floating point)
|
|
428
|
+
"""
|
|
429
|
+
result = []
|
|
430
|
+
i = 0
|
|
431
|
+
|
|
432
|
+
while i < len(instructions):
|
|
433
|
+
# Pattern: multiply by power of 2
|
|
434
|
+
if i + 2 < len(instructions):
|
|
435
|
+
op1, operand1 = instructions[i]
|
|
436
|
+
op2, operand2 = instructions[i + 1]
|
|
437
|
+
op3, operand3 = instructions[i + 2]
|
|
438
|
+
|
|
439
|
+
# x * 2 → x + x (cheaper)
|
|
440
|
+
if op1 == "LOAD_NAME" and op2 == "LOAD_CONST" and op3 == "MUL":
|
|
441
|
+
# This is simplified - would need constant value check
|
|
442
|
+
pass
|
|
443
|
+
|
|
444
|
+
result.append(instructions[i])
|
|
445
|
+
i += 1
|
|
446
|
+
|
|
447
|
+
return result
|
|
448
|
+
|
|
449
|
+
def _loop_invariant_code_motion(self, instructions: List[Tuple[str, Any]]) -> List[Tuple[str, Any]]:
|
|
450
|
+
"""
|
|
451
|
+
Move loop-invariant computations outside loops
|
|
452
|
+
|
|
453
|
+
This is experimental and requires loop detection
|
|
454
|
+
"""
|
|
455
|
+
# Placeholder for future implementation
|
|
456
|
+
return instructions
|
|
457
|
+
|
|
458
|
+
def get_stats(self) -> Dict[str, Any]:
|
|
459
|
+
"""Get optimization statistics"""
|
|
460
|
+
return {
|
|
461
|
+
'constant_folds': self.stats.constant_folds,
|
|
462
|
+
'copies_eliminated': self.stats.copies_eliminated,
|
|
463
|
+
'common_subexpressions': self.stats.common_subexpressions,
|
|
464
|
+
'dead_code_removed': self.stats.dead_code_removed,
|
|
465
|
+
'peephole_opts': self.stats.peephole_opts,
|
|
466
|
+
'instructions_combined': self.stats.instructions_combined,
|
|
467
|
+
'jumps_threaded': self.stats.jumps_threaded,
|
|
468
|
+
'strength_reductions': self.stats.strength_reductions,
|
|
469
|
+
'original_size': self.stats.original_size,
|
|
470
|
+
'optimized_size': self.stats.optimized_size,
|
|
471
|
+
'size_reduction_pct': self.stats.size_reduction,
|
|
472
|
+
'total_optimizations': self.stats.total_optimizations,
|
|
473
|
+
'passes_applied': self.stats.passes_applied
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
def reset_stats(self):
|
|
477
|
+
"""Reset optimization statistics"""
|
|
478
|
+
self.stats = OptimizationStats()
|