never executed always true always false
1 module HelVM.HelMA.Automaton.Optimizer.PeepholeOptimizer (
2 peepholeOptimize,
3 ) where
4
5 import HelVM.HelMA.Automaton.Instruction
6
7 import HelVM.HelMA.Automaton.Instruction.Extras.Common
8 import HelVM.HelMA.Automaton.Instruction.Extras.Constructors
9 import HelVM.HelMA.Automaton.Instruction.Extras.Patterns
10
11 import HelVM.HelMA.Automaton.Instruction.Groups.CFInstruction
12 import HelVM.HelMA.Automaton.Instruction.Groups.SMInstruction
13
14 peepholeOptimize :: InstructionList -> InstructionList
15 peepholeOptimize = peepholeOptimize2 . peepholeOptimize1
16
17 peepholeOptimize1 :: InstructionList -> InstructionList
18 peepholeOptimize1 = fix optimize where
19 optimize :: (InstructionList -> InstructionList) -> InstructionList -> InstructionList
20 optimize f (ConsP i : BinaryP op : il) = optimizeImmediateBinary i op <> f il
21 optimize f (ConsP i : HalibutP : il) = optimizeHalibut i : f il
22 optimize f (ConsP i : PickP : il) = optimizePick i : f il
23 optimize f (ConsP c : ConsP a : BranchTP t : il) = optimizeBranch t c a <> f il
24 optimize f (ConsP a : BranchTP t : il) = optimizeBranchLabel t a <> f il
25 optimize f (ConsP a : ConsP v : StoreP : il) = optimizeStoreID v a : f il
26 optimize f (ConsP a : LoadP : il) = optimizeLoadD a : f il
27 optimize f (i : il) = i : f il
28 optimize _ [] = []
29
30 peepholeOptimize2 :: InstructionList -> InstructionList
31 peepholeOptimize2 = fix optimize where
32 optimize :: (InstructionList -> InstructionList) -> InstructionList -> InstructionList
33 optimize f (ConsP c : MoveIP i : BranchTP t : il) = optimizeBranchCondition i t c <> f il
34 optimize f (MoveIP 1 : BranchTP t : il) = branchSwapI t : f il
35 optimize f (ConsP 0 : CopyIP i : SubP : SubP : il) = copyAdd i <> f il
36 optimize f (ConsP 0 : MoveIP i : SubP : SubP : il) = moveAdd i <> f il
37 optimize f (BNeIP i : SubP : il) = [bNeII i , discardI] <> f il
38 optimize f (ConsP d : LoadDP s : StoreP : il) = optimizeMoveD s d : f il
39 optimize f (i : il) = i : f il
40 optimize _ [] = []
41
42 optimizeImmediateBinary :: Integer -> BinaryOperation -> InstructionList
43 optimizeImmediateBinary 0 Sub = []
44 optimizeImmediateBinary 0 Add = []
45 optimizeImmediateBinary 1 Mul = []
46 optimizeImmediateBinary i op = [immediateBinaryI i op]
47
48 optimizeHalibut :: Integer -> Instruction
49 optimizeHalibut i
50 | 0 < i = moveII $ fromIntegral i
51 | otherwise = copyII $ fromIntegral $ negate i
52
53 optimizePick :: Integer -> Instruction
54 optimizePick i
55 | 0 <= i = copyII $ fromIntegral i
56 | otherwise = moveII $ fromIntegral $ negate i
57
58 optimizeBranch :: BranchTest -> Integer -> Integer -> InstructionList
59 optimizeBranch t c a = check $ isJump t c where
60 check True = [jumpII $ fromIntegral a]
61 check _ = []
62
63 optimizeBranchLabel :: BranchTest -> Integer -> InstructionList
64 optimizeBranchLabel t a = [branchI t $ fromIntegral a]
65
66 optimizeBranchCondition :: Index -> BranchTest -> Integer -> InstructionList
67 optimizeBranchCondition 1 t c = optimizeBranchCondition1 t c
68 optimizeBranchCondition i t c = check $ isJump t c where
69 check True = [moveII1 , jumpTI]
70 check _ = [moveII1 , discardI]
71 moveII1 = moveII (i - 1)
72
73 optimizeBranchCondition1 :: BranchTest -> Integer -> InstructionList
74 optimizeBranchCondition1 t c = check $ isJump t c where
75 check True = [jumpTI]
76 check _ = [discardI]
77
78 copyAdd :: Index -> [Instruction]
79 copyAdd 0 = []
80 copyAdd i = [copyII (i - 1) , addI]
81
82 moveAdd :: Index -> [Instruction]
83 moveAdd 0 = []
84 moveAdd 1 = [addI]
85 moveAdd i = [moveII (i - 1) , addI]
86
87 optimizeStoreID :: Integer -> Integer -> Instruction
88 optimizeStoreID v = storeIDI v . fromIntegral
89
90 optimizeLoadD :: Integer -> Instruction
91 optimizeLoadD = loadDI . fromIntegral
92
93 optimizeMoveD :: Index -> Integer -> Instruction
94 optimizeMoveD s d = moveDI s (fromIntegral d)