-------------------------------------------------------------------------------- -- | The LLVM abstract syntax. -- module Llvm.AbsSyn where import Llvm.MetaData import Llvm.Types import Unique -- | Block labels type LlvmBlockId = Unique -- | A block of LLVM code. data LlvmBlock = LlvmBlock { -- | The code label for this block blockLabel :: LlvmBlockId, -- | A list of LlvmStatement's representing the code for this block. -- This list must end with a control flow statement. blockStmts :: [LlvmStatement] } type LlvmBlocks = [LlvmBlock] -- | An LLVM Module. This is a top level container in LLVM. data LlvmModule = LlvmModule { -- | Comments to include at the start of the module. modComments :: [LMString], -- | LLVM Alias type definitions. modAliases :: [LlvmAlias], -- | LLVM meta data. modMeta :: [MetaDecl], -- | Global variables to include in the module. modGlobals :: [LMGlobal], -- | LLVM Functions used in this module but defined in other modules. modFwdDecls :: LlvmFunctionDecls, -- | LLVM Functions defined in this module. modFuncs :: LlvmFunctions } -- | An LLVM Function data LlvmFunction = LlvmFunction { -- | The signature of this declared function. funcDecl :: LlvmFunctionDecl, -- | The functions arguments funcArgs :: [LMString], -- | The function attributes. funcAttrs :: [LlvmFuncAttr], -- | The section to put the function into, funcSect :: LMSection, -- | The body of the functions. funcBody :: LlvmBlocks } type LlvmFunctions = [LlvmFunction] -- | LLVM ordering types for synchronization purposes. (Introduced in LLVM -- 3.0). Please see the LLVM documentation for a better description. data LlvmSyncOrdering -- | Some partial order of operations exists. = SyncUnord -- | A single total order for operations at a single address exists. | SyncMonotonic -- | Acquire synchronization operation. | SyncAcquire -- | Release synchronization operation. | SyncRelease -- | Acquire + Release synchronization operation. | SyncAcqRel -- | Full sequential Consistency operation. | SyncSeqCst deriving (Show, Eq) -- | Llvm Statements data LlvmStatement {- | Assign an expression to an variable: * dest: Variable to assign to * source: Source expression -} = Assignment LlvmVar LlvmExpression {- | Memory fence operation -} | Fence Bool LlvmSyncOrdering {- | Always branch to the target label -} | Branch LlvmVar {- | Branch to label targetTrue if cond is true otherwise to label targetFalse * cond: condition that will be tested, must be of type i1 * targetTrue: label to branch to if cond is true * targetFalse: label to branch to if cond is false -} | BranchIf LlvmVar LlvmVar LlvmVar {- | Comment Plain comment. -} | Comment [LMString] {- | Set a label on this position. * name: Identifier of this label, unique for this module -} | MkLabel LlvmBlockId {- | Store variable value in pointer ptr. If value is of type t then ptr must be of type t*. * value: Variable/Constant to store. * ptr: Location to store the value in -} | Store LlvmVar LlvmVar {- | Mutliway branch * scrutinee: Variable or constant which must be of integer type that is determines which arm is chosen. * def: The default label if there is no match in target. * target: A list of (value,label) where the value is an integer constant and label the corresponding label to jump to if the scrutinee matches the value. -} | Switch LlvmVar LlvmVar [(LlvmVar, LlvmVar)] {- | Return a result. * result: The variable or constant to return -} | Return (Maybe LlvmVar) {- | An instruction for the optimizer that the code following is not reachable -} | Unreachable {- | Raise an expression to a statement (if don't want result or want to use Llvm unnamed values. -} | Expr LlvmExpression {- | A nop LLVM statement. Useful as its often more efficient to use this then to wrap LLvmStatement in a Just or []. -} | Nop {- | A LLVM statement with metadata attached to it. -} | MetaStmt [MetaAnnot] LlvmStatement deriving (Eq) -- | Llvm Expressions data LlvmExpression {- | Allocate amount * sizeof(tp) bytes on the stack * tp: LlvmType to reserve room for * amount: The nr of tp's which must be allocated -} = Alloca LlvmType Int {- | Perform the machine operator op on the operands left and right * op: operator * left: left operand * right: right operand -} | LlvmOp LlvmMachOp LlvmVar LlvmVar {- | Perform a compare operation on the operands left and right * op: operator * left: left operand * right: right operand -} | Compare LlvmCmpOp LlvmVar LlvmVar {- | Extract a scalar element from a vector * val: The vector * idx: The index of the scalar within the vector -} | Extract LlvmVar LlvmVar {- | Insert a scalar element into a vector * val: The source vector * elt: The scalar to insert * index: The index at which to insert the scalar -} | Insert LlvmVar LlvmVar LlvmVar {- | Allocate amount * sizeof(tp) bytes on the heap * tp: LlvmType to reserve room for * amount: The nr of tp's which must be allocated -} | Malloc LlvmType Int {- | Load the value at location ptr -} | Load LlvmVar {- | Navigate in an structure, selecting elements * inbound: Is the pointer inbounds? (computed pointer doesn't overflow) * ptr: Location of the structure * indexes: A list of indexes to select the correct value. -} | GetElemPtr Bool LlvmVar [LlvmVar] {- | Cast the variable from to the to type. This is an abstraction of three cast operators in Llvm, inttoptr, prttoint and bitcast. * cast: Cast type * from: Variable to cast * to: type to cast to -} | Cast LlvmCastOp LlvmVar LlvmType {- | Call a function. The result is the value of the expression. * tailJumps: CallType to signal if the function should be tail called * fnptrval: An LLVM value containing a pointer to a function to be invoked. Can be indirect. Should be LMFunction type. * args: Concrete arguments for the parameters * attrs: A list of function attributes for the call. Only NoReturn, NoUnwind, ReadOnly and ReadNone are valid here. -} | Call LlvmCallType LlvmVar [LlvmVar] [LlvmFuncAttr] {- | Call a function as above but potentially taking metadata as arguments. * tailJumps: CallType to signal if the function should be tail called * fnptrval: An LLVM value containing a pointer to a function to be invoked. Can be indirect. Should be LMFunction type. * args: Arguments that may include metadata. * attrs: A list of function attributes for the call. Only NoReturn, NoUnwind, ReadOnly and ReadNone are valid here. -} | CallM LlvmCallType LlvmVar [MetaExpr] [LlvmFuncAttr] {- | Merge variables from different basic blocks which are predecessors of this basic block in a new variable of type tp. * tp: type of the merged variable, must match the types of the predecessor variables. * precessors: A list of variables and the basic block that they originate from. -} | Phi LlvmType [(LlvmVar,LlvmVar)] {- | Inline assembly expression. Syntax is very similar to the style used by GCC. * assembly: Actual inline assembly code. * constraints: Operand constraints. * return ty: Return type of function. * vars: Any variables involved in the assembly code. * sideeffect: Does the expression have side effects not visible from the constraints list. * alignstack: Should the stack be conservatively aligned before this expression is executed. -} | Asm LMString LMString LlvmType [LlvmVar] Bool Bool {- | A LLVM expression with metadata attached to it. -} | MExpr [MetaAnnot] LlvmExpression deriving (Eq)