summaryrefslogtreecommitdiff
path: root/compiler/llvmGen/Llvm
diff options
context:
space:
mode:
authorMichal Terepeta <michal.terepeta@gmail.com>2015-07-04 12:52:02 +0200
committerBen Gamari <ben@smart-cactus.org>2015-07-04 12:52:03 +0200
commitb1d1c652908ecd7bfcf13cf2e5dd06ac7926992c (patch)
tree376136663cd16de698e4c957b2da6ffb11381985 /compiler/llvmGen/Llvm
parent69beef56a4c020d08e1b0243d4c1a629f972e019 (diff)
downloadhaskell-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.hs8
-rw-r--r--compiler/llvmGen/Llvm/PpLlvm.hs7
-rw-r--r--compiler/llvmGen/Llvm/Types.hs14
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!"