1+ {-# OPTIONS_GHC  -fprof-auto #-} 
12{-# LANGUAGE  FlexibleInstances #-}
23{-# LANGUAGE  RecordWildCards #-}
34module  Data.BitCode.LLVM.ToBitCode  where 
@@ -7,8 +8,8 @@ import Data.BitCode.LLVM
78import  Data.BitCode.LLVM.Util 
89import  Data.BitCode.LLVM.Function 
910import  Data.BitCode.LLVM.Classes.HasType 
10- import  qualified  Data.BitCode.LLVM.Value  as  V  (Const (.. ), Value (.. ), Named (.. ), Symbol , symbolValue )
11- import  qualified  Data.BitCode.LLVM.Type  as  T  (Ty (.. ), ftypes )
11+ import  qualified  Data.BitCode.LLVM.Value  as  V  (Const (.. ), Value (.. ), Named (.. ), Symbol , symbolValue ,  FunctionExtra ( .. ) )
12+ import  qualified  Data.BitCode.LLVM.Type  as  T  (Ty (.. ), ftypes ,  typeCompare )
1213import  qualified  Data.BitCode.LLVM.Instruction  as  I  (Inst (.. ), TailCallKind (.. ))
1314import  Data.BitCode.LLVM.Flags 
1415
@@ -20,9 +21,11 @@ import qualified Data.BitCode.LLVM.Codes.Type as TC
2021import  qualified  Data.BitCode.LLVM.Codes.Constants  as  CC 
2122import  qualified  Data.BitCode.LLVM.Codes.Function  as  FC 
2223import  qualified  Data.BitCode.LLVM.Codes.ValueSymtab  as  VST 
24+ import  qualified  Data.Map.Strict  as  Map 
25+ import  Data.Map.Strict  (Map )
2326
2427import  Data.BitCode.LLVM.Classes.ToSymbols 
25- import  Data.List  (elemIndex , sort , sortOn , groupBy , nub )
28+ import  Data.List  (elemIndex , sort , sortBy , groupBy , nub )
2629import  Data.Function  (on )
2730
2831import  Data.Maybe  (fromMaybe , catMaybes )
@@ -107,11 +110,18 @@ lookupValueIndex vs v = case elemIndex v vs of
107110 Just  i ->  fromIntegral  i
108111 Nothing  ->  error  .  show  $  text " Unable to find value"   <+>  pretty v <+>  text " in"   <+>  pretty vs
109112
110- lookupSymbolIndex  ::  (HasCallStack , Integral   b ) =>  [ V. Symbol]  ->  V. Symbol  ->  b 
111- lookupSymbolIndex ss s =  case  elemIndex  s ss of 
113+ lookupSymbolIndex  ::  (HasCallStack , Integral   b ) =>  Map V. SymbolInt   ->  V. Symbol  ->  b 
114+ lookupSymbolIndex ss s =  case  Map. lookup  s ss of 
112115 Just  i ->  fromIntegral  i
113116 Nothing  ->  error  .  show  $  text " Unable to find symbol"   <+>  pretty s <+>  text " in"   <+>  pretty ss
114117
118+ -------------------------------------------------------------------------- 
119+ --  PP Utiltiys
120+ prettyIndexed  ::  (Pretty  a ) =>  [a ] ->  Doc 
121+ prettyIndexed =  pretty .  zip  ([0 .. ] ::  [Int  ])
122+ traceShowWith  ::  Show   a  =>  (b  ->  a ) ->  b  ->  b 
123+ traceShowWith f x =  traceShow (f x) x
124+ 115125--  We *can not* have ToNBitCode Module, as we
116126--  need to know the position in the bitcode stream.
117127--  And this includes the Indetification :(
@@ -145,12 +155,6 @@ instance ToNBitCode (Maybe Ident, Module) where
145155 --  , {- Block: SymTab 14 -}
146156 --  ]
147157 where 
148-  -------------------------------------------------------------------------- 
149-  --  PP Utiltiys
150-  prettyIndexed  ::  (Pretty  a ) =>  [a ] ->  Doc 
151-  prettyIndexed =  pretty .  zip  ([0 .. ] ::  [Int  ])
152-  traceShowWith  ::  Show   a  =>  (b  ->  a ) ->  b  ->  b 
153-  traceShowWith f x =  traceShow (f x) x
154158 -------------------------------------------------------------------------- 
155159 --  Compute the offsets
156160 identBlock =  toBitCode i
@@ -187,10 +191,10 @@ instance ToNBitCode (Maybe Ident, Module) where
187191 --  the constants table.
188192 -------------------------------------------------------------------------- 
189193 isDeclaration x
190-  |  f@ (V. Function {}) <-  V. symbolValue x =  V. fIsProto f 
194+  |  f@ (V. Function {}) <-  V. symbolValue x =  V. feProto ( V. fExtra f) 
191195 |  otherwise  =  False 
192196 isFunction x
193-  |  f@ (V. Function {}) <-  V. symbolValue x =  not  (V. fIsProto f )
197+  |  f@ (V. Function {}) <-  V. symbolValue x =  not  (V. feProto ( V. fExtra f) )
194198 |  otherwise  =  False 
195199 isGlobal x
196200 |  (V. Global {}) <-  V. symbolValue x =  True 
@@ -220,7 +224,8 @@ instance ToNBitCode (Maybe Ident, Module) where
220224 -- 
221225 --  TODO: FLAGS: if -dump-valuelist:
222226 --  traceShowWith prettyIndexed $!
223-  valueList =  globalSymbols ++  functionSymbols ++  constantSymbols
227+  valueList  ::  Map  V. Symbol  Int 
228+  valueList =  Map. fromList $  zip  (globalSymbols ++  functionSymbols ++  constantSymbols) [0 .. ]
224229
225230 --  * T Y P E S
226231 --  all top level types, and all the types to construct them. (e.g. i8** -> i8, i8*, and i8**).
@@ -236,7 +241,7 @@ instance ToNBitCode (Maybe Ident, Module) where
236241
237242 --  |  Turn a set of Constant Values unto BitCode Records. 
238243 mkConstBlock  ::  HasCallStack 
239-  =>  [ V. Symbol]  --  ^  values that can be referenced. 
244+  =>  Map V. SymbolInt   --  ^  values that can be referenced. 
240245 ->  [V. Symbol ] --  ^  the constants to turn into BitCode 
241246 ->  [NBitCode ]
242247 mkConstBlock values consts |  length  consts >  0  =  [ mkBlock CONSTANTS  . 
@@ -252,7 +257,7 @@ instance ToNBitCode (Maybe Ident, Module) where
252257 |  (V. Constant  t c) <-  V. symbolValue s
253258 =  (mkRec CC. CST_CODE_SETTYPE  (lookupTypeIndex typeList t ::  Int  )): mkConstRec values c: map  (mkConstRec values .  V. cConst .  V. symbolValue) cs
254259 |  otherwise  =  error  $  " Invalid constant "   ++  show  s
255-  mkConstRec  ::  HasCallStack  =>  [ V. Symbol]  ->  V. Const  ->  NBitCode 
260+  mkConstRec  ::  HasCallStack  =>  Map V. SymbolInt   ->  V. Const  ->  NBitCode 
256261 mkConstRec constantSymbols V. Null  =  mkEmptyRec CC. CST_CODE_NULL
257262 mkConstRec constantSymbols V. Undef  =  mkEmptyRec CC. CST_CODE_UNDEF
258263 mkConstRec constantSymbols (V. Int  n) =  mkRec CC. CST_CODE_INTEGER  (fromSigned n)
@@ -319,18 +324,18 @@ instance ToNBitCode (Maybe Ident, Module) where
319324 mkFunctionRec  ::  HasCallStack  =>  V. Value  ->  NBitCode 
320325 mkFunctionRec (V. Function {.. }) =  mkRec MC. FUNCTION  [ lookupTypeIndex typeList t --  NOTE: Similar to Globals we store the pointee type.
321326 , fromEnum' fCallingConv
322-  , bool fIsProto 
327+  , bool ( V. feProto fExtra) 
323328 , fromEnum' fLinkage
324329 , fParamAttrs
325330 , fAlignment
326331 , fSection
327332 , fromEnum' fVisibility
328333 , fGC
329334 , bool fUnnamedAddr
330-  , fromMaybe 0  ((+ 1 ) .  lookupSymbolIndex valueList <$>  fPrologueData )
335+  , fromMaybe 0  ((+ 1 ) .  lookupSymbolIndex valueList <$>  ( V. fePrologueData fExtra) )
331336 , fromEnum' fDLLStorageClass
332337 , fComdat
333-  , fromMaybe 0  ((+ 1 ) .  lookupSymbolIndex valueList <$>  fPrefixData )
338+  , fromMaybe 0  ((+ 1 ) .  lookupSymbolIndex valueList <$>  ( V. fePrefixData fExtra) )
334339 , fPersonalityFn
335340 ]
336341 where  (T. Ptr  _ t) =  fType
@@ -343,7 +348,7 @@ instance ToNBitCode (Maybe Ident, Module) where
343348 mkSymTabBlock syms =  mkBlock VALUE_SYMTAB  (catMaybes (map  mkSymTabRec namedIdxdSyms))
344349 where  namedIdxdSyms =  [(idx, name, value) |  (idx, (V. Named  name value)) <-  zip  [0 .. ] syms]
345350 mkSymTabRec  ::  (Int  , String  , V. Value ) ->  Maybe   NBitCode 
346-  mkSymTabRec (n, nm, (V. Function {.. })) |  fIsProto  =  Just  (mkRec VST. VST_CODE_ENTRY  (n: map  fromEnum  nm))
351+  mkSymTabRec (n, nm, (V. Function {.. })) |  V. feProto fExtra  =  Just  (mkRec VST. VST_CODE_ENTRY  (n: map  fromEnum  nm))
347352 --  LLVM 3.8 comes with FNENTRY, which has offset at the
348353 --  second position. This however requires computing the
349354 --  offset corret.
@@ -374,17 +379,23 @@ instance ToNBitCode (Maybe Ident, Module) where
374379 fArgs =  map  V. Unnamed  $  zipWith  V. Arg  fArgTys [0 .. ]
375380 --  function local constant
376381 fconstants  ::  [V. Symbol ]
377-  fconstants =  sortOn (V. cTy .  V. symbolValue) (filter  isConst consts)
382+  fconstants =  sortBy (T. typeCompare `on`  (V. cTy .  V. symbolValue))
383+  --  ignore any constants that are available globally already
384+  .  filter  (\ x ->  not  $  x `elem`  constantSymbols)
385+  --  only constants
386+  .  filter  isConst
387+  $  consts
378388 isConst  ::  V. Symbol  ->  Bool 
379389 isConst c |  (V. Constant {}) <-  V. symbolValue c =  True 
380390 |  otherwise  =  False 
381391 --  the values the body can reference.
382- bodyVals ::  [ V. Symbol ] 
392+ 383393 --  globals, functions, constants, (because we order them that way)
384394 --  plus fargs and fconstants per function body ontop of which are
385395 --  the references generated by the instructions will be placed.
386-  bodyVals =  valueList ++  fArgs ++  fconstants
387-  nBodyVals =  length  bodyVals
396+  bodyVals  ::  Map  V. Symbol  Int 
397+  bodyVals =  Map. unionWith (error  .  show ) valueList (Map. fromList $  zip  (fArgs ++  fconstants) [(Map. size valueList).. ])
398+  nBodyVals =  Map. size bodyVals
388399
389400 blockInstructions  ::  HasCallStack  =>  BasicBlock  ->  [I. Inst ]
390401 blockInstructions (BasicBlock  insts) =  map  snd  insts
@@ -394,7 +405,8 @@ instance ToNBitCode (Maybe Ident, Module) where
394405 instVals =  map  V. Unnamed  $  zipWith  V. TRef  [t |  Just  t <-  map  instTy (concatMap  blockInstructions bbs)] [0 .. ]
395406
396407 --  all values. This will be used to lookup indices for values in.
397-  allVals =  bodyVals ++  instVals
408+  allVals  ::  Map  V. Symbol  Int 
409+  allVals =  Map. unionWith (error  .  show ) bodyVals (Map. fromList $  zip  instVals [(Map. size bodyVals).. ])
398410
399411 --  These are in FromBitCode as well. TODO: Refactor move BitMasks into a common file.
400412 inAllocMask =  shift (1  ::  Int  ) 5 
@@ -403,14 +415,14 @@ instance ToNBitCode (Maybe Ident, Module) where
403415
404416 --  Relative Symbol lookup
405417 lookupRelativeSymbolIndex  ::  (HasCallStack , Integral   a )
406-  =>  [ V. Symbol]  --  ^  values prior to entering the instruction block 
418+  =>  Map V. SymbolInt   --  ^  values prior to entering the instruction block 
407419 ->  [V. Symbol ] --  ^  instruction values 
408420 ->  Int   --  ^  current instruction count 
409421 ->  V. Symbol  --  ^  the symbol to lookup 
410422 ->  a 
411423 lookupRelativeSymbolIndex vs ivs iN s =  fromIntegral  $  vN +  iN -  lookupSymbolIndex vals s
412-  where  vN =  length  vs
413-  vals =  vs ++ ivs
424+  where  vN =  Map. size  vs
425+  vals =  Map. unionWith ( error . show )  vs ( Map. fromList  $ zip ivs [vN .. ]) 
414426
415427 lookupRelativeSymbolIndex'  ::  (HasCallStack , Integral   a ) =>  Int   ->  V. Symbol  ->  a 
416428 lookupRelativeSymbolIndex' =  lookupRelativeSymbolIndex bodyVals instVals
0 commit comments