Changes:
 o - deriving
 o s/Var/Reg/
 o s/M./Map./
 o s/Lit/Const/
 o outfacts are a list instead of a factbase
 o - Call and Return
 o - txToMaybe
 o in constProp s/changeTx and return/ -> Just and Nothing

data WithTop a = Elt a | Top
type ConstFact = Map Reg (WithTop Const)

constLattice = DataflowLattice
  { fact_bot    = Map.empty
  , fact_add_to = stdMapJoin constFactAdd
  , fact_name   = "Const var value" }
  where
    constFactAdd new old = (ch, joined)
      where joined = if new == old then new else Top
            ch = if joined == old then NoChange else SomeChange

varHasConst :: ForwardTransfers Node ConstFact
varHasConst (Label bid)        f = lookupFact constLattice f bid
varHasConst (Assign x (Const l)) f = Map.insert x (Elt l) f
varHasConst (Assign x _)       f = Map.insert x Top f
varHasConst (Store _ _)        f = f
varHasConst (Branch bid)       f = [(bid, f)]
varHasConst (Cond _ tid fid)   f = [(tid, f), (fid, f)]

-- I think the getInFacts might disappear with Hoopl4?
constProp :: ForwardRewrites Node ConstFact
constProp n facts =
  map_EN (map_EE rewriteE) n >>= return . toAGraph
  where
    rewriteE e@(Var v) =
      case M.lookup v (getInFacts constLattice facts n) of
        Just (Elt l) -> Just $ Const l
        _            -> Nothing
    rewriteE e = Nothing

-- Simplification ("constant folding")
simplify :: ForwardRewrites Node ConstFact
simplify node _ = s node >>= return . toAGraph
  where
    s :: Node e x -> TxRes (Node e x)
    s (Cond (Const (Bool True))  t _) = Just $ Branch t
    s (Cond (Const (Bool False)) f _) = Just $ Branch f
    s n = map_EN (map_EE s_e) n
    s_e (Binop Add (Const (Int i1)) (Const (Int i2))) ->
       Just $ Const $ Int $ i1 + i2
    ....  -- more cases for constant folding
