diff --git a/LLVM/Core.hs b/LLVM/Core.hs
--- a/LLVM/Core.hs
+++ b/LLVM/Core.hs
@@ -45,6 +45,7 @@
     Value, ConstValue, valueOf, constOf, value,
     zero, allOnes, undef,
     createString, createStringNul,
+    withString, withStringNul,
     --constString, constStringNul,
     constVector, constArray,
     constStruct, constPackedStruct,
diff --git a/LLVM/Core/CodeGen.hs b/LLVM/Core/CodeGen.hs
--- a/LLVM/Core/CodeGen.hs
+++ b/LLVM/Core/CodeGen.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ScopedTypeVariables, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, TypeSynonymInstances, UndecidableInstances, FlexibleContexts, ScopedTypeVariables, DeriveDataTypeable #-}
+{-# LANGUAGE ScopedTypeVariables, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, TypeSynonymInstances, UndecidableInstances, FlexibleContexts, ScopedTypeVariables, DeriveDataTypeable, Rank2Types #-}
 module LLVM.Core.CodeGen(
     -- * Module creation
     newModule, newNamedModule, defineModule, createModule,
@@ -20,6 +20,7 @@
     IsConst(..), valueOf, value,
     zero, allOnes, undef,
     createString, createStringNul,
+    withString, withStringNul,
     constVector, constArray, constStruct, constPackedStruct,
     -- * Basic blocks
     BasicBlock(..), newBasicBlock, newNamedBasicBlock, defineBasicBlock, createBasicBlock, getCurrentBasicBlock,
@@ -121,7 +122,7 @@
 instance IsConst (StablePtr a) where
     constOf p = constOfPtr p (castStablePtrToPtr p)
 
-instance (IsPrimitive a, IsConst a, Nat n) => IsConst (Vector n a) where
+instance (IsPrimitive a, IsConst a, Pos n) => IsConst (Vector n a) where
     constOf (Vector xs) = constVector (map constOf xs)
 
 instance (IsConst a, IsSized a s, Nat n) => IsConst (Array n a) where
@@ -426,12 +427,37 @@
 type TGlobal a = CodeGenModule (Global a)
 
 -- Special string creators
+{-# DEPRECATED createString "use withString instead" #-}
 createString :: String -> TGlobal (Array n Word8)
 createString s = string (length s) (U.constString s)
 
+{-# DEPRECATED createStringNul "use withStringNul instead" #-}
 createStringNul :: String -> TGlobal (Array n Word8)
 createStringNul s = string (length s + 1) (U.constStringNul s)
 
+withString ::
+   String ->
+   (forall n. (Nat n) => Global (Array n Word8) -> CodeGenModule a) ->
+   CodeGenModule a
+withString s act =
+   let n = length s
+   in  reifyIntegral n (\tn ->
+          do arr <- string n (U.constString s)
+             act (fixArraySize tn arr))
+
+withStringNul ::
+   String ->
+   (forall n. (Nat n) => Global (Array n Word8) -> CodeGenModule a) ->
+   CodeGenModule a
+withStringNul s act =
+   let n = length s + 1
+   in  reifyIntegral n (\tn ->
+          do arr <- string n (U.constStringNul s)
+             act (fixArraySize tn arr))
+
+fixArraySize :: n -> Global (Array n a) -> Global (Array n a)
+fixArraySize _ = id
+
 string :: Int -> FFI.ValueRef -> TGlobal (Array n Word8)
 string n s = do
     modul <- getModule
@@ -445,7 +471,7 @@
 --------------------------------------
 
 -- |Make a constant vector.  Replicates or truncates the list to get length /n/.
-constVector :: forall a n . (Nat n) => [ConstValue a] -> ConstValue (Vector n a)
+constVector :: forall a n . (Pos n) => [ConstValue a] -> ConstValue (Vector n a)
 constVector xs =
     ConstValue $ U.constVector (toNum (undefined :: n)) [ v | ConstValue v <- xs ]
 
diff --git a/LLVM/Core/Instructions.hs b/LLVM/Core/Instructions.hs
--- a/LLVM/Core/Instructions.hs
+++ b/LLVM/Core/Instructions.hs
@@ -254,7 +254,8 @@
 --------------------------------------
 
 -- | Get a value from a vector.
-extractelement :: Value (Vector n a)               -- ^ Vector
+extractelement :: (Pos n)
+               => Value (Vector n a)               -- ^ Vector
                -> Value Word32                     -- ^ Index into the vector
                -> CodeGenFunction r (Value a)
 extractelement (Value vec) (Value i) =
@@ -263,7 +264,8 @@
       U.withEmptyCString $ FFI.buildExtractElement bldPtr vec i
 
 -- | Insert a value into a vector, nondestructive.
-insertelement :: Value (Vector n a)                -- ^ Vector
+insertelement :: (Pos n)
+              => Value (Vector n a)                -- ^ Vector
               -> Value a                           -- ^ Value to insert
               -> Value Word32                      -- ^ Index into the vector
               -> CodeGenFunction r (Value (Vector n a))
@@ -275,7 +277,8 @@
 -- XXX The documentation say the mask and result can  different length from
 -- the two first operand, but the C++ code doesn't do that.
 -- | Permute vector.
-shufflevector :: Value (Vector n a)
+shufflevector :: (Pos n)
+              => Value (Vector n a)
               -> Value (Vector n a)
               -> ConstValue (Vector n Word32)
               -> CodeGenFunction r (Value (Vector n a))
@@ -464,7 +467,7 @@
 instance CmpRet Int32 Bool
 instance CmpRet Int64 Bool
 instance CmpRet (Ptr a) Bool
-instance CmpRet (Vector n a) (Vector n Bool)
+instance (Pos n) => CmpRet (Vector n a) (Vector n Bool)
 
 -- | Compare integers.
 icmp :: (IsIntegerOrPointer c, CmpOp a b c d, CmpRet c d) =>
@@ -621,9 +624,9 @@
 
 -- XXX What's the type of free?
 -- | Free heap memory.
-free :: Value (Ptr a) -> CodeGenFunction r (Value ())
+free :: Value (Ptr a) -> CodeGenFunction r ()
 free (Value a) =
-    liftM Value $
+    liftM (const ()) $
     withCurrentBuilder $ \ bldPtr -> FFI.buildFree bldPtr a
 
 -- | Load a value from memory.
@@ -709,11 +712,11 @@
     getIxList _ () = []
 
 -- Index in Array
-instance (GetElementPtr o i n, IsIndexArg a) => GetElementPtr (Array k o) (a, i) n where
+instance (GetElementPtr o i n, IsIndexArg a, Nat k) => GetElementPtr (Array k o) (a, i) n where
     getIxList _ (v, i) = getArg v : getIxList (undefined :: o) i
 
 -- Index in Vector
-instance (GetElementPtr o i n, IsIndexArg a) => GetElementPtr (Vector k o) (a, i) n where
+instance (GetElementPtr o i n, IsIndexArg a, Pos k) => GetElementPtr (Vector k o) (a, i) n where
     getIxList _ (v, i) = getArg v : getIxList (undefined :: o) i
 
 -- Index in Struct and PackedStruct.
diff --git a/LLVM/Core/Type.hs b/LLVM/Core/Type.hs
--- a/LLVM/Core/Type.hs
+++ b/LLVM/Core/Type.hs
@@ -9,6 +9,7 @@
     IsType(..),
     -- ** Special type classifiers
     Nat,
+    Pos,
     IsArithmetic,
     IsInteger,
     IsIntegerOrPointer,
@@ -190,7 +191,7 @@
 instance (Nat n, IsSized a s) => IsType (Array n a)
     where typeDesc _ = TDArray (toNum (undefined :: n))
     	  	               (typeDesc (undefined :: a))
-instance (Nat n, IsPrimitive a) => IsType (Vector n a)
+instance (Pos n, IsPrimitive a) => IsType (Vector n a)
     where typeDesc _ = TDVector (toNum (undefined :: n))
     	  	       		(typeDesc (undefined :: a))
 
@@ -253,12 +254,12 @@
 instance IsArithmetic Word16
 instance IsArithmetic Word32
 instance IsArithmetic Word64
-instance (Nat n, IsPrimitive a, IsArithmetic a) => IsArithmetic (Vector n a)
+instance (Pos n, IsPrimitive a, IsArithmetic a) => IsArithmetic (Vector n a)
 
 instance IsFloating Float
 instance IsFloating Double
 instance IsFloating FP128
-instance (Nat n, IsPrimitive a, IsFloating a) => IsFloating (Vector n a)
+instance (Pos n, IsPrimitive a, IsFloating a) => IsFloating (Vector n a)
 
 instance (Pos n) => IsInteger (IntN n)
 instance (Pos n) => IsInteger (WordN n)
@@ -271,7 +272,7 @@
 instance IsInteger Word16
 instance IsInteger Word32
 instance IsInteger Word64
-instance (Nat n, IsPrimitive a, IsInteger a) => IsInteger (Vector n a)
+instance (Pos n, IsPrimitive a, IsInteger a) => IsInteger (Vector n a)
 
 instance (Pos n) => IsIntegerOrPointer (IntN n)
 instance (Pos n) => IsIntegerOrPointer (WordN n)
@@ -284,7 +285,7 @@
 instance IsIntegerOrPointer Word16
 instance IsIntegerOrPointer Word32
 instance IsIntegerOrPointer Word64
-instance (Nat n, IsPrimitive a, IsInteger a) => IsIntegerOrPointer (Vector n a)
+instance (Pos n, IsPrimitive a, IsInteger a) => IsIntegerOrPointer (Vector n a)
 instance (IsType a) => IsIntegerOrPointer (Ptr a)
 
 instance IsFirstClass Float
@@ -301,7 +302,7 @@
 instance IsFirstClass Word16
 instance IsFirstClass Word32
 instance IsFirstClass Word64
-instance (Nat n, IsPrimitive a) => IsFirstClass (Vector n a)
+instance (Pos n, IsPrimitive a) => IsFirstClass (Vector n a)
 instance (Nat n, IsType a, IsSized a s) => IsFirstClass (Array n a)
 instance (IsType a) => IsFirstClass (Ptr a)
 instance IsFirstClass (StablePtr a)
@@ -324,7 +325,7 @@
 instance IsSized Word32 D32
 instance IsSized Word64 D64
 instance (Nat n, IsSized a s, Mul n s ns, Pos ns) => IsSized (Array n a) ns
-instance (Nat n, IsPrimitive a, IsSized a s, Mul n s ns, Pos ns) => IsSized (Vector n a) ns
+instance (Pos n, IsPrimitive a, IsSized a s, Mul n s ns, Pos ns) => IsSized (Vector n a) ns
 instance (IsType a) => IsSized (Ptr a) PtrSize
 instance IsSized (StablePtr a) PtrSize
 -- instance IsSized Label PtrSize -- labels are not quite first classed
@@ -370,7 +371,7 @@
 instance NumberOfElements D1 Label
 instance NumberOfElements D1 ()
 
-instance (Nat n, IsPrimitive a) =>
+instance (Pos n, IsPrimitive a) =>
          NumberOfElements n (Vector n a)
 
 
diff --git a/LLVM/Core/Vector.hs b/LLVM/Core/Vector.hs
--- a/LLVM/Core/Vector.hs
+++ b/LLVM/Core/Vector.hs
@@ -12,7 +12,7 @@
 import System.IO.Unsafe(unsafePerformIO)
 
 -- XXX Should these really be here?
-class (Nat n, IsPrimitive a) => MkVector va n a | va -> n a, n a -> va where
+class (Pos n, IsPrimitive a) => MkVector va n a | va -> n a, n a -> va where
     toVector :: va -> Vector n a
     fromVector :: Vector n a -> va
 
@@ -36,7 +36,7 @@
     fromVector (Vector [a1, a2, a3, a4, a5, a6, a7, a8]) = (a1, a2, a3, a4, a5, a6, a7, a8)
     fromVector _ = error "fromVector: impossible"
 
-instance (Storable a, Nat n, IsPrimitive a) => Storable (Vector n a) where
+instance (Storable a, Pos n, IsPrimitive a) => Storable (Vector n a) where
     sizeOf a = storeSizeOfType ourTargetData (typeRef a)
     alignment a = aBIAlignmentOfType ourTargetData (typeRef a)
     peek p = fmap Vector $ peekArray (toNum (undefined :: n)) (castPtr p :: Ptr a)
@@ -53,7 +53,7 @@
 
 -- |Make a constant vector.  Replicates or truncates the list to get length /n/.
 -- This behaviour is consistent with that of 'LLVM.Core.CodeGen.constVector'.
-vector :: forall a n. (Nat n) => [a] -> Vector n a
+vector :: forall a n. (Pos n) => [a] -> Vector n a
 vector xs =
    Vector (take (toNum (undefined :: n)) (cycle xs))
 
@@ -64,10 +64,10 @@
 unop :: (a -> b) -> Vector n a -> Vector n b
 unop op = Vector . map op . unVector
 
-instance (Eq a) => Eq (Vector n a) where
+instance (Eq a, Pos n) => Eq (Vector n a) where
     (==) = (==) `on` unVector
 
-instance (Ord a) => Ord (Vector n a) where
+instance (Ord a, Pos n) => Ord (Vector n a) where
     compare = compare `on` unVector
 
 instance (Num a, Pos n) => Num (Vector n a) where
diff --git a/LLVM/FFI/Core.hsc b/LLVM/FFI/Core.hsc
--- a/LLVM/FFI/Core.hsc
+++ b/LLVM/FFI/Core.hsc
@@ -473,9 +473,9 @@
     , constIntGetSExtValue
     , constIntGetZExtValue
 
-    , constUnion
+--    , constUnion
     , contextCreate
-    , countUnionElementTypes
+--    , countUnionElementTypes
     , createFunctionPassManagerForModule
     , getAttribute
     , getCurrentDebugLocation
@@ -485,7 +485,7 @@
     , getMDKindIDInContext
     , getMetadata
     , getOperand
-    , getUnionElementTypes
+--    , getUnionElementTypes
     , hasMetadata
     , insertIntoBuilder
     , mDNode
@@ -497,7 +497,7 @@
     , setInstDebugLocation
     , setMetadata
 --    , unionType
-    , unionTypeInContext
+--    , unionTypeInContext
 
     -- ** Build instruction from opcode
     , buildBinOp
@@ -1624,12 +1624,16 @@
     :: ValueRef -> IO ValueRef
 foreign import ccall unsafe "LLVMConstNUWSub" constNUWSub
     :: ValueRef -> ValueRef -> IO ValueRef
+{-
 foreign import ccall unsafe "LLVMConstUnion" constUnion
     :: TypeRef -> ValueRef -> IO ValueRef
+-}
 foreign import ccall unsafe "LLVMContextCreate" contextCreate
     :: IO ContextRef
+{-
 foreign import ccall unsafe "LLVMCountUnionElementTypes" countUnionElementTypes
     :: TypeRef -> IO CUInt
+-}
 foreign import ccall unsafe "LLVMCreateFunctionPassManagerForModule" createFunctionPassManagerForModule
     :: ModuleRef -> IO PassManagerRef
 foreign import ccall unsafe "LLVMGetAttribute" getAttribute
@@ -1654,8 +1658,10 @@
     :: UseRef -> IO UseRef
 foreign import ccall unsafe "LLVMGetOperand" getOperand
     :: ValueRef -> CUInt -> IO ValueRef
+{-
 foreign import ccall unsafe "LLVMGetUnionElementTypes" getUnionElementTypes
     :: TypeRef -> (Ptr TypeRef) -> IO ()
+-}
 foreign import ccall unsafe "LLVMGetUsedValue" getUsedValue
     :: UseRef -> IO ValueRef
 foreign import ccall unsafe "LLVMGetUser" getUser
@@ -1683,6 +1689,6 @@
 {-
 foreign import ccall unsafe "LLVMUnionType" unionType
     :: (Ptr TypeRef) -> CUInt -> IO TypeRef
--}
 foreign import ccall unsafe "LLVMUnionTypeInContext" unionTypeInContext
     :: ContextRef -> (Ptr TypeRef) -> CUInt -> IO TypeRef
+-}
diff --git a/LLVM/Util/Arithmetic.hs b/LLVM/Util/Arithmetic.hs
--- a/LLVM/Util/Arithmetic.hs
+++ b/LLVM/Util/Arithmetic.hs
@@ -14,6 +14,7 @@
     ) where
 import Data.Word
 import Data.Int
+import Data.TypeLevel (D4)
 import LLVM.Core
 import LLVM.Util.Loop(mapVector, mapVector2)
 
@@ -36,22 +37,22 @@
 instance Cmp Double Bool where cmp = fcmp . adjFloat
 instance Cmp FP128 Bool where cmp = fcmp . adjFloat
 {-
-instance (Nat n) => Cmp (Vector n Bool) (Vector n Bool) where cmp = icmp
-instance (Nat n) => Cmp (Vector n Word8) (Vector n Bool) where cmp = icmp
-instance (Nat n) => Cmp (Vector n Word16) (Vector n Bool) where cmp = icmp
-instance (Nat n) => Cmp (Vector n Word32) (Vector n Bool) where cmp = icmp
-instance (Nat n) => Cmp (Vector n Word64) (Vector n Bool) where cmp = icmp
-instance (Nat n) => Cmp (Vector n Int8) (Vector n Bool) where cmp = icmp . adjSigned
-instance (Nat n) => Cmp (Vector n Int16) (Vector n Bool) where cmp = icmp . adjSigned
-instance (Nat n) => Cmp (Vector n Int32) (Vector n Bool) where cmp = icmp . adjSigned
-instance (Nat n) => Cmp (Vector n Int64) (Vector n Bool) where cmp = icmp . adjSigned
-instance (Nat n) => Cmp (Vector n Float) (Vector n Bool) where cmp = fcmp . adjFloat
-instance (Nat n) => Cmp (Vector n Double) (Vector n Bool) where cmp = fcmp . adjFloat
-instance (Nat n) => Cmp (Vector n FP128) (Vector n Bool) where cmp = fcmp . adjFloat
+instance (Pos n) => Cmp (Vector n Bool) (Vector n Bool) where cmp = icmp
+instance (Pos n) => Cmp (Vector n Word8) (Vector n Bool) where cmp = icmp
+instance (Pos n) => Cmp (Vector n Word16) (Vector n Bool) where cmp = icmp
+instance (Pos n) => Cmp (Vector n Word32) (Vector n Bool) where cmp = icmp
+instance (Pos n) => Cmp (Vector n Word64) (Vector n Bool) where cmp = icmp
+instance (Pos n) => Cmp (Vector n Int8) (Vector n Bool) where cmp = icmp . adjSigned
+instance (Pos n) => Cmp (Vector n Int16) (Vector n Bool) where cmp = icmp . adjSigned
+instance (Pos n) => Cmp (Vector n Int32) (Vector n Bool) where cmp = icmp . adjSigned
+instance (Pos n) => Cmp (Vector n Int64) (Vector n Bool) where cmp = icmp . adjSigned
+instance (Pos n) => Cmp (Vector n Float) (Vector n Bool) where cmp = fcmp . adjFloat
+instance (Pos n) => Cmp (Vector n Double) (Vector n Bool) where cmp = fcmp . adjFloat
+instance (Pos n) => Cmp (Vector n FP128) (Vector n Bool) where cmp = fcmp . adjFloat
 -}
-instance (Nat n) => Cmp (Vector n Float) (Vector n Bool) where
+instance (Pos n) => Cmp (Vector n Float) (Vector n Bool) where
     cmp op = mapVector2 (fcmp (adjFloat op))
-instance (Nat n) => Cmp (Vector n Word32) (Vector n Bool) where
+instance (Pos n) => Cmp (Vector n Word32) (Vector n Bool) where
     cmp op = mapVector2 (cmp op)
 
 adjSigned :: IntPredicate -> IntPredicate
@@ -297,7 +298,7 @@
     callIntrinsic1' = callIntrinsicP1
     callIntrinsic2' = callIntrinsicP2
 
-instance (Nat n, IsPrimitive a, CallIntrinsic a) => CallIntrinsic (Vector n a) where
+instance (Pos n, IsPrimitive a, CallIntrinsic a) => CallIntrinsic (Vector n a) where
     callIntrinsic1' s = mapVector (callIntrinsic1' s)
     callIntrinsic2' s = mapVector2 (callIntrinsic2' s)
 
diff --git a/LLVM/Util/Loop.hs b/LLVM/Util/Loop.hs
--- a/LLVM/Util/Loop.hs
+++ b/LLVM/Util/Loop.hs
@@ -88,7 +88,7 @@
 --------------------------------------
 
 mapVector :: forall a b n r .
-             (Nat n, IsPrimitive b) =>
+             (Pos n, IsPrimitive b) =>
              (Value a -> CodeGenFunction r (Value b)) ->
              Value (Vector n a) -> CodeGenFunction r (Value (Vector n b))
 mapVector f v =
@@ -98,7 +98,7 @@
         insertelement w y i
 
 mapVector2 :: forall a b c n r .
-             (Nat n, IsPrimitive c) =>
+             (Pos n, IsPrimitive c) =>
              (Value a -> Value b -> CodeGenFunction r (Value c)) ->
              Value (Vector n a) -> Value (Vector n b) -> CodeGenFunction r (Value (Vector n c))
 mapVector2 f v1 v2 =
diff --git a/examples/Align.hs b/examples/Align.hs
--- a/examples/Align.hs
+++ b/examples/Align.hs
@@ -1,5 +1,5 @@
 module Align (main) where
-import Data.TypeLevel(D1, D2, D4)
+import Data.TypeLevel(D1, D4)
 import Data.Word
 
 import LLVM.Core
diff --git a/examples/DotProd.hs b/examples/DotProd.hs
--- a/examples/DotProd.hs
+++ b/examples/DotProd.hs
@@ -8,7 +8,7 @@
 import LLVM.Util.File(writeCodeGenModule)
 import LLVM.Util.Foreign
 
-mDotProd :: forall n a . (Nat n,
+mDotProd :: forall n a . (Pos n,
 	                  IsPrimitive a, IsArithmetic a, IsFirstClass a, IsConst a, Num a,
 	                  FunctionRet a
 	                 ) =>
diff --git a/examples/HelloJIT.hs b/examples/HelloJIT.hs
--- a/examples/HelloJIT.hs
+++ b/examples/HelloJIT.hs
@@ -6,14 +6,13 @@
 import LLVM.ExecutionEngine
 
 bldGreet :: CodeGenModule (Function (IO ()))
-bldGreet = do
+bldGreet = withStringNul "Hello, JIT!" (\greetz -> do
     puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32)
-    greetz <- createStringNul "Hello, JIT!"
     func <- createFunction ExternalLinkage $ do
       tmp <- getElementPtr0 greetz (0::Word32, ())
       _ <- call puts tmp -- Throw away return value.
       ret ()
-    return func
+    return func)
 
 main :: IO ()
 main = do
diff --git a/examples/Varargs.hs b/examples/Varargs.hs
--- a/examples/Varargs.hs
+++ b/examples/Varargs.hs
@@ -6,27 +6,28 @@
 import LLVM.ExecutionEngine
 
 bldVarargs :: CodeGenModule (Function (Word32 -> IO ()))
-bldVarargs = do
-    printf <- newNamedFunction ExternalLinkage "printf" :: TFunction (Ptr Word8 -> VarArgs Word32)
-    fmt1 <- createStringNul "Hello\n"
-    fmt2 <- createStringNul "A number %d\n"
-    fmt3 <- createStringNul "Two numbers %d %d\n"
-    func <- createFunction ExternalLinkage $ \ x -> do
+bldVarargs =
+   withStringNul "Hello\n" (\fmt1 ->
+   withStringNul "A number %d\n" (\fmt2 ->
+   withStringNul "Two numbers %d %d\n" (\fmt3 -> do
+      printf <- newNamedFunction ExternalLinkage "printf" :: TFunction (Ptr Word8 -> VarArgs Word32)
+      func <- createFunction ExternalLinkage $ \ x -> do
 
-      tmp1 <- getElementPtr0 fmt1 (0::Word32, ())
-      let p1 = castVarArgs printf :: Function (Ptr Word8 -> IO Word32)
-      _ <- call p1 tmp1
+        tmp1 <- getElementPtr0 fmt1 (0::Word32, ())
+        let p1 = castVarArgs printf :: Function (Ptr Word8 -> IO Word32)
+        _ <- call p1 tmp1
 
-      tmp2 <- getElementPtr0 fmt2 (0::Word32, ())
-      let p2 = castVarArgs printf :: Function (Ptr Word8 -> Word32 -> IO Word32)
-      _ <- call p2 tmp2 x
+        tmp2 <- getElementPtr0 fmt2 (0::Word32, ())
+        let p2 = castVarArgs printf :: Function (Ptr Word8 -> Word32 -> IO Word32)
+        _ <- call p2 tmp2 x
 
-      tmp3 <- getElementPtr0 fmt3 (0::Word32, ())
-      let p3 = castVarArgs printf :: Function (Ptr Word8 -> Word32 -> Word32 -> IO Word32)
-      _ <- call p3 tmp3 x x
+        tmp3 <- getElementPtr0 fmt3 (0::Word32, ())
+        let p3 = castVarArgs printf :: Function (Ptr Word8 -> Word32 -> Word32 -> IO Word32)
+        _ <- call p3 tmp3 x x
 
-      ret ()
-    return func
+        ret ()
+      return func
+   )))
 
 main :: IO ()
 main = do
diff --git a/examples/Vector.hs b/examples/Vector.hs
--- a/examples/Vector.hs
+++ b/examples/Vector.hs
@@ -1,15 +1,16 @@
 {-# LANGUAGE TypeOperators #-}
 module Vector where
-import System.Cmd(system)
-import Control.Monad
-import Data.TypeLevel.Num(D16, toNum)
-import Data.Word
 
+import Convert
+
 import LLVM.Core
 import LLVM.ExecutionEngine
-import LLVM.Util.Loop
+import LLVM.Util.Optimize (optimizeModule, )
+import LLVM.Util.Loop (forLoop, )
 
-import Convert
+import Control.Monad (liftM2, )
+import Data.TypeLevel.Num (D16, toNum, )
+import Data.Word (Word32, )
 
 -- Type of vector elements.
 type T = Float
@@ -60,14 +61,6 @@
 --    liftIO $ dumpValue f
     return f
 
--- Run LLVM optimizer at standard level.
-optimize :: String -> IO ()
-optimize name = do
-    _rc <- system $ "opt -std-compile-opts " ++ name ++ " -f -o " ++ name
-    return ()
-
--- Optimize the module by writing the bit code to file, running the optimizer, and then reading the file back in.
--- XXX With a working pass manager it wouldn't be necessary to go via a file.
 main :: IO ()
 main = do
     -- Initialize jitter
@@ -86,21 +79,18 @@
     vec 10 >>= print
 
     -- And then optimize and run.
-    let name = "Vec.bc"
-    writeBitcodeToFile name m
-    optimize name
-    m' <- readBitcodeFromFile name
+    _ <- optimizeModule 1 m
 
-    funcs <- getModuleValues m'
+    funcs <- getModuleValues m
     print $ map fst funcs
 
     let iovec' :: Function (T -> IO T)
         Just iovec' = castModuleValue =<< lookup "vectest" funcs
 	ioretacc' :: Function (IO T)
         Just ioretacc' = castModuleValue =<< lookup "retacc" funcs
-    
+
     (vec', retacc') <- runEngineAccess $ do
-        addModule m'
+        addModule m
         liftM2 (,) (generateFunction iovec') (generateFunction ioretacc')
 
     dumpValue iovec'
@@ -108,6 +98,3 @@
     vec' 10 >>= print
     vec' 0 >>= print
     retacc' >>= print
-
-
-
diff --git a/llvm.cabal b/llvm.cabal
--- a/llvm.cabal
+++ b/llvm.cabal
@@ -1,9 +1,11 @@
 name:          llvm
-version:       0.8.2.0
+version:       0.9.0.1
 license:       BSD3
 license-file:  LICENSE
 synopsis:      Bindings to the LLVM compiler toolkit.
 description:   Bindings to the LLVM compiler toolkit.
+               * New in 0.9.0.0: Adapted to LLVM 2.8 (removed support for Union types);
+               .
                * New in 0.8.2.0: Support for GHC calling convention.
                .
                * New in 0.8.1.0: Numerous small changes.
