2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "DFGCommon.h"
32 #include "FTLAbbreviations.h"
33 #include "FTLAbstractHeapRepository.h"
34 #include "FTLCommonValues.h"
35 #include "FTLIntrinsicRepository.h"
37 #include "FTLSwitchCase.h"
38 #include "FTLTypedPointer.h"
39 #include "FTLWeight.h"
40 #include "FTLWeightedTarget.h"
41 #include <wtf/StringPrintStream.h>
43 namespace JSC
{ namespace FTL
{
45 // Idiomatic LLVM IR builder specifically designed for FTL. This uses our own lowering
46 // terminology, and has some of its own notions:
48 // We say that a "reference" is what LLVM considers to be a "pointer". That is, it has
49 // an element type and can be passed directly to memory access instructions. Note that
50 // broadly speaking the users of FTL::Output should only use references for alloca'd
51 // slots for mutable local variables.
53 // We say that a "pointer" is what LLVM considers to be a pointer-width integer.
55 // We say that a "typed pointer" is a pointer that carries TBAA meta-data (i.e. an
56 // AbstractHeap). These should usually not have further computation performed on them
57 // prior to access, though there are exceptions (like offsetting into the payload of
58 // a typed pointer to a JSValue).
60 // We say that "get" and "set" are what LLVM considers to be "load" and "store". Get
61 // and set take references.
63 // We say that "load" and "store" are operations that take a typed pointer. These
64 // operations translate the pointer into a reference (or, a pointer in LLVM-speak),
65 // emit get or set on the reference (or, load and store in LLVM-speak), and apply the
66 // TBAA meta-data to the get or set.
68 enum Scale
{ ScaleOne
, ScaleTwo
, ScaleFour
, ScaleEight
, ScalePtr
};
70 class Output
: public IntrinsicRepository
{
75 void initialize(LModule
, LValue
, AbstractHeapRepository
&);
77 LBasicBlock
insertNewBlocksBefore(LBasicBlock nextBlock
)
79 LBasicBlock lastNextBlock
= m_nextBlock
;
80 m_nextBlock
= nextBlock
;
84 LBasicBlock
appendTo(LBasicBlock
, LBasicBlock nextBlock
);
86 void appendTo(LBasicBlock
);
88 LBasicBlock
newBlock(const char* name
= "");
90 LValue
param(unsigned index
) { return getParam(m_function
, index
); }
91 LValue
constBool(bool value
) { return constInt(boolean
, value
); }
92 LValue
constInt8(int8_t value
) { return constInt(int8
, value
); }
93 LValue
constInt32(int32_t value
) { return constInt(int32
, value
); }
95 LValue
constIntPtr(T
* value
) { return constInt(intPtr
, bitwise_cast
<intptr_t>(value
)); }
97 LValue
constIntPtr(T value
) { return constInt(intPtr
, static_cast<intptr_t>(value
)); }
98 LValue
constInt64(int64_t value
) { return constInt(int64
, value
); }
99 LValue
constDouble(double value
) { return constReal(doubleType
, value
); }
101 LValue
phi(LType type
) { return buildPhi(m_builder
, type
); }
102 template<typename
... Params
>
103 LValue
phi(LType type
, ValueFromBlock value
, Params
... theRest
)
105 LValue result
= phi(type
, theRest
...);
106 addIncoming(result
, value
);
109 template<typename VectorType
>
110 LValue
phi(LType type
, const VectorType
& vector
)
112 LValue result
= phi(type
);
113 for (unsigned i
= 0; i
< vector
.size(); ++i
)
114 addIncoming(result
, vector
[i
]);
118 LValue
add(LValue left
, LValue right
) { return buildAdd(m_builder
, left
, right
); }
119 LValue
sub(LValue left
, LValue right
) { return buildSub(m_builder
, left
, right
); }
120 LValue
mul(LValue left
, LValue right
) { return buildMul(m_builder
, left
, right
); }
121 LValue
div(LValue left
, LValue right
) { return buildDiv(m_builder
, left
, right
); }
122 LValue
rem(LValue left
, LValue right
) { return buildRem(m_builder
, left
, right
); }
123 LValue
neg(LValue value
) { return buildNeg(m_builder
, value
); }
125 LValue
doubleAdd(LValue left
, LValue right
) { return buildFAdd(m_builder
, left
, right
); }
126 LValue
doubleSub(LValue left
, LValue right
) { return buildFSub(m_builder
, left
, right
); }
127 LValue
doubleMul(LValue left
, LValue right
) { return buildFMul(m_builder
, left
, right
); }
128 LValue
doubleDiv(LValue left
, LValue right
) { return buildFDiv(m_builder
, left
, right
); }
129 LValue
doubleRem(LValue left
, LValue right
) { return buildFRem(m_builder
, left
, right
); }
130 LValue
doubleNeg(LValue value
) { return buildFNeg(m_builder
, value
); }
132 LValue
bitAnd(LValue left
, LValue right
) { return buildAnd(m_builder
, left
, right
); }
133 LValue
bitOr(LValue left
, LValue right
) { return buildOr(m_builder
, left
, right
); }
134 LValue
bitXor(LValue left
, LValue right
) { return buildXor(m_builder
, left
, right
); }
135 LValue
shl(LValue left
, LValue right
) { return buildShl(m_builder
, left
, right
); }
136 LValue
aShr(LValue left
, LValue right
) { return buildAShr(m_builder
, left
, right
); }
137 LValue
lShr(LValue left
, LValue right
) { return buildLShr(m_builder
, left
, right
); }
138 LValue
bitNot(LValue value
) { return buildNot(m_builder
, value
); }
140 LValue
insertElement(LValue vector
, LValue element
, LValue index
) { return buildInsertElement(m_builder
, vector
, element
, index
); }
142 LValue
addWithOverflow32(LValue left
, LValue right
)
144 return call(addWithOverflow32Intrinsic(), left
, right
);
146 LValue
subWithOverflow32(LValue left
, LValue right
)
148 return call(subWithOverflow32Intrinsic(), left
, right
);
150 LValue
mulWithOverflow32(LValue left
, LValue right
)
152 return call(mulWithOverflow32Intrinsic(), left
, right
);
154 LValue
addWithOverflow64(LValue left
, LValue right
)
156 return call(addWithOverflow64Intrinsic(), left
, right
);
158 LValue
subWithOverflow64(LValue left
, LValue right
)
160 return call(subWithOverflow64Intrinsic(), left
, right
);
162 LValue
mulWithOverflow64(LValue left
, LValue right
)
164 return call(mulWithOverflow64Intrinsic(), left
, right
);
166 LValue
doubleAbs(LValue value
)
168 return call(doubleAbsIntrinsic(), value
);
171 LValue
doubleSin(LValue value
)
173 return call(doubleSinIntrinsic(), value
);
175 LValue
doubleCos(LValue value
)
177 return call(doubleCosIntrinsic(), value
);
180 LValue
doubleSqrt(LValue value
)
182 return call(doubleSqrtIntrinsic(), value
);
185 static bool hasSensibleDoubleToInt() { return isX86(); }
186 LValue
sensibleDoubleToInt(LValue
);
188 LValue
signExt(LValue value
, LType type
) { return buildSExt(m_builder
, value
, type
); }
189 LValue
zeroExt(LValue value
, LType type
) { return buildZExt(m_builder
, value
, type
); }
190 LValue
fpToInt(LValue value
, LType type
) { return buildFPToSI(m_builder
, value
, type
); }
191 LValue
fpToUInt(LValue value
, LType type
) { return buildFPToUI(m_builder
, value
, type
); }
192 LValue
fpToInt32(LValue value
) { return fpToInt(value
, int32
); }
193 LValue
fpToUInt32(LValue value
) { return fpToUInt(value
, int32
); }
194 LValue
intToFP(LValue value
, LType type
) { return buildSIToFP(m_builder
, value
, type
); }
195 LValue
intToDouble(LValue value
) { return intToFP(value
, doubleType
); }
196 LValue
unsignedToFP(LValue value
, LType type
) { return buildUIToFP(m_builder
, value
, type
); }
197 LValue
unsignedToDouble(LValue value
) { return unsignedToFP(value
, doubleType
); }
198 LValue
intCast(LValue value
, LType type
) { return buildIntCast(m_builder
, value
, type
); }
199 LValue
castToInt32(LValue value
) { return intCast(value
, int32
); }
200 LValue
fpCast(LValue value
, LType type
) { return buildFPCast(m_builder
, value
, type
); }
201 LValue
intToPtr(LValue value
, LType type
) { return buildIntToPtr(m_builder
, value
, type
); }
202 LValue
ptrToInt(LValue value
, LType type
) { return buildPtrToInt(m_builder
, value
, type
); }
203 LValue
bitCast(LValue value
, LType type
) { return buildBitCast(m_builder
, value
, type
); }
205 LValue
alloca(LType type
) { return buildAlloca(m_builder
, type
); }
207 // Access the value of an alloca. Also used as a low-level implementation primitive for
208 // load(). Never use this to load from "pointers" in the FTL sense, since FTL pointers
209 // are actually integers. This requires an LLVM pointer. Broadly speaking, you don't
210 // have any LLVM pointers even if you really think you do. A TypedPointer is not an
211 // LLVM pointer. See comment block at top of this file to understand the distinction
212 // between LLVM pointers, FTL pointers, and FTL references.
213 LValue
get(LValue reference
) { return buildLoad(m_builder
, reference
); }
214 // Similar to get() but for storing to the value in an alloca.
215 LValue
set(LValue value
, LValue reference
) { return buildStore(m_builder
, value
, reference
); }
217 LValue
load(TypedPointer
, LType refType
);
218 void store(LValue
, TypedPointer
, LType refType
);
220 LValue
load8(TypedPointer pointer
) { return load(pointer
, ref8
); }
221 LValue
load16(TypedPointer pointer
) { return load(pointer
, ref16
); }
222 LValue
load32(TypedPointer pointer
) { return load(pointer
, ref32
); }
223 LValue
load64(TypedPointer pointer
) { return load(pointer
, ref64
); }
224 LValue
loadPtr(TypedPointer pointer
) { return load(pointer
, refPtr
); }
225 LValue
loadFloat(TypedPointer pointer
) { return load(pointer
, refFloat
); }
226 LValue
loadDouble(TypedPointer pointer
) { return load(pointer
, refDouble
); }
227 void store8(LValue value
, TypedPointer pointer
) { store(value
, pointer
, ref8
); }
228 void store16(LValue value
, TypedPointer pointer
) { store(value
, pointer
, ref16
); }
229 void store32(LValue value
, TypedPointer pointer
) { store(value
, pointer
, ref32
); }
230 void store64(LValue value
, TypedPointer pointer
) { store(value
, pointer
, ref64
); }
231 void storePtr(LValue value
, TypedPointer pointer
) { store(value
, pointer
, refPtr
); }
232 void storeFloat(LValue value
, TypedPointer pointer
) { store(value
, pointer
, refFloat
); }
233 void storeDouble(LValue value
, TypedPointer pointer
) { store(value
, pointer
, refDouble
); }
235 LValue
addPtr(LValue value
, ptrdiff_t immediate
= 0)
239 return add(value
, constIntPtr(immediate
));
242 // Construct an address by offsetting base by the requested amount and ascribing
243 // the requested abstract heap to it.
244 TypedPointer
address(const AbstractHeap
& heap
, LValue base
, ptrdiff_t offset
= 0)
246 return TypedPointer(heap
, addPtr(base
, offset
));
248 // Construct an address by offsetting base by the amount specified by the field,
249 // and optionally an additional amount (use this with care), and then creating
250 // a TypedPointer with the given field as the heap.
251 TypedPointer
address(LValue base
, const AbstractField
& field
, ptrdiff_t offset
= 0)
253 return address(field
, base
, offset
+ field
.offset());
256 LValue
baseIndex(LValue base
, LValue index
, Scale
, ptrdiff_t offset
= 0);
258 TypedPointer
baseIndex(const AbstractHeap
& heap
, LValue base
, LValue index
, Scale scale
, ptrdiff_t offset
= 0)
260 return TypedPointer(heap
, baseIndex(base
, index
, scale
, offset
));
262 TypedPointer
baseIndex(IndexedAbstractHeap
& heap
, LValue base
, LValue index
, JSValue indexAsConstant
= JSValue(), ptrdiff_t offset
= 0)
264 return heap
.baseIndex(*this, base
, index
, indexAsConstant
, offset
);
267 TypedPointer
absolute(void* address
)
269 return TypedPointer(m_heaps
->absolute
[address
], constIntPtr(address
));
272 LValue
load8(LValue base
, const AbstractField
& field
) { return load8(address(base
, field
)); }
273 LValue
load16(LValue base
, const AbstractField
& field
) { return load16(address(base
, field
)); }
274 LValue
load32(LValue base
, const AbstractField
& field
) { return load32(address(base
, field
)); }
275 LValue
load64(LValue base
, const AbstractField
& field
) { return load64(address(base
, field
)); }
276 LValue
loadPtr(LValue base
, const AbstractField
& field
) { return loadPtr(address(base
, field
)); }
277 LValue
loadDouble(LValue base
, const AbstractField
& field
) { return loadDouble(address(base
, field
)); }
278 void store8(LValue value
, LValue base
, const AbstractField
& field
) { store8(value
, address(base
, field
)); }
279 void store32(LValue value
, LValue base
, const AbstractField
& field
) { store32(value
, address(base
, field
)); }
280 void store64(LValue value
, LValue base
, const AbstractField
& field
) { store64(value
, address(base
, field
)); }
281 void storePtr(LValue value
, LValue base
, const AbstractField
& field
) { storePtr(value
, address(base
, field
)); }
282 void storeDouble(LValue value
, LValue base
, const AbstractField
& field
) { storeDouble(value
, address(base
, field
)); }
284 void ascribeRange(LValue loadInstruction
, const ValueRange
& range
)
286 range
.decorateInstruction(m_context
, loadInstruction
, rangeKind
);
289 LValue
nonNegative32(LValue loadInstruction
)
291 ascribeRange(loadInstruction
, nonNegativeInt32
);
292 return loadInstruction
;
295 LValue
load32NonNegative(TypedPointer pointer
) { return nonNegative32(load32(pointer
)); }
296 LValue
load32NonNegative(LValue base
, const AbstractField
& field
) { return nonNegative32(load32(base
, field
)); }
298 LValue
icmp(LIntPredicate cond
, LValue left
, LValue right
) { return buildICmp(m_builder
, cond
, left
, right
); }
299 LValue
equal(LValue left
, LValue right
) { return icmp(LLVMIntEQ
, left
, right
); }
300 LValue
notEqual(LValue left
, LValue right
) { return icmp(LLVMIntNE
, left
, right
); }
301 LValue
above(LValue left
, LValue right
) { return icmp(LLVMIntUGT
, left
, right
); }
302 LValue
aboveOrEqual(LValue left
, LValue right
) { return icmp(LLVMIntUGE
, left
, right
); }
303 LValue
below(LValue left
, LValue right
) { return icmp(LLVMIntULT
, left
, right
); }
304 LValue
belowOrEqual(LValue left
, LValue right
) { return icmp(LLVMIntULE
, left
, right
); }
305 LValue
greaterThan(LValue left
, LValue right
) { return icmp(LLVMIntSGT
, left
, right
); }
306 LValue
greaterThanOrEqual(LValue left
, LValue right
) { return icmp(LLVMIntSGE
, left
, right
); }
307 LValue
lessThan(LValue left
, LValue right
) { return icmp(LLVMIntSLT
, left
, right
); }
308 LValue
lessThanOrEqual(LValue left
, LValue right
) { return icmp(LLVMIntSLE
, left
, right
); }
310 LValue
fcmp(LRealPredicate cond
, LValue left
, LValue right
) { return buildFCmp(m_builder
, cond
, left
, right
); }
311 LValue
doubleEqual(LValue left
, LValue right
) { return fcmp(LLVMRealOEQ
, left
, right
); }
312 LValue
doubleNotEqualOrUnordered(LValue left
, LValue right
) { return fcmp(LLVMRealUNE
, left
, right
); }
313 LValue
doubleLessThan(LValue left
, LValue right
) { return fcmp(LLVMRealOLT
, left
, right
); }
314 LValue
doubleLessThanOrEqual(LValue left
, LValue right
) { return fcmp(LLVMRealOLE
, left
, right
); }
315 LValue
doubleGreaterThan(LValue left
, LValue right
) { return fcmp(LLVMRealOGT
, left
, right
); }
316 LValue
doubleGreaterThanOrEqual(LValue left
, LValue right
) { return fcmp(LLVMRealOGE
, left
, right
); }
317 LValue
doubleEqualOrUnordered(LValue left
, LValue right
) { return fcmp(LLVMRealUEQ
, left
, right
); }
318 LValue
doubleNotEqual(LValue left
, LValue right
) { return fcmp(LLVMRealONE
, left
, right
); }
319 LValue
doubleLessThanOrUnordered(LValue left
, LValue right
) { return fcmp(LLVMRealULT
, left
, right
); }
320 LValue
doubleLessThanOrEqualOrUnordered(LValue left
, LValue right
) { return fcmp(LLVMRealULE
, left
, right
); }
321 LValue
doubleGreaterThanOrUnordered(LValue left
, LValue right
) { return fcmp(LLVMRealUGT
, left
, right
); }
322 LValue
doubleGreaterThanOrEqualOrUnordered(LValue left
, LValue right
) { return fcmp(LLVMRealUGE
, left
, right
); }
324 LValue
isZero8(LValue value
) { return equal(value
, int8Zero
); }
325 LValue
notZero8(LValue value
) { return notEqual(value
, int8Zero
); }
326 LValue
isZero32(LValue value
) { return equal(value
, int32Zero
); }
327 LValue
notZero32(LValue value
) { return notEqual(value
, int32Zero
); }
328 LValue
isZero64(LValue value
) { return equal(value
, int64Zero
); }
329 LValue
notZero64(LValue value
) { return notEqual(value
, int64Zero
); }
330 LValue
isNull(LValue value
) { return equal(value
, intPtrZero
); }
331 LValue
notNull(LValue value
) { return notEqual(value
, intPtrZero
); }
333 LValue
testIsZero8(LValue value
, LValue mask
) { return isZero8(bitAnd(value
, mask
)); }
334 LValue
testNonZero8(LValue value
, LValue mask
) { return notZero8(bitAnd(value
, mask
)); }
335 LValue
testIsZero32(LValue value
, LValue mask
) { return isZero32(bitAnd(value
, mask
)); }
336 LValue
testNonZero32(LValue value
, LValue mask
) { return notZero32(bitAnd(value
, mask
)); }
337 LValue
testIsZero64(LValue value
, LValue mask
) { return isZero64(bitAnd(value
, mask
)); }
338 LValue
testNonZero64(LValue value
, LValue mask
) { return notZero64(bitAnd(value
, mask
)); }
340 LValue
select(LValue value
, LValue taken
, LValue notTaken
) { return buildSelect(m_builder
, value
, taken
, notTaken
); }
341 LValue
extractValue(LValue aggVal
, unsigned index
) { return buildExtractValue(m_builder
, aggVal
, index
); }
343 LValue
fence(LAtomicOrdering ordering
= LLVMAtomicOrderingSequentiallyConsistent
, SynchronizationScope scope
= CrossThread
) { return buildFence(m_builder
, ordering
, scope
); }
344 LValue
fenceAcqRel() { return fence(LLVMAtomicOrderingAcquireRelease
); }
346 template<typename VectorType
>
347 LValue
call(LValue function
, const VectorType
& vector
) { return buildCall(m_builder
, function
, vector
); }
348 LValue
call(LValue function
) { return buildCall(m_builder
, function
); }
349 LValue
call(LValue function
, LValue arg1
) { return buildCall(m_builder
, function
, arg1
); }
350 LValue
call(LValue function
, LValue arg1
, LValue arg2
) { return buildCall(m_builder
, function
, arg1
, arg2
); }
351 LValue
call(LValue function
, LValue arg1
, LValue arg2
, LValue arg3
) { return buildCall(m_builder
, function
, arg1
, arg2
, arg3
); }
352 LValue
call(LValue function
, LValue arg1
, LValue arg2
, LValue arg3
, LValue arg4
) { return buildCall(m_builder
, function
, arg1
, arg2
, arg3
, arg4
); }
353 LValue
call(LValue function
, LValue arg1
, LValue arg2
, LValue arg3
, LValue arg4
, LValue arg5
) { return buildCall(m_builder
, function
, arg1
, arg2
, arg3
, arg4
, arg5
); }
354 LValue
call(LValue function
, LValue arg1
, LValue arg2
, LValue arg3
, LValue arg4
, LValue arg5
, LValue arg6
) { return buildCall(m_builder
, function
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
); }
355 LValue
call(LValue function
, LValue arg1
, LValue arg2
, LValue arg3
, LValue arg4
, LValue arg5
, LValue arg6
, LValue arg7
) { return buildCall(m_builder
, function
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
); }
356 LValue
call(LValue function
, LValue arg1
, LValue arg2
, LValue arg3
, LValue arg4
, LValue arg5
, LValue arg6
, LValue arg7
, LValue arg8
) { return buildCall(m_builder
, function
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
, arg8
); }
358 template<typename FunctionType
>
359 LValue
operation(FunctionType function
)
361 return intToPtr(constIntPtr(function
), pointerType(operationType(function
)));
364 void jump(LBasicBlock destination
) { buildBr(m_builder
, destination
); }
365 void branch(LValue condition
, LBasicBlock taken
, Weight takenWeight
, LBasicBlock notTaken
, Weight notTakenWeight
);
366 void branch(LValue condition
, WeightedTarget taken
, WeightedTarget notTaken
)
368 branch(condition
, taken
.target(), taken
.weight(), notTaken
.target(), notTaken
.weight());
371 template<typename VectorType
>
372 void switchInstruction(LValue value
, const VectorType
& cases
, LBasicBlock fallThrough
, Weight fallThroughWeight
)
374 LValue inst
= buildSwitch(m_builder
, value
, cases
, fallThrough
);
377 if (!fallThroughWeight
)
379 total
+= fallThroughWeight
.value();
380 for (unsigned i
= cases
.size(); i
--;) {
381 if (!cases
[i
].weight())
383 total
+= cases
[i
].weight().value();
386 Vector
<LValue
> mdArgs
;
387 mdArgs
.append(branchWeights
);
388 mdArgs
.append(constInt32(fallThroughWeight
.scaleToTotal(total
)));
389 for (unsigned i
= 0; i
< cases
.size(); ++i
)
390 mdArgs
.append(constInt32(cases
[i
].weight().scaleToTotal(total
)));
392 setMetadata(inst
, profKind
, mdNode(m_context
, mdArgs
));
395 void ret(LValue value
) { buildRet(m_builder
, value
); }
397 void unreachable() { buildUnreachable(m_builder
); }
401 call(trapIntrinsic());
404 void crashNonTerminal();
412 ValueFromBlock
anchor(LValue value
)
414 return ValueFromBlock(value
, m_block
);
418 AbstractHeapRepository
* m_heaps
;
421 LBasicBlock m_nextBlock
;
424 #define FTL_NEW_BLOCK(output, nameArguments) \
425 (LIKELY(!verboseCompilationEnabled()) \
426 ? (output).newBlock() \
427 : (output).newBlock((toCString nameArguments).data()))
429 } } // namespace JSC::FTL
431 #endif // ENABLE(FTL_JIT)
433 #endif // FTLOutput_h