diff options
author | Michal Terepeta <michal.terepeta@gmail.com> | 2015-07-04 12:52:02 +0200 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2015-07-04 12:52:03 +0200 |
commit | b1d1c652908ecd7bfcf13cf2e5dd06ac7926992c (patch) | |
tree | 376136663cd16de698e4c957b2da6ffb11381985 /compiler/llvmGen/Llvm | |
parent | 69beef56a4c020d08e1b0243d4c1a629f972e019 (diff) | |
download | haskell-b1d1c652908ecd7bfcf13cf2e5dd06ac7926992c.tar.gz |
Support MO_{Add,Sub}IntC and MO_Add2 in the LLVM backend
This includes:
- Adding new LlvmType called LMStructP that represents an unpacked
struct (this is necessary since LLVM's instructions the
llvm.sadd.with.overflow.* return an unpacked struct).
- Modifications to LlvmCodeGen.CodeGen to generate the LLVM
instructions for the primops.
- Modifications to StgCmmPrim to actually use those three instructions
if we use the LLVM backend (so far they were only used for NCG).
Test Plan: validate
Reviewers: austin, rwbarton, bgamari
Reviewed By: bgamari
Subscribers: thomie, bgamari
Differential Revision: https://phabricator.haskell.org/D991
GHC Trac Issues: #9430
Diffstat (limited to 'compiler/llvmGen/Llvm')
-rw-r--r-- | compiler/llvmGen/Llvm/AbsSyn.hs | 8 | ||||
-rw-r--r-- | compiler/llvmGen/Llvm/PpLlvm.hs | 7 | ||||
-rw-r--r-- | compiler/llvmGen/Llvm/Types.hs | 14 |
3 files changed, 28 insertions, 1 deletions
diff --git a/compiler/llvmGen/Llvm/AbsSyn.hs b/compiler/llvmGen/Llvm/AbsSyn.hs index b0eae2cbfe..8a53df00fe 100644 --- a/compiler/llvmGen/Llvm/AbsSyn.hs +++ b/compiler/llvmGen/Llvm/AbsSyn.hs @@ -209,6 +209,14 @@ data LlvmExpression | Extract LlvmVar LlvmVar {- | + Extract a scalar element from a structure + * val: The structure + * idx: The index of the scalar within the structure + Corresponds to "extractvalue" instruction. + -} + | ExtractV LlvmVar Int + + {- | Insert a scalar element into a vector * val: The source vector * elt: The scalar to insert diff --git a/compiler/llvmGen/Llvm/PpLlvm.hs b/compiler/llvmGen/Llvm/PpLlvm.hs index 0b3deac764..db9ef1fccf 100644 --- a/compiler/llvmGen/Llvm/PpLlvm.hs +++ b/compiler/llvmGen/Llvm/PpLlvm.hs @@ -239,6 +239,7 @@ ppLlvmExpression expr Cast op from to -> ppCast op from to Compare op left right -> ppCmpOp op left right Extract vec idx -> ppExtract vec idx + ExtractV struct idx -> ppExtractV struct idx Insert vec elt idx -> ppInsert vec elt idx GetElemPtr inb ptr indexes -> ppGetElementPtr inb ptr indexes Load ptr -> ppLoad ptr @@ -430,6 +431,12 @@ ppExtract vec idx = <+> ppr (getVarType vec) <+> ppName vec <> comma <+> ppr idx +ppExtractV :: LlvmVar -> Int -> SDoc +ppExtractV struct idx = + text "extractvalue" + <+> ppr (getVarType struct) <+> ppName struct <> comma + <+> ppr idx + ppInsert :: LlvmVar -> LlvmVar -> LlvmVar -> SDoc ppInsert vec elt idx = text "insertelement" diff --git a/compiler/llvmGen/Llvm/Types.hs b/compiler/llvmGen/Llvm/Types.hs index a9d81a1828..b3b173096b 100644 --- a/compiler/llvmGen/Llvm/Types.hs +++ b/compiler/llvmGen/Llvm/Types.hs @@ -50,7 +50,8 @@ data LlvmType | LMVector Int LlvmType -- ^ A vector of 'LlvmType' | LMLabel -- ^ A 'LlvmVar' can represent a label (address) | LMVoid -- ^ Void type - | LMStruct [LlvmType] -- ^ Structure type + | LMStruct [LlvmType] -- ^ Packed structure type + | LMStructU [LlvmType] -- ^ Unpacked structure type | LMAlias LlvmAlias -- ^ A type alias | LMMetadata -- ^ LLVM Metadata @@ -70,6 +71,7 @@ instance Outputable LlvmType where ppr (LMLabel ) = text "label" ppr (LMVoid ) = text "void" ppr (LMStruct tys ) = text "<{" <> ppCommaJoin tys <> text "}>" + ppr (LMStructU tys ) = text "{" <> ppCommaJoin tys <> text "}" ppr (LMMetadata ) = text "metadata" ppr (LMFunction (LlvmFunctionDecl _ _ _ r varg p _)) @@ -326,6 +328,16 @@ llvmWidthInBits dflags (LMVector n ty) = n * llvmWidthInBits dflags ty llvmWidthInBits _ LMLabel = 0 llvmWidthInBits _ LMVoid = 0 llvmWidthInBits dflags (LMStruct tys) = sum $ map (llvmWidthInBits dflags) tys +llvmWidthInBits _ (LMStructU _) = + -- It's not trivial to calculate the bit width of the unpacked structs, + -- since they will be aligned depending on the specified datalayout ( + -- http://llvm.org/docs/LangRef.html#data-layout ). One way we could support + -- this could be to make the LlvmCodeGen.Ppr.moduleLayout be a data type + -- that exposes the alignment information. However, currently the only place + -- we use unpacked structs is LLVM intrinsics that return them (e.g., + -- llvm.sadd.with.overflow.*), so we don't actually need to compute their + -- bit width. + panic "llvmWidthInBits: not implemented for LMStructU" llvmWidthInBits _ (LMFunction _) = 0 llvmWidthInBits dflags (LMAlias (_,t)) = llvmWidthInBits dflags t llvmWidthInBits _ LMMetadata = panic "llvmWidthInBits: Meta-data has no runtime representation!" |