hLLVM-0.5.0.0: src/Llvm/Pass/Uda.hs
{-# OPTIONS_GHC -cpp #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
#define FLC (FileLoc $(srcLoc))
{-
This module compute the use, def, and Addr of CoreIr
-}
module Llvm.Pass.Uda where
import Llvm.Data.CoreIr
import qualified Data.Set as Ds
import Data.Monoid
import Prelude (Show, Eq, Ord, fst, (.), ($), map, maybe, Maybe, (++), show, Bool(False), undefined, foldl,error
,fmap)
#ifdef DEBUG
import Debug.Trace
#endif
import Llvm.Query.TypeConstValue
import Llvm.Query.IrCxt
import qualified Llvm.Query.TypeConstValue as Tc
class Uda a where
use :: a -> Ds.Set GlobalOrLocalId
def :: a -> Ds.Set LocalId -- defined ssa variables
storeTo :: a -> Ds.Set Value
storeTo _ = Ds.empty
loadFrom :: a -> Ds.Set Value
loadFrom _ = Ds.empty
instance Uda Const where
use c = case c of
C_globalAddr i -> Ds.insert (GolG i) Ds.empty
_ -> Ds.empty
def _ = Ds.empty
instance Uda v => Uda (GetElementPtr s v) where
use (GetElementPtr _ (T _ ptr) indices) = use ptr `Ds.union` (foldl (\p e -> Ds.union p (use e)) Ds.empty indices)
def _ = Ds.empty
instance Uda v => Uda (Maybe v) where
use x = maybe Ds.empty use x
def x = maybe Ds.empty def x
storeTo x = maybe Ds.empty storeTo x
instance Uda v => Uda (T t v) where
use (T _ x) = use x
def (T _ x) = def x
storeTo (T _ x) = storeTo x
instance Uda LocalId where
use x = Ds.insert (GolL x) Ds.empty
def x = Ds.insert x Ds.empty
storeTo x = Ds.insert (Val_ssa x) Ds.empty
instance Uda Value where
use x = case x of
Val_ssa l -> Ds.insert (GolL l) Ds.empty
Val_const c -> use c
def _ = error $ "cannot happen"
storeTo x = Ds.insert x Ds.empty
instance Uda ActualParam where
use ap = case ap of
ActualParamData _ _ _ v _ -> use v
ActualParamLabel _ _ _ v _ -> use v
ActualParamMeta _ -> Ds.empty
def _ = errorLoc FLC $ "cannot happen"
storeTo _ = errorLoc FLC $ "cannot happen"
loadFrom _ = errorLoc FLC $ "cannot happen"
instance Uda x => Uda [x] where
use l = Ds.unions (fmap use l)
def l = Ds.unions (fmap def l)
storeTo l = Ds.unions (fmap storeTo l)
loadFrom l = Ds.unions (fmap loadFrom l)
instance Uda CallSite where
use x = case x of
CsFun _ _ _ _ l _ -> use l
CsAsm _ _ _ _ _ _ l _ -> use l
CsConversion _ _ _ l _ -> use l
instance Uda CInst where
use ci = case ci of
I_alloca{..} -> use size
I_load{..} -> use pointer
I_loadatomic{..} -> use pointer
I_store{..} -> Ds.union (use storedvalue) (use pointer)
I_storeatomic{..} -> Ds.union (use storedvalue) (use pointer)
I_fence{..} -> Ds.empty
I_cmpxchg_I{..} -> Ds.unions [use pointer,use cmpi,use newi]
I_cmpxchg_F{..} -> Ds.unions [use pointer,use cmpf,use newf]
I_cmpxchg_P{..} -> Ds.unions [use pointer,use cmpp,use newp]
I_atomicrmw{..} -> Ds.unions [use pointer,use val]
I_call_fun{..} -> use actualParams
I_call_other{..} -> use callSite
I_extractelement_I{..} -> Ds.unions [use vectorI, use index]
I_extractelement_F{..} -> Ds.unions [use vectorF, use index]
I_extractelement_P{..} -> Ds.unions [use vectorP, use index]
I_bitcast{..} -> use srcP
I_ptrtoint{..} -> use srcP
I_inttoptr{..} -> use srcI
I_add{..} -> use operand1 `mappend` use operand2
I_getelementptr{..} -> use pointer `mappend` (foldl (\p e -> p `mappend` (use e)) Ds.empty indices)
I_getelementptr_V{..} -> use vpointer `mappend` (foldl (\p e -> p `mappend` (use e)) Ds.empty vindices)
I_llvm_dbg_declare{..} -> Ds.empty
I_icmp{..} -> use operand1 `mappend` use operand2
I_icmp_V{..} -> use operand1 `mappend` use operand2
I_va_end{..} -> use pointer
I_va_start{..} -> use pointer
I_va_arg tv _ _ -> use tv
_ -> errorLoc FLC $ "unsupported " ++ show ci
def ci = case ci of
I_alloca{..} -> def result
I_load{..} -> def result
I_store{..} -> Ds.empty
I_bitcast{..} -> def result
I_ptrtoint{..} -> def result
I_inttoptr{..} -> def result
I_add{..} -> def result
I_sub{..} -> def result
I_mul{..} -> def result
I_udiv{..} -> def result
I_sdiv{..} -> def result
I_urem{..} -> def result
I_srem{..} -> def result
I_shl{..} -> def result
I_lshr{..} -> def result
I_ashr{..} -> def result
I_and{..} -> def result
I_or{..} -> def result
I_xor{..} -> def result
I_getelementptr{..} -> def result
I_llvm_dbg_declare{..} -> Ds.empty
I_icmp{..} -> def result
I_icmp_V{..} -> def result
I_trunc{..} -> def result
I_sext{..} -> def result
I_va_start{..} -> Ds.empty
I_va_arg{..} -> def result
I_va_end{..} -> Ds.empty
_ -> errorLoc FLC $ "unsupported " ++ show ci
storeTo ci = case ci of
I_store{..} -> storeTo pointer
I_va_start tv -> storeTo tv
_ -> Ds.empty
loadFrom ci = case ci of
I_load{..} -> let T _ v = pointer
in Ds.insert v Ds.empty
_ -> Ds.empty
instance Uda CInstWithDbg where
use (CInstWithDbg ci _) = use ci
def (CInstWithDbg ci _) = def ci
storeTo (CInstWithDbg ci _) = storeTo ci
loadFrom (CInstWithDbg ci _) = loadFrom ci