[commit: ghc] wip/kavon-nosplit-llvm: fixing mangler issue that produced wrong RAs due to adjacent labels (027868b)
git at git.haskell.org
git at git.haskell.org
Tue Jun 27 09:17:00 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/kavon-nosplit-llvm
Link : http://ghc.haskell.org/trac/ghc/changeset/027868b8f240a6927ffe20f216ce194470872662/ghc
>---------------------------------------------------------------
commit 027868b8f240a6927ffe20f216ce194470872662
Author: Kavon Farvardin <kavon at farvard.in>
Date: Tue Jun 20 18:27:13 2017 +0100
fixing mangler issue that produced wrong RAs due to adjacent labels
>---------------------------------------------------------------
027868b8f240a6927ffe20f216ce194470872662
compiler/llvmGen/LlvmMangler.hs | 60 +++++++++++++++++++++++++++--------------
1 file changed, 40 insertions(+), 20 deletions(-)
diff --git a/compiler/llvmGen/LlvmMangler.hs b/compiler/llvmGen/LlvmMangler.hs
index 27f4a1f..bf17e86 100644
--- a/compiler/llvmGen/LlvmMangler.hs
+++ b/compiler/llvmGen/LlvmMangler.hs
@@ -38,24 +38,31 @@ import Data.Maybe ( fromMaybe )
type ManglerStr = [B.ByteString -> B.ByteString]
type ManglerInfo = Maybe (LabelMap ManglerStr)
+-- to manage the simple state machine for adjacent labels
+data State
+ = Default
+ | FirstLabel
+ | OtherLabel
+
-- | Read in assembly file and process
llvmFixupAsm :: DynFlags -> LabelMap ManglerStr -> FilePath -> FilePath -> IO ()
llvmFixupAsm dflags gcInfo f1 f2 = {-# SCC "llvm_mangler" #-}
withTiming (pure dflags) (text "LLVM Mangler") id $
withBinaryFile f1 ReadMode $ \r -> withBinaryFile f2 WriteMode $ \w -> do
- go r w
+ go r w Default
hClose r
hClose w
return ()
where
- doRewrite a = rewriteLine dflags (labRewrites gcInfo) rewrites a
+ doRewrite = rewriteLine dflags (labRewrites gcInfo) rewrites
- go :: Handle -> Handle -> IO ()
- go r w = do
+ go :: Handle -> Handle -> State -> IO ()
+ go r w s = do
e_l <- try $ B.hGetLine r ::IO (Either IOError B.ByteString)
- let writeline a = B.hPutStrLn w (doRewrite a) >> go r w
+ let writeline a s = let (newL, newS) = doRewrite a s in
+ B.hPutStrLn w newL >> go r w newS
case e_l of
- Right l -> writeline l
+ Right l -> writeline l s
Left _ -> return ()
-- | These are the non-label rewrites that the mangler will perform
@@ -63,21 +70,16 @@ rewrites :: [Rewrite]
rewrites = [rewriteSymType, rewriteAVX]
-- | These are the label-based rewrites that the mangler will perform
-labRewrites :: LabelMap ManglerStr -> [Rewrite]
+labRewrites :: LabelMap ManglerStr -> [LabRewrite]
labRewrites info = [addInfoTable info]
type Rewrite = DynFlags -> B.ByteString -> Maybe B.ByteString
-
--- XXX(kavon): debug only delete me later
-withComment :: String -> B.ByteString -> B.ByteString
-withComment com line = B.concat [B.pack $ wrap com, line]
- where
- wrap c = "## comment -- " ++ c ++ "\n"
+type LabRewrite = State -> Rewrite
-- | This rewrite looks for return points of a llvm.cpscall and adds GC info
-- above that label.
-addInfoTable :: LabelMap ManglerStr -> Rewrite
-addInfoTable info _ line = do
+addInfoTable :: LabelMap ManglerStr -> LabRewrite
+addInfoTable info FirstLabel _ line = do
retPt <- B.stripPrefix labPrefix line
(i, _) <- B.readInt retPt
statics <- mapLookup (toKey i) info
@@ -89,21 +91,35 @@ addInfoTable info _ line = do
colon = B.pack ":"
toKey = uniqueToLbl . intToUnique
+addInfoTable _ _ _ _ = Nothing
+
-- | Rewrite a line of assembly source with the given rewrites,
-- taking the first rewrite that applies for each kind of rewrite (label and non-label).
-rewriteLine :: DynFlags -> [Rewrite] -> [Rewrite] -> B.ByteString -> B.ByteString
-rewriteLine dflags labRewrites rewrites l =
+rewriteLine :: DynFlags -> [LabRewrite] -> [Rewrite] -> B.ByteString -> State -> (B.ByteString, State)
+rewriteLine dflags labRewrites rewrites l state = withState $
case (maybNewSym, maybNewRest) of
(Nothing, Nothing) -> l -- avoid concat
(newS, newR) -> cat (fromMaybe symbol newS) (fromMaybe rest newR)
where
+
+ -- the transition function of the state machine
+ withState l = (l, curState)
+ curState = case (isOnlyLabel split, state) of
+ (True, Default) -> FirstLabel
+ (True, FirstLabel) -> OtherLabel
+ (False, _) -> Default
+ _ -> state
+
cat sym rst = B.concat $ [sym, B.pack "\t", rst]
+ addState state rws = map (\rw -> rw state) rws
findRwOf txt rws = firstJust $ map (\rw -> rw dflags txt) rws
- (symbol, rest) = splitLine l
- maybNewSym = findRwOf symbol labRewrites -- check for new label part
- maybNewRest = findRwOf rest rewrites -- check for new non-label part
+ (split @ (symbol, rest)) = splitLine l
+ -- check for new label part
+ maybNewSym = findRwOf symbol $ addState curState labRewrites
+ -- check for new non-label part
+ maybNewRest = findRwOf rest rewrites
firstJust :: [Maybe a] -> Maybe a
firstJust (jx@(Just _):_) = jx
@@ -167,3 +183,7 @@ splitLine l = (symbol, B.dropWhile isSpace rest)
isSpace '\t' = True
isSpace _ = False
(symbol, rest) = B.span (not . isSpace) l
+
+isOnlyLabel :: (B.ByteString, B.ByteString) -> Bool
+isOnlyLabel (symbol, rest) =
+ (B.null rest || B.head rest == '#') && not (B.null symbol)
More information about the ghc-commits
mailing list