ddc-core-llvm-0.4.2.1: DDC/Llvm/Analysis/Defs.hs
module DDC.Llvm.Analysis.Defs
( Def (..)
, takeDefOfInstr
, defsOfBlock)
where
import DDC.Llvm.Syntax
import Data.Map (Map)
import qualified Data.Foldable as Seq
import qualified Data.Map as Map
-- | How a variable is defined.
data Def
-- | Variable is given a non-constant value.
= DefVar
-- | Variable is an alias of another variable.
| DefAlias Var
-- | Variable binds some closed, constant expression.
| DefClosedConstant Exp
deriving Show
-- | Collect information about how all the local variables in this block
-- are defined.
defsOfBlock :: Block -> Map Var (Label, Def)
defsOfBlock block
= Map.fromList
$ [ (v, (blockLabel block, def))
| Just (v, def) <- map (takeDefOfInstr . annotInstr)
$ Seq.toList $ blockInstrs block ]
-- | If this instruction defines a variable,
-- then collect some information about it.
takeDefOfInstr :: Instr -> Maybe (Var, Def)
takeDefOfInstr instr
= case instr of
-- Comments
IComment{}
-> Nothing
-- Set meta instruction.
ISet v1 x2
| XVar v2 <- x2
-> Just (v1, DefAlias v2)
| isClosedConstantExp x2
-> Just (v1, DefClosedConstant x2)
| otherwise
-> Just (v1, DefVar)
-- No operation.
INop -> Nothing
-- Phi nodes
-- Even if both branches are constant,
-- we can't form an expression to represent this,
-- so the result gets marked as non-constant.
IPhi v _ -> Just (v, DefVar)
-- Terminator Instructions
IReturn{} -> Nothing
IBranch{} -> Nothing
IBranchIf{} -> Nothing
ISwitch{} -> Nothing
IUnreachable{} -> Nothing
-- Binary Operators
IOp v _ _ _ -> Just (v, DefVar)
-- Conversion Operators
IConv v _ _ -> Just (v, DefVar)
-- Get element pointer
IGet v _ _ -> Just (v, DefVar)
-- Load a value from memory.
ILoad v _ -> Just (v, DefVar)
-- Store a value to memory.
IStore{} -> Nothing
-- Comparisons
ICmp v _ _ _ -> Just (v, DefVar)
-- Function calls
ICall mv _ _ _ _ _ _
-> case mv of
Just v -> Just (v, DefVar)
_ -> Nothing