22{-# LANGUAGE GeneralizedNewtypeDeriving #-}
33
44module CodeGen (
5- LLVM (.. ),
5+ LLVM (.. ),
66 runLLVM ,
7+ execCodegen ,
8+
79 define ,
810 addDef ,
9- getDef ,
11+
1012 getType ,
1113 getName ,
1214 intL ,
1315 getArgList ,
16+
17+ Codegen (.. ),
1418 Names (.. ),
19+ CodegenState (.. ),
20+ BlockState (.. ),
21+ unikName ,
22+
1523 load ,
1624 store ,
1725 local ,
1826 terminator ,
1927 ret ,
2028 getvar ,
2129 assign ,
22- createBlocks ,
23- external ,
24- Codegen (.. ),
25- CodegenState (.. ),
26- BlockState (.. ),
27- instr ,
2830 alloca ,
29- execCodegen ,
31+ instr ,
32+ external ,
33+
34+ createBlocks ,
3035 setBlock ,
31- getBlock ,
3236 emptyBlock ,
33- unikName ,
3437 entryBlockName ,
38+
39+ getBlock ,
40+
3541 br ,
3642 phi ,
3743 cbr ,
38- fcmp
39-
44+ fcmp ,
45+ uitofp
46+
4047)where
4148
4249
@@ -71,17 +78,17 @@ import qualified AST as ASTLp
7178
7279
7380
74- -- -- 1. Variable Declaration Done
75- -- var = GLB.globalVariableDefaults { name = "Var1", GLB.type' = int }
81+ -- | utility Functions for Working on Module
82+ -- | LLVM monad to manage the contained LLVM module State
7683
77- -- | Utility Functions for Working on Module
7884newtype LLVM a = LLVM (State ASTL. Module a )
7985 deriving (Functor , Applicative , Monad , MonadState ASTL.Module )
8086
87+ -- | execute the given LLVM State with the given module as state
8188runLLVM :: ASTL. Module -> LLVM a -> ASTL. Module
8289runLLVM mod (LLVM m) = execState m mod
8390
84- -- Defines a function here the return type is Type
91+ -- | Action to add a function to state
8592define :: ASTL. Type -> String -> [(ASTL. Type , ASTL. Name )] -> [ASTL. BasicBlock ] -> LLVM ()
8693define retty label argtys body = addDef $
8794 ASTL. GlobalDefinition $ functionDefaults {
@@ -92,18 +99,18 @@ define retty label argtys body = addDef $
9299 }
93100
94101
95- -- | Defines a function here the return type is Type
102+ -- | Action to add external function
96103external :: ASTL. Type -> String -> [(ASTL. Type , ASTL. Name )] -> LLVM ()
97104external retty label argtys = define retty label argtys []
98105
106+ -- | Action to add definition to the LLVM state
99107addDef :: ASTL. Definition -> LLVM ()
100108addDef def = do
101109 prev <- gets ASTL. moduleDefinitions
102110 modify $ \ s -> s { ASTL. moduleDefinitions = prev ++ [def] }
111+ ------------------------------------------------
103112
104113
105- -- | BackEnd
106- -- From Parsed ASTL to LLVM Definitions
107114getDef :: ASTLp. Func -> ASTL. Definition
108115getDef (ASTLp. Func fname farg fret fbody ) = ASTL. GlobalDefinition $ functionDefaults {
109116 name = getName fname,
@@ -120,6 +127,7 @@ getExtern (ASTLp.ExternDecl fname fargs fret) =
120127 })
121128
122129
130+ -- | Utility Function for conversion and constant
123131getType :: ASTLp. Type -> TypeQ. Type
124132getType ASTLp. IntC = ASTL. IntegerType 32
125133
@@ -131,46 +139,51 @@ intL = ASTL.IntegerType 32
131139
132140getArgList :: ASTLp. ArgList -> [(ASTL. Type , ASTL. Name )]
133141getArgList = map (\ (t, n) -> (getType t, getName n))
142+ ------------------------------------------------
134143
135144
136- type Names = Map. Map String Int
137145
138146
139- -- Takes a name and check if present in names and then checks if the name already there or not.
147+ -- | Takes a name and check if present in names and then checks if the name already there or not.
140148-- returns updated map and prev. name if any otherwise the name itself.
141- -- Can be used to ask if this name is avaible and if so then use it otherwise it returns you
142- -- an updated name that can be used.
143149unikName :: String -> Names -> (String , Names )
144150unikName name mapping = case Map. lookup name mapping of
145151 Nothing -> (name, Map. insert name 1 mapping)
146152 Just idx -> (name ++ (show idx) , Map. insert name (idx+ 1 ) mapping)
147153
148- type SymbolTable = [(String , ASTL. Operand )]
149154
155+ -- | Data Structure that the State stores inside the LLVM monad
156+ type Names = Map. Map String Int
157+ type SymbolTable = [(String , ASTL. Operand )]
150158
151159
152160
161+ -- | A CodegenState represent a file/ code file and the current execution block
153162data CodegenState
154163 = CodegenState {
155164 currentBlock :: ASTL. Name -- Name of the active block to append to
156165 , blocks :: Map. Map ASTL. Name BlockState -- Blocks for function
157- , symtab :: SymbolTable -- Function scope symbol table
158- , blockCount :: Int -- Count of basic blocks
159- , count :: Word -- Count of unnamed instructions a.k.a like function args
160- , names :: Names -- Name Supply
166+ , symtab :: SymbolTable -- Function scope symbol table
167+ , blockCount :: Int -- Count of basic blocks
168+ , count :: Word -- Count of unnamed instructions a.k.a like function args
169+ , names :: Names -- Name Supply
161170 } deriving Show
162171
172+ -- | A BlockState represent a function section
163173data BlockState
164174 = BlockState {
165- idx :: Int -- Block index
175+ idx :: Int -- Block index
166176 , stack :: [ASTL. Named ASTL. Instruction ] -- Stack of instructions Head --> |_| |_| |_| |_|
167177 , term :: Maybe (ASTL. Named ASTL. Terminator ) -- Block terminator
168178 } deriving Show
169179
170180
181+ -- | A action executor on LLVM state
171182newtype Codegen a = Codegen { runCodegen :: State CodegenState a }
172183 deriving (Functor , Applicative , Monad , MonadState CodegenState )
173184
185+ ------------------------------- Block Operations ------------------------
186+
174187sortBlocks :: [(ASTL. Name , BlockState )] -> [(ASTL. Name , BlockState )]
175188sortBlocks = sortBy (compare `on` (idx . snd ))
176189
@@ -189,22 +202,24 @@ entryBlockName = "entry"
189202emptyBlock :: Int -> BlockState
190203emptyBlock i = BlockState i [] Nothing
191204
192- emptyCodegen :: CodegenState
193- emptyCodegen = CodegenState (ASTL. Name entryBlockName) Map. empty [] 1 0 Map. empty
194-
195- execCodegen :: Codegen a -> CodegenState
196- execCodegen m = execState (runCodegen m) emptyCodegen
197-
198-
199- ------------------------------- Block Operations ------------------------
200205
201- -- Modifies the current block that is being used using the block name arg.
206+ -- | Modifies the current block that is being used using the block name arg.
202207-- Returns the input bname after successfull updation
203208setBlock :: ASTL. Name -> Codegen ASTL. Name
204209setBlock bname = do
205210 modify $ \ s -> s { currentBlock = bname }
206211 return bname
207212
213+ ------------------------------------------------------------------------
214+
215+ ------------------------- CodeGen constants and actions ---------------
216+
217+ emptyCodegen :: CodegenState
218+ emptyCodegen = CodegenState (ASTL. Name entryBlockName) Map. empty [] 1 0 Map. empty
219+
220+ execCodegen :: Codegen a -> CodegenState
221+ execCodegen m = execState (runCodegen m) emptyCodegen
222+
208223getBlock :: Codegen ASTL. Name
209224getBlock = gets currentBlock
210225
@@ -224,13 +239,12 @@ fresh = do
224239
225240instr :: ASTL. Instruction -> Codegen (ASTL. Operand )
226241instr ins = do
227- n <- fresh -- Updated the count of variables/ n=count
228- let ref = (ASTL. UnName n) -- a number for a nameless thing
229- blk <- current -- got the current blockState
230- let i = stack blk -- Got the list of statements
231- modifyBlock (blk { stack = (ref := ins) : i } ) -- (ref := ins ) is a Named Instruction with name ref and ins and instruction
232- return $ local ref -- Returning the operands
233-
242+ n <- fresh -- Updated the count of variables/ n=count
243+ let ref = (ASTL. UnName n) -- a number for a nameless thing
244+ blk <- current -- got the current blockState
245+ let i = stack blk -- Got the list of statements
246+ modifyBlock (blk { stack = (ref := ins) : i } ) -- (ref := ins ) is a Named Instruction with name ref and ins and instruction
247+ return $ local ref -- Returning the operands
234248
235249
236250current :: Codegen BlockState
@@ -243,7 +257,7 @@ current = do
243257
244258
245259
246- -- Updating the blocks with due to addition of named instructions
260+ -- | Updating the blocks with due to addition of named instructions
247261-- Simply replacing whole prev block with the new one
248262modifyBlock :: BlockState -> Codegen ()
249263modifyBlock new = do
@@ -253,7 +267,6 @@ modifyBlock new = do
253267
254268
255269
256-
257270-- | Update the symbol table with the current value and identifier
258271assign :: String -> ASTL. Operand -> Codegen ()
259272assign var x = do
@@ -268,23 +281,22 @@ getvar var = do
268281 Nothing -> error $ " Local variable not in scope: " ++ show var
269282
270283
271-
272- -- Takes the operand and create a terminator based on that .
284+ -- | Takes the operand and create a terminator based on that .
273285-- Do simply names the instruction
274286-- terminator just uplift the value further to Codegen while updating the blockState
275287ret :: ASTL. Operand -> Codegen (ASTL. Named ASTL. Terminator )
276288ret val = terminator $ ASTL. Do $ ASTL. Ret (Just val) []
277289
278290
279- -- Update the terminator of the current active block
291+ -- | Update the terminator of the current active block
280292terminator :: ASTL. Named ASTL. Terminator -> Codegen (ASTL. Named ASTL. Terminator )
281293terminator trm = do
282294 blk <- current
283295 modifyBlock (blk { term = Just trm })
284296 return trm
285297
286298
287- -- Takes a name and gives you an operands
299+ -- | Takes a name and gives you an operands
288300local :: ASTL. Name -> ASTL. Operand
289301local = ASTL. LocalReference intL
290302
@@ -308,4 +320,7 @@ phi :: ASTL.Type -> [(ASTL.Operand, ASTL.Name)] -> Codegen ASTL.Operand
308320phi ty incoming = instr $ ASTL. Phi ty incoming []
309321
310322fcmp :: IP. IntegerPredicate -> ASTL. Operand -> ASTL. Operand -> Codegen ASTL. Operand
311- fcmp cond a b = instr $ ICmp cond a b []
323+ fcmp cond a b = instr $ ICmp cond a b []
324+
325+ uitofp :: ASTL. Type -> ASTL. Operand -> Codegen ASTL. Operand
326+ uitofp ty a = instr $ ASTL. UIToFP a ty []
0 commit comments