| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
LLVM.IR
Description
Main entry point for the ir-builder library.
A single import provides the complete public API for constructing, verifying, and rendering LLVM IR:
import LLVM.IR
This module re-exports the builder DSL, all instruction and type constructors, the IR data types, and the verification and rendering functions. Every sub-module remains directly importable for users who need more fine-grained control.
Quick start
Build an IR module containing a simple void function:
import LLVM.IR
example :: Text
example = compileModule "example" $
define void "hello" [] LExternal [] $ do
beginBlock "entry"
retVoid
Produces:
define void @hello() {
entry:
ret void
}
Run the builder with explicit error handling using compileModuleWith:
case compileModuleWith "example" builder of Left err -> putStrLn (displayError err) Right ir -> Data.Text.IO.putStr ir
Operand constants
Both LLVM.IRType.Constructors (re-exported here) and
LLVM.IROperand.Constructors export names like i32 and ptr — one as
a type, one as a constant-operand helper.
To avoid conflicts, LLVM.IROperand.Constructors is not re-exported. Import it qualified whenever you need constant operand helpers:
import LLVM.IR
import qualified LLVM.IROperand.Constructors as C
example :: IRBuilder ()
example =
define i32 "add" [(i32, "a"), (i32, "b")] LExternal [] $ do
beginBlock "entry"
r <- add i32 (C.i32 1) (C.i32 2)
ret r
Alternatively, use the OConstant and CInt constructors re-exported
from LLVM.IROperand directly:
ret (OConstant (CInt 32 0))
Key concepts
IRBuilder,IRBuilderT- The builder monad. Run it with
compileModule(produces LLVM assembly asText) orbuildModule(produces anIRModule). UsecompileModuleWithandbuildModuleWithforEither-based error handling. define- Declare a function. Takes return type, name,
[(type, paramName)]pairs,IRLinkage,[, and a monadic body computation.IRAttribute] beginBlock,block- Open a new basic block. Use
blockinsidemdonotation to capture the generated label for use as a branch target — see the extended example. - Instruction constructors
- Re-exported from LLVM.IRInstruction.Constructors. Each function (e.g.
add,load,icmp,phi,call) emits one instruction and returns the result as anIROperand. ret,br,condbr,switch,unreachable- Terminators from LLVM.IRTerminator.Constructors. Every basic block must end with exactly one terminator.
- Type constructors
- From LLVM.IRType.Constructors:
i1,i8,i16,i32,i64,i128,ptr,void,float,double,struct,array,vector,fun,named. emitAnnotation,comment,commentBlock- Emit a stand-alone comment into the current block.
commentandcommentBlockconstruct anIRAnnotationvalue to pass toemitAnnotation. (<##>),withComment- Attach an inline comment to an instruction.
(<##>)is the idiomatic operator form — postfix, reads left-to-right:
result <- add i32 a b <##> "note"
withComment is the equivalent function form, convenient with $:
result <- withComment "note" $ add i32 a b
OLocal,OGlobal,OConstant- Construct operands.
OLocalreferences a function parameter or previous instruction result by name —OLocal i32 "x"where"x"matches the declared parameter name or a binding captured with<-.OGlobalreferences a module-level value:OGlobal i64 "fact".OConstantwraps a constant:OConstant (CInt 32 0)orOConstant (CFloat 1.0). For brevity, use the helpers fromConstructorsimported qualified (e.g.C.i32 0,C.i64 1).
Invariants
The following rules must hold for every generated module:
- Every block needs a terminator. Each basic block must end with
exactly one of:
ret,retVoid,br,condbr,switch,unreachable. A block without a terminator raisesBlockMissingTerminatorat finalization. A block with two terminators raisesBlockAlreadyTerminated. - The first block is
"entry". Always callbeginBlock "entry"as the first statement inside everydefinebody. - Parameters are
OLocal. A parameter declared as[(i32, "x")]indefineis accessed asOLocal i32 "x". The name must match exactly. - Results are SSA bindings. Capture instruction results with
<-and pass theIROperandbinding directly. Never reconstruct a result from a name string. - Use
mdofor forward references. Enable{-# LANGUAGE RecursiveDo #-}and usemdowhen a phi source or branch target is a Haskell binding defined later in the block sequence. Usedowhen there are no such forward references. - Declare before calling. Invoke
declareordeclareVarArgbefore anycallorcallVoidon external functions. Duplicate declarations are silently ignored.
Extended example
An iterative factorial using mdo for forward block references. The
pattern loopLabel <- block "loop" captures the generated unique label
so it can be referenced in branch targets and phi nodes that appear
lexically earlier in the mdo block.
A phi node selects among its incoming pairs based on which predecessor
block control arrived from: phi ty [(v1, "lbl1"), (v2, "lbl2")] returns
v1 if the previous block was "lbl1", v2 if it was "lbl2".
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecursiveDo #-}
import LLVM.IR
import qualified LLVM.IROperand.Constructors as C
factorial :: Text
factorial = compileModule "mymod" $
define i64 "fact" [(i64, "n")] LExternal [] $ mdo
beginBlock "entry"
br loopLabel
loopLabel <- block "loop"
acc <- phi i64 [(C.i64 1, "entry"), (newAcc, bodyLabel)]
n <- phi i64 [(OLocal i64 "n", "entry"), (newN, bodyLabel)]
cond <- icmp ICmpSGt i64 n (C.i64 0)
condbr cond bodyLabel exitLabel
bodyLabel <- block "body"
newAcc <- mul i64 acc n
newN <- sub i64 n (C.i64 1)
br loopLabel
exitLabel <- block "exit"
ret acc
Module reference
- LLVM.IRBuilder
- Builder monad and compilation functions:
compileModule,buildModule,compileModuleWith,buildModuleWith,define,beginBlock,block,emitInstruction,emitAnnotation,emitTerminator,emitGlobal,emitTypeDecl,declare,declareVarArg, and the(<##>)inline-comment operator. - LLVM.IRBuilder.Error
IRBuilderErrortype anddisplayErrorfor programs that use explicit error handling viacompileModuleWithorbuildModuleWith.- LLVM.IRInstruction
- IR instruction data types and condition codes:
IRICmpCond,IRFCmpCond,IRTailMarker,IRInstrOp,IRInstruction. - LLVM.IRInstruction.Constructors
- Instruction smart constructors:
add,sub,mul,sdiv,udiv,load,store,gep,call,callVoid,icmp,fcmp,phi,select,bitcast,sext,zext,trunc,alloca,freeze,atomicRMW,cmpXchg,fence, and more. - LLVM.IRTerminator.Constructors
- Block terminators:
ret,retVoid,br,condbr,switch,unreachable. - LLVM.IRType
- The
IRTypealgebraic data type and theIRNametype alias (type IRName = Text). - LLVM.IRType.Constructors
- Type smart constructors:
i1,i8,i16,i32,i64,i128,ptr,void,float,double,struct,array,vector,fun,named. - LLVM.IRModule
- Module-level IR data types (
IRModule,IRFunction,IRBlock,IRGlobal,IRBlockItem) and validation (verifyModule,typeCheckModule).IRLinkagevalues:LExternal(visible outside module),LInternal(module-local),LPrivate(not in symbol table).IRAttributevalues:NoReturn,NoUnwind,ReadOnly,ReadNone,AlwaysInline,NoInline,TailCall,MustTailCall,Cold,Hot,InlineHint,NoAlias,GC "name". - LLVM.IROperand
- Operand and constant data types:
IROperand,IRConstant,IRTerminator. Helper functions:operandType,constantType,opComponents. - LLVM.IRAnnotation
- The
IRAnnotationtype (Comment,CommentBlock). - LLVM.IRAnnotation.Constructors
- Annotation helpers:
comment,commentBlock,withComment. The(<##>)operator comes fromIRBuilder. - LLVM.IROperand.Constructors
- Integer and floating-point operand
constants (
i32,i64,float,local,global, etc.). Not re-exported here — import this module qualified to avoid collisions with the type constructors above. - LLVM.IR.Examples
- Complete, runnable examples:
helloWorld,addNumbers, andfactorial.
Synopsis
- module LLVM.IRBuilder
- module LLVM.IRBuilder.Error
- data IRICmpCond
- data IRFCmpCond
- data IRTailMarker
- data IRInstrOp
- = IAShr IRType IROperand IROperand
- | IAdd IRType IROperand IROperand
- | IAlloca IRType IROperand
- | IAnd IRType IROperand IROperand
- | IBitcast IROperand IRType
- | ICall IRTailMarker IRType [IRType] Bool IROperand [IROperand]
- | IFAdd IRType IROperand IROperand
- | IFCmp IRFCmpCond IRType IROperand IROperand
- | IFDiv IRType IROperand IROperand
- | IFMul IRType IROperand IROperand
- | IFNeg IRType IROperand
- | IFSub IRType IROperand IROperand
- | IGep IRType IROperand [IROperand]
- | IICmp IRICmpCond IRType IROperand IROperand
- | IInttoptr IROperand IRType
- | ILShr IRType IROperand IROperand
- | ILoad IRType IROperand
- | IMul IRType IROperand IROperand
- | IOr IRType IROperand IROperand
- | IPhi IRType [(IROperand, IRName)]
- | IPtrtoint IROperand IRType
- | ISDiv IRType IROperand IROperand
- | ISRem IRType IROperand IROperand
- | ISelect IRType IROperand IROperand IROperand
- | ISext IROperand IRType
- | IShl IRType IROperand IROperand
- | IStore IROperand IROperand
- | ISub IRType IROperand IROperand
- | ITrunc IROperand IRType
- | IUDiv IRType IROperand IROperand
- | IURem IRType IROperand IROperand
- | IXOr IRType IROperand IROperand
- | IZext IROperand IRType
- | IExtractValue IROperand [Int]
- | IInsertValue IROperand IROperand [Int]
- | IExtractElement IROperand IROperand
- | IInsertElement IROperand IROperand IROperand
- | IShuffleVector IROperand IROperand [Int]
- | IAtomicRMW IRAtomicOrdering IRAtomicOp IROperand IROperand
- | ICmpXchg Bool IRAtomicOrdering IRAtomicOrdering IROperand IROperand IROperand
- | IFence IRAtomicOrdering
- | IFreeze IROperand
- data IRInstruction a = IRInstruction {
- instrResult :: Maybe (IRName, IRType)
- instrOp :: IRInstrOp
- instrMetadata :: a
- module LLVM.IRInstruction.Constructors
- module LLVM.IRTerminator.Constructors
- module LLVM.IRType
- module LLVM.IRType.Constructors
- module LLVM.IRModule
- module LLVM.IROperand
- module LLVM.IRAnnotation
- comment :: Text -> IRAnnotation
- commentBlock :: [Text] -> IRAnnotation
- withComment :: MonadIRBuilder m => Text -> m a -> m a
Builder monad and compilation
module LLVM.IRBuilder
module LLVM.IRBuilder.Error
Instruction types and condition codes
data IRICmpCond Source #
Condition codes for the icmp instruction.
Instances
| Show IRICmpCond Source # | |
Defined in LLVM.IRInstruction Methods showsPrec :: Int -> IRICmpCond -> ShowS # show :: IRICmpCond -> String # showList :: [IRICmpCond] -> ShowS # | |
| Eq IRICmpCond Source # | |
Defined in LLVM.IRInstruction | |
| Ord IRICmpCond Source # | |
Defined in LLVM.IRInstruction Methods compare :: IRICmpCond -> IRICmpCond -> Ordering # (<) :: IRICmpCond -> IRICmpCond -> Bool # (<=) :: IRICmpCond -> IRICmpCond -> Bool # (>) :: IRICmpCond -> IRICmpCond -> Bool # (>=) :: IRICmpCond -> IRICmpCond -> Bool # max :: IRICmpCond -> IRICmpCond -> IRICmpCond # min :: IRICmpCond -> IRICmpCond -> IRICmpCond # | |
data IRFCmpCond Source #
Condition codes for the fcmp instruction.
Constructors
| FCmpOEq | |
| FCmpOGt | |
| FCmpOGe | |
| FCmpOLt | |
| FCmpOLe | |
| FCmpONe | |
| FCmpUeq | |
| FCmpUGt | |
| FCmpUGe | |
| FCmpULt | |
| FCmpULe | |
| FCmpUNe | |
| FCmpOrd | |
| FCmpUno | |
| FCmpTrue | |
| FCmpFalse |
Instances
| Show IRFCmpCond Source # | |
Defined in LLVM.IRInstruction Methods showsPrec :: Int -> IRFCmpCond -> ShowS # show :: IRFCmpCond -> String # showList :: [IRFCmpCond] -> ShowS # | |
| Eq IRFCmpCond Source # | |
Defined in LLVM.IRInstruction | |
| Ord IRFCmpCond Source # | |
Defined in LLVM.IRInstruction Methods compare :: IRFCmpCond -> IRFCmpCond -> Ordering # (<) :: IRFCmpCond -> IRFCmpCond -> Bool # (<=) :: IRFCmpCond -> IRFCmpCond -> Bool # (>) :: IRFCmpCond -> IRFCmpCond -> Bool # (>=) :: IRFCmpCond -> IRFCmpCond -> Bool # max :: IRFCmpCond -> IRFCmpCond -> IRFCmpCond # min :: IRFCmpCond -> IRFCmpCond -> IRFCmpCond # | |
data IRTailMarker Source #
Instances
| Show IRTailMarker Source # | |
Defined in LLVM.IRInstruction Methods showsPrec :: Int -> IRTailMarker -> ShowS # show :: IRTailMarker -> String # showList :: [IRTailMarker] -> ShowS # | |
| Eq IRTailMarker Source # | |
Defined in LLVM.IRInstruction | |
| Ord IRTailMarker Source # | |
Defined in LLVM.IRInstruction Methods compare :: IRTailMarker -> IRTailMarker -> Ordering # (<) :: IRTailMarker -> IRTailMarker -> Bool # (<=) :: IRTailMarker -> IRTailMarker -> Bool # (>) :: IRTailMarker -> IRTailMarker -> Bool # (>=) :: IRTailMarker -> IRTailMarker -> Bool # max :: IRTailMarker -> IRTailMarker -> IRTailMarker # min :: IRTailMarker -> IRTailMarker -> IRTailMarker # | |
All supported IR instruction operations.
Constructors
Instances
| Show IRInstrOp Source # | |
| Eq IRInstrOp Source # | |
| Ord IRInstrOp Source # | |
data IRInstruction a Source #
Constructors
| IRInstruction | |
Fields
| |
Instances
| Show a => Show (IRInstruction a) Source # | |
Defined in LLVM.IRInstruction Methods showsPrec :: Int -> IRInstruction a -> ShowS # show :: IRInstruction a -> String # showList :: [IRInstruction a] -> ShowS # | |
| Eq a => Eq (IRInstruction a) Source # | |
Defined in LLVM.IRInstruction Methods (==) :: IRInstruction a -> IRInstruction a -> Bool # (/=) :: IRInstruction a -> IRInstruction a -> Bool # | |
| Ord a => Ord (IRInstruction a) Source # | |
Defined in LLVM.IRInstruction Methods compare :: IRInstruction a -> IRInstruction a -> Ordering # (<) :: IRInstruction a -> IRInstruction a -> Bool # (<=) :: IRInstruction a -> IRInstruction a -> Bool # (>) :: IRInstruction a -> IRInstruction a -> Bool # (>=) :: IRInstruction a -> IRInstruction a -> Bool # max :: IRInstruction a -> IRInstruction a -> IRInstruction a # min :: IRInstruction a -> IRInstruction a -> IRInstruction a # | |
Instruction constructors
Terminator constructors
Type system
module LLVM.IRType
module LLVM.IRType.Constructors
IR data types
module LLVM.IRModule
module LLVM.IROperand
Annotations
module LLVM.IRAnnotation
comment :: Text -> IRAnnotation Source #
Create a single-line comment annotation.
Example:
emitAnnotation (comment "This is a comment")
Output:
; This is a comment
commentBlock :: [Text] -> IRAnnotation Source #
Create a multi-line comment block annotation.
Example:
emitAnnotation (commentBlock ["Line 1", "Line 2", "Line 3"])
Output:
; Line 1 ; Line 2 ; Line 3
withComment :: MonadIRBuilder m => Text -> m a -> m a Source #
Attach an inline comment to the result of a builder action.
Example:
reg <- withComment "comment explaining this" $ add i32 a b
Output:
%reg = add i32 %a, %b ; comment explaining this