Skip to content

Commit e404c73

Browse files
committed
cc-proposed ir opts
1 parent 261ad16 commit e404c73

File tree

3 files changed

+93
-14
lines changed

3 files changed

+93
-14
lines changed

compiler/app/Main.hs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import System.Environment
1111
import Util.FileUtil
1212
import qualified ClosureConv as CC
1313
import qualified IR as CCIR
14-
-- import qualified IROpt
14+
import qualified IROpt
1515
-- import qualified RetRewrite as Rewrite
1616
import qualified CPSOpt as CPSOpt
1717
import qualified IR2JS
@@ -138,9 +138,8 @@ process flags fname input = do
138138

139139
when verbose $ writeFileD "out/out.ir" (show ir)
140140

141-
-- let iropt = IROpt.iropt ir
142-
let iropt = ir
143-
--when verbose $ writeFileD "out/out.iropt" (show iropt)
141+
let iropt = IROpt.iropt ir
142+
when verbose $ writeFileD "out/out.iropt" (show iropt)
144143

145144

146145
--------------------------------------------------

compiler/src/CPSOpt.hs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -406,18 +406,18 @@ state_info = do
406406

407407
failFree :: SimpleTerm -> Bool -- 2021-05-19; AA; hack
408408
failFree st = case st of
409-
Bin op _ _ -> op `elem` [Basics.Eq, Basics.Neq]
410-
Un _ _ -> False
409+
Bin op _ _ -> op `elem` [Basics.Eq, Basics.Neq] -- Equality comparisons are safe (return boolean)
410+
Un _ _ -> False -- Unary operations can fail (e.g., head on empty list, arithmetic on non-numbers)
411411
ValSimpleTerm _ -> True
412412
Tuple _ -> True
413413
Record _ -> True
414414
WithRecord _ _ -> True
415-
ProjField _ _ -> False
416-
ProjIdx _ _ -> False
415+
ProjField _ _ -> False -- Field projection can fail if field doesn't exist
416+
ProjIdx _ _ -> False -- Index projection can fail if index out of bounds
417417
List _ -> True
418-
ListCons _ _ -> False
419-
Base _ -> True
420-
Lib _ _ -> True
418+
ListCons _ _ -> False -- List cons can fail if second arg is not a list
419+
Base _ -> False -- Base function calls can have side effects or fail
420+
Lib _ _ -> False -- Library function calls can have side effects or fail
421421

422422
instance Simplifiable KTerm where
423423
simpl k = do

compiler/src/IROpt.hs

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,84 @@ class PEval a where
118118

119119
markUsed x = tell $ Set.singleton x -- collect the use of the local
120120
markUsed' (VarEnv _) = return ()
121-
markUsed' (VarLocal x) = markUsed x
121+
markUsed' (VarLocal x) = markUsed x
122+
123+
-- | Check if an expression can fail at runtime or has side effects
124+
-- This is used to prevent unsound dead code elimination
125+
canFailOrHasEffects :: IRExpr -> Bool
126+
canFailOrHasEffects expr = case expr of
127+
-- Binary operations that can fail due to type errors
128+
Bin op _ _ -> case op of
129+
-- Arithmetic operations can fail if operands are not numbers
130+
Basics.Plus -> True
131+
Basics.Minus -> True
132+
Basics.Mult -> True
133+
Basics.Div -> True -- Also division by zero
134+
Basics.IntDiv -> True
135+
Basics.Mod -> True
136+
-- Bitwise operations require numbers
137+
Basics.BinAnd -> True
138+
Basics.BinOr -> True
139+
Basics.BinXor -> True
140+
Basics.BinShiftLeft -> True
141+
Basics.BinShiftRight -> True
142+
Basics.BinZeroShiftRight -> True
143+
-- String concatenation can fail if operands are not strings
144+
Basics.Concat -> True
145+
-- Comparisons that require numbers
146+
Basics.Le -> True
147+
Basics.Lt -> True
148+
Basics.Ge -> True
149+
Basics.Gt -> True
150+
-- These are generally safe
151+
Basics.Eq -> False
152+
Basics.Neq -> False
153+
Basics.And -> False
154+
Basics.Or -> False
155+
Basics.HasField -> False
156+
-- Level operations might be safe but conservative
157+
Basics.FlowsTo -> True
158+
Basics.LatticeJoin -> True
159+
Basics.LatticeMeet -> True
160+
Basics.RaisedTo -> True
161+
162+
-- Unary operations
163+
Un op _ -> case op of
164+
-- List/tuple operations can fail
165+
Basics.Head -> True
166+
Basics.Tail -> True
167+
Basics.Fst -> True
168+
Basics.Snd -> True
169+
-- Arithmetic
170+
Basics.UnMinus -> True
171+
-- Length operations are safe if the value is the right type
172+
Basics.ListLength -> True
173+
Basics.TupleLength -> True
174+
Basics.RecordSize -> True
175+
-- Type tests are safe
176+
Basics.IsTuple -> False
177+
Basics.IsList -> False
178+
Basics.IsRecord -> False
179+
-- Level operations
180+
Basics.LevelOf -> False
181+
182+
-- Field/index projections can fail
183+
ProjField _ _ -> True
184+
ProjIdx _ _ -> True
185+
186+
-- List operations
187+
ListCons _ _ -> True -- Second argument must be a list
188+
189+
-- Function calls can have side effects
190+
Base _ -> True
191+
Lib _ _ -> True
192+
193+
-- These are generally safe
194+
Tuple _ -> False
195+
Record _ -> False
196+
WithRecord _ _ -> False -- Assuming the base is a record
197+
List _ -> False
198+
Const _ -> False
122199

123200
-- | Get evaluation of a variable.
124201
varPEval :: VarAccess -> Opt PValue
@@ -239,7 +316,9 @@ irExprPeval e =
239316
Nothing -> def_
240317
_ -> def_
241318
-- TODO Implement optimization for ProjIdx
242-
ProjIdx x idx -> def_
319+
ProjIdx x idx -> do
320+
markUsed' x -- Mark the tuple variable as used
321+
def_
243322
-- ProjIdx x idx -> do
244323
-- v <- varPEval x
245324
-- case v of
@@ -432,7 +511,8 @@ instance PEval IRBBTree where
432511

433512
(BB insts_ tr_, used) <- listen $ bbPeval bb
434513

435-
let isNotDeadAssign (Assign x _) = Set.member x used
514+
let isNotDeadAssign (Assign x e) =
515+
Set.member x used || canFailOrHasEffects e
436516
isNotDeadAssign _ = True
437517

438518
instsFiltered = filter isNotDeadAssign insts_

0 commit comments

Comments
 (0)