module LLVM.Analysis.UsesOf ( UseSummary, computeUsesOf, usedBy ) where import qualified Data.Foldable as F import Data.HashMap.Strict ( HashMap ) import qualified Data.HashMap.Strict as HM import qualified Data.HashSet as HS import Data.Maybe ( fromMaybe ) import LLVM.Analysis data UseSummary = UseSummary (HashMap Value [Instruction]) -- | Compute the uses of every value in the 'Module' -- -- This information can be used to answer the query: -- -- > usedBy useSummary foo -- -- which will return all of the Instructions that reference -- the provided value @foo@. -- -- Note that this is a simple index. It does not look through bitcasts -- at all. computeUsesOf :: Module -> UseSummary computeUsesOf m = UseSummary $ fmap HS.toList uses where uses = F.foldl' funcUses HM.empty fs fs = moduleDefinedFunctions m funcUses acc f = F.foldl' addInstUses acc (functionInstructions f) addInstUses acc i = F.foldl' (addUses i) acc (instructionOperands i) addUses i acc v = HM.insertWith HS.union v (HS.singleton i) acc -- | > usedBy summ val -- -- Find the instructions using @val@ in the function that @summ@ was -- computed for. usedBy :: UseSummary -> Value -> [Instruction] usedBy (UseSummary m) v = fromMaybe [] $ HM.lookup v m