-
Notifications
You must be signed in to change notification settings - Fork 7
Add support for LLVM address spaces #280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
ee0163d
fa4236e
4a85f6f
c56e3da
80ccf1f
491fb19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| +1 −1 | llvm-pretty.cabal | |
| +5 −5 | src/Text/LLVM.hs | |
| +92 −23 | src/Text/LLVM/AST.hs | |
| +1 −1 | src/Text/LLVM/Labels.hs | |
| +55 −18 | src/Text/LLVM/PP.hs | |
| +8 −2 | src/Text/LLVM/Parser.hs | |
| +1 −1 | test/Output.hs |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,18 +50,37 @@ parseGlobalVar n r = label "GLOBALVAR" $ do | |
| vis <- if length (recordFields r) > (6 + offset) && not (link `elem` [Internal, Private]) | ||
| then field 6 visibility | ||
| else pure DefaultVisibility | ||
| tl <- if length (recordFields r) > (7 + offset) -- && not (link `elem` [Internal, Private]) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this comment be deleted? I think thread locality is parsed independently of the linkage, based on my reading of the LLVM implementation here. |
||
| then field 7 threadLocal | ||
| else pure NotThreadLocal | ||
|
|
||
| unnamed <- | ||
| if length (recordFields r) > (8 + offset) | ||
| then do | ||
| field 8 unnamedAddr | ||
| else return Nothing | ||
|
|
||
| addrspace <- if explicitTy | ||
| then return . AddrSpace . fromIntegral $ shiftR mask 2 | ||
| else case ptrty of | ||
| PtrTo as _ -> return as | ||
| PtrOpaque as -> return as | ||
| _ -> fail $ "Invalid type for value: " ++ show ptrty | ||
|
Comment on lines
+65
to
+68
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this |
||
|
|
||
| ty <- if explicitTy | ||
| then return ptrty | ||
| else elimPtrTo ptrty `mplus` (fail $ "Invalid type for value: " ++ show ptrty) | ||
|
|
||
| _ <- pushValue (Typed (PtrTo ty) (ValSymbol name)) | ||
| _ <- pushValue (Typed (PtrTo addrspace ty) (ValSymbol name)) | ||
| let valid | initid == 0 = Nothing | ||
| | otherwise = Just (initid - 1) | ||
| attrs = GlobalAttrs | ||
| { gaLinkage = Just link | ||
| , gaVisibility = Just vis | ||
| , gaConstant = isconst | ||
| { gaLinkage = Just link | ||
| , gaVisibility = Just vis | ||
| , gaThreadLocality = Just tl | ||
| , gaUnnamedAddr = unnamed | ||
| , gaConstant = isconst | ||
| , gaAddrSpace = addrspace | ||
| } | ||
|
|
||
| return PartialGlobal | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -116,11 +116,13 @@ parseTypeBlockEntry (fromEntry -> Just r) = case recordCode r of | |
| 8 -> label "TYPE_CODE_POINTER" $ do | ||
| let field = parseField r | ||
| ty <- field 0 typeRef | ||
| when (length (recordFields r) == 2) $ do | ||
| -- We do not currently store address spaces in the @llvm-pretty@ AST. | ||
| _space <- field 1 keep | ||
| return () | ||
| addType (PtrTo ty) | ||
| space <- AddrSpace <$> if length (recordFields r) == 2 | ||
| then | ||
| field 1 numeric | ||
| else | ||
| return 0 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another candidate for defaultAddrSpace, alhtough the |
||
|
|
||
| addType (PtrTo space ty) | ||
|
|
||
| -- [vararg, attrid, [retty, paramty x N]] | ||
| 9 -> label "TYPE_CODE_FUNCTION_OLD" $ do | ||
|
|
@@ -203,9 +205,8 @@ parseTypeBlockEntry (fromEntry -> Just r) = case recordCode r of | |
| let field = parseField r | ||
| when (length (recordFields r) /= 1) $ | ||
| fail "Invalid opaque pointer record" | ||
| -- We do not currently store address spaces in the @llvm-pretty@ AST. | ||
| _space <- field 0 keep | ||
| addType PtrOpaque | ||
| space <- AddrSpace <$> field 0 numeric | ||
| addType $ PtrOpaque space | ||
|
|
||
| 26 -> label "TYPE_CODE_TARGET_TYPE" $ do | ||
| notImplemented | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -111,9 +111,11 @@ data ParseState = ParseState | |||||
| , psNextResultId :: !Int | ||||||
| , psTypeName :: Maybe String | ||||||
| , psNextTypeId :: !Int | ||||||
| , psNextSymbolId :: !Int | ||||||
| , psLastLoc :: Maybe PDebugLoc | ||||||
| , psKinds :: !KindTable | ||||||
| , psModVersion :: !Int | ||||||
| , psDataLayout :: Maybe DataLayout | ||||||
| } deriving (Show) | ||||||
|
|
||||||
| -- | The initial parsing state. | ||||||
|
|
@@ -129,9 +131,11 @@ emptyParseState = ParseState | |||||
| , psNextResultId = 0 | ||||||
| , psTypeName = Nothing | ||||||
| , psNextTypeId = 0 | ||||||
| , psNextSymbolId = 0 | ||||||
| , psLastLoc = Nothing | ||||||
| , psKinds = emptyKindTable | ||||||
| , psModVersion = 0 | ||||||
| , psDataLayout = Nothing | ||||||
| } | ||||||
|
|
||||||
| -- | The next implicit result id. | ||||||
|
|
@@ -141,6 +145,14 @@ nextResultId = Parse $ do | |||||
| put ps { psNextResultId = psNextResultId ps + 1 } | ||||||
| return (psNextResultId ps) | ||||||
|
|
||||||
| -- | The next implicit result id. | ||||||
| nextSymbolId :: Parse Int | ||||||
| nextSymbolId = Parse $ do | ||||||
| ps <- get | ||||||
| put ps { psNextSymbolId = psNextSymbolId ps + 1 } | ||||||
| return (psNextSymbolId ps) | ||||||
|
|
||||||
|
|
||||||
| type PDebugLoc = DebugLoc' Int | ||||||
|
|
||||||
| setLastLoc :: PDebugLoc -> Parse () | ||||||
|
|
@@ -173,6 +185,22 @@ setModVersion v = Parse $ do | |||||
| getModVersion :: Parse Int | ||||||
| getModVersion = Parse (psModVersion <$> get) | ||||||
|
|
||||||
| setDataLayout :: DataLayout -> Parse () | ||||||
| setDataLayout v = Parse $ do | ||||||
| ps <- get | ||||||
| put $! ps { psDataLayout = Just v } | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| getDataLayout :: Parse (Maybe DataLayout) | ||||||
| getDataLayout = Parse (psDataLayout <$> get) | ||||||
|
|
||||||
| getDefaultFunctionAddrSpace :: Parse AddrSpace | ||||||
| getDefaultFunctionAddrSpace = | ||||||
| maybe (AddrSpace 0) programAddrSpace <$> getDataLayout | ||||||
|
|
||||||
| getDefaultAllocaAddrSpace :: Parse AddrSpace | ||||||
| getDefaultAllocaAddrSpace = | ||||||
| maybe (AddrSpace 0) allocaAddrSpace <$> getDataLayout | ||||||
|
|
||||||
| -- | Sort of a hack to preserve state between function body parses. It would | ||||||
| -- really be nice to separate this into a different monad, that could just run | ||||||
| -- under the Parse monad, but sort of unnecessary in the long run. | ||||||
|
|
@@ -449,14 +477,16 @@ setMdRefs refs = Parse $ do | |||||
| -- Function Prototypes --------------------------------------------------------- | ||||||
|
|
||||||
| data FunProto = FunProto | ||||||
| { protoType :: Type | ||||||
| , protoLinkage :: Maybe Linkage | ||||||
| , protoVisibility :: Maybe Visibility | ||||||
| , protoGC :: Maybe GC | ||||||
| , protoSym :: Symbol | ||||||
| , protoIndex :: Int | ||||||
| , protoSect :: Maybe String | ||||||
| , protoComdat :: Maybe String | ||||||
| { protoType :: Type | ||||||
| , protoLinkage :: Maybe Linkage | ||||||
| , protoVisibility :: Maybe Visibility | ||||||
| , protoUnnamedAddr :: Maybe UnnamedAddr | ||||||
| , protoGC :: Maybe GC | ||||||
| , protoSym :: Symbol | ||||||
| , protoIndex :: Int | ||||||
| , protoSect :: Maybe String | ||||||
| , protoComdat :: Maybe String | ||||||
| , protoAddrSpace :: AddrSpace | ||||||
| } deriving Show | ||||||
|
|
||||||
| -- | Push a function prototype on to the prototype stack. | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -182,5 +182,10 @@ oldOrStrtabName n r = do | |
| Just st -> do | ||
| offset <- parseField r 0 numeric | ||
| len <- parseField r 1 numeric | ||
| return (resolveStrtabSymbol st offset len, 2) | ||
| if len == 0 | ||
| then do | ||
| n <- show <$> nextSymbolId | ||
| return (Symbol n, 2) | ||
|
Comment on lines
+185
to
+188
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you leave some comments explaining what is going on in the |
||
| else | ||
| return (resolveStrtabSymbol st offset len, 2) | ||
| Nothing -> fail "New-style name encountered with no string table." | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would still be a sensible construct if they were not equal, but it hasn't been used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, that is tricky. Do you know what LLVM does here? If nothing else, it might be worth checking for an (opt-in)
assert.