LLVM IR コードを生成するためにllvm Haskell パッケージをいじっています。次の 2D 集約 LLVM 配列を考えてみましょう。これは、8 ビット整数の長さ 4 の配列の、長さ 2 の配列です。
[2 x [4 x i8]]
簡単なエクササイズをまとめてみましたが、行き詰まっています。配列の各要素の値をインクリメントしたいと思います。
{- input 2D array
[ [1 , 2 , 3 , 4]
, [5 , 6 , 7 , 8] ]
-}
{- desired output 2D array
[ [3 , 4 , 5 , 6 ]
, [7 , 8 , 9 , 10] ]
-}
課題: ネストされたforLoop
.
{-# LANGUAGE ScopedTypeVariables #-}
module TwoDArray where
import Data.Int
import Data.Word
import LLVM.Core
import LLVM.Util.Loop
import Data.TypeLevel (D2,D4)
f :: CodeGenModule (Function (IO ()))
f = createNamedFunction ExternalLinkage "test" $ do
let xss = [[1,2,3,4],[5,6,7,8]]
height = 2
width = 4
let arr = Array $ map Array xss :: Array D2 (Array D4 Word8)
(ptr :: Value (Ptr (Array D2 (Array D4 Word8)))) <- malloc
store (valueOf arr) ptr
forLoop (valueOf 0) (valueOf (fromIntegral height) :: Value Int32) () $ \ h () -> do
forLoop (valueOf 0) (valueOf (fromIntegral width) :: Value Int32) () $ \ w () -> do
{- 1. load element at <h/w> position in 2D array arr -}
{- 2. add 2 to the value as y -}
{- 3. put value of y in to position <h/w> in 2D array arr -}
ret ()
ret ()
return () -- better still, return the pointer `ptr`