Quick actions

cmd+k|ctrl+k

Navigation

Languages

SSA usage caching

Snippet info

Language

Haskell

Visibility

public

Author

rightfold

Created

2017-03-31T21:41:59Z

Updated

2017-03-31T21:53:16Z

module Main
  ( main
  ) where

import Control.Monad (forM_)
import Control.Monad.State (State, runState)
import Data.Map (Map)

import qualified Control.Monad.State.Class as State
import qualified Data.Map as Map

newtype InstructionID = InstructionID Int deriving (Eq, Ord, Show)

data Instruction
  = ConstInstruction Int
  | IncrementInstruction InstructionID
  deriving (Show)

operands :: Instruction -> [InstructionID]
operands (ConstInstruction _) = []
operands (IncrementInstruction operand) = [operand]

type SSA = State (Int, [(InstructionID, Instruction)], Map InstructionID [InstructionID])

freshInstructionID :: SSA InstructionID
freshInstructionID = do
  id <- State.gets $ \(next, _, _) -> next
  State.modify $ \(next, is, us) -> (next + 1, is, us)
  pure $ InstructionID id

appendInstruction :: Instruction -> SSA InstructionID
appendInstruction instruction = do
  id <- freshInstructionID
  State.modify $ \(next, is, us) -> (next, is ++ [(id, instruction)], us)
  forM_ (operands instruction) $ \operand -> do
    let alter Nothing   = Just [id]
        alter (Just os) = Just $ id : os
    State.modify $ \(next, is, us) -> (next, is, Map.alter alter operand us)
  pure id

main :: IO ()
main = print . flip runState (0, [], Map.empty) $ do
  a <- appendInstruction $ ConstInstruction 42
  b <- appendInstruction $ IncrementInstruction a
  pure b
INFO