1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
(*
Copyright (c) 2012, 2016-18 David C.J. Matthews
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License version 2.1 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*)
(* Intermediate code tree for the back end of the compiler. *)
signature BackendIntermediateCodeSig =
sig
type machineWord = Address.machineWord
datatype argumentType =
GeneralType
| DoubleFloatType
| SingleFloatType
structure BuiltIns: BUILTINS
datatype backendIC =
BICNewenv of bicCodeBinding list * backendIC (* Set of bindings with an expression. *)
| BICConstnt of machineWord * Universal.universal list (* Load a constant *)
| BICExtract of bicLoadForm (* Get a local variable, an argument or a closure value *)
| BICField of {base: backendIC, offset: int }
(* Load a field from a tuple or record *)
| BICEval of (* Evaluate a function with an argument list. *)
{
function: backendIC,
argList: (backendIC * argumentType) list,
resultType: argumentType
}
(* Built-in functions. *)
| BICUnary of {oper: BuiltIns.unaryOps, arg1: backendIC}
| BICBinary of {oper: BuiltIns.binaryOps, arg1: backendIC, arg2: backendIC}
| BICArbitrary of {oper: BuiltIns.arithmeticOperations, shortCond: backendIC, arg1: backendIC, arg2: backendIC, longCall: backendIC}
| BICLambda of bicLambdaForm (* Lambda expressions. *)
| BICCond of backendIC * backendIC * backendIC (* If-then-else expression *)
| BICCase of (* Case expressions *)
{
cases : backendIC option list, (* NONE means "jump to the default". *)
test : backendIC,
default : backendIC,
isExhaustive: bool,
firstIndex: word
}
| BICBeginLoop of (* Start of tail-recursive inline function. *)
{ loop: backendIC, arguments: (bicSimpleBinding * argumentType) list }
| BICLoop of (backendIC * argumentType) list (* Jump back to start of tail-recursive function. *)
| BICRaise of backendIC (* Raise an exception *)
| BICHandle of (* Exception handler. *) { exp: backendIC, handler: backendIC, exPacketAddr: int }
| BICTuple of backendIC list (* Tuple *)
| BICSetContainer of (* Copy a tuple to a container. *)
{
container: backendIC,
tuple: backendIC,
filter: BoolVector.vector
}
| BICLoadContainer of {base: backendIC, offset: int }
| BICTagTest of { test: backendIC, tag: word, maxTag: word }
| BICLoadOperation of { kind: loadStoreKind, address: bicAddress }
| BICStoreOperation of { kind: loadStoreKind, address: bicAddress, value: backendIC }
| BICBlockOperation of
{ kind: blockOpKind, sourceLeft: bicAddress, destRight: bicAddress, length: backendIC }
| BICGetThreadId
| BICAllocateWordMemory of {numWords: backendIC, flags: backendIC, initial: backendIC}
and bicCodeBinding =
BICDeclar of bicSimpleBinding (* Make a local declaration or push an argument *)
| BICRecDecs of { addr: int, lambda: bicLambdaForm } list (* Set of mutually recursive declarations. *)
| BICNullBinding of backendIC (* Just evaluate the expression and discard the result. *)
| BICDecContainer of { addr: int, size: int } (* Create a container for a tuple on the stack. *)
and caseType =
CaseWord (* Word or fixed-precision integer. *)
| CaseTag of word
and bicLoadForm =
BICLoadLocal of int (* Local binding *)
| BICLoadArgument of int (* Argument - 0 is first arg etc.*)
| BICLoadClosure of int (* Closure - 0 is first closure item etc *)
| BICLoadRecursive (* Recursive call *)
and loadStoreKind =
LoadStoreMLWord of {isImmutable: bool} (* Load/Store an ML word in an ML word cell. *)
| LoadStoreMLByte of {isImmutable: bool} (* Load/Store a byte, tagging and untagging as appropriate, in an ML byte cell. *)
| LoadStoreC8 (* Load/Store C values - The base address is a boxed SysWord.word value. *)
| LoadStoreC16
| LoadStoreC32
| LoadStoreC64
| LoadStoreCFloat
| LoadStoreCDouble
| LoadStoreUntaggedUnsigned
and blockOpKind =
BlockOpMove of {isByteMove: bool}
| BlockOpEqualByte
| BlockOpCompareByte
withtype bicSimpleBinding =
{ (* Declare a value or push an argument. *)
value: backendIC,
addr: int
}
and bicLambdaForm =
{ (* Lambda expressions. *)
body : backendIC,
name : string,
closure : bicLoadForm list,
argTypes : argumentType list,
resultType : argumentType,
localCount : int,
heapClosure : bool
}
and bicAddress =
(* Address form used in loads, store and block operations. The base is an ML
address if this is to/from ML memory or a (boxed) SysWord.word if it is
to/from C memory. The index is a value in units of the size of the item
being loaded/stored and the offset is always in bytes. *)
{base: backendIC, index: backendIC option, offset: word}
type pretty
val pretty : backendIC -> pretty
val loadStoreKindRepr: loadStoreKind -> string
and blockOpKindRepr: blockOpKind -> string
structure CodeTags:
sig
val tupleTag: Universal.universal list list Universal.tag
val mergeTupleProps:
Universal.universal list * Universal.universal list -> Universal.universal list
end
structure Sharing:
sig
type backendIC = backendIC
and bicLoadForm = bicLoadForm
and caseType = caseType
and pretty = pretty
and argumentType = argumentType
and bicCodeBinding = bicCodeBinding
and bicSimpleBinding = bicSimpleBinding
and loadStoreKind = loadStoreKind
and blockOpKind = blockOpKind
and unaryOps = BuiltIns.unaryOps
and binaryOps = BuiltIns.binaryOps
and testConditions = BuiltIns.testConditions
and arithmeticOperations = BuiltIns.arithmeticOperations
end
end;
|